Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement CLEAR for SET_KINEMATIC_POSITION #6262

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/Code_Overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -359,10 +359,10 @@ Useful steps:
be efficient as it is typically only called during homing and
probing operations.
5. Other methods. Implement the `check_move()`, `get_status()`,
`get_steppers()`, `home()`, and `set_position()` methods. These
functions are typically used to provide kinematic specific checks.
However, at the start of development one can use boiler-plate code
here.
`get_steppers()`, `home()`, `clear_homing_state()`, and `set_position()`
methods. These functions are typically used to provide kinematic
specific checks. However, at the start of development one can use
boiler-plate code here.
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
[debugging documentation](Debugging.md) to convert this g-code file
Expand Down
19 changes: 10 additions & 9 deletions docs/G-Codes.md
Original file line number Diff line number Diff line change
Expand Up @@ -585,15 +585,16 @@ state; issue a G28 afterwards to reset the kinematics. This command is
intended for low-level diagnostics and debugging.

#### SET_KINEMATIC_POSITION
`SET_KINEMATIC_POSITION [X=<value>] [Y=<value>] [Z=<value>]`: Force
the low-level kinematic code to believe the toolhead is at the given
cartesian position. This is a diagnostic and debugging command; use
SET_GCODE_OFFSET and/or G92 for regular axis transformations. If an
axis is not specified then it will default to the position that the
head was last commanded to. Setting an incorrect or invalid position
may lead to internal software errors. This command may invalidate
future boundary checks; issue a G28 afterwards to reset the
kinematics.
`SET_KINEMATIC_POSITION [X=<value>] [Y=<value>] [Z=<value>]
[CLEAR=<[X][Y][Z]>]`: Force the low-level kinematic code to believe the
toolhead is at the given cartesian position. This is a diagnostic and
debugging command; use SET_GCODE_OFFSET and/or G92 for regular axis
transformations. If an axis is not specified then it will default to the
position that the head was last commanded to. Setting an incorrect or
invalid position may lead to internal software errors. Use the CLEAR
parameter to forget the homing state for the given axes. This command
may invalidate future boundary checks; issue a G28 afterwards to reset
the kinematics.

### [gcode]

Expand Down
12 changes: 10 additions & 2 deletions klippy/extras/force_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,16 @@ def cmd_SET_KINEMATIC_POSITION(self, gcmd):
x = gcmd.get_float('X', curpos[0])
y = gcmd.get_float('Y', curpos[1])
z = gcmd.get_float('Z', curpos[2])
logging.info("SET_KINEMATIC_POSITION pos=%.3f,%.3f,%.3f", x, y, z)
toolhead.set_position([x, y, z, curpos[3]], homing_axes=(0, 1, 2))
clear = gcmd.get('CLEAR', '').upper()
axes = ['X', 'Y', 'Z']
twelho marked this conversation as resolved.
Show resolved Hide resolved
clear_axes = [axes.index(a) for a in axes if a in clear]
logging.info("SET_KINEMATIC_POSITION pos=%.3f,%.3f,%.3f clear=%s",
x, y, z, ','.join((axes[i] for i in clear_axes)))
toolhead.set_position(
[x, y, z, curpos[3]],
homing_axes=(0, 1, 2),
clear_axes=clear_axes
)

