From 36be1cfc5109355fb50cececedee936905fc6c7d Mon Sep 17 00:00:00 2001 From: Dmitry Butyugin Date: Tue, 1 Aug 2023 18:23:52 +0200 Subject: idex_modes: COPY and MIRROR mode implementation (#6297) COPY and MIRROR mode implementation Correctly apply input shaper params to new dual_carriage Added SAVE_/RESTORE_IDEX_STATE commands Documentation updates for the new IDEX modes Signed-off-by: Dmitry Butyugin --- klippy/kinematics/cartesian.py | 83 +++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 50 deletions(-) (limited to 'klippy/kinematics/cartesian.py') diff --git a/klippy/kinematics/cartesian.py b/klippy/kinematics/cartesian.py index 0cd7849a..59604197 100644 --- a/klippy/kinematics/cartesian.py +++ b/klippy/kinematics/cartesian.py @@ -5,6 +5,7 @@ # This file may be distributed under the terms of the GNU GPLv3 license. import logging import stepper +from . import idex_modes class CartKinematics: def __init__(self, toolhead, config): @@ -16,6 +17,25 @@ class CartKinematics: for n in 'xyz'] for rail, axis in zip(self.rails, 'xyz'): rail.setup_itersolve('cartesian_stepper_alloc', axis.encode()) + ranges = [r.get_range() for r in self.rails] + self.axes_min = toolhead.Coord(*[r[0] for r in ranges], e=0.) + self.axes_max = toolhead.Coord(*[r[1] for r in ranges], e=0.) + self.dc_module = None + if config.has_section('dual_carriage'): + dc_config = config.getsection('dual_carriage') + dc_axis = dc_config.getchoice('axis', {'x': 'x', 'y': 'y'}) + self.dual_carriage_axis = {'x': 0, 'y': 1}[dc_axis] + # setup second dual carriage rail + self.rails.append(stepper.LookupMultiRail(dc_config)) + self.rails[3].setup_itersolve('cartesian_stepper_alloc', + dc_axis.encode()) + dc_rail_0 = idex_modes.DualCarriagesRail( + self.rails[0], axis=self.dual_carriage_axis, active=True) + dc_rail_1 = idex_modes.DualCarriagesRail( + self.rails[3], axis=self.dual_carriage_axis, active=False) + self.dc_module = idex_modes.DualCarriages( + dc_config, dc_rail_0, dc_rail_1, + axis=self.dual_carriage_axis) for s in self.get_steppers(): s.set_trapq(toolhead.get_trapq()) toolhead.register_step_generator(s.generate_steps) @@ -28,31 +48,18 @@ class CartKinematics: self.max_z_accel = config.getfloat('max_z_accel', max_accel, above=0., maxval=max_accel) self.limits = [(1.0, -1.0)] * 3 - ranges = [r.get_range() for r in self.rails] - self.axes_min = toolhead.Coord(*[r[0] for r in ranges], e=0.) - self.axes_max = toolhead.Coord(*[r[1] for r in ranges], e=0.) - # Check for dual carriage support - if config.has_section('dual_carriage'): - dc_config = config.getsection('dual_carriage') - dc_axis = dc_config.getchoice('axis', {'x': 'x', 'y': 'y'}) - self.dual_carriage_axis = {'x': 0, 'y': 1}[dc_axis] - dc_rail = stepper.LookupMultiRail(dc_config) - dc_rail.setup_itersolve('cartesian_stepper_alloc', dc_axis.encode()) - for s in dc_rail.get_steppers(): - toolhead.register_step_generator(s.generate_steps) - self.dual_carriage_rails = [ - self.rails[self.dual_carriage_axis], dc_rail] - self.printer.lookup_object('gcode').register_command( - 'SET_DUAL_CARRIAGE', self.cmd_SET_DUAL_CARRIAGE, - desc=self.cmd_SET_DUAL_CARRIAGE_help) def get_steppers(self): - rails = self.rails - if self.dual_carriage_axis is not None: - dca = self.dual_carriage_axis - rails = rails[:dca] + self.dual_carriage_rails + rails[dca+1:] - return [s for rail in rails for s in rail.get_steppers()] + return [s for rail in self.rails for s in rail.get_steppers()] def calc_position(self, stepper_positions): return [stepper_positions[rail.get_name()] for rail in self.rails] + def update_limits(self, i, range): + l, h = self.limits[i] + # Only update limits if this axis was already homed, + # otherwise leave in un-homed state. + if l <= h: + self.limits[i] = range + def override_rail(self, i, rail): + self.rails[i] = rail def set_position(self, newpos, homing_axes): for i, rail in enumerate(self.rails): rail.set_position(newpos) @@ -61,7 +68,7 @@ class CartKinematics: def note_z_not_homed(self): # Helper for Safe Z Home self.limits[2] = (1.0, -1.0) - def _home_axis(self, homing_state, axis, rail): + def home_axis(self, homing_state, axis, rail): # Determine movement position_min, position_max = rail.get_range() hi = rail.get_homing_info() @@ -77,16 +84,10 @@ class CartKinematics: def home(self, homing_state): # Each axis is homed independently and in order for axis in homing_state.get_axes(): - if axis == self.dual_carriage_axis: - dc1, dc2 = self.dual_carriage_rails - altc = self.rails[axis] == dc2 - self._activate_carriage(0) - self._home_axis(homing_state, axis, dc1) - self._activate_carriage(1) - self._home_axis(homing_state, axis, dc2) - self._activate_carriage(altc) + if self.dc_module is not None and axis == self.dual_carriage_axis: + self.dc_module.home(homing_state) else: - self._home_axis(homing_state, axis, self.rails[axis]) + self.home_axis(homing_state, axis, self.rails[axis]) def _motor_off(self, print_time): self.limits = [(1.0, -1.0)] * 3 def _check_endstops(self, move): @@ -119,24 +120,6 @@ class CartKinematics: 'axis_minimum': self.axes_min, 'axis_maximum': self.axes_max, } - # Dual carriage support - def _activate_carriage(self, carriage): - toolhead = self.printer.lookup_object('toolhead') - toolhead.flush_step_generation() - dc_rail = self.dual_carriage_rails[carriage] - dc_axis = self.dual_carriage_axis - self.rails[dc_axis].set_trapq(None) - dc_rail.set_trapq(toolhead.get_trapq()) - self.rails[dc_axis] = dc_rail - pos = toolhead.get_position() - pos[dc_axis] = dc_rail.get_commanded_position() - toolhead.set_position(pos) - if self.limits[dc_axis][0] <= self.limits[dc_axis][1]: - self.limits[dc_axis] = dc_rail.get_range() - cmd_SET_DUAL_CARRIAGE_help = "Set which carriage is active" - def cmd_SET_DUAL_CARRIAGE(self, gcmd): - carriage = gcmd.get_int('CARRIAGE', minval=0, maxval=1) - self._activate_carriage(carriage) def load_kinematics(toolhead, config): return CartKinematics(toolhead, config) -- cgit v1.2.3-70-g09d2