mirror of
https://github.com/andreili/klipper.git
synced 2025-09-14 17:31:12 +02:00
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 <kevin@koconnor.net>
This commit is contained in:
parent
d1974c0d3d
commit
5426943501
@ -56,6 +56,8 @@ defs_stepcompress = """
|
|||||||
, uint64_t start_clock, uint64_t end_clock);
|
, uint64_t start_clock, uint64_t end_clock);
|
||||||
void stepcompress_set_stepper_kinematics(struct stepcompress *sc
|
void stepcompress_set_stepper_kinematics(struct stepcompress *sc
|
||||||
, struct stepper_kinematics *sk);
|
, struct stepper_kinematics *sk);
|
||||||
|
struct stepper_kinematics *stepcompress_get_stepper_kinematics(
|
||||||
|
struct stepcompress *sc);
|
||||||
"""
|
"""
|
||||||
|
|
||||||
defs_steppersync = """
|
defs_steppersync = """
|
||||||
@ -76,11 +78,14 @@ defs_itersolve = """
|
|||||||
int32_t itersolve_is_active_axis(struct stepper_kinematics *sk, char axis);
|
int32_t itersolve_is_active_axis(struct stepper_kinematics *sk, char axis);
|
||||||
void itersolve_set_trapq(struct stepper_kinematics *sk, struct trapq *tq
|
void itersolve_set_trapq(struct stepper_kinematics *sk, struct trapq *tq
|
||||||
, double step_dist);
|
, double step_dist);
|
||||||
|
struct trapq *itersolve_get_trapq(struct stepper_kinematics *sk);
|
||||||
double itersolve_calc_position_from_coord(struct stepper_kinematics *sk
|
double itersolve_calc_position_from_coord(struct stepper_kinematics *sk
|
||||||
, double x, double y, double z);
|
, double x, double y, double z);
|
||||||
void itersolve_set_position(struct stepper_kinematics *sk
|
void itersolve_set_position(struct stepper_kinematics *sk
|
||||||
, double x, double y, double z);
|
, double x, double y, double z);
|
||||||
double itersolve_get_commanded_pos(struct stepper_kinematics *sk);
|
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 = """
|
defs_trapq = """
|
||||||
@ -157,8 +162,6 @@ defs_kin_extruder = """
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
defs_kin_shaper = """
|
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 input_shaper_set_shaper_params(struct stepper_kinematics *sk, char axis
|
||||||
, int n, double a[], double t[]);
|
, int n, double a[], double t[]);
|
||||||
int input_shaper_set_sk(struct stepper_kinematics *sk
|
int input_shaper_set_sk(struct stepper_kinematics *sk
|
||||||
|
@ -248,6 +248,12 @@ itersolve_set_trapq(struct stepper_kinematics *sk, struct trapq *tq
|
|||||||
sk->step_dist = step_dist;
|
sk->step_dist = step_dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct trapq * __visible
|
||||||
|
itersolve_get_trapq(struct stepper_kinematics *sk)
|
||||||
|
{
|
||||||
|
return sk->tq;
|
||||||
|
}
|
||||||
|
|
||||||
double __visible
|
double __visible
|
||||||
itersolve_calc_position_from_coord(struct stepper_kinematics *sk
|
itersolve_calc_position_from_coord(struct stepper_kinematics *sk
|
||||||
, double x, double y, double z)
|
, double x, double y, double z)
|
||||||
@ -273,3 +279,15 @@ itersolve_get_commanded_pos(struct stepper_kinematics *sk)
|
|||||||
{
|
{
|
||||||
return sk->commanded_pos;
|
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;
|
||||||
|
}
|
||||||
|
@ -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);
|
int32_t itersolve_is_active_axis(struct stepper_kinematics *sk, char axis);
|
||||||
void itersolve_set_trapq(struct stepper_kinematics *sk, struct trapq *tq
|
void itersolve_set_trapq(struct stepper_kinematics *sk, struct trapq *tq
|
||||||
, double step_dist);
|
, double step_dist);
|
||||||
|
struct trapq *itersolve_get_trapq(struct stepper_kinematics *sk);
|
||||||
double itersolve_calc_position_from_coord(struct stepper_kinematics *sk
|
double itersolve_calc_position_from_coord(struct stepper_kinematics *sk
|
||||||
, double x, double y, double z);
|
, double x, double y, double z);
|
||||||
void itersolve_set_position(struct stepper_kinematics *sk
|
void itersolve_set_position(struct stepper_kinematics *sk
|
||||||
, double x, double y, double z);
|
, double x, double y, double z);
|
||||||
double itersolve_get_commanded_pos(struct stepper_kinematics *sk);
|
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
|
#endif // itersolve.h
|
||||||
|
@ -239,14 +239,6 @@ input_shaper_set_shaper_params(struct stepper_kinematics *sk, char axis
|
|||||||
return status;
|
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
|
struct stepper_kinematics * __visible
|
||||||
input_shaper_alloc(void)
|
input_shaper_alloc(void)
|
||||||
{
|
{
|
||||||
|
@ -674,6 +674,13 @@ stepcompress_set_stepper_kinematics(struct stepcompress *sc
|
|||||||
sc->sk = sk;
|
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
|
// Generate steps (via itersolve) and flush
|
||||||
int32_t
|
int32_t
|
||||||
stepcompress_generate_steps(struct stepcompress *sc, double gen_steps_time
|
stepcompress_generate_steps(struct stepcompress *sc, double gen_steps_time
|
||||||
|
@ -41,6 +41,8 @@ int stepcompress_extract_old(struct stepcompress *sc
|
|||||||
struct stepper_kinematics;
|
struct stepper_kinematics;
|
||||||
void stepcompress_set_stepper_kinematics(struct stepcompress *sc
|
void stepcompress_set_stepper_kinematics(struct stepcompress *sc
|
||||||
, struct stepper_kinematics *sk);
|
, struct stepper_kinematics *sk);
|
||||||
|
struct stepper_kinematics *stepcompress_get_stepper_kinematics(
|
||||||
|
struct stepcompress *sc);
|
||||||
int32_t stepcompress_generate_steps(struct stepcompress *sc
|
int32_t stepcompress_generate_steps(struct stepcompress *sc
|
||||||
, double gen_steps_time
|
, double gen_steps_time
|
||||||
, uint64_t flush_clock);
|
, uint64_t flush_clock);
|
||||||
|
@ -146,12 +146,8 @@ class InputShaper:
|
|||||||
is_sk = self._get_input_shaper_stepper_kinematics(s)
|
is_sk = self._get_input_shaper_stepper_kinematics(s)
|
||||||
if is_sk is None:
|
if is_sk is None:
|
||||||
continue
|
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)
|
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):
|
def _update_input_shaping(self, error=None):
|
||||||
self.toolhead.flush_step_generation()
|
self.toolhead.flush_step_generation()
|
||||||
ffi_main, ffi_lib = chelper.get_ffi()
|
ffi_main, ffi_lib = chelper.get_ffi()
|
||||||
@ -163,16 +159,11 @@ class InputShaper:
|
|||||||
is_sk = self._get_input_shaper_stepper_kinematics(s)
|
is_sk = self._get_input_shaper_stepper_kinematics(s)
|
||||||
if is_sk is None:
|
if is_sk is None:
|
||||||
continue
|
continue
|
||||||
old_delay = ffi_lib.input_shaper_get_step_generation_window(is_sk)
|
|
||||||
for shaper in self.shapers:
|
for shaper in self.shapers:
|
||||||
if shaper in failed_shapers:
|
if shaper in failed_shapers:
|
||||||
continue
|
continue
|
||||||
if not shaper.set_shaper_kinematics(is_sk):
|
if not shaper.set_shaper_kinematics(is_sk):
|
||||||
failed_shapers.append(shaper)
|
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:
|
if failed_shapers:
|
||||||
error = error or self.printer.command_error
|
error = error or self.printer.command_error
|
||||||
raise error("Failed to configure shaper(s) %s with given parameters"
|
raise error("Failed to configure shaper(s) %s with given parameters"
|
||||||
|
@ -49,6 +49,7 @@ class PrinterMotionQueuing:
|
|||||||
if self.mcu.is_fileoutput():
|
if self.mcu.is_fileoutput():
|
||||||
self.can_pause = False
|
self.can_pause = False
|
||||||
# Kinematic step generation scan window time tracking
|
# Kinematic step generation scan window time tracking
|
||||||
|
self.need_calc_kin_flush_delay = True
|
||||||
self.kin_flush_delay = SDS_CHECK_TIME
|
self.kin_flush_delay = SDS_CHECK_TIME
|
||||||
# Register handlers
|
# Register handlers
|
||||||
printer.register_event_handler("klippy:shutdown", self._handle_shutdown)
|
printer.register_event_handler("klippy:shutdown", self._handle_shutdown)
|
||||||
@ -118,8 +119,6 @@ class PrinterMotionQueuing:
|
|||||||
def lookup_trapq_append(self):
|
def lookup_trapq_append(self):
|
||||||
ffi_main, ffi_lib = chelper.get_ffi()
|
ffi_main, ffi_lib = chelper.get_ffi()
|
||||||
return ffi_lib.trapq_append
|
return ffi_lib.trapq_append
|
||||||
def set_step_generate_scan_time(self, delay):
|
|
||||||
self.kin_flush_delay = delay
|
|
||||||
def stats(self, eventtime):
|
def stats(self, eventtime):
|
||||||
# Hack to globally invoke mcu check_active()
|
# Hack to globally invoke mcu check_active()
|
||||||
for m in self.all_mcus:
|
for m in self.all_mcus:
|
||||||
@ -128,6 +127,24 @@ class PrinterMotionQueuing:
|
|||||||
est_print_time = self.mcu.estimated_print_time(eventtime)
|
est_print_time = self.mcu.estimated_print_time(eventtime)
|
||||||
self.clear_history_time = est_print_time - MOVE_HISTORY_EXPIRE
|
self.clear_history_time = est_print_time - MOVE_HISTORY_EXPIRE
|
||||||
return False, ""
|
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
|
# Flush tracking
|
||||||
def _handle_shutdown(self):
|
def _handle_shutdown(self):
|
||||||
self.can_pause = False
|
self.can_pause = False
|
||||||
@ -137,6 +154,7 @@ class PrinterMotionQueuing:
|
|||||||
if target_time is None:
|
if target_time is None:
|
||||||
# This is a full flush
|
# This is a full flush
|
||||||
target_time = self.need_step_gen_time
|
target_time = self.need_step_gen_time
|
||||||
|
self.need_calc_kin_flush_delay = True
|
||||||
want_flush_time = want_step_gen_time = target_time
|
want_flush_time = want_step_gen_time = target_time
|
||||||
if lazy_target:
|
if lazy_target:
|
||||||
# Account for step gen scan windows and optimize step compression
|
# Account for step gen scan windows and optimize step compression
|
||||||
@ -162,6 +180,8 @@ class PrinterMotionQueuing:
|
|||||||
if flush_time >= want_flush_time:
|
if flush_time >= want_flush_time:
|
||||||
break
|
break
|
||||||
def calc_step_gen_restart(self, est_print_time):
|
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)
|
kin_time = max(est_print_time + MIN_KIN_TIME, self.last_step_gen_time)
|
||||||
return kin_time + self.kin_flush_delay
|
return kin_time + self.kin_flush_delay
|
||||||
def _flush_handler(self, eventtime):
|
def _flush_handler(self, eventtime):
|
||||||
|
@ -69,14 +69,16 @@ class ExtruderStepper:
|
|||||||
if not pressure_advance:
|
if not pressure_advance:
|
||||||
new_smooth_time = 0.
|
new_smooth_time = 0.
|
||||||
toolhead = self.printer.lookup_object("toolhead")
|
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()
|
ffi_main, ffi_lib = chelper.get_ffi()
|
||||||
espa = ffi_lib.extruder_set_pressure_advance
|
espa = ffi_lib.extruder_set_pressure_advance
|
||||||
toolhead.register_lookahead_callback(
|
if new_smooth_time != old_smooth_time:
|
||||||
lambda print_time: espa(self.sk_extruder, print_time,
|
# Need full kinematic flush to change the smooth time
|
||||||
pressure_advance, new_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 = pressure_advance
|
||||||
self.pressure_advance_smooth_time = smooth_time
|
self.pressure_advance_smooth_time = smooth_time
|
||||||
cmd_SET_PRESSURE_ADVANCE_help = "Set pressure advance parameters"
|
cmd_SET_PRESSURE_ADVANCE_help = "Set pressure advance parameters"
|
||||||
|
@ -193,7 +193,6 @@ class LookAheadQueue:
|
|||||||
BUFFER_TIME_LOW = 1.0
|
BUFFER_TIME_LOW = 1.0
|
||||||
BUFFER_TIME_HIGH = 2.0
|
BUFFER_TIME_HIGH = 2.0
|
||||||
BUFFER_TIME_START = 0.250
|
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
|
# Main code to track events (and their timing) on the printer toolhead
|
||||||
class ToolHead:
|
class ToolHead:
|
||||||
@ -225,9 +224,6 @@ class ToolHead:
|
|||||||
self.print_time = 0.
|
self.print_time = 0.
|
||||||
self.special_queuing_state = "NeedPrime"
|
self.special_queuing_state = "NeedPrime"
|
||||||
self.priming_timer = None
|
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
|
# Setup for generating moves
|
||||||
self.motion_queuing = self.printer.load_object(config, 'motion_queuing')
|
self.motion_queuing = self.printer.load_object(config, 'motion_queuing')
|
||||||
self.motion_queuing.setup_lookahead_flush_callback(
|
self.motion_queuing.setup_lookahead_flush_callback(
|
||||||
@ -469,7 +465,8 @@ class ToolHead:
|
|||||||
if move.move_d:
|
if move.move_d:
|
||||||
self.kin.check_move(move)
|
self.kin.check_move(move)
|
||||||
# Make sure stepper movement doesn't start before nominal start time
|
# 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
|
# Transmit move in "drip" mode
|
||||||
self._process_lookahead()
|
self._process_lookahead()
|
||||||
start_time, end_time = self._drip_load_trapq(move)
|
start_time, end_time = self._drip_load_trapq(move)
|
||||||
@ -510,15 +507,6 @@ class ToolHead:
|
|||||||
return self.kin
|
return self.kin
|
||||||
def get_trapq(self):
|
def get_trapq(self):
|
||||||
return self.trapq
|
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):
|
def register_lookahead_callback(self, callback):
|
||||||
last_move = self.lookahead.get_last()
|
last_move = self.lookahead.get_last()
|
||||||
if last_move is None:
|
if last_move is None:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user