stepper_enable: Move motor_off() logic to stepper_enable.py

Directly disable all the stepper motors on a global motor_off() from
the StepperEnable() class in stepper_enable.py.  This simplifies the
toolhead and kinematic classes.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2019-11-12 11:41:41 -05:00
parent f50e054bd0
commit bfb34e0701
13 changed files with 37 additions and 49 deletions

View File

@ -336,10 +336,9 @@ Useful steps:
need to be efficient as it is typically only called during homing need to be efficient as it is typically only called during homing
and probing operations. and probing operations.
5. Other methods. Implement the `check_move()`, `home()`, 5. Other methods. Implement the `check_move()`, `home()`,
`motor_off()`, `set_position()`, and `get_steppers()` methods. `set_position()`, and `get_steppers()` methods. These functions are
These functions are typically used to provide kinematic specific typically used to provide kinematic specific checks. However, at
checks. However, at the start of development one can use the start of development one can use boiler-plate code here.
boiler-plate code here.
6. Implement test cases. Create a g-code file with a series of moves 6. Implement test cases. Create a g-code file with a series of moves
that can test important cases for the given kinematics. Follow the that can test important cases for the given kinematics. Follow the
[debugging documentation](Debugging.md) to convert this g-code file [debugging documentation](Debugging.md) to convert this g-code file

View File

@ -35,8 +35,6 @@ class ManualStepper:
self.gcode.register_mux_command('MANUAL_STEPPER', "STEPPER", self.gcode.register_mux_command('MANUAL_STEPPER', "STEPPER",
stepper_name, self.cmd_MANUAL_STEPPER, stepper_name, self.cmd_MANUAL_STEPPER,
desc=self.cmd_MANUAL_STEPPER_help) desc=self.cmd_MANUAL_STEPPER_help)
self.printer.register_event_handler(
"toolhead:motor_off", self.handle_motor_off)
def sync_print_time(self): def sync_print_time(self):
toolhead = self.printer.lookup_object('toolhead') toolhead = self.printer.lookup_object('toolhead')
print_time = toolhead.get_last_move_time() print_time = toolhead.get_last_move_time()
@ -114,8 +112,6 @@ class ManualStepper:
elif 'MOVE' in params: elif 'MOVE' in params:
movepos = self.gcode.get_float('MOVE', params) movepos = self.gcode.get_float('MOVE', params)
self.do_move(movepos, speed, accel) self.do_move(movepos, speed, accel)
def handle_motor_off(self, print_time):
self.do_enable(0)
def load_config_prefix(config): def load_config_prefix(config):
return ManualStepper(config) return ManualStepper(config)

View File

@ -3,18 +3,36 @@
# Copyright (C) 2019 Kevin O'Connor <kevin@koconnor.net> # Copyright (C) 2019 Kevin O'Connor <kevin@koconnor.net>
# #
# This file may be distributed under the terms of the GNU GPLv3 license. # This file may be distributed under the terms of the GNU GPLv3 license.
import logging
DISABLE_STALL_TIME = 0.100
class StepperEnable: class StepperEnable:
def __init__(self, config): def __init__(self, config):
self.printer = config.get_printer() self.printer = config.get_printer()
self.steppers = {}
self.printer.register_event_handler("gcode:request_restart",
self._handle_request_restart)
# Register M18/M84 commands # Register M18/M84 commands
gcode = self.printer.lookup_object('gcode') gcode = self.printer.lookup_object('gcode')
gcode.register_command("M18", self.cmd_M18) gcode.register_command("M18", self.cmd_M18)
gcode.register_command("M84", self.cmd_M18) gcode.register_command("M84", self.cmd_M18)
def register_stepper(self, stepper):
self.steppers[stepper.get_name()] = stepper
def motor_off(self):
toolhead = self.printer.lookup_object('toolhead')
toolhead.dwell(DISABLE_STALL_TIME)
print_time = toolhead.get_last_move_time()
for s in self.steppers.values():
s.motor_enable(print_time, 0)
self.printer.send_event("stepper_enable:motor_off", print_time)
toolhead.dwell(DISABLE_STALL_TIME)
logging.debug('; Max time of %f', print_time)
def _handle_request_restart(self, print_time):
self.motor_off()
def cmd_M18(self, params): def cmd_M18(self, params):
# Turn off motors # Turn off motors
toolhead = self.printer.lookup_object('toolhead') self.motor_off()
toolhead.motor_off()
def load_config(config): def load_config(config):
return StepperEnable(config) return StepperEnable(config)

