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>
This commit is contained in:
parent
a69de2be93
commit
2c877e1729
|
@ -311,15 +311,43 @@ class BedMeshCalibrate:
|
||||||
def _init_mesh_params(self, config, points):
|
def _init_mesh_params(self, config, points):
|
||||||
pps = parse_pair(config, ('mesh_pps', '2'), check=False,
|
pps = parse_pair(config, ('mesh_pps', '2'), check=False,
|
||||||
cast=int, minval=0)
|
cast=int, minval=0)
|
||||||
self.mesh_params['mesh_x_pps'] = pps[0]
|
params = self.mesh_params
|
||||||
self.mesh_params['mesh_y_pps'] = pps[1]
|
params['mesh_x_pps'] = pps[0]
|
||||||
self.mesh_params['algo'] = config.get('algorithm', 'lagrange') \
|
params['mesh_y_pps'] = pps[1]
|
||||||
.strip().lower()
|
params['algo'] = config.get('algorithm', 'lagrange').strip().lower()
|
||||||
if self.mesh_params['algo'] not in self.ALGOS:
|
if params['algo'] not in self.ALGOS:
|
||||||
raise config.error(
|
raise config.error(
|
||||||
"bed_mesh: Unknown algorithm <%s>"
|
"bed_mesh: Unknown algorithm <%s>"
|
||||||
% (self.mesh_params['algo']))
|
% (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.)
|
'bicubic_tension', .2, minval=0., maxval=2.)
|
||||||
def _load_storage(self, config):
|
def _load_storage(self, config):
|
||||||
stored_profs = config.get_prefix_sections(self.name)
|
stored_profs = config.get_prefix_sections(self.name)
|
||||||
|
@ -584,24 +612,18 @@ class ZMesh:
|
||||||
"bed_mesh: Mesh Min: (%.2f,%.2f) Mesh Max: (%.2f,%.2f)"
|
"bed_mesh: Mesh Min: (%.2f,%.2f) Mesh Max: (%.2f,%.2f)"
|
||||||
% (self.mesh_x_min, self.mesh_y_min,
|
% (self.mesh_x_min, self.mesh_y_min,
|
||||||
self.mesh_x_max, self.mesh_y_max))
|
self.mesh_x_max, self.mesh_y_max))
|
||||||
if params['algo'] == 'bicubic':
|
# Set the interpolation algorithm
|
||||||
self._sample = self._sample_bicubic
|
interpolation_algos = {
|
||||||
else:
|
'lagrange': self._sample_lagrange,
|
||||||
self._sample = self._sample_lagrange
|
'bicubic': self._sample_bicubic,
|
||||||
# Nummber of points to interpolate per segment
|
'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_x_pps = params['mesh_x_pps']
|
||||||
mesh_y_pps = params['mesh_y_pps']
|
mesh_y_pps = params['mesh_y_pps']
|
||||||
px_cnt = params['x_count']
|
px_cnt = params['x_count']
|
||||||
py_cnt = params['y_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_x_count = (px_cnt - 1) * mesh_x_pps + px_cnt
|
||||||
self.mesh_y_count = (py_cnt - 1) * mesh_y_pps + py_cnt
|
self.mesh_y_count = (py_cnt - 1) * mesh_y_pps + py_cnt
|
||||||
self.x_mult = mesh_x_pps + 1
|
self.x_mult = mesh_x_pps + 1
|
||||||
|
|
Loading…
Reference in New Issue