Skip to content

Commit

Permalink
force_move: implement CLEAR for SET_KINEMATIC_POSITION
Browse files Browse the repository at this point in the history
`CLEAR` clears the homing status (resets the axis limits) without turning off
the motors. This is particularly useful when implementing safe Z homing in
`[homing_override]` on printers with multiple independent Z steppers (where
`FORCE_MOVE` can't be used).

Signed-off-by: Dennis Marttinen <[email protected]>
  • Loading branch information
twelho committed Aug 18, 2024
1 parent d9707ea commit 259afc0
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 12 deletions.
19 changes: 10 additions & 9 deletions docs/G-Codes.md
Original file line number Diff line number Diff line change
Expand Up @@ -553,15 +553,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']
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)
3 changes: 2 additions & 1 deletion klippy/toolhead.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,13 +453,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 move(self, newpos, speed):
move = Move(self, self.commanded_pos, newpos, speed)
Expand Down

0 comments on commit 259afc0

Please sign in to comment.