Skip to content

Sync Klipper#7001..#7052: motion_queuing + steppersync (fixes #744, #897)#932

Open
rogerlz wants to merge 67 commits into
mainfrom
klipper-pr-7001
Open

Sync Klipper#7001..#7052: motion_queuing + steppersync (fixes #744, #897)#932
rogerlz wants to merge 67 commits into
mainfrom
klipper-pr-7001

Conversation

@rogerlz

@rogerlz rogerlz commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Cherry-picks the full upstream chain that reworks host motion flushing and fixes the stepcompress history_list use-after-free (#744, #897 — crashes with MPC + Beacon/Cartographer readers). The actual fix is 414679ac9 (history clearing moved to the background thread), which requires the whole series:

Kalico integration:

  • All Kalico toolhead features relocated/preserved: RESET_VELOCITY_LIMIT + per-axis limited_* params in the new command helper, set_accel/reset_accel, danger_options (bgflush_extra_time hooks in motion_queuing, velocity-limit logging), homing current helpers, recon_mcu untouched, macOS serialqueue guards kept.
  • trad_rack updated to the current Annex-Engineering module (maintained against this exact architecture; the TR toolhead now participates via a motion_queuing flush callback). z_tilt_ng adapted to the new stepper_enable:motor_off event signature.
  • toolhead.wait_moves() generates all steps in batch mode so regression tests read deterministic positions.
  • generic_cartesian hunks dropped (Klipper#6815 not synced yet).

Test plan

  • pytest: 110 passed / 1 xfailed / 14 env-only failures (missing MCU dicts) — identical to main, including trad_rack, belay, mixing_extruder tests
  • Hardware battery on a Voron 2.4 (CoreXY, sensorless XY, Beacon, Pi 4 / py3.9): fresh chelper compile with the new step-generation threads, G28, sensorless rehome path, QGL, SET_VELOCITY_LIMIT/M204/RESET_VELOCITY_LIMIT, dry-run print via virtual_sdcard to completion, zero log errors, M84 + must-home enforcement

KevinOConnor and others added 30 commits July 14, 2026 19:44
Load these extra modules from add_printer_objects() instead.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
… class

Move the g-code command handlers to a new class.  This reduces the
size of the main Toolhead() class.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Timofey Titovets <nefelim4ag@gmail.com>
Change note_mcu_movequeue_activity() to default to setting the
step_gen_time (instead of the previous default to not set it).

Most users of the mcu "move queue" will be for stepper activity.
There is also little harm in incrementing the tracking of the last
possible step generation time, but accidentally generating a step
without incrementing the tracking can lead to very hard to debug
failures.

The two cases (output_pin.py and pwm_tool.py) where
note_mcu_movequeue_activity() is called and definitely not related to
step generation can explicitly pass 'is_step_gen=False'.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Create a new module to assist with host management of motion queues.
Register all MCU_stepper objects with this module and use the module
for step generation.

All steppers will now automatically generate steps whenever
toolhead._advance_flush_time() is invoked.  It is no longer necessary
for callers to individually call stepper.generate_steps().

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Add an allocate_trapq() helper function to facilitate the creation of
a low-level C trapq object.  Track all trapq objects and clear history
on them globally when the main motion queues are flushed.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Allocate the low-level C steppersync object from the motion_queuing
module.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Allocate the low-level C stepcompress object in the motion_queuing
module.  This simplifies the mcu.py code as it no longer needs to
track the stepqueues for the steppersync object.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Move register_flush_callback() from mcu.py code to motion_queuing
module.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Move the mcu.flush_moves() code to motion_queuing.flush_steppersync().

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Don't implement history expiration from the main steppersync_flush()
code.  Instead, have callers directly invoke
steppersync_history_expire().

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Move code from flush_steppersync() to existing flush_motion_queues()
and clean_motion_queues() functions.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Implement the 30 second clear_history_time offset checking directly in
the motion_queuing module.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
…_callback()

Use the existing register_flush_callback() system to implement motor
activity checking.  This simplifies the generate_steps() code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Pass in the 'struct stepcompress' reference to each call of
itersolve_generate_steps().

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Support storing a reference to 'struct stepper_kinematics' in 'struct
stepcompress' and support globally generating steps via the
steppersync mechanism.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Merge the clean_motion_queues() code into the existing
flush_motion_queues() code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Use the klippy package namespace import and apply Ruff formatting to the
new module introduced by the Klipper#7001 cherry-picks.

Signed-off-by: Rogerio Goncalves <rogerlz@gmail.com>
Track the kin_flush_delay in both toolhead.py and motion_queuing.py .

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Commit 3d3b87f renamed last_sg_flush_time to min_restart_time to
ensure that flush_step_generation() would fully flush out moves
generated from the force_move module.  However, now that force_move
calls note_mcu_movequeue_activity() with is_step_gen=True, this is no
longer necessary.

Rework min_restart_time to last_step_gen_time.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Automatically add kin_flush_delay to the requested flush time if
is_step_gen=True.  This simplifies the callers.

Also, rename self.step_gen_time to self.need_step_gen_time.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Move the code that implements flushing in waves from
_advance_move_time() to _advance_flush_time().  This also separates
print_time tracking from the _advance_flush_time() implementation.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
…head()

Separate out the lookahead specific flushing logic from the
_flush_handler() code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Separate out step generation specific handling from _calc_print_time()
code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Implement drip_update_time() using _advance_flush_time() instead of
_advance_move_time().

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
…odule

Move low-level step generation timing code to the motion_queing
module.  This helps simplify the toolhead module.  It also helps
centralize the step generation code into the motion_queing module.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Remove the toolhead note_step_generation_scan_time() code and
automatically detect the itersolve scan windows that are in use.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Move the "full flush" code from advance_flush_time() to a new
flush_all_steps() method.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
KevinOConnor and others added 25 commits July 14, 2026 21:25
If a stepper kinematics has a "scan window" defined during its first
flush then the iterative solver may walk past the head sentinel.  Set
a small negative print_time for the head sentinel to avoid this corner
case.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Don't tie the step generation logic to the toolhead lookahead logic.
Instead, use regular timers to generate steps with a goal of staying
500-750ms ahead of the micro-controllers.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
If a flush_all_steps() request is for a time far in the future, then
wait for that time to become close prior to flushing steps.  This
avoids committing to a step schedule that is far in the future.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
…ime()

Now that the host code does not flush far into the future, it is no
longer necessary to flush in waves.  Integrate _advance_flush_time()
into _flush_motion_queues().

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Use the next_batch_time even if it is slightly past or before the
ideal flushing window.  This should improve run to run reproducibility
of flush timing.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Further encourage flushing steps in batches by delaying flushing if a
batch isn't needed yet.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Avoid unnecessary reactor wakeups if a batch is close to being ready.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Only code movement - no code changes.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Add a new function for filling the fields of 'struct clock_estimate'.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Add a new C based mechanism for tracking all the 'struct steppersync'
instances.  This simplifies memory management.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Generate and flush all the steppersync instances from a single
steppersyncmgr_gen_steps() call.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
…_alloc()

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Create a new 'struct syncemitter' for each object that can generate
messages for a 'struct steppersync' and store in a regular linked
list.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Move msg_queue allocation from stepcompress to syncemitter.  With this
change the pwm_tool module does not need to allocate a stepcompress
object.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
…ersync.c

Implement step generation from 'struct syncemitter' instead of in the
stepcompress code.  This simplifies the stepcompress code and
simplifies the overall interface.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Callers can use syncemitter_queue_msg() instead.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Timofey Titovets <nefelim4ag@gmail.com>
Signed-off-by: Timofey Titovets <nefelim4ag@gmail.com>
Replace the vendored trad_rack module with the current version from
Annex-Engineering/TradRack (Kalico/klippy_module/trad_rack.py), which
is maintained against the new motion queuing architecture: the
TradRack toolhead participates in flushing via a motion_queuing flush
callback instead of running its own flush timeline, resolving the
incompatibility with global step generation. Imports adapted to the
klippy package namespace and Ruff formatting applied.

Signed-off-by: Rogerio Goncalves <rogerlz@gmail.com>
Restore the four-argument extruder_set_pressure_advance() definition,
add the extruder_stepper_free() and input_shaper_update_sk()
definitions, and free extruder kinematics via extruder_stepper_free()
to match the upstream chelper code brought in by the Klipper#7014 and
Klipper#7052 cherry-picks.

Signed-off-by: Rogerio Goncalves <rogerlz@gmail.com>
The C-side changes from the Klipper#7014 cherry-picks (time-based
pressure advance parameters, extruder_stepper_free(), and
input_shaper_update_sk()) were partially lost while resolving
conflicts; restore both files to the upstream state at the end of the
Klipper#7052 series (Kalico had no local changes in these files).

Signed-off-by: Rogerio Goncalves <rogerlz@gmail.com>
The stepper_enable:motor_off event no longer passes print_time after
the Klipper#7029 cherry-picks.

Signed-off-by: Rogerio Goncalves <rogerlz@gmail.com>
With the new motion queuing architecture the background flush
intentionally lags behind in debugoutput mode, so stepper position
queries right after an M400 could observe stale positions in the
klippy regression tests (eg, the mixing_extruder test). Flush all
pending steps before returning from wait_moves() when pausing is not
possible.

Signed-off-by: Rogerio Goncalves <rogerlz@gmail.com>
@rogerlz rogerlz changed the title Sync Klipper#7001: Simplify host motion flushing (motion_queuing) Sync Klipper#7001..#7052: motion_queuing + steppersync (fixes #744, #897) Jul 14, 2026
rogerlz added 2 commits July 14, 2026 22:11
The lambda formatting in the vendored module differs between the Ruff
version pinned in pre-commit (0.4.5) and the one used by CI (0.15.x);
use the shape both versions accept.

Signed-off-by: Rogerio Goncalves <rogerlz@gmail.com>
With clock calibration moved to motion_queuing.stats(), a disconnected
non-critical mcu gets calibrate_clock() -> _check_timeout() ->
handle_non_critical_disconnect() re-entered every stats tick (1s),
spamming "disconnected!" to the console, re-firing the disconnect
event and re-arming the reconnect timer. Return early if the
disconnect was already handled.

Verified on hardware (beacon usb unbind/rebind): one message per
disconnect, automatic reconnect and homing still work.

Signed-off-by: Rogerio Goncalves <rogerlz@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Segmentation Fault in stepcompress.c

4 participants