cartesian: Initial support for dual carriages
Add support for additional carriages on cartesian printers. This is used by some printers to handle multiple extruders. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
6c1e1dcc8d
commit
4d48c111d8
|
@ -98,6 +98,30 @@
|
|||
# activation.
|
||||
|
||||
|
||||
# Support for cartesian printers with dual carriages on a single
|
||||
# axis. The active carriage is set via the SET_DUAL_CARRIAGE extended
|
||||
# g-code command. The "SET_DUAL_CARRIAGE CARRIAGE=1" command will
|
||||
# activate the carriage defined in this section (CARRIAGE=0 will
|
||||
# return activation to the primary carriage). Dual carriage support is
|
||||
# typically combined with extra extruders - use the SET_DUAL_CARRIAGE
|
||||
# command in the activate_gcode / deactivate_gcode section of the
|
||||
# appropriate extruder. Be sure to also use that mechanism to park the
|
||||
# carriages during deactivation.
|
||||
#[dual_carriage]
|
||||
#axis:
|
||||
# The axis this extra carriage is on (either x or y). This parameter
|
||||
# must be provided.
|
||||
#step_pin:
|
||||
#dir_pin:
|
||||
#enable_pin:
|
||||
#step_distance:
|
||||
#endstop_pin:
|
||||
#position_endstop:
|
||||
#position_min:
|
||||
#position_max:
|
||||
# See the example.cfg for the definition of the above parameters.
|
||||
|
||||
|
||||
# Multi-stepper axes. On a cartesian style printer, the stepper
|
||||
# controlling a given axis may have additional config blocks defining
|
||||
# steppers that should be stepped in concert with the primary
|
||||
|
|
|
@ -10,6 +10,7 @@ StepList = (0, 1, 2)
|
|||
|
||||
class CartKinematics:
|
||||
def __init__(self, toolhead, printer, config):
|
||||
self.printer = printer
|
||||
self.steppers = [stepper.LookupMultiHomingStepper(
|
||||
printer, config.getsection('stepper_' + n))
|
||||
for n in ['x', 'y', 'z']]
|
||||
|
@ -26,6 +27,20 @@ class CartKinematics:
|
|||
self.steppers[1].set_max_jerk(max_halt_velocity, max_accel)
|
||||
self.steppers[2].set_max_jerk(
|
||||
min(max_halt_velocity, self.max_z_velocity), max_accel)
|
||||
# Check for dual carriage support
|
||||
self.dual_carriage_axis = None
|
||||
self.dual_carriage_steppers = []
|
||||
if config.has_section('dual_carriage'):
|
||||
dc_config = config.getsection('dual_carriage')
|
||||
self.dual_carriage_axis = dc_config.getchoice(
|
||||
'axis', {'x': 0, 'y': 1})
|
||||
dc_stepper = stepper.LookupMultiHomingStepper(printer, dc_config)
|
||||
dc_stepper.set_max_jerk(max_halt_velocity, max_accel)
|
||||
self.dual_carriage_steppers = [
|
||||
self.steppers[self.dual_carriage_axis], dc_stepper]
|
||||
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, flags=""):
|
||||
if flags == "Z":
|
||||
return [self.steppers[2]]
|
||||
|
@ -38,44 +53,57 @@ class CartKinematics:
|
|||
s.set_position(newpos[i])
|
||||
if i in homing_axes:
|
||||
self.limits[i] = (s.position_min, s.position_max)
|
||||
def _home_axis(self, homing_state, axis, stepper):
|
||||
s = stepper
|
||||
# Determine moves
|
||||
if s.homing_positive_dir:
|
||||
pos = s.position_endstop - 1.5*(
|
||||
s.position_endstop - s.position_min)
|
||||
rpos = s.position_endstop - s.homing_retract_dist
|
||||
r2pos = rpos - s.homing_retract_dist
|
||||
else:
|
||||
pos = s.position_endstop + 1.5*(
|
||||
s.position_max - s.position_endstop)
|
||||
rpos = s.position_endstop + s.homing_retract_dist
|
||||
r2pos = rpos + s.homing_retract_dist
|
||||
# Initial homing
|
||||
homing_speed = s.homing_speed
|
||||
if axis == 2:
|
||||
homing_speed = min(homing_speed, self.max_z_velocity)
|
||||
homepos = [None, None, None, None]
|
||||
homepos[axis] = s.position_endstop
|
||||
coord = [None, None, None, None]
|
||||
coord[axis] = pos
|
||||
homing_state.home(coord, homepos, s.get_endstops(), homing_speed)
|
||||
# Retract
|
||||
coord[axis] = rpos
|
||||
homing_state.retract(coord, homing_speed)
|
||||
# Home again
|
||||
coord[axis] = r2pos
|
||||
homing_state.home(coord, homepos, s.get_endstops(),
|
||||
homing_speed/2.0, second_home=True)
|
||||
# Set final homed position
|
||||
coord[axis] = s.position_endstop + s.get_homed_offset()
|
||||
homing_state.set_homed_position(coord)
|
||||
def home(self, homing_state):
|
||||
# Each axis is homed independently and in order
|
||||
for axis in homing_state.get_axes():
|
||||
s = self.steppers[axis]
|
||||
# Determine moves
|
||||
if s.homing_positive_dir:
|
||||
pos = s.position_endstop - 1.5*(
|
||||
s.position_endstop - s.position_min)
|
||||
rpos = s.position_endstop - s.homing_retract_dist
|
||||
r2pos = rpos - s.homing_retract_dist
|
||||
if axis == self.dual_carriage_axis:
|
||||
dc1, dc2 = self.dual_carriage_steppers
|
||||
altc = self.steppers[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)
|
||||
else:
|
||||
pos = s.position_endstop + 1.5*(
|
||||
s.position_max - s.position_endstop)
|
||||
rpos = s.position_endstop + s.homing_retract_dist
|
||||
r2pos = rpos + s.homing_retract_dist
|
||||
# Initial homing
|
||||
homing_speed = s.homing_speed
|
||||
if axis == 2:
|
||||
homing_speed = min(homing_speed, self.max_z_velocity)
|
||||
homepos = [None, None, None, None]
|
||||
homepos[axis] = s.position_endstop
|
||||
coord = [None, None, None, None]
|
||||
coord[axis] = pos
|
||||
homing_state.home(coord, homepos, s.get_endstops(), homing_speed)
|
||||
# Retract
|
||||
coord[axis] = rpos
|
||||
homing_state.retract(coord, homing_speed)
|
||||
# Home again
|
||||
coord[axis] = r2pos
|
||||
homing_state.home(coord, homepos, s.get_endstops(),
|
||||
homing_speed/2.0, second_home=True)
|
||||
# Set final homed position
|
||||
coord[axis] = s.position_endstop + s.get_homed_offset()
|
||||
homing_state.set_homed_position(coord)
|
||||
self._home_axis(homing_state, axis, self.steppers[axis])
|
||||
def motor_off(self, print_time):
|
||||
self.limits = [(1.0, -1.0)] * 3
|
||||
for stepper in self.steppers:
|
||||
stepper.motor_enable(print_time, 0)
|
||||
for stepper in self.dual_carriage_steppers:
|
||||
stepper.motor_enable(print_time, 0)
|
||||
self.need_motor_enable = True
|
||||
def _check_motor_enable(self, print_time, move):
|
||||
need_motor_enable = False
|
||||
|
@ -139,3 +167,24 @@ class CartKinematics:
|
|||
if move.decel_r:
|
||||
decel_d = move.decel_r * axis_d
|
||||
step_const(move_time, start_pos, decel_d, cruise_v, -accel)
|
||||
# Dual carriage support
|
||||
def _activate_carriage(self, carriage):
|
||||
toolhead = self.printer.lookup_object('toolhead')
|
||||
toolhead.get_last_move_time()
|
||||
dc_stepper = self.dual_carriage_steppers[carriage]
|
||||
dc_axis = self.dual_carriage_axis
|
||||
self.steppers[dc_axis] = dc_stepper
|
||||
extruder_pos = toolhead.get_position()[3]
|
||||
toolhead.set_position(self.get_position() + [extruder_pos])
|
||||
if self.limits[dc_axis][0] <= self.limits[dc_axis][1]:
|
||||
self.limits[dc_axis] = (
|
||||
dc_stepper.position_min, dc_stepper.position_max)
|
||||
self.need_motor_enable = True
|
||||
cmd_SET_DUAL_CARRIAGE_help = "Set which carriage is active"
|
||||
def cmd_SET_DUAL_CARRIAGE(self, params):
|
||||
gcode = self.printer.lookup_object('gcode')
|
||||
carriage = gcode.get_int('CARRIAGE', params)
|
||||
if carriage not in (0, 1):
|
||||
raise gcode.error("Invalid carriage")
|
||||
self._activate_carriage(carriage)
|
||||
gcode.reset_last_position()
|
||||
|
|
Loading…
Reference in New Issue