From 5989f7a8a67a0900e1283f9534948f6185424322 Mon Sep 17 00:00:00 2001 From: Len Trigg Date: Fri, 7 Jun 2019 01:10:09 +1200 Subject: [PATCH] firmware_retraction: Implementation of tuneable G10/G11 firmware retraction (#1617) This supports getting and setting of retraction parameters without having to restart klippy. Signed-off-by: Len Trigg --- config/example-extras.cfg | 21 +++++++ docs/G-Codes.md | 30 ++++++++++ klippy/extras/firmware_retraction.py | 89 ++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+) create mode 100644 klippy/extras/firmware_retraction.py diff --git a/config/example-extras.cfg b/config/example-extras.cfg index d3e1f1c7..b0f8cdf3 100644 --- a/config/example-extras.cfg +++ b/config/example-extras.cfg @@ -1593,6 +1593,27 @@ #measurement_delay: 100 +# Firmware filament retraction. This enables G10 (retract) and G11 +# (unretract) GCODE commands issued by many slicers. The parameters +# below provide startup defaults, although the values can be adjusted +# via the SET_RETRACTION command, allowing per-filament settings and +# runtime tuning. +#[firmware_retraction] +#retract_length: 0 +# The length of filament (in mm) to retract when G10 is activated, and to +# unretract when G11 is activated (but see unretract_extra_length below). +# The default is 0 mm. +#retract_speed: 20 +# The speed of retraction, in mm/s. The default is 20 mm/s. +#unretract_extra_length: 0 +# The length (in mm) of *additional* filament to add when unretracting. +#unretract_speed: 10 +# The speed of unretraction, in mm/s. The default is 10 mm/s. +#z_hop: 0 +# The amount of lift applied to the Z axis (in mm) on retract and +# restored on unretract. The default is 0 mm. + + # Include file support. One may include additional config file from # the main printer config file. Wildcards may also be used (eg, # "configs/*.cfg"). diff --git a/docs/G-Codes.md b/docs/G-Codes.md index 966371e7..03d35460 100644 --- a/docs/G-Codes.md +++ b/docs/G-Codes.md @@ -422,3 +422,33 @@ section is enabled. - `QUERY_FILAMENT_SENSOR SENSOR=`: Queries the current status of the filament sensor. The data displayed on the terminal will depend on the sensor type defined in the confguration. + +## Firmware Retraction + +The following commands are available when the "firmware_retraction" +config section is enabled. These commands allow you to utilise the +firmware retraction feature available in many slicers, to reduce +stringing during non-extrusion moves from one part of the print to +another. Appropriately configuring pressure advance reduces the length +of retraction required. + - `SET_RETRACTION [RETRACT_LENGTH=] [RETRACT_SPEED=] + [UNRETRACT_EXTRA_LENGTH=] [UNRETRACT_SPEED=] [Z_HOP=]`: + Adjust the parameters used by firmware retraction. RETRACT_LENGTH + determines the length of filament to retract and unretract. The + speed of retraction is adjusted via RETRACT_SPEED, and is typically + set relatively high. The speed of unretraction is adjusted via + UNRETRACT_SPEED, and is not particularly critical, although often + lower than RETRACT_SPEED. In some cases it is useful to add a small + amount of additional length on unretraction, and this is set via + UNRETRACT_EXTRA_LENGTH. It is possible to lift the Z axis by a small + amount when in retracted state by setting Z_HOP, although this is + more commonly used for printers where fast Z movements are supported, + such as delta printers. SET_RETRACTION is commonly set as part of + slicer per-filament configuration, as different filaments require + different parameter settings. + - `GET_RETRACTION`: Queries the current parameters used by firmware + retraction and displays them on the terminal. + - `G10`: Retracts the extruder using the currently configured + parameters. + - `G11`: Unretracts the extruder using the currently configured + parameters. diff --git a/klippy/extras/firmware_retraction.py b/klippy/extras/firmware_retraction.py new file mode 100644 index 00000000..c4b2a3ac --- /dev/null +++ b/klippy/extras/firmware_retraction.py @@ -0,0 +1,89 @@ +# Support for Marlin/Smoothie/Reprap style firmware retraction via G10/G11 +# +# Copyright (C) 2019 Len Trigg +# +# This file may be distributed under the terms of the GNU GPLv3 license. + +class FirmwareRetraction: + def __init__(self, config): + self.printer = config.get_printer() + self.retract_length = config.getfloat('retract_length', 0., minval=0.) + self.retract_speed = config.getfloat('retract_speed', 20., minval=1) + self.unretract_extra_length = config.getfloat( + 'unretract_extra_length', 0., minval=0.) + self.unretract_speed = config.getfloat('unretract_speed', 10., minval=1) + self.z_hop = config.getfloat('z_hop', 0., minval=0.) + self.unretract_length = (self.retract_length + + self.unretract_extra_length) + self.is_retracted = False + self.gcode = self.printer.lookup_object('gcode') + self.gcode.register_command('SET_RETRACTION', self.cmd_SET_RETRACTION) + self.gcode.register_command('GET_RETRACTION', self.cmd_GET_RETRACTION) + self.gcode.register_command('G10', self.cmd_G10) + self.gcode.register_command('G11', self.cmd_G11) + + def get_status(self, eventtime): + return { + "retract_length": self.retract_length, + "retract_speed": self.retract_speed, + "unretract_extra_length": self.unretract_extra_length, + "unretract_speed": self.unretract_speed, + "z_hop": self.z_hop + } + + def cmd_SET_RETRACTION(self, params): + self.retract_length = self.gcode.get_float( + 'RETRACT_LENGTH', + params, self.retract_length, minval=0.) + self.retract_speed = self.gcode.get_float( + 'RETRACT_SPEED', + params, self.retract_speed, minval=1) + self.unretract_extra_length = self.gcode.get_float( + 'UNRETRACT_EXTRA_LENGTH', + params, self.unretract_extra_length, minval=0.) + self.unretract_speed = self.gcode.get_float( + 'UNRETRACT_SPEED', + params, self.unretract_speed, minval=1) + self.z_hop = self.gcode.get_float( + 'Z_HOP', + params, self.z_hop, minval=0.) + self.unretract_length = (self.retract_length + + self.unretract_extra_length) + self.is_retracted = False + + def cmd_GET_RETRACTION(self, params): + msg = ("RETRACT_LENGTH=%.5f RETRACT_SPEED=%.5f " + "UNRETRACT_EXTRA_LENGTH=%.5f UNRETRACT_SPEED=%.5f " + "Z_HOP=%.5f" + % (self.retract_length, self.retract_speed, + self.unretract_extra_length, self.unretract_speed, + self.z_hop)) + self.gcode.respond_info(msg) + + def cmd_G10(self, params): + if not self.is_retracted: + self.gcode.run_script_from_command( + "SAVE_GCODE_STATE NAME=_retract_state\n" + "G92 E0\n" + "G91\n" + "G1 E-%.5f F%d\n" + "G1 Z%.5f\n" + "RESTORE_GCODE_STATE NAME=_retract_state" + % (self.retract_length, self.retract_speed*60, self.z_hop)) + self.is_retracted = True + + def cmd_G11(self, params): + if self.is_retracted: + self.gcode.run_script_from_command( + "SAVE_GCODE_STATE NAME=_retract_state\n" + "G92 E0\n" + "G91\n" + "G1 E%.5f F%d\n" + "G1 Z-%.5f\n" + "RESTORE_GCODE_STATE NAME=_retract_state" + % (self.unretract_length, self.unretract_speed*60, self.z_hop)) + self.is_retracted = False + + +def load_config(config): + return FirmwareRetraction(config)