klipper/klippy/extras/tuning_tower.py

78 lines
3.2 KiB
Python

# Helper script to adjust parameters based on Z level
#
# Copyright (C) 2019 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import math, logging
CANCEL_Z_DELTA=2.0
class TuningTower:
def __init__(self, config):
self.printer = config.get_printer()
self.normal_transform = None
self.last_position = [0., 0., 0., 0.]
self.last_z = self.start = self.factor = self.band = 0.
self.command_fmt = ""
# Register command
self.gcode = self.printer.lookup_object("gcode")
self.gcode.register_command("TUNING_TOWER", self.cmd_TUNING_TOWER,
desc=self.cmd_TUNING_TOWER_help)
cmd_TUNING_TOWER_help = "Tool to adjust a parameter at each Z height"
def cmd_TUNING_TOWER(self, gcmd):
if self.normal_transform is not None:
self.end_test()
# Get parameters
command = gcmd.get('COMMAND')
parameter = gcmd.get('PARAMETER')
self.start = gcmd.get_float('START', 0.)
self.factor = gcmd.get_float('FACTOR')
self.band = gcmd.get_float('BAND', 0., minval=0.)
# Enable test mode
if self.gcode.is_traditional_gcode(command):
self.command_fmt = "%s %s%%.9f" % (command, parameter)
else:
self.command_fmt = "%s %s=%%.9f" % (command, parameter)
self.normal_transform = self.gcode.set_move_transform(self, force=True)
self.last_z = -99999999.9
self.gcode.reset_last_position()
self.get_position()
gcmd.respond_info("Starting tuning test (start=%.6f factor=%.6f)"
% (self.start, self.factor))
def get_position(self):
pos = self.normal_transform.get_position()
self.last_position = list(pos)
return pos
def calc_value(self, z):
if self.band:
z = (math.floor(z / self.band) + .5) * self.band
return self.start + z * self.factor
def move(self, newpos, speed):
normal_transform = self.normal_transform
if (newpos[3] > self.last_position[3] and newpos[2] != self.last_z
and newpos[:3] != self.last_position[:3]):
# Extrusion move at new z height
z = newpos[2]
if z < self.last_z - CANCEL_Z_DELTA:
# Extrude at a lower z height - probably start of new print
self.end_test()
else:
# Process update
z_offset = self.gcode.get_status()['base_zpos']
oldval = self.calc_value(self.last_z - z_offset)
newval = self.calc_value(z - z_offset)
self.last_z = z
if newval != oldval:
self.gcode.run_script_from_command(self.command_fmt
% (newval,))
# Forward move to actual handler
self.last_position[:] = newpos
normal_transform.move(newpos, speed)
def end_test(self):
self.gcode.respond_info("Ending tuning test mode")
self.gcode.set_move_transform(self.normal_transform, force=True)
self.normal_transform = None
def load_config(config):
return TuningTower(config)