From 2e0c2262e7c52cbc2ea4784e582fac2f1d3b9d67 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Sun, 21 Dec 2025 12:28:36 -0500 Subject: [PATCH] probe: Convert ProbePointsHelper to use ProbeResult Change the ProbePointsHelper class to return ProbeResult tuples. Callers of this class are also updated so that they use the tuple's bed_xyz parameters instead of manually calculating these values from the probe xyz offsets. Signed-off-by: Kevin O'Connor --- docs/Config_Changes.md | 14 +++++++++++--- klippy/extras/bed_mesh.py | 22 +++++++++++++--------- klippy/extras/bed_tilt.py | 13 +++++-------- klippy/extras/delta_calibrate.py | 8 ++++---- klippy/extras/probe.py | 10 ++++++---- klippy/extras/quad_gantry_level.py | 20 ++++++++++---------- klippy/extras/screws_tilt_adjust.py | 8 ++++---- klippy/extras/z_tilt.py | 13 +++++-------- 8 files changed, 58 insertions(+), 50 deletions(-) diff --git a/docs/Config_Changes.md b/docs/Config_Changes.md index 6846e034d..76f455af5 100644 --- a/docs/Config_Changes.md +++ b/docs/Config_Changes.md @@ -8,9 +8,17 @@ All dates in this document are approximate. ## Changes -20251122: An option `axis` has been added to `[carriage ]` sections -for `generic_cartesian` kinematics, allowing arbitrary names for primary -carriages. Users are encouraged to explicitly specify `axis` option now. +20260109: The `[screws_tilt_adjust]` module now reports the status +variable `{printer.screws_tilt_adjust.result.screw1.z}` with the +probe's `z_offset` applied. That is, one would previously need to +subtract the probe's configured `z_offset` to find the absolute Z +deviation at the given screw location and now one must not apply the +`z_offset`. + +20251122: An option `axis` has been added to `[carriage ]` +sections for `generic_cartesian` kinematics, allowing arbitrary names +for primary carriages. Users are encouraged to explicitly specify +`axis` option now. 20251106: The status fields `{printer.toolhead.position}`, `{printer.gcode_move.position}`, diff --git a/klippy/extras/bed_mesh.py b/klippy/extras/bed_mesh.py index a8e5764c0..f752980e0 100644 --- a/klippy/extras/bed_mesh.py +++ b/klippy/extras/bed_mesh.py @@ -651,9 +651,9 @@ class BedMeshCalibrate: except BedMeshError as e: raise gcmd.error(str(e)) self.probe_mgr.start_probe(gcmd) - def probe_finalize(self, offsets, positions): - z_offset = offsets[2] - positions = [[round(p[0], 2), round(p[1], 2), p[2]] + def probe_finalize(self, positions): + z_offset = 0. + positions = [[round(p.bed_x, 2), round(p.bed_y, 2), p.bed_z] for p in positions] if self.probe_mgr.get_zero_ref_mode() == ZrefMode.PROBE: ref_pos = positions.pop() @@ -682,7 +682,7 @@ class BedMeshCalibrate: idx_offset = 0 start_idx = 0 for i, pts in substitutes.items(): - fpt = [p - o for p, o in zip(base_points[i], offsets[:2])] + fpt = base_points[i][:2] # offset the index to account for additional samples idx = i + idx_offset # Add "normal" points @@ -702,7 +702,7 @@ class BedMeshCalibrate: # validate length of result if len(base_points) != len(positions): - self._dump_points(probed_pts, positions, offsets) + self._dump_points(probed_pts, positions) raise self.gcode.error( "bed_mesh: invalid position list size, " "generated count: %d, probed count: %d" @@ -713,7 +713,7 @@ class BedMeshCalibrate: row = [] prev_pos = base_points[0] for pos, result in zip(base_points, positions): - offset_pos = [p - o for p, o in zip(pos, offsets[:2])] + offset_pos = pos[:2] if ( not isclose(offset_pos[0], result[0], abs_tol=.5) or not isclose(offset_pos[1], result[1], abs_tol=.5) @@ -786,7 +786,7 @@ class BedMeshCalibrate: self.gcode.respond_info("Mesh Bed Leveling Complete") if self._profile_name is not None: self.bedmesh.save_profile(self._profile_name) - def _dump_points(self, probed_pts, corrected_pts, offsets): + def _dump_points(self, probed_pts, corrected_pts): # logs generated points with offset applied, points received # from the finalize callback, and the list of corrected points points = self.probe_mgr.get_base_points() @@ -797,7 +797,7 @@ class BedMeshCalibrate: for i in list(range(max_len)): gen_pt = probed_pt = corr_pt = "" if i < len(points): - off_pt = [p - o for p, o in zip(points[i], offsets[:2])] + off_pt = points[i][:2] gen_pt = "(%.2f, %.2f)" % tuple(off_pt) if i < len(probed_pts): probed_pt = "(%.2f, %.2f, %.4f)" % tuple(probed_pts[i]) @@ -1220,8 +1220,12 @@ class RapidScanHelper: if is_probe_pt: probe_session.run_probe(gcmd) results = probe_session.pull_probed_results() + import manual_probe # XXX + results = [manual_probe.ProbeResult( + r[0]+offsets[0], r[1]+offsets[1], r[2]-offsets[2], r[0], r[1], r[2]) + for r in results] toolhead.get_last_move_time() - self.finalize_callback(offsets, results) + self.finalize_callback(results) probe_session.end_probe_session() def _raise_tool(self, gcmd, scan_height): diff --git a/klippy/extras/bed_tilt.py b/klippy/extras/bed_tilt.py index e5686cbeb..feb924997 100644 --- a/klippy/extras/bed_tilt.py +++ b/klippy/extras/bed_tilt.py @@ -58,19 +58,17 @@ class BedTiltCalibrate: cmd_BED_TILT_CALIBRATE_help = "Bed tilt calibration script" def cmd_BED_TILT_CALIBRATE(self, gcmd): self.probe_helper.start_probe(gcmd) - def probe_finalize(self, offsets, positions): + def probe_finalize(self, positions): # Setup for coordinate descent analysis - z_offset = offsets[2] logging.info("Calculating bed_tilt with: %s", positions) params = { 'x_adjust': self.bedtilt.x_adjust, 'y_adjust': self.bedtilt.y_adjust, - 'z_adjust': z_offset } + 'z_adjust': 0. } logging.info("Initial bed_tilt parameters: %s", params) # Perform coordinate descent def adjusted_height(pos, params): - x, y, z = pos - return (z - x*params['x_adjust'] - y*params['y_adjust'] - - params['z_adjust']) + return (pos.bed_z - pos.bed_x*params['x_adjust'] + - pos.bed_y*params['y_adjust'] - params['z_adjust']) def errorfunc(params): total_error = 0. for pos in positions: @@ -81,8 +79,7 @@ class BedTiltCalibrate: # Update current bed_tilt calculations x_adjust = new_params['x_adjust'] y_adjust = new_params['y_adjust'] - z_adjust = (new_params['z_adjust'] - z_offset - - x_adjust * offsets[0] - y_adjust * offsets[1]) + z_adjust = new_params['z_adjust'] self.bedtilt.update_adjust(x_adjust, y_adjust, z_adjust) # Log and report results logging.info("Calculated bed_tilt parameters: %s", new_params) diff --git a/klippy/extras/delta_calibrate.py b/klippy/extras/delta_calibrate.py index 4054e2310..df7f39356 100644 --- a/klippy/extras/delta_calibrate.py +++ b/klippy/extras/delta_calibrate.py @@ -152,12 +152,12 @@ class DeltaCalibrate: "%.3f,%.3f,%.3f" % tuple(spos1)) configfile.set(section, "distance%d_pos2" % (i,), "%.3f,%.3f,%.3f" % tuple(spos2)) - def probe_finalize(self, offsets, positions): + def probe_finalize(self, positions): # Convert positions into (z_offset, stable_position) pairs - z_offset = offsets[2] kin = self.printer.lookup_object('toolhead').get_kinematics() - delta_params = kin.get_calibration() - probe_positions = [(z_offset, delta_params.calc_stable_position(p)) + csp = kin.get_calibration().calc_stable_position + probe_positions = [(p.test_z - p.bed_z, + csp([p.test_x, p.test_y, p.test_z])) for p in positions] # Perform analysis self.calculate_params(probe_positions, self.last_distances) diff --git a/klippy/extras/probe.py b/klippy/extras/probe.py index 15c3db255..600d64e47 100644 --- a/klippy/extras/probe.py +++ b/klippy/extras/probe.py @@ -466,7 +466,7 @@ class ProbePointsHelper: toolhead = self.printer.lookup_object('toolhead') toolhead.get_last_move_time() # Invoke callback - res = self.finalize_callback(self.probe_offsets, results) + res = self.finalize_callback(results) return res != "retry" def _move_next(self, probe_num): # Move to next XY probe point @@ -502,6 +502,10 @@ class ProbePointsHelper: self._raise_tool(not probe_num) if probe_num >= len(self.probe_points): results = probe_session.pull_probed_results() + results = [manual_probe.ProbeResult( + r[0] + self.probe_offsets[0], r[1] + self.probe_offsets[1], + r[2] - self.probe_offsets[2], r[0], r[1], r[2]) + for r in results] done = self._invoke_callback(results) if done: break @@ -514,9 +518,7 @@ class ProbePointsHelper: def _manual_probe_start(self): self._raise_tool(not self.manual_results) if len(self.manual_results) >= len(self.probe_points): - results = [[mpr.bed_x, mpr.bed_y, mpr.bed_z] - for mpr in self.manual_results] - done = self._invoke_callback(results) + done = self._invoke_callback(self.manual_results) if done: return # Caller wants a "retry" - clear results and restart probing diff --git a/klippy/extras/quad_gantry_level.py b/klippy/extras/quad_gantry_level.py index 98cd53c5a..5556d5e1d 100644 --- a/klippy/extras/quad_gantry_level.py +++ b/klippy/extras/quad_gantry_level.py @@ -51,34 +51,34 @@ class QuadGantryLevel: self.z_status.reset() self.retry_helper.start(gcmd) self.probe_helper.start_probe(gcmd) - def probe_finalize(self, offsets, positions): + def probe_finalize(self, positions): # Mirror our perspective so the adjustments make sense # from the perspective of the gantry - z_positions = [self.horizontal_move_z - p[2] for p in positions] + z_positions = [self.horizontal_move_z - p.bed_z for p in positions] points_message = "Gantry-relative probe points:\n%s\n" % ( " ".join(["%s: %.6f" % (z_id, z_positions[z_id]) for z_id in range(len(z_positions))])) self.gcode.respond_info(points_message) # Calculate slope along X axis between probe point 0 and 3 - ppx0 = [positions[0][0] + offsets[0], z_positions[0]] - ppx3 = [positions[3][0] + offsets[0], z_positions[3]] + ppx0 = [positions[0].bed_x, z_positions[0]] + ppx3 = [positions[3].bed_x, z_positions[3]] slope_x_pp03 = self.linefit(ppx0, ppx3) # Calculate slope along X axis between probe point 1 and 2 - ppx1 = [positions[1][0] + offsets[0], z_positions[1]] - ppx2 = [positions[2][0] + offsets[0], z_positions[2]] + ppx1 = [positions[1].bed_x, z_positions[1]] + ppx2 = [positions[2].bed_x, z_positions[2]] slope_x_pp12 = self.linefit(ppx1, ppx2) logging.info("quad_gantry_level f1: %s, f2: %s" % (slope_x_pp03, slope_x_pp12)) # Calculate gantry slope along Y axis between stepper 0 and 1 - a1 = [positions[0][1] + offsets[1], + a1 = [positions[0].bed_y, self.plot(slope_x_pp03, self.gantry_corners[0][0])] - a2 = [positions[1][1] + offsets[1], + a2 = [positions[1].bed_y, self.plot(slope_x_pp12, self.gantry_corners[0][0])] slope_y_s01 = self.linefit(a1, a2) # Calculate gantry slope along Y axis between stepper 2 and 3 - b1 = [positions[0][1] + offsets[1], + b1 = [positions[0].bed_y, self.plot(slope_x_pp03, self.gantry_corners[1][0])] - b2 = [positions[1][1] + offsets[1], + b2 = [positions[1].bed_y, self.plot(slope_x_pp12, self.gantry_corners[1][0])] slope_y_s23 = self.linefit(b1, b2) logging.info("quad_gantry_level af: %s, bf: %s" diff --git a/klippy/extras/screws_tilt_adjust.py b/klippy/extras/screws_tilt_adjust.py index b988c7cef..b3327ba49 100644 --- a/klippy/extras/screws_tilt_adjust.py +++ b/klippy/extras/screws_tilt_adjust.py @@ -63,7 +63,7 @@ class ScrewsTiltAdjust: 'max_deviation': self.max_diff, 'results': self.results} - def probe_finalize(self, offsets, positions): + def probe_finalize(self, positions): self.results = {} self.max_diff_error = False # Factors used for CW-M3, CCW-M3, CW-M4, CCW-M4, CW-M5, CCW-M5, CW-M6 @@ -79,15 +79,15 @@ class ScrewsTiltAdjust: or (not is_clockwise_thread and self.direction == 'CCW')) min_or_max = max if use_max else min i_base, z_base = min_or_max( - enumerate([pos[2] for pos in positions]), key=lambda v: v[1]) + enumerate([pos.bed_z for pos in positions]), key=lambda v: v[1]) else: # First screw is the base position used for comparison - i_base, z_base = 0, positions[0][2] + i_base, z_base = 0, positions[0].bed_z # Provide the user some information on how to read the results self.gcode.respond_info("01:20 means 1 full turn and 20 minutes, " "CW=clockwise, CCW=counter-clockwise") for i, screw in enumerate(self.screws): - z = positions[i][2] + z = positions[i].bed_z coord, name = screw if i == i_base: # Show the results diff --git a/klippy/extras/z_tilt.py b/klippy/extras/z_tilt.py index 0316ee721..28763f1f0 100644 --- a/klippy/extras/z_tilt.py +++ b/klippy/extras/z_tilt.py @@ -143,16 +143,14 @@ class ZTilt: self.z_status.reset() self.retry_helper.start(gcmd) self.probe_helper.start_probe(gcmd) - def probe_finalize(self, offsets, positions): + def probe_finalize(self, positions): # Setup for coordinate descent analysis - z_offset = offsets[2] logging.info("Calculating bed tilt with: %s", positions) - params = { 'x_adjust': 0., 'y_adjust': 0., 'z_adjust': z_offset } + params = { 'x_adjust': 0., 'y_adjust': 0., 'z_adjust': 0. } # Perform coordinate descent def adjusted_height(pos, params): - x, y, z = pos - return (z - x*params['x_adjust'] - y*params['y_adjust'] - - params['z_adjust']) + return (pos.bed_z - pos.bed_x*params['x_adjust'] + - pos.bed_y*params['y_adjust'] - params['z_adjust']) def errorfunc(params): total_error = 0. for pos in positions: @@ -165,8 +163,7 @@ class ZTilt: logging.info("Calculated bed tilt parameters: %s", new_params) x_adjust = new_params['x_adjust'] y_adjust = new_params['y_adjust'] - z_adjust = (new_params['z_adjust'] - z_offset - - x_adjust * offsets[0] - y_adjust * offsets[1]) + z_adjust = new_params['z_adjust'] adjustments = [x*x_adjust + y*y_adjust + z_adjust for x, y in self.z_positions] self.z_helper.adjust_steppers(adjustments, speed)