From 5426943501bf716903d4797d334634c4b0e28e49 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Wed, 29 Nov 2023 01:04:28 -0500 Subject: [PATCH] motion_queuing: Automatically detect changes to kin_flush_delay 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 --- klippy/chelper/__init__.py | 7 +++++-- klippy/chelper/itersolve.c | 18 ++++++++++++++++++ klippy/chelper/itersolve.h | 3 +++ klippy/chelper/kin_shaper.c | 8 -------- klippy/chelper/stepcompress.c | 7 +++++++ klippy/chelper/stepcompress.h | 2 ++ klippy/extras/input_shaper.py | 11 +---------- klippy/extras/motion_queuing.py | 24 ++++++++++++++++++++++-- klippy/kinematics/extruder.py | 14 ++++++++------ klippy/toolhead.py | 16 ++-------------- 10 files changed, 68 insertions(+), 42 deletions(-) diff --git a/klippy/chelper/__init__.py b/klippy/chelper/__init__.py index 60ba91e7..59971c1c 100644 --- a/klippy/chelper/__init__.py +++ b/klippy/chelper/__init__.py @@ -56,6 +56,8 @@ defs_stepcompress = """ , uint64_t start_clock, uint64_t end_clock); void stepcompress_set_stepper_kinematics(struct stepcompress *sc , struct stepper_kinematics *sk); + struct stepper_kinematics *stepcompress_get_stepper_kinematics( + struct stepcompress *sc); """ defs_steppersync = """ @@ -76,11 +78,14 @@ defs_itersolve = """ int32_t itersolve_is_active_axis(struct stepper_kinematics *sk, char axis); void itersolve_set_trapq(struct stepper_kinematics *sk, struct trapq *tq , double step_dist); + struct trapq *itersolve_get_trapq(struct stepper_kinematics *sk); double itersolve_calc_position_from_coord(struct stepper_kinematics *sk , double x, double y, double z); void itersolve_set_position(struct stepper_kinematics *sk , double x, double y, double z); double itersolve_get_commanded_pos(struct stepper_kinematics *sk); + double itersolve_get_gen_steps_pre_active(struct stepper_kinematics *sk); + double itersolve_get_gen_steps_post_active(struct stepper_kinematics *sk); """ defs_trapq = """ @@ -157,8 +162,6 @@ defs_kin_extruder = """ """ defs_kin_shaper = """ - double input_shaper_get_step_generation_window( - struct stepper_kinematics *sk); int input_shaper_set_shaper_params(struct stepper_kinematics *sk, char axis , int n, double a[], double t[]); int input_shaper_set_sk(struct stepper_kinematics *sk diff --git a/klippy/chelper/itersolve.c b/klippy/chelper/itersolve.c index eba1deef..9b120624 100644 --- a/klippy/chelper/itersolve.c +++ b/klippy/chelper/itersolve.c @@ -248,6 +248,12 @@ itersolve_set_trapq(struct stepper_kinematics *sk, struct trapq *tq sk->step_dist = step_dist; } +struct trapq * __visible +itersolve_get_trapq(struct stepper_kinematics *sk) +{ + return sk->tq; +} + double __visible itersolve_calc_position_from_coord(struct stepper_kinematics *sk , double x, double y, double z) @@ -273,3 +279,15 @@ itersolve_get_commanded_pos(struct stepper_kinematics *sk) { return sk->commanded_pos; } + +double __visible +itersolve_get_gen_steps_pre_active(struct stepper_kinematics *sk) +{ + return sk->gen_steps_pre_active; +} + +double __visible +itersolve_get_gen_steps_post_active(struct stepper_kinematics *sk) +{ + return sk->gen_steps_post_active; +} diff --git a/klippy/chelper/itersolve.h b/klippy/chelper/itersolve.h index e2e46ebe..50a30f7d 100644 --- a/klippy/chelper/itersolve.h +++ b/klippy/chelper/itersolve.h @@ -31,10 +31,13 @@ double itersolve_check_active(struct stepper_kinematics *sk, double flush_time); int32_t itersolve_is_active_axis(struct stepper_kinematics *sk, char axis); void itersolve_set_trapq(struct stepper_kinematics *sk, struct trapq *tq , double step_dist); +struct trapq *itersolve_get_trapq(struct stepper_kinematics *sk); double itersolve_calc_position_from_coord(struct stepper_kinematics *sk , double x, double y, double z); void itersolve_set_position(struct stepper_kinematics *sk , double x, double y, double z); double itersolve_get_commanded_pos(struct stepper_kinematics *sk); +double itersolve_get_gen_steps_pre_active(struct stepper_kinematics *sk); +double itersolve_get_gen_steps_post_active(struct stepper_kinematics *sk); #endif // itersolve.h diff --git a/klippy/chelper/kin_shaper.c b/klippy/chelper/kin_shaper.c index 42d572d0..d5138ff0 100644 --- a/klippy/chelper/kin_shaper.c +++ b/klippy/chelper/kin_shaper.c @@ -239,14 +239,6 @@ input_shaper_set_shaper_params(struct stepper_kinematics *sk, char axis return status; } -double __visible -input_shaper_get_step_generation_window(struct stepper_kinematics *sk) -{ - struct input_shaper *is = container_of(sk, struct input_shaper, sk); - return is->sk.gen_steps_pre_active > is->sk.gen_steps_post_active - ? is->sk.gen_steps_pre_active : is->sk.gen_steps_post_active; -} - struct stepper_kinematics * __visible input_shaper_alloc(void) { diff --git a/klippy/chelper/stepcompress.c b/klippy/chelper/stepcompress.c index 2889570d..52dd4077 100644 --- a/klippy/chelper/stepcompress.c +++ b/klippy/chelper/stepcompress.c @@ -674,6 +674,13 @@ stepcompress_set_stepper_kinematics(struct stepcompress *sc sc->sk = sk; } +// Report current stepper_kinematics +struct stepper_kinematics * __visible +stepcompress_get_stepper_kinematics(struct stepcompress *sc) +{ + return sc->sk; +} + // Generate steps (via itersolve) and flush int32_t stepcompress_generate_steps(struct stepcompress *sc, double gen_steps_time diff --git a/klippy/chelper/stepcompress.h b/klippy/chelper/stepcompress.h index e21c4fd9..7ca0f2e4 100644 --- a/klippy/chelper/stepcompress.h +++ b/klippy/chelper/stepcompress.h @@ -41,6 +41,8 @@ int stepcompress_extract_old(struct stepcompress *sc struct stepper_kinematics; void stepcompress_set_stepper_kinematics(struct stepcompress *sc , struct stepper_kinematics *sk); +struct stepper_kinematics *stepcompress_get_stepper_kinematics( + struct stepcompress *sc); int32_t stepcompress_generate_steps(struct stepcompress *sc , double gen_steps_time , uint64_t flush_clock); diff --git a/klippy/extras/input_shaper.py b/klippy/extras/input_shaper.py index 67a287cd..cb9027d9 100644 --- a/klippy/extras/input_shaper.py +++ b/klippy/extras/input_shaper.py @@ -146,12 +146,8 @@ class InputShaper: is_sk = self._get_input_shaper_stepper_kinematics(s) if is_sk is None: continue - old_delay = ffi_lib.input_shaper_get_step_generation_window(is_sk) + self.toolhead.flush_step_generation() ffi_lib.input_shaper_update_sk(is_sk) - new_delay = ffi_lib.input_shaper_get_step_generation_window(is_sk) - if old_delay != new_delay: - self.toolhead.note_step_generation_scan_time(new_delay, - old_delay) def _update_input_shaping(self, error=None): self.toolhead.flush_step_generation() ffi_main, ffi_lib = chelper.get_ffi() @@ -163,16 +159,11 @@ class InputShaper: is_sk = self._get_input_shaper_stepper_kinematics(s) if is_sk is None: continue - old_delay = ffi_lib.input_shaper_get_step_generation_window(is_sk) for shaper in self.shapers: if shaper in failed_shapers: continue if not shaper.set_shaper_kinematics(is_sk): failed_shapers.append(shaper) - new_delay = ffi_lib.input_shaper_get_step_generation_window(is_sk) - if old_delay != new_delay: - self.toolhead.note_step_generation_scan_time(new_delay, - old_delay) if failed_shapers: error = error or self.printer.command_error raise error("Failed to configure shaper(s) %s with given parameters" diff --git a/klippy/extras/motion_queuing.py b/klippy/extras/motion_queuing.py index 226aa9f2..0b0981f1 100644 --- a/klippy/extras/motion_queuing.py +++ b/klippy/extras/motion_queuing.py @@ -49,6 +49,7 @@ class PrinterMotionQueuing: if self.mcu.is_fileoutput(): self.can_pause = False # Kinematic step generation scan window time tracking + self.need_calc_kin_flush_delay = True self.kin_flush_delay = SDS_CHECK_TIME # Register handlers printer.register_event_handler("klippy:shutdown", self._handle_shutdown) @@ -118,8 +119,6 @@ class PrinterMotionQueuing: def lookup_trapq_append(self): ffi_main, ffi_lib = chelper.get_ffi() return ffi_lib.trapq_append - def set_step_generate_scan_time(self, delay): - self.kin_flush_delay = delay def stats(self, eventtime): # Hack to globally invoke mcu check_active() for m in self.all_mcus: @@ -128,6 +127,24 @@ class PrinterMotionQueuing: est_print_time = self.mcu.estimated_print_time(eventtime) self.clear_history_time = est_print_time - MOVE_HISTORY_EXPIRE return False, "" + # Kinematic step generation scan window time tracking + def get_kin_flush_delay(self): + return self.kin_flush_delay + def _calc_kin_flush_delay(self): + self.need_calc_kin_flush_delay = False + ffi_main, ffi_lib = chelper.get_ffi() + kin_flush_delay = SDS_CHECK_TIME + for mcu, sc in self.stepcompress: + sk = ffi_lib.stepcompress_get_stepper_kinematics(sc) + if sk == ffi_main.NULL: + continue + trapq = ffi_lib.itersolve_get_trapq(sk) + if trapq == ffi_main.NULL: + continue + pre_active = ffi_lib.itersolve_get_gen_steps_pre_active(sk) + post_active = ffi_lib.itersolve_get_gen_steps_post_active(sk) + kin_flush_delay = max(kin_flush_delay, pre_active, post_active) + self.kin_flush_delay = kin_flush_delay # Flush tracking def _handle_shutdown(self): self.can_pause = False @@ -137,6 +154,7 @@ class PrinterMotionQueuing: if target_time is None: # This is a full flush target_time = self.need_step_gen_time + self.need_calc_kin_flush_delay = True want_flush_time = want_step_gen_time = target_time if lazy_target: # Account for step gen scan windows and optimize step compression @@ -162,6 +180,8 @@ class PrinterMotionQueuing: if flush_time >= want_flush_time: break def calc_step_gen_restart(self, est_print_time): + if self.need_calc_kin_flush_delay: + self._calc_kin_flush_delay() kin_time = max(est_print_time + MIN_KIN_TIME, self.last_step_gen_time) return kin_time + self.kin_flush_delay def _flush_handler(self, eventtime): diff --git a/klippy/kinematics/extruder.py b/klippy/kinematics/extruder.py index a89e3bdf..4e6f14e4 100644 --- a/klippy/kinematics/extruder.py +++ b/klippy/kinematics/extruder.py @@ -69,14 +69,16 @@ class ExtruderStepper: if not pressure_advance: new_smooth_time = 0. toolhead = self.printer.lookup_object("toolhead") - if new_smooth_time != old_smooth_time: - toolhead.note_step_generation_scan_time( - new_smooth_time * .5, old_delay=old_smooth_time * .5) ffi_main, ffi_lib = chelper.get_ffi() espa = ffi_lib.extruder_set_pressure_advance - toolhead.register_lookahead_callback( - lambda print_time: espa(self.sk_extruder, print_time, - pressure_advance, new_smooth_time)) + if new_smooth_time != old_smooth_time: + # Need full kinematic flush to change the smooth time + toolhead.flush_step_generation() + espa(self.sk_extruder, 0., pressure_advance, new_smooth_time) + else: + toolhead.register_lookahead_callback( + lambda print_time: espa(self.sk_extruder, print_time, + pressure_advance, new_smooth_time)) self.pressure_advance = pressure_advance self.pressure_advance_smooth_time = smooth_time cmd_SET_PRESSURE_ADVANCE_help = "Set pressure advance parameters" diff --git a/klippy/toolhead.py b/klippy/toolhead.py index 3eadbb3d..877e4f34 100644 --- a/klippy/toolhead.py +++ b/klippy/toolhead.py @@ -193,7 +193,6 @@ class LookAheadQueue: BUFFER_TIME_LOW = 1.0 BUFFER_TIME_HIGH = 2.0 BUFFER_TIME_START = 0.250 -SDS_CHECK_TIME = 0.001 # step+dir+step filter in stepcompress.c # Main code to track events (and their timing) on the printer toolhead class ToolHead: @@ -225,9 +224,6 @@ class ToolHead: self.print_time = 0. self.special_queuing_state = "NeedPrime" self.priming_timer = None - # Kinematic step generation scan window time tracking - self.kin_flush_delay = SDS_CHECK_TIME - self.kin_flush_times = [] # Setup for generating moves self.motion_queuing = self.printer.load_object(config, 'motion_queuing') self.motion_queuing.setup_lookahead_flush_callback( @@ -469,7 +465,8 @@ class ToolHead: if move.move_d: self.kin.check_move(move) # Make sure stepper movement doesn't start before nominal start time - self.dwell(self.kin_flush_delay) + kin_flush_delay = self.motion_queuing.get_kin_flush_delay() + self.dwell(kin_flush_delay) # Transmit move in "drip" mode self._process_lookahead() start_time, end_time = self._drip_load_trapq(move) @@ -510,15 +507,6 @@ class ToolHead: return self.kin def get_trapq(self): return self.trapq - def note_step_generation_scan_time(self, delay, old_delay=0.): - self.flush_step_generation() - if old_delay: - self.kin_flush_times.pop(self.kin_flush_times.index(old_delay)) - if delay: - self.kin_flush_times.append(delay) - new_delay = max(self.kin_flush_times + [SDS_CHECK_TIME]) - self.kin_flush_delay = new_delay - self.motion_queuing.set_step_generate_scan_time(new_delay) def register_lookahead_callback(self, callback): last_move = self.lookahead.get_last() if last_move is None: