aboutsummaryrefslogtreecommitdiffstats
path: root/klippy
diff options
context:
space:
mode:
authorEric Callahan <arksine.code@gmail.com>2023-04-29 12:31:05 -0400
committerKevinOConnor <kevin@koconnor.net>2023-06-20 11:48:17 -0400
commit1ad4c0fd6e2501dd635dbf2648c70c997612378f (patch)
tree2432a3222d58fe5a62a3449837fe88f08b89f3fa /klippy
parent775092fc016784317dbd443c7d6c31de9cc518af (diff)
downloadkutter-1ad4c0fd6e2501dd635dbf2648c70c997612378f.tar.gz
kutter-1ad4c0fd6e2501dd635dbf2648c70c997612378f.tar.xz
kutter-1ad4c0fd6e2501dd635dbf2648c70c997612378f.zip
bed_mesh: improve zero reference offset
The relative_reference_index will now refer to a coordinate that is static and cannot be changed at runtime. If new mesh parameters are specifed and the reference lies outside of the mesh then the reference location will be probed. Additionally this introduces a 'zero_reference_position' option which accepts a specific X/Y coordinate. This may be used in place of the relative_reference_index. Signed-off-by: Eric Callahan <arksine.code@gmail.com>
Diffstat (limited to 'klippy')
-rw-r--r--klippy/extras/bed_mesh.py125
1 files changed, 97 insertions, 28 deletions
diff --git a/klippy/extras/bed_mesh.py b/klippy/extras/bed_mesh.py
index eb7002b4..3af1b9db 100644
--- a/klippy/extras/bed_mesh.py
+++ b/klippy/extras/bed_mesh.py
@@ -278,6 +278,12 @@ class BedMesh:
gcmd.respond_info("No mesh loaded to offset")
+class ZrefMode:
+ DISABLED = 0 # Zero reference disabled
+ IN_MESH = 1 # Zero reference position within mesh
+ PROBE = 2 # Zero refrennce position outside of mesh, probe needed
+
+
class BedMeshCalibrate:
ALGOS = ['lagrange', 'bicubic']
def __init__(self, config, bedmesh):
@@ -285,11 +291,25 @@ class BedMeshCalibrate:
self.orig_config = {'radius': None, 'origin': None}
self.radius = self.origin = None
self.mesh_min = self.mesh_max = (0., 0.)
+ self.zero_ref_pos = config.getfloatlist(
+ "zero_reference_position", None, count=2
+ )
self.relative_reference_index = config.getint(
- 'relative_reference_index', None)
+ 'relative_reference_index', None, minval=0)
+ config.deprecate('relative_reference_index')
+ if (
+ self.zero_ref_pos is not None and
+ self.relative_reference_index is not None
+ ):
+ self.relative_reference_index = None
+ logging.info(
+ "bed_mesh: both 'zero_reference_postion' and "
+ "'relative_reference_index' options are specified, "
+ "the 'zero_reference_position' value will be used."
+ )
+ self.zero_reference_mode = ZrefMode.DISABLED
self.faulty_regions = []
self.substituted_indices = collections.OrderedDict()
- self.orig_config['rri'] = self.relative_reference_index
self.bedmesh = bedmesh
self.mesh_config = collections.OrderedDict()
self._init_mesh_config(config)
@@ -346,9 +366,37 @@ class BedMeshCalibrate:
(self.origin[0] + pos_x, self.origin[1] + pos_y))
pos_y += y_dist
self.points = points
+ rri = self.relative_reference_index
+ if self.zero_ref_pos is None and rri is not None:
+ # Zero ref position needs to be initialized
+ if rri >= len(self.points):
+ raise error("bed_mesh: relative reference index out of range")
+ self.zero_ref_pos = points[rri]
+ if self.zero_ref_pos is None:
+ # Zero Reference Disabled
+ self.zero_reference_mode = ZrefMode.DISABLED
+ elif within(self.zero_ref_pos, self.mesh_min, self.mesh_max):
+ # Zero Reference position within mesh
+ self.zero_reference_mode = ZrefMode.IN_MESH
+ else:
+ # Zero Reference position outside of mesh
+ self.zero_reference_mode = ZrefMode.PROBE
if not self.faulty_regions:
return
self.substituted_indices.clear()
+ if self.zero_reference_mode == ZrefMode.PROBE:
+ # Cannot probe a reference within a faulty region
+ for min_c, max_c in self.faulty_regions:
+ if within(self.zero_ref_pos, min_c, max_c):
+ opt = "zero_reference_position"
+ if self.relative_reference_index is not None:
+ opt = "relative_reference_index"
+ raise error(
+ "bed_mesh: Cannot probe zero reference position at "
+ "(%.2f, %.2f) as it is located within a faulty region."
+ " Check the value for option '%s'"
+ % (self.zero_ref_pos[0], self.zero_ref_pos[1], opt,)
+ )
# Check to see if any points fall within faulty regions
last_y = self.points[0][1]
is_reversed = False
@@ -398,11 +446,18 @@ class BedMeshCalibrate:
mesh_pt = "(%.1f, %.1f)" % (x, y)
print_func(
" %-4d| %-16s| %s" % (i, adj_pt, mesh_pt))
- if self.relative_reference_index is not None:
+ if self.zero_ref_pos is not None:
rri = self.relative_reference_index
- print_func(
- "bed_mesh: relative_reference_index %d is (%.2f, %.2f)"
- % (rri, self.points[rri][0], self.points[rri][1]))
+ if rri is not None:
+ print_func(
+ "bed_mesh: relative_reference_index %d is (%.2f, %.2f)"
+ % (rri, self.zero_ref_pos[0], self.zero_ref_pos[1])
+ )
+ else:
+ print_func(
+ "bed_mesh: zero_reference_position is (%.2f, %.2f)"
+ % (self.zero_ref_pos[0], self.zero_ref_pos[1])
+ )
if self.substituted_indices:
print_func("bed_mesh: faulty region points")
for i, v in self.substituted_indices.items():
@@ -522,7 +577,6 @@ class BedMeshCalibrate:
# reset default configuration
self.radius = self.orig_config['radius']
self.origin = self.orig_config['origin']
- self.relative_reference_index = self.orig_config['rri']
self.mesh_min = self.orig_config['mesh_min']
self.mesh_max = self.orig_config['mesh_max']
for key in list(self.mesh_config.keys()):
@@ -530,12 +584,6 @@ class BedMeshCalibrate:
params = gcmd.get_command_parameters()
need_cfg_update = False
- if 'RELATIVE_REFERENCE_INDEX' in params:
- self.relative_reference_index = gcmd.get_int(
- 'RELATIVE_REFERENCE_INDEX')
- if self.relative_reference_index < 0:
- self.relative_reference_index = None
- need_cfg_update = True
if self.radius is not None:
if "MESH_RADIUS" in params:
self.radius = gcmd.get_float("MESH_RADIUS")
@@ -585,17 +633,20 @@ class BedMeshCalibrate:
pts = self._get_adjusted_points()
self.probe_helper.update_probe_points(pts, 3)
def _get_adjusted_points(self):
- if not self.substituted_indices:
- return self.points
adj_pts = []
- last_index = 0
- for i, pts in self.substituted_indices.items():
- adj_pts.extend(self.points[last_index:i])
- adj_pts.extend(pts)
- # Add one to the last index to skip the point
- # we are replacing
- last_index = i + 1
- adj_pts.extend(self.points[last_index:])
+ if self.substituted_indices:
+ last_index = 0
+ for i, pts in self.substituted_indices.items():
+ adj_pts.extend(self.points[last_index:i])
+ adj_pts.extend(pts)
+ # Add one to the last index to skip the point
+ # we are replacing
+ last_index = i + 1
+ adj_pts.extend(self.points[last_index:])
+ else:
+ adj_pts = list(self.points)
+ if self.zero_reference_mode == ZrefMode.PROBE:
+ adj_pts.append(self.zero_ref_pos)
return adj_pts
cmd_BED_MESH_CALIBRATE_help = "Perform Mesh Bed Leveling"
def cmd_BED_MESH_CALIBRATE(self, gcmd):
@@ -609,6 +660,14 @@ class BedMeshCalibrate:
x_offset, y_offset, z_offset = offsets
positions = [[round(p[0], 2), round(p[1], 2), p[2]]
for p in positions]
+ if self.zero_reference_mode == ZrefMode.PROBE :
+ ref_pos = positions.pop()
+ logging.info(
+ "bed_mesh: z-offset replaced with probed z value at "
+ "position (%.2f, %.2f, %.6f)"
+ % (ref_pos[0], ref_pos[1], ref_pos[2])
+ )
+ z_offset = ref_pos[2]
params = dict(self.mesh_config)
params['min_x'] = min(positions, key=lambda p: p[0])[0] + x_offset
params['max_x'] = max(positions, key=lambda p: p[0])[0] + x_offset
@@ -659,11 +718,6 @@ class BedMeshCalibrate:
% (off_pt[0], off_pt[1], probed[0], probed[1]))
positions = corrected_pts
- if self.relative_reference_index is not None:
- # zero out probe z offset and
- # set offset relative to reference index
- z_offset = positions[self.relative_reference_index][2]
-
probed_matrix = []
row = []
prev_pos = positions[0]
@@ -720,6 +774,11 @@ class BedMeshCalibrate:
z_mesh.build_mesh(probed_matrix)
except BedMeshError as e:
raise self.gcode.error(str(e))
+ if self.zero_reference_mode == ZrefMode.IN_MESH:
+ # The reference can be anywhere in the mesh, therefore
+ # it is necessary to set the reference after the initial mesh
+ # is generated to lookup the correct z value.
+ z_mesh.set_zero_reference(*self.zero_ref_pos)
self.bedmesh.set_mesh(z_mesh)
self.gcode.respond_info("Mesh Bed Leveling Complete")
self.bedmesh.save_profile(self._profile_name)
@@ -899,6 +958,16 @@ class ZMesh:
# z step distances
self.avg_z = round(self.avg_z, 2)
self.print_mesh(logging.debug)
+ def set_zero_reference(self, xpos, ypos):
+ offset = self.calc_z(xpos, ypos)
+ logging.info(
+ "bed_mesh: setting zero reference at (%.2f, %.2f, %.6f)"
+ % (xpos, ypos, offset)
+ )
+ for matrix in [self.probed_matrix, self.mesh_matrix]:
+ for yidx in range(len(matrix)):
+ for xidx in range(len(matrix[yidx])):
+ matrix[yidx][xidx] -= offset
def set_mesh_offsets(self, offsets):
for i, o in enumerate(offsets):
if o is not None: