Commit Graph

59 Commits (0fbcb9dac2853e74fedfa0f26306493d950c4526)

Author SHA1 Message Date
D.R.racer 0fbcb9dac2 Tag all source files with @file for doxygen 2021-10-18 17:59:46 +02:00
D.R.racer 1a5cd52d58 Fix some doxygen comments 2021-09-29 13:28:34 +02:00
Yuri D'Elia ad096c9d14 Motion: make Motion::Step finally inline 2021-09-07 15:09:49 +02:00
Yuri D'Elia b7fcfa5cb5 Add tests for single and multi-axis AbortPlannedMoves()
This introduces a new #define UNITTEST_MOTION which is used to control
the testing scenario:

- Normal tests, we allow the stub to override the built-in definition.
- For motion tests, we stub the lower-level classes and test the
  effective implementation

We also repeat the prototype of the function, which IMHO is more
readable and more flexible: we need to use inline for the real
definition, which would require even more macros otherwise.
2021-09-07 15:09:49 +02:00
D.R.racer 52a6d57704 Remove Motion::Home completely 2021-09-07 15:03:36 +02:00
Yuri D'Elia d18032b729 Motion: allow to abort movement on a single axis
This can be useful for things like faster homing in the future and comes
at no expense.
2021-09-07 14:48:06 +02:00
Yuri D'Elia 6f3540a14d Fix Motion::SetMode(axis, mode) and introduce SetMode(mode)
Motion::SetMode(axis, mode) was incorrectly looping through all axes,
setting the same axis three times.

