aboutsummaryrefslogtreecommitdiffstats
path: root/klippy/extras
diff options
context:
space:
mode:
authorArksine <arksine.code@gmail.com>2019-12-17 10:38:13 -0500
committerKevinOConnor <kevin@koconnor.net>2020-01-09 14:14:13 -0500
commit2c877e172922d55340bf178d7c6e1b20ba357376 (patch)
treeff1b90e2fec8eb88d70ef8a8f360e455bdb1a6ae /klippy/extras
parenta69de2be9318fcadc5dc74c45e68a6cda23c1321 (diff)
downloadkutter-2c877e172922d55340bf178d7c6e1b20ba357376.tar.gz
kutter-2c877e172922d55340bf178d7c6e1b20ba357376.tar.xz
kutter-2c877e172922d55340bf178d7c6e1b20ba357376.zip
bed_mesh: improve interpolation checks
Move interpolation checks to _init_mesh_params() so they can be done whle the config is being parsed. Do not allow a probe_count higher than 6 for lagrange interpolation, as this typically leads to oscillation. Signed-off-by: Eric Callahan <arksine.code@gmail.com>
Diffstat (limited to 'klippy/extras')
-rw-r--r--klippy/extras/bed_mesh.py62
1 files changed, 42 insertions, 20 deletions
diff --git a/klippy/extras/bed_mesh.py b/klippy/extras/bed_mesh.py
index cf378d76..6b7a0b50 100644
--- a/klippy/extras/bed_mesh.py
+++ b/klippy/extras/bed_mesh.py
@@ -311,15 +311,43 @@ class BedMeshCalibrate:
def _init_mesh_params(self, config, points):
pps = parse_pair(config, ('mesh_pps', '2'), check=False,
cast=int, minval=0)
- self.mesh_params['mesh_x_pps'] = pps[0]
- self.mesh_params['mesh_y_pps'] = pps[1]
- self.mesh_params['algo'] = config.get('algorithm', 'lagrange') \
- .strip().lower()
- if self.mesh_params['algo'] not in self.ALGOS:
+ params = self.mesh_params
+ params['mesh_x_pps'] = pps[0]
+ params['mesh_y_pps'] = pps[1]
+ params['algo'] = config.get('algorithm', 'lagrange').strip().lower()
+ if params['algo'] not in self.ALGOS:
raise config.error(
"bed_mesh: Unknown algorithm <%s>"
% (self.mesh_params['algo']))
- self.mesh_params['tension'] = config.getfloat(
+ # Check the algorithm against the current configuration
+ max_probe_cnt = max(params['x_count'], params['y_count'])
+ min_probe_cnt = min(params['x_count'], params['y_count'])
+ if max(pps[0], pps[1]) == 0:
+ # Interpolation disabled
+ self.mesh_params['algo'] = 'direct'
+ elif params['algo'] == 'lagrange' and max_probe_cnt > 6:
+ # Lagrange interpolation tends to oscillate when using more
+ # than 6 samples
+ raise config.error(
+ "bed_mesh: cannot exceed a probe_count of 6 when using "
+ "langrange interpolation. Configured Probe Count: %d, %d" %
+ (self.mesh_params['x_count'], self.mesh_params['y_count']))
+ elif params['algo'] == 'bicubic' and min_probe_cnt < 4:
+ if max_probe_cnt > 6:
+ raise config.error(
+ "bed_mesh: invalid probe_count option when using bicubic "
+ "interpolation. Combination of 3 points on one axis with "
+ "more than 6 on another is not permitted. "
+ "Configured Probe Count: %d, %d" %
+ (self.mesh_params['x_count'], self.mesh_params['y_count']))
+ else:
+ logging.info(
+ "bed_mesh: bicubic interpolation with a probe_count of "
+ "less than 4 points detected. Forcing lagrange "
+ "interpolation. Configured Probe Count: %d, %d" %
+ (self.mesh_params['x_count'], self.mesh_params['y_count']))
+ params['algo'] = 'lagrange'
+ params['tension'] = config.getfloat(
'bicubic_tension', .2, minval=0., maxval=2.)
def _load_storage(self, config):
stored_profs = config.get_prefix_sections(self.name)
@@ -584,24 +612,18 @@ class ZMesh:
"bed_mesh: Mesh Min: (%.2f,%.2f) Mesh Max: (%.2f,%.2f)"
% (self.mesh_x_min, self.mesh_y_min,
self.mesh_x_max, self.mesh_y_max))
- if params['algo'] == 'bicubic':
- self._sample = self._sample_bicubic
- else:
- self._sample = self._sample_lagrange
- # Nummber of points to interpolate per segment
+ # Set the interpolation algorithm
+ interpolation_algos = {
+ 'lagrange': self._sample_lagrange,
+ 'bicubic': self._sample_bicubic,
+ 'direct': self._sample_direct
+ }
+ self._sample = interpolation_algos.get(params['algo'])
+ # Number of points to interpolate per segment
mesh_x_pps = params['mesh_x_pps']
mesh_y_pps = params['mesh_y_pps']
px_cnt = params['x_count']
py_cnt = params['y_count']
- if px_cnt == 3 or py_cnt == 3:
- # a mesh with 3 points on either axis defaults to legrange
- # upsampling
- self._sample = self._sample_lagrange
- self.mesh_params['algo'] = 'lagrange'
- if mesh_x_pps == 0 and mesh_y_pps == 0:
- # No interpolation, sample the probed points directly
- self._sample = self._sample_direct
- self.mesh_params['algo'] = 'direct'
self.mesh_x_count = (px_cnt - 1) * mesh_x_pps + px_cnt
self.mesh_y_count = (py_cnt - 1) * mesh_y_pps + py_cnt
self.x_mult = mesh_x_pps + 1