aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2019-05-26 11:08:48 -0400
committerKevinOConnor <kevin@koconnor.net>2019-05-31 10:23:56 -0400
commitc54b8da530dc724b129066d1f3a825226926c5e6 (patch)
tree53427f9698d057714120afa9c7158222eab149ec
parent9e7ef3cf890e30aa82cef27f6155cffa152b2c7f (diff)
downloadkutter-c54b8da530dc724b129066d1f3a825226926c5e6.tar.gz
kutter-c54b8da530dc724b129066d1f3a825226926c5e6.tar.xz
kutter-c54b8da530dc724b129066d1f3a825226926c5e6.zip
gcode: Add support for SAVE_GCODE_STATE and RESTORE_GCODE_STATE commands
Add commands to save and restore the current g-code state. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
-rw-r--r--docs/G-Codes.md16
-rw-r--r--klippy/gcode.py42
-rw-r--r--test/klippy/commands.test15
3 files changed, 71 insertions, 2 deletions
diff --git a/docs/G-Codes.md b/docs/G-Codes.md
index 486be0da..6f895e52 100644
--- a/docs/G-Codes.md
+++ b/docs/G-Codes.md
@@ -105,6 +105,22 @@ The following standard commands are supported:
axis). If "MOVE_SPEED" is specified then the toolhead move will be
performed with the given speed (in mm/s); otherwise the toolhead
move will use the last specified G-Code speed.
+- `SAVE_GCODE_STATE [NAME=<state_name>]`: Save the current
+ g-code coordinate parsing state. Saving and restoring the g-code
+ state is useful in scripts and macros. This command saves the
+ current g-code absolute coordinate mode (G90/G91), absolute extrude
+ mode (M82/M83), origin (G92), offset (SET_GCODE_OFFSET), speed
+ override (M220), extruder override (M221), move speed, current XYZ
+ position, and relative extruder "E" position. If NAME is provided it
+ allows one to name the saved state to the given string. If NAME is
+ not provided it defaults to "default".
+- `RESTORE_GCODE_STATE [NAME=<state_name>]
+ [MOVE=1 [MOVE_SPEED=<speed>]]`: Restore a state previously saved via
+ SAVE_GCODE_STATE. If "MOVE=1" is specified then a toolhead move will
+ be issued to move back to the previous XYZ position. If "MOVE_SPEED"
+ is specified then the toolhead move will be performed with the given
+ speed (in mm/s); otherwise the toolhead move will use the restored
+ g-code speed.
- `PID_CALIBRATE HEATER=<config_name> TARGET=<temperature>
[WRITE_FILE=1]`: Perform a PID calibration test. The specified
heater will be enabled until the specified target temperature is
diff --git a/klippy/gcode.py b/klippy/gcode.py
index 5328ae4e..975bfcfe 100644
--- a/klippy/gcode.py
+++ b/klippy/gcode.py
@@ -53,9 +53,10 @@ class GCodeParser:
self.speed = 25.
self.speed_factor = 1. / 60.
self.extrude_factor = 1.
+ # G-Code state
+ self.saved_states = {}
self.move_transform = self.move_with_transform = None
self.position_with_transform = (lambda: [0., 0., 0., 0.])
- # G-Code state
self.need_ack = False
self.toolhead = self.fan = self.extruder = None
self.heaters = None
@@ -485,7 +486,7 @@ class GCodeParser:
all_handlers = [
'G1', 'G4', 'G28', 'M18', 'M400',
'G20', 'M82', 'M83', 'G90', 'G91', 'G92', 'M114', 'M220', 'M221',
- 'SET_GCODE_OFFSET', 'M206',
+ 'SET_GCODE_OFFSET', 'M206', 'SAVE_GCODE_STATE', 'RESTORE_GCODE_STATE',
'M105', 'M104', 'M109', 'M140', 'M190', 'M106', 'M107',
'M112', 'M115', 'IGNORE', 'GET_POSITION',
'RESTART', 'FIRMWARE_RESTART', 'ECHO', 'STATUS', 'HELP']
@@ -631,6 +632,43 @@ class GCodeParser:
delta = offset - self.homing_position[pos]
self.base_position[pos] += delta
self.homing_position[pos] = offset
+ cmd_SAVE_GCODE_STATE_help = "Save G-Code coordinate state"
+ def cmd_SAVE_GCODE_STATE(self, params):
+ state_name = self.get_str('NAME', params, 'default')
+ self.saved_states[state_name] = {
+ 'absolute_coord': self.absolute_coord,
+ 'absolute_extrude': self.absolute_extrude,
+ 'base_position': list(self.base_position),
+ 'last_position': list(self.last_position),
+ 'homing_position': list(self.homing_position),
+ 'speed': self.speed, 'speed_factor': self.speed_factor,
+ 'extrude_factor': self.extrude_factor,
+ }
+ cmd_RESTORE_GCODE_STATE_help = "Restore a previously saved G-Code state"
+ def cmd_RESTORE_GCODE_STATE(self, params):
+ state_name = self.get_str('NAME', params, 'default')
+ state = self.saved_states.get(state_name)
+ if state is None:
+ raise error("Unknown g-code state: %s" % (state_name,))
+ # Restore state
+ self.absolute_coord = state['absolute_coord']
+ self.absolute_extrude = state['absolute_extrude']
+ self.base_position = list(state['base_position'])
+ self.homing_position = list(state['homing_position'])
+ self.speed = state['speed']
+ self.speed_factor = state['speed_factor']
+ self.extrude_factor = state['extrude_factor']
+ # Restore the relative E position
+ e_diff = self.last_position[3] - state['last_position'][3]
+ self.base_position[3] += e_diff
+ # Move the toolhead back if requested
+ if self.get_int('MOVE', params, 0):
+ speed = self.get_float('MOVE_SPEED', params, self.speed, above=0.)
+ self.last_position[:3] = state['last_position'][:3]
+ try:
+ self.move_with_transform(self.last_position, speed)
+ except homing.EndstopError as e:
+ raise error(str(e))
# G-Code temperature and fan commands
cmd_M105_when_not_ready = True
def cmd_M105(self, params):
diff --git a/test/klippy/commands.test b/test/klippy/commands.test
index a32b26e2..3327696e 100644
--- a/test/klippy/commands.test
+++ b/test/klippy/commands.test
@@ -19,6 +19,21 @@ RESTART
M18
+# G-code state commands
+G28
+SAVE_GCODE_STATE
+G92 Z-5
+G92 E5
+SAVE_GCODE_STATE NAME=test
+G1 Z-5
+G91
+G1 Z0
+RESTORE_GCODE_STATE NAME=test
+G1 Z-5
+RESTORE_GCODE_STATE
+G1 Z0 E0
+RESTORE_GCODE_STATE MOVE=1
+
# Update commands
SET_GCODE_OFFSET Z=.1
M206 Z-.2