mirror of
https://github.com/andreili/klipper.git
synced 2025-08-23 19:34:06 +02:00
stepcompress: Store a reference to 'struct stepper_kinematics'
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>
This commit is contained in:
parent
dd4cc8eb4c
commit
2919f37343
@ -54,6 +54,8 @@ defs_stepcompress = """
|
|||||||
int stepcompress_extract_old(struct stepcompress *sc
|
int stepcompress_extract_old(struct stepcompress *sc
|
||||||
, struct pull_history_steps *p, int max
|
, struct pull_history_steps *p, int max
|
||||||
, uint64_t start_clock, uint64_t end_clock);
|
, uint64_t start_clock, uint64_t end_clock);
|
||||||
|
void stepcompress_set_stepper_kinematics(struct stepcompress *sc
|
||||||
|
, struct stepper_kinematics *sk);
|
||||||
"""
|
"""
|
||||||
|
|
||||||
defs_steppersync = """
|
defs_steppersync = """
|
||||||
@ -62,13 +64,13 @@ defs_steppersync = """
|
|||||||
void steppersync_free(struct steppersync *ss);
|
void steppersync_free(struct steppersync *ss);
|
||||||
void steppersync_set_time(struct steppersync *ss
|
void steppersync_set_time(struct steppersync *ss
|
||||||
, double time_offset, double mcu_freq);
|
, double time_offset, double mcu_freq);
|
||||||
|
int32_t steppersync_generate_steps(struct steppersync *ss
|
||||||
|
, double gen_steps_time, uint64_t flush_clock);
|
||||||
void steppersync_history_expire(struct steppersync *ss, uint64_t end_clock);
|
void steppersync_history_expire(struct steppersync *ss, uint64_t end_clock);
|
||||||
int steppersync_flush(struct steppersync *ss, uint64_t move_clock);
|
int steppersync_flush(struct steppersync *ss, uint64_t move_clock);
|
||||||
"""
|
"""
|
||||||
|
|
||||||
defs_itersolve = """
|
defs_itersolve = """
|
||||||
int32_t itersolve_generate_steps(struct stepper_kinematics *sk
|
|
||||||
, struct stepcompress *sc, double flush_time);
|
|
||||||
double itersolve_check_active(struct stepper_kinematics *sk
|
double itersolve_check_active(struct stepper_kinematics *sk
|
||||||
, double flush_time);
|
, 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);
|
||||||
|
@ -143,7 +143,7 @@ check_active(struct stepper_kinematics *sk, struct move *m)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate step times for a range of moves on the trapq
|
// Generate step times for a range of moves on the trapq
|
||||||
int32_t __visible
|
int32_t
|
||||||
itersolve_generate_steps(struct stepper_kinematics *sk, struct stepcompress *sc
|
itersolve_generate_steps(struct stepper_kinematics *sk, struct stepcompress *sc
|
||||||
, double flush_time)
|
, double flush_time)
|
||||||
{
|
{
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <stdlib.h> // malloc
|
#include <stdlib.h> // malloc
|
||||||
#include <string.h> // memset
|
#include <string.h> // memset
|
||||||
#include "compiler.h" // DIV_ROUND_UP
|
#include "compiler.h" // DIV_ROUND_UP
|
||||||
|
#include "itersolve.h" // itersolve_generate_steps
|
||||||
#include "pyhelper.h" // errorf
|
#include "pyhelper.h" // errorf
|
||||||
#include "serialqueue.h" // struct queue_message
|
#include "serialqueue.h" // struct queue_message
|
||||||
#include "stepcompress.h" // stepcompress_alloc
|
#include "stepcompress.h" // stepcompress_alloc
|
||||||
@ -46,6 +47,8 @@ struct stepcompress {
|
|||||||
// History tracking
|
// History tracking
|
||||||
int64_t last_position;
|
int64_t last_position;
|
||||||
struct list_head history_list;
|
struct list_head history_list;
|
||||||
|
// Itersolve reference
|
||||||
|
struct stepper_kinematics *sk;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct step_move {
|
struct step_move {
|
||||||
@ -538,7 +541,7 @@ stepcompress_commit(struct stepcompress *sc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Flush pending steps
|
// Flush pending steps
|
||||||
int
|
static int
|
||||||
stepcompress_flush(struct stepcompress *sc, uint64_t move_clock)
|
stepcompress_flush(struct stepcompress *sc, uint64_t move_clock)
|
||||||
{
|
{
|
||||||
if (sc->next_step_clock && move_clock >= sc->next_step_clock) {
|
if (sc->next_step_clock && move_clock >= sc->next_step_clock) {
|
||||||
@ -662,3 +665,26 @@ stepcompress_extract_old(struct stepcompress *sc, struct pull_history_steps *p
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Store a reference to stepper_kinematics
|
||||||
|
void __visible
|
||||||
|
stepcompress_set_stepper_kinematics(struct stepcompress *sc
|
||||||
|
, struct stepper_kinematics *sk)
|
||||||
|
{
|
||||||
|
sc->sk = sk;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate steps (via itersolve) and flush
|
||||||
|
int32_t
|
||||||
|
stepcompress_generate_steps(struct stepcompress *sc, double gen_steps_time
|
||||||
|
, uint64_t flush_clock)
|
||||||
|
{
|
||||||
|
if (!sc->sk)
|
||||||
|
return 0;
|
||||||
|
// Generate steps
|
||||||
|
int32_t ret = itersolve_generate_steps(sc->sk, sc, gen_steps_time);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
// Flush steps
|
||||||
|
return stepcompress_flush(sc, flush_clock);
|
||||||
|
}
|
||||||
|
@ -27,7 +27,6 @@ void stepcompress_set_time(struct stepcompress *sc
|
|||||||
int stepcompress_append(struct stepcompress *sc, int sdir
|
int stepcompress_append(struct stepcompress *sc, int sdir
|
||||||
, double print_time, double step_time);
|
, double print_time, double step_time);
|
||||||
int stepcompress_commit(struct stepcompress *sc);
|
int stepcompress_commit(struct stepcompress *sc);
|
||||||
int stepcompress_flush(struct stepcompress *sc, uint64_t move_clock);
|
|
||||||
int stepcompress_reset(struct stepcompress *sc, uint64_t last_step_clock);
|
int stepcompress_reset(struct stepcompress *sc, uint64_t last_step_clock);
|
||||||
int stepcompress_set_last_position(struct stepcompress *sc, uint64_t clock
|
int stepcompress_set_last_position(struct stepcompress *sc, uint64_t clock
|
||||||
, int64_t last_position);
|
, int64_t last_position);
|
||||||
@ -39,5 +38,11 @@ int stepcompress_queue_mq_msg(struct stepcompress *sc, uint64_t req_clock
|
|||||||
int stepcompress_extract_old(struct stepcompress *sc
|
int stepcompress_extract_old(struct stepcompress *sc
|
||||||
, struct pull_history_steps *p, int max
|
, struct pull_history_steps *p, int max
|
||||||
, uint64_t start_clock, uint64_t end_clock);
|
, uint64_t start_clock, uint64_t end_clock);
|
||||||
|
struct stepper_kinematics;
|
||||||
|
void stepcompress_set_stepper_kinematics(struct stepcompress *sc
|
||||||
|
, struct stepper_kinematics *sk);
|
||||||
|
int32_t stepcompress_generate_steps(struct stepcompress *sc
|
||||||
|
, double gen_steps_time
|
||||||
|
, uint64_t flush_clock);
|
||||||
|
|
||||||
#endif // stepcompress.h
|
#endif // stepcompress.h
|
||||||
|
@ -76,6 +76,22 @@ steppersync_set_time(struct steppersync *ss, double time_offset
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate steps and flush stepcompress objects
|
||||||
|
int32_t __visible
|
||||||
|
steppersync_generate_steps(struct steppersync *ss, double gen_steps_time
|
||||||
|
, uint64_t flush_clock)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i=0; i<ss->sc_num; i++) {
|
||||||
|
struct stepcompress *sc = ss->sc_list[i];
|
||||||
|
int32_t ret = stepcompress_generate_steps(sc, gen_steps_time
|
||||||
|
, flush_clock);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Expire the stepcompress history before the given clock time
|
// Expire the stepcompress history before the given clock time
|
||||||
void __visible
|
void __visible
|
||||||
steppersync_history_expire(struct steppersync *ss, uint64_t end_clock)
|
steppersync_history_expire(struct steppersync *ss, uint64_t end_clock)
|
||||||
@ -116,14 +132,6 @@ heap_replace(struct steppersync *ss, uint64_t req_clock)
|
|||||||
int __visible
|
int __visible
|
||||||
steppersync_flush(struct steppersync *ss, uint64_t move_clock)
|
steppersync_flush(struct steppersync *ss, uint64_t move_clock)
|
||||||
{
|
{
|
||||||
// Flush each stepcompress to the specified move_clock
|
|
||||||
int i;
|
|
||||||
for (i=0; i<ss->sc_num; i++) {
|
|
||||||
int ret = stepcompress_flush(ss->sc_list[i], move_clock);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Order commands by the reqclock of each pending command
|
// Order commands by the reqclock of each pending command
|
||||||
struct list_head msgs;
|
struct list_head msgs;
|
||||||
list_init(&msgs);
|
list_init(&msgs);
|
||||||
@ -131,6 +139,7 @@ steppersync_flush(struct steppersync *ss, uint64_t move_clock)
|
|||||||
// Find message with lowest reqclock
|
// Find message with lowest reqclock
|
||||||
uint64_t req_clock = MAX_CLOCK;
|
uint64_t req_clock = MAX_CLOCK;
|
||||||
struct queue_message *qm = NULL;
|
struct queue_message *qm = NULL;
|
||||||
|
int i;
|
||||||
for (i=0; i<ss->sc_num; i++) {
|
for (i=0; i<ss->sc_num; i++) {
|
||||||
struct stepcompress *sc = ss->sc_list[i];
|
struct stepcompress *sc = ss->sc_list[i];
|
||||||
struct list_head *sc_mq = stepcompress_get_msg_queue(sc);
|
struct list_head *sc_mq = stepcompress_get_msg_queue(sc);
|
||||||
|
@ -10,6 +10,8 @@ struct steppersync *steppersync_alloc(
|
|||||||
void steppersync_free(struct steppersync *ss);
|
void steppersync_free(struct steppersync *ss);
|
||||||
void steppersync_set_time(struct steppersync *ss, double time_offset
|
void steppersync_set_time(struct steppersync *ss, double time_offset
|
||||||
, double mcu_freq);
|
, double mcu_freq);
|
||||||
|
int32_t steppersync_generate_steps(struct steppersync *ss, double gen_steps_time
|
||||||
|
, uint64_t flush_clock);
|
||||||
void steppersync_history_expire(struct steppersync *ss, uint64_t end_clock);
|
void steppersync_history_expire(struct steppersync *ss, uint64_t end_clock);
|
||||||
int steppersync_flush(struct steppersync *ss, uint64_t move_clock);
|
int steppersync_flush(struct steppersync *ss, uint64_t move_clock);
|
||||||
|
|
||||||
|
@ -11,13 +11,13 @@ MOVE_HISTORY_EXPIRE = 30.
|
|||||||
class PrinterMotionQueuing:
|
class PrinterMotionQueuing:
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
self.printer = config.get_printer()
|
self.printer = config.get_printer()
|
||||||
self.steppers = []
|
|
||||||
self.trapqs = []
|
self.trapqs = []
|
||||||
self.stepcompress = []
|
self.stepcompress = []
|
||||||
self.steppersyncs = []
|
self.steppersyncs = []
|
||||||
self.flush_callbacks = []
|
self.flush_callbacks = []
|
||||||
ffi_main, ffi_lib = chelper.get_ffi()
|
ffi_main, ffi_lib = chelper.get_ffi()
|
||||||
self.trapq_finalize_moves = ffi_lib.trapq_finalize_moves
|
self.trapq_finalize_moves = ffi_lib.trapq_finalize_moves
|
||||||
|
self.steppersync_generate_steps = ffi_lib.steppersync_generate_steps
|
||||||
self.steppersync_flush = ffi_lib.steppersync_flush
|
self.steppersync_flush = ffi_lib.steppersync_flush
|
||||||
self.steppersync_history_expire = ffi_lib.steppersync_history_expire
|
self.steppersync_history_expire = ffi_lib.steppersync_history_expire
|
||||||
self.clear_history_time = 0.
|
self.clear_history_time = 0.
|
||||||
@ -46,8 +46,6 @@ class PrinterMotionQueuing:
|
|||||||
ffi_lib.steppersync_free)
|
ffi_lib.steppersync_free)
|
||||||
self.steppersyncs.append((mcu, ss))
|
self.steppersyncs.append((mcu, ss))
|
||||||
return ss
|
return ss
|
||||||
def register_stepper(self, config, stepper):
|
|
||||||
self.steppers.append(stepper)
|
|
||||||
def register_flush_callback(self, callback):
|
def register_flush_callback(self, callback):
|
||||||
self.flush_callbacks.append(callback)
|
self.flush_callbacks.append(callback)
|
||||||
def unregister_flush_callback(self, callback):
|
def unregister_flush_callback(self, callback):
|
||||||
@ -59,12 +57,14 @@ class PrinterMotionQueuing:
|
|||||||
# Invoke flush callbacks (if any)
|
# Invoke flush callbacks (if any)
|
||||||
for cb in self.flush_callbacks:
|
for cb in self.flush_callbacks:
|
||||||
cb(must_flush_time, max_step_gen_time)
|
cb(must_flush_time, max_step_gen_time)
|
||||||
# Generate itersolve steps
|
|
||||||
for stepper in self.steppers:
|
|
||||||
stepper.generate_steps(max_step_gen_time)
|
|
||||||
# Flush steps from stepcompress and steppersync
|
|
||||||
for mcu, ss in self.steppersyncs:
|
for mcu, ss in self.steppersyncs:
|
||||||
clock = max(0, mcu.print_time_to_clock(must_flush_time))
|
clock = max(0, mcu.print_time_to_clock(must_flush_time))
|
||||||
|
# Generate steps
|
||||||
|
ret = self.steppersync_generate_steps(ss, max_step_gen_time, clock)
|
||||||
|
if ret:
|
||||||
|
raise mcu.error("Internal error in MCU '%s' stepcompress"
|
||||||
|
% (mcu.get_name(),))
|
||||||
|
# Flush steps from steppersync
|
||||||
ret = self.steppersync_flush(ss, clock)
|
ret = self.steppersync_flush(ss, clock)
|
||||||
if ret:
|
if ret:
|
||||||
raise mcu.error("Internal error in MCU '%s' stepcompress"
|
raise mcu.error("Internal error in MCU '%s' stepcompress"
|
||||||
|
@ -48,7 +48,6 @@ class MCU_stepper:
|
|||||||
ffi_main, ffi_lib = chelper.get_ffi()
|
ffi_main, ffi_lib = chelper.get_ffi()
|
||||||
ffi_lib.stepcompress_set_invert_sdir(self._stepqueue, self._invert_dir)
|
ffi_lib.stepcompress_set_invert_sdir(self._stepqueue, self._invert_dir)
|
||||||
self._stepper_kinematics = None
|
self._stepper_kinematics = None
|
||||||
self._itersolve_generate_steps = ffi_lib.itersolve_generate_steps
|
|
||||||
self._itersolve_check_active = ffi_lib.itersolve_check_active
|
self._itersolve_check_active = ffi_lib.itersolve_check_active
|
||||||
self._trapq = ffi_main.NULL
|
self._trapq = ffi_main.NULL
|
||||||
printer.register_event_handler('klippy:connect',
|
printer.register_event_handler('klippy:connect',
|
||||||
@ -192,6 +191,8 @@ class MCU_stepper:
|
|||||||
if old_sk is not None:
|
if old_sk is not None:
|
||||||
mcu_pos = self.get_mcu_position()
|
mcu_pos = self.get_mcu_position()
|
||||||
self._stepper_kinematics = sk
|
self._stepper_kinematics = sk
|
||||||
|
ffi_main, ffi_lib = chelper.get_ffi()
|
||||||
|
ffi_lib.stepcompress_set_stepper_kinematics(self._stepqueue, sk);
|
||||||
self.set_trapq(self._trapq)
|
self.set_trapq(self._trapq)
|
||||||
self._set_mcu_position(mcu_pos)
|
self._set_mcu_position(mcu_pos)
|
||||||
return old_sk
|
return old_sk
|
||||||
@ -253,12 +254,6 @@ class MCU_stepper:
|
|||||||
# Invoke callbacks
|
# Invoke callbacks
|
||||||
for cb in cbs:
|
for cb in cbs:
|
||||||
cb(ret)
|
cb(ret)
|
||||||
def generate_steps(self, flush_time):
|
|
||||||
# Generate steps
|
|
||||||
sk = self._stepper_kinematics
|
|
||||||
ret = self._itersolve_generate_steps(sk, self._stepqueue, flush_time)
|
|
||||||
if ret:
|
|
||||||
raise error("Internal error in stepcompress")
|
|
||||||
def is_active_axis(self, axis):
|
def is_active_axis(self, axis):
|
||||||
ffi_main, ffi_lib = chelper.get_ffi()
|
ffi_main, ffi_lib = chelper.get_ffi()
|
||||||
a = axis.encode()
|
a = axis.encode()
|
||||||
@ -281,8 +276,7 @@ def PrinterStepper(config, units_in_radians=False):
|
|||||||
rotation_dist, steps_per_rotation,
|
rotation_dist, steps_per_rotation,
|
||||||
step_pulse_duration, units_in_radians)
|
step_pulse_duration, units_in_radians)
|
||||||
# Register with helper modules
|
# Register with helper modules
|
||||||
mods = ['stepper_enable', 'force_move', 'motion_report', 'motion_queuing']
|
for mname in ['stepper_enable', 'force_move', 'motion_report']:
|
||||||
for mname in mods:
|
|
||||||
m = printer.load_object(config, mname)
|
m = printer.load_object(config, mname)
|
||||||
m.register_stepper(config, mcu_stepper)
|
m.register_stepper(config, mcu_stepper)
|
||||||
return mcu_stepper
|
return mcu_stepper
|
||||||
|
Loading…
x
Reference in New Issue
Block a user