tuning_tower: Add STEP_DELTA and STEP_HEIGHT parameters as alternate tuning tower syntax

Signed-off-by: Matthew Lloyd <github@matthewlloyd.net>
This commit is contained in:
github@matthewlloyd.net 2021-08-31 20:06:13 -04:00 committed by KevinOConnor
parent 286cc1becc
commit 830c80a88a
2 changed files with 51 additions and 15 deletions

View File

@ -212,18 +212,33 @@ The following standard commands are supported:
babystepping), and subtract it from the stepper_z endstop_position.
This acts to take a frequently used babystepping value, and "make
it permanent". Requires a `SAVE_CONFIG` to take effect.
- `TUNING_TOWER COMMAND=<command> PARAMETER=<name> START=<value>
FACTOR=<value> [BAND=<value>] [SKIP=<value>]`: A tool for tuning
a parameter on each Z height during a print. The tool will run
the given COMMAND with the given PARAMETER assigned to the value
using the formula `value = start + factor * z_height`. If BAND is
provided then the adjustment will only be made every BAND
millimeters of z height - in that case the formula used is
`value = start + factor * ((floor(z_height / band) + .5) * band)`.
If `SKIP=<value>` is specified, the tuning process doesn't begin
until Z height `<value>` is reached, and below that the value will
be set to `START`; in this case, the `z_height` used in the
formulas above is actually `max(z - skip, 0)`.
- `TUNING_TOWER COMMAND=<command> PARAMETER=<name> START=<value> [SKIP=<value>]
[FACTOR=<value> [BAND=<value>]] | [STEP_DELTA=<value> STEP_HEIGHT=<value>]`:
A tool for tuning a parameter on each Z height during a print.
The tool will run the given `COMMAND` with the given `PARAMETER`
assigned to a value that varies with `Z` according to a formula. Use `FACTOR`
if you will use a ruler or calipers to measure the Z height of the optimum
value, or `STEP_DELTA` and `STEP_HEIGHT` if the tuning tower model has bands
of discrete values as is common with temperature towers. If `SKIP=<value>`
is specified, the tuning process doesn't begin until Z height `<value>` is
reached, and below that the value will be set to `START`; in this case, the
`z_height` used in the formulas below is actually `max(z - skip, 0)`.
There are three possible combinations of options:
- `FACTOR`: The value changes at a rate of `factor` per millimeter.
The formula used is
`value = start + factor * z_height`.
You can plug the optimum Z height directly into the formula to
determine the optimum parameter value.
- `FACTOR` and `BAND`: The value changes at an average rate of `factor` per
millimeter, but in discrete bands where the adjustment will only be made
every `BAND` millimeters of Z height.
The formula used is
`value = start + factor * ((floor(z_height / band) + .5) * band)`.
- `STEP_DELTA` and `STEP_HEIGHT`: The value changes by `STEP_DELTA` every
`STEP_HEIGHT` millimeters. The formula used is
`value = start + step_delta * floor(z_height / step_height)`.
You can simply count bands or read tuning tower labels to determine the
optimum value.
- `SET_DISPLAY_GROUP [DISPLAY=<display>] GROUP=<group>`: Set the
active display group of an lcd display. This allows to define
multiple display data groups in the config,

View File

@ -28,9 +28,16 @@ class TuningTower:
command = gcmd.get('COMMAND')
parameter = gcmd.get('PARAMETER')
self.start = gcmd.get_float('START', 0.)
self.factor = gcmd.get_float('FACTOR')
self.factor = gcmd.get_float('FACTOR', 0.)
self.band = gcmd.get_float('BAND', 0., minval=0.)
self.step_delta = gcmd.get_float('STEP_DELTA', 0.)
self.step_height = gcmd.get_float('STEP_HEIGHT', 0., minval=0.)
self.skip = gcmd.get_float('SKIP', 0., minval=0.)
if self.factor and (self.step_height or self.step_delta):
raise gcmd.error(
"Cannot specify both FACTOR and STEP_DELTA/STEP_HEIGHT")
if (self.step_delta != 0.) != (self.step_height != 0.):
raise gcmd.error("Must specify both STEP_DELTA and STEP_HEIGHT")
# Enable test mode
if self.gcode.is_traditional_gcode(command):
self.command_fmt = "%s %s%%.9f" % (command, parameter)
@ -41,8 +48,19 @@ class TuningTower:
self.last_z = -99999999.9
self.last_command_value = None
self.get_position()
gcmd.respond_info("Starting tuning test (start=%.6f factor=%.6f)"
% (self.start, self.factor))
message_parts = []
message_parts.append("start=%.6f" % (self.start,))
if self.factor:
message_parts.append("factor=%.6f" % (self.factor,))
if self.band:
message_parts.append("band=%.6f" % (self.band,))
else:
message_parts.append("step_delta=%.6f" % (self.step_delta,))
message_parts.append("step_height=%.6f" % (self.step_height,))
if self.skip:
message_parts.append("skip=%.6f" % (self.skip,))
gcmd.respond_info(
"Starting tuning test (" + " ".join(message_parts) + ")")
def get_position(self):
pos = self.normal_transform.get_position()
self.last_position = list(pos)
@ -50,6 +68,9 @@ class TuningTower:
def calc_value(self, z):
if self.skip:
z = max(0., z - self.skip)
if self.step_height:
return self.start + \
self.step_delta * math.floor(z / self.step_height)
if self.band:
z = (math.floor(z / self.band) + .5) * self.band
return self.start + z * self.factor