View File

@ -125,7 +125,7 @@ class Homing:
try: try:
self.toolhead.get_kinematics().home(self) self.toolhead.get_kinematics().home(self)
except CommandError: except CommandError:
self.toolhead.motor_off() self.printer.lookup_object('stepper_enable').motor_off()
raise raise
class CommandError(Exception): class CommandError(Exception):

View File

@ -17,6 +17,8 @@ class CartKinematics:
for s in self.get_steppers(): for s in self.get_steppers():
s.set_trapq(toolhead.get_trapq()) s.set_trapq(toolhead.get_trapq())
toolhead.register_step_generator(s.generate_steps) toolhead.register_step_generator(s.generate_steps)
self.printer.register_event_handler("stepper_enable:motor_off",
self._motor_off)
# Setup boundary checks # Setup boundary checks
max_velocity, max_accel = toolhead.get_max_velocity() max_velocity, max_accel = toolhead.get_max_velocity()
self.max_z_velocity = config.getfloat( self.max_z_velocity = config.getfloat(
@ -84,12 +86,8 @@ class CartKinematics:
self._activate_carriage(altc) self._activate_carriage(altc)
else: 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): def _motor_off(self, print_time):
self.limits = [(1.0, -1.0)] * 3 self.limits = [(1.0, -1.0)] * 3
for rail in self.rails:
rail.motor_enable(print_time, 0)
for rail in self.dual_carriage_rails:
rail.motor_enable(print_time, 0)
def _check_endstops(self, move): def _check_endstops(self, move):
end_pos = move.end_pos end_pos = move.end_pos
for i in (0, 1, 2): for i in (0, 1, 2):
@ -131,7 +129,6 @@ class CartKinematics:
toolhead.set_position(self.calc_position() + [extruder_pos]) toolhead.set_position(self.calc_position() + [extruder_pos])
if self.limits[dc_axis][0] <= self.limits[dc_axis][1]: if self.limits[dc_axis][0] <= self.limits[dc_axis][1]:
self.limits[dc_axis] = dc_rail.get_range() self.limits[dc_axis] = dc_rail.get_range()
self.need_motor_enable = True
cmd_SET_DUAL_CARRIAGE_help = "Set which carriage is active" cmd_SET_DUAL_CARRIAGE_help = "Set which carriage is active"
def cmd_SET_DUAL_CARRIAGE(self, params): def cmd_SET_DUAL_CARRIAGE(self, params):
gcode = self.printer.lookup_object('gcode') gcode = self.printer.lookup_object('gcode')

View File

@ -20,6 +20,8 @@ class CoreXYKinematics:
for s in self.get_steppers(): for s in self.get_steppers():
s.set_trapq(toolhead.get_trapq()) s.set_trapq(toolhead.get_trapq())
toolhead.register_step_generator(s.generate_steps) toolhead.register_step_generator(s.generate_steps)
config.get_printer().register_event_handler("stepper_enable:motor_off",
self._motor_off)
# Setup boundary checks # Setup boundary checks
max_velocity, max_accel = toolhead.get_max_velocity() max_velocity, max_accel = toolhead.get_max_velocity()
self.max_z_velocity = config.getfloat( self.max_z_velocity = config.getfloat(
@ -63,10 +65,8 @@ class CoreXYKinematics:
forcepos[axis] += 1.5 * (position_max - hi.position_endstop) forcepos[axis] += 1.5 * (position_max - hi.position_endstop)
# Perform homing # Perform homing
homing_state.home_rails([rail], forcepos, homepos) homing_state.home_rails([rail], forcepos, homepos)
def motor_off(self, print_time): def _motor_off(self, print_time):
self.limits = [(1.0, -1.0)] * 3 self.limits = [(1.0, -1.0)] * 3
for rail in self.rails:
rail.motor_enable(print_time, 0)
def _check_endstops(self, move): def _check_endstops(self, move):
end_pos = move.end_pos end_pos = move.end_pos
for i in (0, 1, 2): for i in (0, 1, 2):

View File

@ -23,6 +23,8 @@ class DeltaKinematics:
stepper_configs[2], need_position_minmax = False, stepper_configs[2], need_position_minmax = False,
default_position_endstop=a_endstop) default_position_endstop=a_endstop)
self.rails = [rail_a, rail_b, rail_c] self.rails = [rail_a, rail_b, rail_c]
config.get_printer().register_event_handler("stepper_enable:motor_off",
self._motor_off)
# Setup stepper max halt velocity # Setup stepper max halt velocity
self.max_velocity, self.max_accel = toolhead.get_max_velocity() self.max_velocity, self.max_accel = toolhead.get_max_velocity()
self.max_z_velocity = config.getfloat( self.max_z_velocity = config.getfloat(
@ -105,10 +107,8 @@ class DeltaKinematics:
forcepos = list(self.home_position) forcepos = list(self.home_position)
forcepos[2] = -1.5 * math.sqrt(max(self.arm2)-self.max_xy2) forcepos[2] = -1.5 * math.sqrt(max(self.arm2)-self.max_xy2)
homing_state.home_rails(self.rails, forcepos, self.home_position) homing_state.home_rails(self.rails, forcepos, self.home_position)
def motor_off(self, print_time): def _motor_off(self, print_time):
self.limit_xy2 = -1. self.limit_xy2 = -1.
for rail in self.rails:
rail.motor_enable(print_time, 0)
self.need_home = True self.need_home = True
def check_move(self, move): def check_move(self, move):
end_pos = move.end_pos end_pos = move.end_pos

View File

@ -87,8 +87,6 @@ class PrinterExtruder:
return self.deactivate_gcode.render() return self.deactivate_gcode.render()
def stats(self, eventtime): def stats(self, eventtime):
return self.heater.stats(eventtime) return self.heater.stats(eventtime)
def motor_off(self, print_time):
self.stepper.motor_enable(print_time, 0)
def check_move(self, move): def check_move(self, move):
move.extrude_r = move.axes_r[3] move.extrude_r = move.axes_r[3]
move.extrude_max_corner_v = 0. move.extrude_max_corner_v = 0.
@ -231,8 +229,6 @@ class PrinterExtruder:
class DummyExtruder: class DummyExtruder:
def set_active(self, print_time, is_active): def set_active(self, print_time, is_active):
return 0. return 0.
def motor_off(self, move_time):
pass
def check_move(self, move): def check_move(self, move):
raise homing.EndstopMoveError( raise homing.EndstopMoveError(
move.end_pos, "Extrude when no extruder present") move.end_pos, "Extrude when no extruder present")

View File

@ -15,8 +15,6 @@ class NoneKinematics:
pass pass
def home(self, homing_state): def home(self, homing_state):
pass pass
def motor_off(self, print_time):
pass
def check_move(self, move): def check_move(self, move):
pass pass
def get_status(self): def get_status(self):

View File

@ -21,6 +21,8 @@ class PolarKinematics:
for s in self.get_steppers(): for s in self.get_steppers():
s.set_trapq(toolhead.get_trapq()) s.set_trapq(toolhead.get_trapq())
toolhead.register_step_generator(s.generate_steps) toolhead.register_step_generator(s.generate_steps)
config.get_printer().register_event_handler("stepper_enable:motor_off",
self._motor_off)
# Setup boundary checks # Setup boundary checks
max_velocity, max_accel = toolhead.get_max_velocity() max_velocity, max_accel = toolhead.get_max_velocity()
self.max_z_velocity = config.getfloat( self.max_z_velocity = config.getfloat(
@ -82,11 +84,9 @@ class PolarKinematics:
self._home_axis(homing_state, 0, self.rails[0]) self._home_axis(homing_state, 0, self.rails[0])
if home_z: if home_z:
self._home_axis(homing_state, 2, self.rails[1]) self._home_axis(homing_state, 2, self.rails[1])
def motor_off(self, print_time): def _motor_off(self, print_time):
self.limit_z = [(1.0, -1.0)] self.limit_z = [(1.0, -1.0)]
self.limit_xy2 = -1. self.limit_xy2 = -1.
for s in self.steppers:
s.motor_enable(print_time, 0)
def check_move(self, move): def check_move(self, move):
end_pos = move.end_pos end_pos = move.end_pos
xy2 = end_pos[0]**2 + end_pos[1]**2 xy2 = end_pos[0]**2 + end_pos[1]**2

View File

@ -42,9 +42,6 @@ class WinchKinematics:
# XXX - homing not implemented # XXX - homing not implemented
homing_state.set_axes([0, 1, 2]) homing_state.set_axes([0, 1, 2])
homing_state.set_homed_position([0., 0., 0.]) homing_state.set_homed_position([0., 0., 0.])
def motor_off(self, print_time):
for s in self.steppers:
s.motor_enable(print_time, 0)
def check_move(self, move): def check_move(self, move):
# XXX - boundary checks and speed limits not implemented # XXX - boundary checks and speed limits not implemented
pass pass

View File

@ -72,6 +72,7 @@ class PrinterStepper:
mcu_stepper.setup_step_distance(step_dist) mcu_stepper.setup_step_distance(step_dist)
# Enable pin handling # Enable pin handling
stepper_enable = printer.try_load_module(config, 'stepper_enable') stepper_enable = printer.try_load_module(config, 'stepper_enable')
stepper_enable.register_stepper(self)
mcu_stepper.add_active_callback(self._stepper_active) mcu_stepper.add_active_callback(self._stepper_active)
self.enable = lookup_enable_pin(ppins, config.get('enable_pin', None)) self.enable = lookup_enable_pin(ppins, config.get('enable_pin', None))
# Register STEPPER_BUZZ command # Register STEPPER_BUZZ command

View File

@ -182,7 +182,6 @@ class MoveQueue:
# Enough moves have been queued to reach the target flush time. # Enough moves have been queued to reach the target flush time.
self.flush(lazy=True) self.flush(lazy=True)
STALL_TIME = 0.100
MOVE_BATCH_TIME = 0.500 MOVE_BATCH_TIME = 0.500
DRIP_SEGMENT_TIME = 0.050 DRIP_SEGMENT_TIME = 0.050
@ -203,8 +202,6 @@ class ToolHead:
self.can_pause = False self.can_pause = False
self.move_queue = MoveQueue(self) self.move_queue = MoveQueue(self)
self.commanded_pos = [0., 0., 0., 0.] self.commanded_pos = [0., 0., 0., 0.]
self.printer.register_event_handler("gcode:request_restart",
self._handle_request_restart)
self.printer.register_event_handler("klippy:shutdown", self.printer.register_event_handler("klippy:shutdown",
self._handle_shutdown) self._handle_shutdown)
# Velocity and acceleration control # Velocity and acceleration control
@ -405,15 +402,6 @@ class ToolHead:
next_print_time = self.get_last_move_time() + max(0., delay) next_print_time = self.get_last_move_time() + max(0., delay)
self._update_move_time(next_print_time) self._update_move_time(next_print_time)
self._check_stall() self._check_stall()
def motor_off(self):
self.dwell(STALL_TIME)
last_move_time = self.get_last_move_time()
self.kin.motor_off(last_move_time)
for ext in kinematics.extruder.get_printer_extruders(self.printer):
ext.motor_off(last_move_time)
self.printer.send_event("toolhead:motor_off", last_move_time)
self.dwell(STALL_TIME)
logging.debug('; Max time of %f', last_move_time)
def wait_moves(self): def wait_moves(self):
self._flush_lookahead() self._flush_lookahead()
eventtime = self.reactor.monotonic() eventtime = self.reactor.monotonic()
@ -493,8 +481,6 @@ class ToolHead:
'estimated_print_time': estimated_print_time, 'estimated_print_time': estimated_print_time,
'position': homing.Coord(*self.commanded_pos), 'position': homing.Coord(*self.commanded_pos),
'printing_time': print_time - last_print_start_time } 'printing_time': print_time - last_print_start_time }
def _handle_request_restart(self, print_time):
self.motor_off()
def _handle_shutdown(self): def _handle_shutdown(self):
self.can_pause = False self.can_pause = False
self.move_queue.reset() self.move_queue.reset()