Adaptive `horizontal_move_z` for Bed Mesh

In the current source code klipper performs an absolute move to the horizontal_move_z height after each probe. This has a few knock on effects on users that are not super obvious:

Because horizontal_move_z is an absolute height relative to the homed position, it needs to be large enough to exceed all of the variation in height that might exist in a bed mesh. It has to exceed any tilt that might exists between the bed and the X/Y axis as well. So it has to be a global offset or the tool head may crash into the bed (or the probe may trigger before movement etc.). This encourages users to set a large value

Using a large value encourages faster probing speeds to make up for the long time the probe spends descending. We know that probes become less accurate and repeatable when they are used a higher speeds. But this behavior has urged klipper users to probe from higher up at faster speeds.

So I propose making a small change to this behavior: make the horizontal_move_z a minimum

  • if the z value of the last probe is less than or equal to 0, then the move height is horizontal_move_z, same as now
  • if the z value of the last probe is greater than 0, the move height is the probed height +horizontal_move_z

The result of this change is that you can use very small values for horizontal_move_z with [bed_mesh]. It only has to be large enough to account for local changes between adjacent probe points. Even values that are smaller than the measured global variance in the bed mesh can work, so long as the bed is a “smooth curve”. So this works with “tacos”, which is the most common bed shape.

e.g. this mesh was captured with horizontal_move_z: 0.2 but has a total variance of nearly 0.4mm:


Using a nozzle probe at 0.2mm would have resulted in a crash using the old code as z=0 was measured in the center of the bed.

With a smaller horizontal_move_z, the probing speed can be cut to achieve higher accuracy in the same time. I.e. with 1/2 the probe speed and 1/2 the horizontal_move_z, you get the same total meshing time but with improved accuracy, essentially for free.

Making this change could improve bed mesh accuracy for the majority of users at no cost in meshing time and with an improved safety margin.

PR: Adaptive horizontal_move_z by garethky · Pull Request #6933 · Klipper3d/klipper · GitHub

1 Like

It turns out that the setting is used to lower the Z axis when the first probe is issued. This is kind of a “fast travel” for z to get close to the value before doing the first probe. The Z move is performed at the probing speed. It seems like the code goes out of its way to do something special for this first move when it could skip it entirely and start the homing move down. They are going to be at the same speed, and a homing move is safer than an unconditional downward move.

The explanation for this is in manual mode, where this is actually useful. In that mode the tool is dropped/raised to horizontal_move_z above the bed and then the user manually adjusts it for the paper test. So in that case the move cant be a PROBE, because there is no probe. After that its never moved again.

So it feels like the two code paths want different behavior. Manual mode wants the Z dropped/raised by fiat. Automatic mode wants to just run the probe, assuming that the user started out the sequence at a safe height.

This would, ideally improve safety as the automatic mode would no longer make moves towards the bed that aren’t homing moves.

JFYI:
Inductive probes do have a hysteresis, so in reality there is no way to raise the toolhead by just 0.2..0.4 mm, because the probe will be still triggered.
I suspect that something like a BTT microprobe/BLTouch would also struggle with that.