klipper/klippy/extras/screws_tilt_adjust.py

93 lines
4.1 KiB
Python

# Helper script to adjust bed screws tilt using Z probe
#
# Copyright (C) 2019 Rui Caridade <rui.mcbc@gmail.com>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import math
import probe
def parse_coord(config, param):
pair = config.get(param).strip().split(',', 1)
try:
return (float(pair[0]), float(pair[1]))
except:
raise config.error("%s:%s needs to be an x,y coordinate" % (
config.get_name(), param))
class ScrewsTiltAdjust:
def __init__(self, config):
self.config = config
self.printer = config.get_printer()
self.screws = []
# Read config
for i in range(99):
prefix = "screw%d" % (i + 1,)
if config.get(prefix, None) is None:
break
screw_coord = parse_coord(config, prefix)
screw_name = "screw at %.3f,%.3f" % screw_coord
screw_name = config.get(prefix + "_name", screw_name)
self.screws.append((screw_coord, screw_name))
if len(self.screws) < 3:
raise config.error("screws_tilt_adjust: Must have "
"at least three screws")
self.threads = {'CW-M3': 0, 'CCW-M3': 1, 'CW-M4': 2, 'CCW-M4': 3,
'CW-M5': 4, 'CCW-M5': 5}
self.thread = config.getchoice('screw_thread', self.threads,
default='CW-M3')
# Initialize ProbePointsHelper
points = [coord for coord, name in self.screws]
self.probe_helper = probe.ProbePointsHelper(self.config,
self.probe_finalize,
default_points=points)
self.probe_helper.minimum_points(3)
# Register command
self.gcode = self.printer.lookup_object('gcode')
self.gcode.register_command("SCREWS_TILT_CALCULATE",
self.cmd_SCREWS_TILT_CALCULATE,
desc=self.cmd_SCREWS_TILT_CALCULATE_help)
cmd_SCREWS_TILT_CALCULATE_help = "Tool to help adjust bed leveling " \
"screws by calculating the number " \
"of turns to level it."
def cmd_SCREWS_TILT_CALCULATE(self, params):
self.probe_helper.start_probe(params)
def probe_finalize(self, offsets, positions):
# Factors used for CW-M3, CCW-M3, CW-M4, CCW-M4, CW-M5 and CCW-M5
threads_factor = {0: 0.5, 1: 0.5, 2: 0.7, 3: 0.7, 4: 0.8, 5: 0.8}
# Process the read Z values and
for i, screw in enumerate(self.screws):
if i == 0:
# First screw is the base position used for comparison
z_base = positions[i][2]
coord_base, name_base = screw
# Show the results
self.gcode.respond_info("%s (Base): X %.1f, Y %.1f, Z %.5f" %
(name_base, coord_base[0],
coord_base[1], z_base))
else:
# Calculate how knob must me adjusted for other positions
z = positions[i][2]
coord, name = screw
diff = z_base - z
if abs(diff) < 0.001:
adjust = 0
else:
adjust = diff / threads_factor.get(self.thread, 0.5)
if (self.thread & 1) == 1:
sign = "CW" if adjust < 0 else "CCW"
else:
sign = "CCW" if adjust < 0 else "CW"
full_turns = math.trunc(adjust)
decimal_part = adjust - full_turns
minutes = round(decimal_part * 60, 0)
# Show the results
self.gcode.respond_info("%s : X %.1f, Y %.1f, Z %.5f : "
"Adjust -> %s %02d:%02d" %
(name, coord[0], coord[1], z, sign,
abs(full_turns), abs(minutes)))
def load_config(config):
return ScrewsTiltAdjust(config)