def load_config(config):
return ForceMove(config)
4 changes: 2 additions & 2 deletions klippy/extras/safe_z_home.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ def cmd_G28(self, gcmd):
toolhead.set_position(pos, homing_axes=[2])
toolhead.manual_move([None, None, self.z_hop],
self.z_hop_speed)
if hasattr(toolhead.get_kinematics(), "note_z_not_homed"):
toolhead.get_kinematics().note_z_not_homed()
if hasattr(toolhead.get_kinematics(), "clear_homing_state"):
toolhead.get_kinematics().clear_homing_state((2,))
elif pos[2] < self.z_hop:
# If the Z axis is homed, and below z_hop, lift it to z_hop
toolhead.manual_move([None, None, self.z_hop],
Expand Down
9 changes: 5 additions & 4 deletions klippy/kinematics/cartesian.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,10 @@ def set_position(self, newpos, homing_axes):
else:
rail = self.rails[axis]
self.limits[axis] = rail.get_range()
def note_z_not_homed(self):
# Helper for Safe Z Home
self.limits[2] = (1.0, -1.0)
def clear_homing_state(self, axes):
for i, _ in enumerate(self.limits):
if i in axes:
self.limits[i] = (1.0, -1.0)
def home_axis(self, homing_state, axis, rail):
# Determine movement
position_min, position_max = rail.get_range()
Expand All @@ -97,7 +98,7 @@ def home(self, homing_state):
else:
self.home_axis(homing_state, axis, self.rails[axis])
def _motor_off(self, print_time):
self.limits = [(1.0, -1.0)] * 3
self.clear_homing_state((0, 1, 2))
def _check_endstops(self, move):
end_pos = move.end_pos
for i in (0, 1, 2):
Expand Down
9 changes: 5 additions & 4 deletions klippy/kinematics/corexy.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ def set_position(self, newpos, homing_axes):
rail.set_position(newpos)
if i in homing_axes:
self.limits[i] = rail.get_range()
def note_z_not_homed(self):
# Helper for Safe Z Home
self.limits[2] = (1.0, -1.0)
def clear_homing_state(self, axes):
for i, _ in enumerate(self.limits):
if i in axes:
self.limits[i] = (1.0, -1.0)
def home(self, homing_state):
# Each axis is homed independently and in order
for axis in homing_state.get_axes():
Expand All @@ -63,7 +64,7 @@ def home(self, homing_state):
# Perform homing
homing_state.home_rails([rail], forcepos, homepos)
def _motor_off(self, print_time):
self.limits = [(1.0, -1.0)] * 3
self.clear_homing_state((0, 1, 2))
def _check_endstops(self, move):
end_pos = move.end_pos
for i in (0, 1, 2):
Expand Down
9 changes: 5 additions & 4 deletions klippy/kinematics/corexz.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ def set_position(self, newpos, homing_axes):
rail.set_position(newpos)
if i in homing_axes:
self.limits[i] = rail.get_range()
def note_z_not_homed(self):
# Helper for Safe Z Home
self.limits[2] = (1.0, -1.0)
def clear_homing_state(self, axes):
for i, _ in enumerate(self.limits):
if i in axes:
self.limits[i] = (1.0, -1.0)
def home(self, homing_state):
# Each axis is homed independently and in order
for axis in homing_state.get_axes():
Expand All @@ -63,7 +64,7 @@ def home(self, homing_state):
# Perform homing
homing_state.home_rails([rail], forcepos, homepos)
def _motor_off(self, print_time):
self.limits = [(1.0, -1.0)] * 3
self.clear_homing_state((0, 1, 2))
def _check_endstops(self, move):
end_pos = move.end_pos
for i in (0, 1, 2):
Expand Down
8 changes: 6 additions & 2 deletions klippy/kinematics/delta.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,19 @@ def set_position(self, newpos, homing_axes):
self.limit_xy2 = -1.
if tuple(homing_axes) == (0, 1, 2):
self.need_home = False
def clear_homing_state(self, axes):
# Clearing homing state for each axis individually is not implemented
if 0 in axes or 1 in axes or 2 in axes:
self.limit_xy2 = -1
self.need_home = True
def home(self, homing_state):
# All axes are homed simultaneously
homing_state.set_axes([0, 1, 2])
forcepos = list(self.home_position)
forcepos[2] = -1.5 * math.sqrt(max(self.arm2)-self.max_xy2)
homing_state.home_rails(self.rails, forcepos, self.home_position)
def _motor_off(self, print_time):
self.limit_xy2 = -1.
self.need_home = True
self.clear_homing_state((0, 1, 2))
def check_move(self, move):
end_pos = move.end_pos
end_xy2 = end_pos[0]**2 + end_pos[1]**2
Expand Down
4 changes: 4 additions & 0 deletions klippy/kinematics/deltesian.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ def set_position(self, newpos, homing_axes):
rail.set_position(newpos)
for n in homing_axes:
self.homed_axis[n] = True
def clear_homing_state(self, axes):
for i, _ in enumerate(self.limits):
if i in axes:
self.homed_axis[i] = False
def home(self, homing_state):
homing_axes = homing_state.get_axes()
home_xz = 0 in homing_axes or 2 in homing_axes
Expand Down
9 changes: 5 additions & 4 deletions klippy/kinematics/hybrid_corexy.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,10 @@ def set_position(self, newpos, homing_axes):
else:
rail = self.rails[axis]
self.limits[axis] = rail.get_range()
def note_z_not_homed(self):
# Helper for Safe Z Home
self.limits[2] = (1.0, -1.0)
def clear_homing_state(self, axes):
for i, _ in enumerate(self.limits):
if i in axes:
self.limits[i] = (1.0, -1.0)
def home_axis(self, homing_state, axis, rail):
position_min, position_max = rail.get_range()
hi = rail.get_homing_info()
Expand All @@ -97,7 +98,7 @@ def home(self, homing_state):
else:
self.home_axis(homing_state, axis, self.rails[axis])
def _motor_off(self, print_time):
self.limits = [(1.0, -1.0)] * 3
self.clear_homing_state((0, 1, 2))
def _check_endstops(self, move):
end_pos = move.end_pos
for i in (0, 1, 2):
Expand Down
9 changes: 5 additions & 4 deletions klippy/kinematics/hybrid_corexz.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,10 @@ def set_position(self, newpos, homing_axes):
else:
rail = self.rails[axis]
self.limits[axis] = rail.get_range()
def note_z_not_homed(self):
# Helper for Safe Z Home
self.limits[2] = (1.0, -1.0)
def clear_homing_state(self, axes):
for i, _ in enumerate(self.limits):
if i in axes:
self.limits[i] = (1.0, -1.0)
def home_axis(self, homing_state, axis, rail):
position_min, position_max = rail.get_range()
hi = rail.get_homing_info()
Expand All @@ -97,7 +98,7 @@ def home(self, homing_state):
else:
self.home_axis(homing_state, axis, self.rails[axis])
def _motor_off(self, print_time):
self.limits = [(1.0, -1.0)] * 3
self.clear_homing_state((0, 1, 2))
def _check_endstops(self, move):
end_pos = move.end_pos
for i in (0, 1, 2):
Expand Down
2 changes: 2 additions & 0 deletions klippy/kinematics/none.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ def calc_position(self, stepper_positions):
return [0, 0, 0]
def set_position(self, newpos, homing_axes):
pass
def clear_homing_state(self, axes):
pass
def home(self, homing_state):
pass
def check_move(self, move):
Expand Down
12 changes: 7 additions & 5 deletions klippy/kinematics/polar.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,12 @@ def set_position(self, newpos, homing_axes):
self.limit_z = self.rails[1].get_range()
if 0 in homing_axes and 1 in homing_axes:
self.limit_xy2 = self.rails[0].get_range()[1]**2
def note_z_not_homed(self):
# Helper for Safe Z Home
self.limit_z = (1.0, -1.0)
def clear_homing_state(self, axes):
if 0 in axes or 1 in axes:
# X and Y cannot be cleared separately
self.limit_xy2 = -1.
if 2 in axes:
self.limit_z = (1.0, -1.0)
def _home_axis(self, homing_state, axis, rail):
# Determine movement
position_min, position_max = rail.get_range()
Expand Down Expand Up @@ -86,8 +89,7 @@ def home(self, homing_state):
if home_z:
self._home_axis(homing_state, 2, self.rails[1])
def _motor_off(self, print_time):
self.limit_z = (1.0, -1.0)
self.limit_xy2 = -1.
self.clear_homing_state((0, 1, 2))
def check_move(self, move):
end_pos = move.end_pos
xy2 = end_pos[0]**2 + end_pos[1]**2
Expand Down
8 changes: 6 additions & 2 deletions klippy/kinematics/rotary_delta.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ def set_position(self, newpos, homing_axes):
self.limit_xy2 = -1.
if tuple(homing_axes) == (0, 1, 2):
self.need_home = False
def clear_homing_state(self, axes):
# Clearing homing state for each axis individually is not implemented
if 0 in axes or 1 in axes or 2 in axes:
self.limit_xy2 = -1
self.need_home = True
def home(self, homing_state):
# All axes are homed simultaneously
homing_state.set_axes([0, 1, 2])
Expand All @@ -97,8 +102,7 @@ def home(self, homing_state):
forcepos[2] = -1.
homing_state.home_rails(self.rails, forcepos, self.home_position)
def _motor_off(self, print_time):
self.limit_xy2 = -1.
self.need_home = True
self.clear_homing_state((0, 1, 2))
def check_move(self, move):
end_pos = move.end_pos
end_xy2 = end_pos[0]**2 + end_pos[1]**2
Expand Down
3 changes: 3 additions & 0 deletions klippy/kinematics/winch.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ def calc_position(self, stepper_positions):
def set_position(self, newpos, homing_axes):
for s in self.steppers:
s.set_position(newpos)
def clear_homing_state(self, axes):
# XXX - homing not implemented
pass
def home(self, homing_state):
# XXX - homing not implemented
homing_state.set_axes([0, 1, 2])
Expand Down
2 changes: 1 addition & 1 deletion klippy/stepper.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ def add_extra_stepper(self, config):
changed_invert = pin_params['invert'] != endstop['invert']
changed_pullup = pin_params['pullup'] != endstop['pullup']
if changed_invert or changed_pullup:
raise error("Pinter rail %s shared endstop pin %s "
raise error("Printer rail %s shared endstop pin %s "
"must specify the same pullup/invert settings" % (
self.get_name(), pin_name))
mcu_endstop.add_stepper(stepper)
Expand Down
3 changes: 2 additions & 1 deletion klippy/toolhead.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,13 +457,14 @@ def _flush_handler(self, eventtime):
# Movement commands
def get_position(self):
return list(self.commanded_pos)
def set_position(self, newpos, homing_axes=()):
def set_position(self, newpos, homing_axes=(), clear_axes=()):
self.flush_step_generation()
ffi_main, ffi_lib = chelper.get_ffi()
ffi_lib.trapq_set_position(self.trapq, self.print_time,
newpos[0], newpos[1], newpos[2])
self.commanded_pos[:] = newpos
self.kin.set_position(newpos, homing_axes)
self.kin.clear_homing_state(clear_axes)
self.printer.send_event("toolhead:set_position")
def limit_next_junction_speed(self, speed):
last_move = self.lookahead.get_last()
Expand Down