Fix this and introduce Motion::SetMode(mode) which actually loops
through all axes (see PR #110)
2021-09-02 12:04:59 +02:00
D.R.racer 1d884d9099 Make motion::QueueEmpty inline for non-UNITTEST builds 2021-09-02 08:35:56 +02:00
D.R.racer ffe5bc2807 Make Idler and Selector only wait for their own axis
... and fix the unit tests for this
2021-09-02 08:35:56 +02:00
Yuri D'Elia 04631677cc Motion/PulseGen: implement move chaining and end-speed control
Allow to chain moves by adding one extra parameter to the PlanMove[to]
functions: ending speed.

A move will always be accelerated from the last speed towards end ending
speed. The following:

  PlanMove(100._mm, 50._mm_s, 50._mm_s);
  PlanMove(200._mm, 100._mm_s);

Will first move the axis 100mm, accelerating towards 50mm/s, then
accelerate again to 100mm/s. The move will for then decelerate towards a
full stop after reaching 300mm in total.

Acceleration can be changed for each segment, so that a custom
acceleration curve can be created:

  SetAcceleration(10._mm_s2);
  PlanMove(100._mm, 50._mm_s, 50._mm_s);
  SetAcceleration(100._mm_s2);
  PlanMove(100._mm, 50._mm_s, 50._mm_s);

The ending speed might not always be reached, depending on the current
acceleration settings. The new function "Rate()" will return the ending
feedrate of the last move, if necessary.

AbortPlannedMoves accepts a new "halt" parameter to control how moves
will be chanined when interrupting the current move. By default
(halt=true) the move is completely interrupted.

When halt=false is requested, a subsequent move will be chained starting
at the currently aborted velocity. This allows to chain moves in reponse
to events, for example to accelerate the pulley without stopping as soon
as the FINDA is triggered, it's sufficient to interrupt the current move
followed by a new one:

  PlanMove(maximum_loading_lenght, slow_feedrate);
  ... wait for PINDA trigger ...
  AbortPlannedMoves(true);
  PlanMove(bowden_lenght, fast_feedrate);

will seamlessy continue loading and transition to the fast feedrate.

Jerk control has been simplified. It now handles only the maximal
velocity change of the last segment, which doesn't require reverse
planning.
2021-08-30 12:49:34 +02:00
Yuri D'Elia d55e01bb58 Motion/PulseGen: allow to abort a move for chaining
Add a new parameter "halt" (default to true) to control the stopping
behavior:

- halt=true: no subsequent moves will be planned, motions stops abruptly
- half=false: a new move will be chained after the current one
2021-08-30 12:49:34 +02:00
Yuri D'Elia d18143dff2 PulseGen: store/return the last segment speed 2021-08-30 12:49:34 +02:00
Yuri D'Elia 60c83b0af2 Allow to set axis acceleration with AxisUnit and physical units 2021-08-30 12:49:34 +02:00
Yuri D'Elia 9c3b31756e Optimize timer multiplexing and increase stepTimerQuantum
Avoid calling PulseGen::Step() on idle axes by checking for a non-zero
queue size (which is more efficient to compute).

Increase stepTimerQuantum to 128us to ensure acceleration can be
computed in realtime for 3 axes at the same time.

Fix the logic of the static assertion, which was flipped: we need to
create slices larger than the maximal step frequency in order to ensure
no axis is starved while moving.
2021-08-30 07:10:54 +02:00
Yuri D'Elia c7f3fae266 Implement an initial Motion ISR for AVR
This is a tentative/crude implementation of an Init and ISR for the MMU
in order to check the motion API.

We remove the "extern void Isr", declaring it "static inline" instead.
We need to inline the ISR here in order to avoid the function call.

Include the missing speed_table data in the executable. This bumps the
code size to ~60% of the flash.

Implemement motion::Init to setup the ISR and timers, and replace the
call in main from tmc::Init to motion::Init. Motion will init each
driver every time the axis is enabled, so there should be no need for
a global module initialization (we need SPI, but this is initialized
earlier on by it's own module anyway).

The timer is currently setup without any HAL or proper TIMER1 wrapper.
This is to be improved later.

The real MMU unit seems to slow down quite a bit during acceleration.
At this point we need to inline some methods in PulseGen to avoid
overhead, however this breaks the stubs.
2021-08-27 10:13:23 +02:00
Yuri D'Elia 288e74283d Introduce config::MRes and fix (real) axis units
The parameter config::AxisConfig::uSteps was supposed to be
microstepping resolution, but it's instead being used as the driver's
MRES directly.

To avoid a runtime conversion, rename the field to mRes and define a new
enum listing all the possible (and valid) microstepping resolutions.

This simplifies the code and makes clear the stepsPerUnit scale.

Assign correct stepsPerUnit to all axes as a result, including working
limits.
2021-08-25 09:16:56 +02:00
Yuri D'Elia 9a93ebecfc Motion: add tests for the axis autoenable
Add Motion::Enabled() to get the current axis enablement status.
2021-08-25 07:57:19 +02:00
D.R.racer 2f5dff6c5b Introduce short namespace aliases
especially for modules
2021-08-04 11:03:56 +02:00
D.R.racer ef96d998a3 Link top level error reporting to TMC2130 error flags 2021-08-02 07:45:45 +02:00
D.R.racer df2c1ba7fe Add prototype of unified handling of HW errors in the logic layer 2021-08-02 07:45:45 +02:00
Alex Voinea 8577852b09 tmc2130: Stallguard and Isr 2021-07-29 10:01:33 +02:00
D.R.racer 3d1880c006 Make tests compile
Introduces a nasty hack to forcefully write into the constexpr SPI descriptor's registers
(which is the correct way in ASM, but kind of cumbersome in C++ now)
2021-07-29 10:01:33 +02:00
Alex Voinea 1022603f9d tmc2130: Initial spi communication 2021-07-29 10:01:33 +02:00
DRracer 151a672f56
Merge pull request #71 from wavexx/motion_units
Motion units
2021-07-27 06:34:32 +02:00
D.R.racer 7f39f07679 Avoid repeated Enable/Disable on an axis if already in desired state 2021-07-27 06:25:01 +02:00
DRracer dc36afb82c
Merge branch 'main' into motion_units 2021-07-26 09:35:13 +02:00
D.R.racer 6af65bc4c8 Rename ISR -> Isr to avoid clash with AVR libc ISR #define 2021-07-26 09:34:24 +02:00
Yuri D'Elia b133c8b975 Simplify and enhance unit conversion
- Move unit/step conversion to modules/axisunit.h
- Unify motion::unitToAxisUnit<> and motion::unitToSteps<>,
  making conversion in other modules just as easy as motion.
- Improve the documentation
2021-07-25 22:25:48 +02:00
Yuri D'Elia 402a2b91ce Define Motion::PlanMove/PlanMoveTo as constexpr 2021-07-25 17:08:15 +02:00
Yuri D'Elia 888cdf7cd5 Introduce compile-time axis unit type checks and conversions
Introduces:

- config::Unit: base class for physical quantities
- motion::AxisUnit: type-checked steps type

"config/unit.h" defines basic physical quantities, which are not
normally used elsewhere besides config.h.

"modules/axisunit.h" extends the modules::motion namespace with
Axis-aware units, with one type per axis per unit.

P_pos_t defines step positions for the pulley, I_pos_t for the idler,
etc. These are defined through the literar operators which are
similarly named and automatically convert a physical quantity to an
AxisUnit at compile time:

P_pos_t pulley_pos = 10.0_P_mm;

Besides type-checking, AxisUnit are otherwise identical to raw step
counts and are intended to be used along with the updated Motion API.

PlanMove/PlanMoveTo has been extended to support moves using these units
or physical quantities. Again, conversion is performed at compile time.
2021-07-25 16:39:54 +02:00
Yuri D'Elia 5e04d4ccaf Add getters/setters for Jerk in Motion/PulseGen
This allows us to make tests that expect jerk to be the same across two
axes, even if they're statically configured differently.
2021-07-25 01:24:40 +02:00
Yuri D'Elia 606b22a9ad Make Motion::Acceleration const 2021-07-25 01:17:25 +02:00
Yuri D'Elia 8f0732a0cc Motion: initial StallGuard support
Add the code in the right position to sample StallGuard and set/reset
the trigger flag.
2021-07-13 20:36:43 +02:00
Yuri D'Elia eec95d6fb7 Motion: add assertions for stepTimerQuantum 2021-07-13 19:40:00 +02:00
Yuri D'Elia 324fb92fd5 Motion: implement timer multiplexing 2021-07-13 19:21:13 +02:00
Yuri D'Elia d0581bf494 Motion: Add more methods and tests
- Add SetPosition/CurPosition (not only) for testing
- Implement some real tests
2021-07-13 17:43:50 +02:00
Yuri D'Elia 98845008aa Rename Motion::CurrentPos to Position()
This matches PulseGen::Position() and avoids confusion around the term
"current": Position() returns the head position in the queue, not the
"live" axis position.

We have PulseGen::CurPosition() now for this purpose, although we don't
expose it to Motion yet.
2021-07-13 01:03:03 +02:00
Yuri D'Elia 9b0dd2d633 Motion: fix new Step() prototype 2021-07-12 09:58:53 +02:00
Yuri D'Elia e53a91d563 Implement more methods in Motion, remove Motion::Full()
Motion::Full() (without a specific axis) is counter-productive.

When planning new moves the axis needs to be known beforehand, so it
might be as well be given to Full() to check the proper queue.
2021-07-11 22:07:23 +02:00
Yuri D'Elia 7337e97765 Rename Motion::DisableAxis to Disable
Implement Motion::SetEnabled (for symmetry with TMC2130::SetEnabled).

Rename DisableAxis to Disable and use the new SetEnabled. This makes the
member names more consistent.
2021-07-11 21:38:01 +02:00
Yuri D'Elia be30314634 Motion: initialize axes in the same order as the enumeration 2021-07-07 16:59:40 +02:00
Yuri D'Elia 2875e61484 Motion: allow to query the buffer per-axis
We might want to schedule new moves while a single motor is moving.
Allow to do that by introducing per-axis query functions.

The main QueueEmpty() and Full() still function as before:

- Call QueueEmpty() to wait for all moves to finish.
- Use !Full() to know that a Plan() move will never be discarded.
2021-07-07 16:59:40 +02:00
Yuri D'Elia bd8ae62211 PulseGen: cleanup AxisData initialization 2021-07-07 16:59:40 +02:00
Yuri D'Elia d87db1ff76 Revised WIP for the Motion API
- Remove the combined PlanMove(a,b,c,rate) call. If we allow the units
  of the various motors to be changed at compile time, the unit of
  rate can vary between axes.
- Build PlanMove on top of the absolute PlanMoveTo.
- Add required stubs for TMC2130.
- Allow each axis mode to be set independently, since we have this
  feature for free anyway.
- Rework internals to use PulseGen data types and structs.
2021-07-07 16:59:39 +02:00
Yuri D'Elia de88ed4c6b Add initial Axis configuration static structs 2021-07-07 16:59:04 +02:00
Yuri D'Elia ef7c776461 Update Motion for the new TMC2130/pins definitions 2021-07-07 16:59:04 +02:00
D.R.racer 4d6d6fe0af Add more checks (esp. positions of idler and selector)
that resulted in finding several weak spots and now Cut and Eject filament
do not pass the test (which is correct, they really have logical issues)
2021-06-21 10:28:56 +02:00
D.R.racer 3cb3cebed9 Add forced reinit of all automata for the unit tests
+ added a few constexpr to constructors on the way
2021-06-21 10:22:17 +02:00
D.R.racer b8f6bc9a4e Tune Feed to FINDA state machine and its unit test
so that it works as expected

Still, there is a task of resetting all of the state machines just for
the next unit test to be run.
2021-06-21 10:22:17 +02:00
D.R.racer f0a042c1b6 Add unit tests for Feed to FINDA state machine
+ improve infrastructure
2021-06-21 10:22:17 +02:00