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>
This commit is contained in:
Kevin O'Connor 2019-05-26 11:08:48 -04:00 committed by KevinOConnor
parent 9e7ef3cf89
commit c54b8da530
3 changed files with 71 additions and 2 deletions

View File

@ -105,6 +105,22 @@ The following standard commands are supported:
axis). If "MOVE_SPEED" is specified then the toolhead move will be axis). If "MOVE_SPEED" is specified then the toolhead move will be
performed with the given speed (in mm/s); otherwise the toolhead performed with the given speed (in mm/s); otherwise the toolhead
move will use the last specified G-Code speed. 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> - `PID_CALIBRATE HEATER=<config_name> TARGET=<temperature>
[WRITE_FILE=1]`: Perform a PID calibration test. The specified [WRITE_FILE=1]`: Perform a PID calibration test. The specified
heater will be enabled until the specified target temperature is heater will be enabled until the specified target temperature is

View File

@ -53,9 +53,10 @@ class GCodeParser:
self.speed = 25. self.speed = 25.
self.speed_factor = 1. / 60. self.speed_factor = 1. / 60.
self.extrude_factor = 1. self.extrude_factor = 1.
# G-Code state
self.saved_states = {}
self.move_transform = self.move_with_transform = None self.move_transform = self.move_with_transform = None
self.position_with_transform = (lambda: [0., 0., 0., 0.]) self.position_with_transform = (lambda: [0., 0., 0., 0.])
# G-Code state
self.need_ack = False self.need_ack = False
self.toolhead = self.fan = self.extruder = None self.toolhead = self.fan = self.extruder = None
self.heaters = None self.heaters = None
@ -485,7 +486,7 @@ class GCodeParser:
all_handlers = [ all_handlers = [
'G1', 'G4', 'G28', 'M18', 'M400', 'G1', 'G4', 'G28', 'M18', 'M400',
'G20', 'M82', 'M83', 'G90', 'G91', 'G92', 'M114', 'M220', 'M221', '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', 'M105', 'M104', 'M109', 'M140', 'M190', 'M106', 'M107',
'M112', 'M115', 'IGNORE', 'GET_POSITION', 'M112', 'M115', 'IGNORE', 'GET_POSITION',
'RESTART', 'FIRMWARE_RESTART', 'ECHO', 'STATUS', 'HELP'] 'RESTART', 'FIRMWARE_RESTART', 'ECHO', 'STATUS', 'HELP']
@ -631,6 +632,43 @@ class GCodeParser:
delta = offset - self.homing_position[pos] delta = offset - self.homing_position[pos]
self.base_position[pos] += delta self.base_position[pos] += delta
self.homing_position[pos] = offset 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 # G-Code temperature and fan commands
cmd_M105_when_not_ready = True cmd_M105_when_not_ready = True
def cmd_M105(self, params): def cmd_M105(self, params):

View File

@ -19,6 +19,21 @@ RESTART
M18 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 # Update commands
SET_GCODE_OFFSET Z=.1 SET_GCODE_OFFSET Z=.1
M206 Z-.2 M206 Z-.2