Commit Graph

120 Commits (e9e43f744d8be3c5821d4273ac8f62e13d933528)

Author SHA1 Message Date
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 fe621eb280 test_motion_ramp: improve robustness when checking multiple axes
When checking multiple axes together, also reconstruct the step rate, so
that subsequent checks do not fail randomly.
2021-08-30 07:10:54 +02:00
Yuri D'Elia e4af0717f6 test_ramp_gen: cosmetic fixes 2021-08-30 07:10:54 +02:00
Yuri D'Elia bb9e2a075b temp_motion_ramp: test single and multiple axes moving
stepTimerQuantum introduces discretization error, which makes the
acceleration curves noisy.

In rampgen generate ramps for a single moving axis in addition
of two axes moving together.

Then, in test_ramp_gen, test a single axis moving accurately, while
allow for some discretization error when two (or more) axes are running.
2021-08-30 07:10:54 +02:00
Yuri D'Elia 734612238e test_motion_ramp: do not skip tests
Remove a debugging left-over causing just the first ramp to be checked
2021-08-30 07:10:54 +02:00
Yuri D'Elia 1b0a67826a Improve motion::unit tests to handle fractional scaling
Pulley doesn't result in an exact step count due to the fractional
count.result in an exact step count due to the fractional count.

Use Selector instead to test values exacly.

Still check Pulley and Idler, but allowing for a +/-1 step of rounding
error.
2021-08-25 09:16:56 +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 f7f0df4afa Move hal/avr/tmc2130 into hal/ directly
There are no dependencies on AVR in TMC2130, so move into the main tree
2021-08-25 07:57:19 +02:00
Yuri D'Elia 6a9f2a2df9 Motion: test the middle driver's Enabled status too 2021-08-25 07:57:19 +02:00
Yuri D'Elia 0548c17078 Motion: test low-level enable changes via GPIO stub
This fixes the driver's enable/disable incorrectly setting the direction
bit instead.
2021-08-25 07:57:19 +02:00
Yuri D'Elia 8e24d1e084 Motion: Use an SPI stub in order to test TMC2130 2021-08-25 07:57:19 +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
Alex Voinea 36e63e678c Fix tests 2021-08-23 08:18:47 +02:00
Yuri D'Elia 0d1441b721 Skip motion::test_motion_ramp test if pandas is not installed 2021-08-12 17:50:07 +02:00
Yuri D'Elia d8454df5af Add rampgen as a dependency of tests 2021-08-12 17:50:07 +02:00
Yuri D'Elia 240f4c28ab Complete motion ramp checks
- Add additional information in the output generated by rampgen in order
  to allow recalculating the acceleration curves independently
- Implement motion ramp checks inside test_motion_ramp.py

test_motion_ramp reads the output of a merged stepping sequence and
splits the motion of each axis, checking the acceleration curves
independently.

This ensures both that the acceleration curves are correct (as generated
by the PulseGen class) and that the multiplexed moves are too.

The nominal rate is checked exactly, while the acceleration/deceleration
segment allow for some deviation from an ideal curve.

This is currently 5% for both expected speed and acceleration, with
an absolute limit of 20mm/s of maximum difference in each point.
2021-08-12 17:50:07 +02:00
Yuri D'Elia 89ab29dbde Move motion::dual_move_ramp into the separate motion::rampgen test
- Remove motion::dual_move_ramp from the Catch2 tests and reimplement
  it as a minimal c++ program for the ramp validation.
- Add a skeleton python validator to check the ramp output
- Use test "fixtures" to ensure the rampgen is run (both as a test,
  and to generate output) when the test_motion_ramp.py is requested.
2021-08-12 17:50:07 +02:00
Yuri D'Elia f37c9e363c Remove no-longer-needed operators import 2021-08-12 17:50:07 +02:00
D.R.racer 87d0f1c8f7 Add K1, 2, 3, 4 into unit tests 2021-08-12 10:55:27 +02:00
D.R.racer f0b8cc9895 Fix encoding of Query responses for high numbers of errors
+ improve unit tests directly for the enumerated errors in logic/error_codes.h
2021-08-12 10:55:27 +02:00
D.R.racer e0ea47595f Add unit tests for logic state machines reusal
as it will work in the real FW
2021-08-12 10:30:40 +02:00
D.R.racer 9ba116e06e Handle slot indices out of range correctly at top level
Besides Unload Filament, which only operates on active slot, all other
top level state machines check the validity of the command's parameter.
If the parameter is out of range for available slots, they return
ErrorCode::INVALID_TOOL now.
2021-08-12 10:30:40 +02:00
D.R.racer 2053729a75 Fix LED unit tests 2021-08-04 11:40:02 +02:00
D.R.racer 2f5dff6c5b Introduce short namespace aliases
especially for modules
2021-08-04 11:03:56 +02:00
D.R.racer 8694c53033 Fixes after rebase onto main 2021-08-02 10:52:18 +02:00
D.R.racer aa5995368d Update to latest main + fix unit tests
... in relation to the newly introduced stepping in physical units rather than in steps
2021-08-02 10:52:18 +02:00
D.R.racer 16dc129b49 Set real slot positions for the Idler and Selector
Extracted from the previous FW, may need some tuning based on units selected
for each of these axes (degrees, millimeters) - waiting for an update
of the motion implementation.

Updated starting conditions of the unit tests to reflect the global configuration.

MMU-58
2021-08-02 10:52:18 +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 751ee46450 Add bit masks for error codes for the TMC drivers
+ add common error handling for idler and selector
+ improve error handling in command_base
+ rename ERR1xxxx errors to ERRxxxx (remove the '1')
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
D.R.racer f5df642eb5 Improve error codes
- Distinguish among FINDA on/off failuje
- The same applies to newly introduced Filament sensor errors
- Add TMC init error
- Add a communication error ID - to be used on the printer
2021-08-02 07:45:45 +02:00
D.R.racer a8147be803 Fix unit tests + rebase onto main + extract TMC parameters into config 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
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 d955897829 Convert config::selectorSlotPositions to physical units 2021-07-25 23:13:28 +02:00
Yuri D'Elia 6daf7fd060 Convert config::idlerSlotPositions to physical units 2021-07-25 22:39:18 +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
D.R.racer f62cb99b13 Fix TMC2130 stub
so that motion unit tests build and run
2021-07-14 08:38:10 +02:00
Yuri D'Elia f28567a051 Motion tests: improve comments 2021-07-13 20:21:28 +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 4fd22f0656 Motion: add initial test infrastructure and stubs 2021-07-13 16:16:56 +02:00
Yuri D'Elia 18ced44341 Merge remote-tracking branch 'upstream/main' into motion_wip 2021-07-13 15:31:31 +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 16e7f62aee PulseGen: introduce CurPosition() for testing
CurPosition() returns the live axis position, which in this
implementation is inherently expensive to compute.

This shouldn't be required for the MMU, but it /will/ come in handy to
check for the axis position/s in Motion tests.
2021-07-13 00:48:44 +02:00
D.R.racer eed1c3f07a Fix buttons unit tests after ADC update 2021-07-12 18:01:57 +02:00
VintagePC 55637e6055 Fix pathing for gcovr 2021-07-12 12:50:06 +02:00