Axis_twist_compensation: applies twist for probe using the nozzle

Basic Information:

Printer Model: ratrig
MCU / Printerboard: octopus pro
Host / SBC rpi4

Describe your issue:

I’ve done a lot of digging into the twist module and discovered that it applies to nozzle probing. Here is an example part of start macro:

G28 
Z_TILT_ADJUST METHOD=TAP

In this case, the twist compensation value is added to all nozzle probe measurements.

Example 2:

G28
Z_TILT_ADJUST 
G28 Z 
BED_MESH_CALIBRATE 
SET_Z_FROM_PROBE (or any command that shifts zero based on the nozzle tap)

BED_MESH_CALIBRATE shifted all coordinates during measurement via twist compensation, and the tap will shift them again. Logging has been added to the `axis_twist_compensation.py` file:

@@ -4,7 +4,7 @@
 #
 # This file may be distributed under the terms of the GNU GPLv3 license.

-import math
+import math, logging
 from . import manual_probe, bed_mesh, probe


@@ -71,6 +75,9 @@ class AxisTwistCompensation:
                     self.compensation_end_y
                     )

+            logging.info(
+                    "twist change offset bed_x: %.2f ,bed_y: %.2f, bed_z: %.4f test x: %.2f , test y: %.2f, test z: %.4f, zo: %.4f, final z: %.4f"
+                    % (pos.bed_x, pos.bed_y, pos.bed_z, pos.test_x, pos.test_y, pos.test_z, zo, pos.bed_z+zo ))
             pos = manual_probe.ProbeResult(pos.bed_x, pos.bed_y, pos.bed_z + zo,
                                            pos.test_x, pos.test_y, pos.test_z)
             poslist[i] = pos

Console output:

twist change offset bed_x: 150.00 ,bed_y: 150.00, bed_z: 4.9731 test x: 150.00 , test y: 127.50, test z: 5.4628, zo: 0.0241, final z: 4.9973
twist change offset bed_x: 150.00 ,bed_y: 150.00, bed_z: -0.1156 test x: 150.00 , test y: 150.00, test z: -0.1629, zo: 0.0241, final z: -0.0915


first line - G28 Z, second PROBE METHOD=TAP. Same for tilt with tap method.

I created patch :axis_twist_ignore_nozzle_tap, maybe some caveats in probes, maybe loadcell or nozzle klicky need twist compensation(for my guess, no, but…)

After patch:

twist change offset bed_x: 150.00 ,bed_y: 150.00, bed_z: 4.9735 test x: 150.00 , test y: 127.50, test z: 5.4634, zo: 0.0241, final z: 4.9976
twist change offset bed_x: 150.00 ,bed_y: 150.00, bed_z: -0.1188 test x: 150.00 , test y: 150.00, test z: -0.1642, zo: 0.0000, final z: -0.1188

Nice detective work digging into the twist module — I never would have thought about it interacting with nozzle tap probing. Hope someone familiar with the code chimes in on your patch.

As far as I understand the original intentions. Axis twist intended to cancel out the toolhead twist.

Or in picture terms:

So, depending on the X position, both the nozzle and the probe are twisted, so both require some offset.

Where the same logic as here: axis_twist_compensation: add new calculation methods by shinanca · Pull Request #7393 · Klipper3d/klipper · GitHub
Applies there if you run tap once in some static point to offset the bed mesh, which is already “untwisted”.

Tap with axis_twist_compensation “should” have the same correction, as it is affected by the toolhead twist.
Where if one initially did some calibration and set some tap_z_offset, it is possible that after axis_twist_compensation calibration procedure, it has to be adjusted.

Maybe I’m wrong somewhere, of course, not sure,
-Timofey

Nope.

Twist is for correction measurement of probe to nozzle position. The point of contact between the nozzle and the surface serves as the reference point, and the probe offset—accounting for the Twist—ensures correction of the nozzle’s position.

Now in mainline we correct scan probe, then second time correct nozzle tap with same correction(double twist correction in same point), but tap(nozzle) is reference.

How measurement nozzle twist relative to bed? If i understand your twist compensation logic.

the probe offset—accounting for the Twist

For example, if I have X compensation enabled, so, it depends on the position of the toolhead on the “X” axis.

I have zero x_offset:

[probe_eddy_current ldc1612]
x_offset: 0
y_offset: 14.6

So, from a calculation perspective, there is zero offset on the axis with compensation.
But I still have the “difference” in the measurement.

[axis_twist_compensation]
z_compensations = 0.029570, -0.001228, -0.028342
compensation_start_x = 25.0
compensation_end_x = 390.0
zy_compensations: 0.011599, -0.008020, -0.003579
compensation_start_y: 20.0
compensation_end_y: 368.0

So, it seems to me that my portal/rail is twisted a little for whatever reason.
So, one compensates for tilt along X axis, and another for the same tilt along Y coordinates.
So, the tilt is the same, but it can happen for slightly different reasons.

How measurement nozzle twist relative to bed? If i understand your twist compensation logic.

If one has only one probe and it is the nozzle, there is no way to measure that (I guess?).
For example, with a load cell there is no second reference point.
Huh, I guess, one can try to make sense of accelerometer measurments, as Z vector will tilt a little with the toolhead :D.

Where, if we want to make it fully “correct”, I guess we have to introduce the offset to the rail (rotation point), and do some trigonometry.

Also, I suppose there is an exception, as my assumptions are more or less correct only as long as the probe and the nozzle are on the same side of the rail; the twist is correlated.

For example: if the probe is between the nozzle and the rail. The nozzle will be twisted by the same angle, but from a compensation perspective, slightly more than the probe (and vise versa).

But if the probe is on the other side of the rail, things get complicated, and I guess the signs can invert, and in such a case, axis twist will break the tap bed_mesh for sure.

-Timofey


In the end, I’m actually not sure how axis twist compensation should be applied to the “tap”.
I can generally agree that the current implementation can be wrong/impossible to use for the nozzle probes.

This does look like an error to me. It was not intended for “tap” probes to be modified by the axis_twist_compensation module. As I understand it, only probes with an x/y offset were intended to be updated by that module.

I suspect there are two different ways to fix this - the axis_twist_compensation module could be change to not apply compensation if there is no x/y offset (as in the original message) or the eddy “tap” code could somehow request that the SampleAveragingHelper() class not apply compensation.

Thoughts?
-Kevin

Thanks for taking a look at it, Kevin.

I see three potential ways to address this issue::

  1. Modify the eddy current probe module. The downside: new sensors similar to eddy current ones may appear in the future, and developers will have to remember to make additional adjustments for them..
  2. Change the “tap” method in the probe module. The downside: not all “tap” probes have a zero offset on the X/Y axes.
  3. Modify the axis twist compensation module. The downside: this would require recalibrating one of the axes, as the twist compensation was applied to the second axis(via tap) after the calibration of the first axis had already been completed.

Maybe someone else sees another solution that won’t involve multiple settings changes and code compatibility. That’s why I started this thread.

I honestly not sure that I like either, but I’m also not sure about how to fix/calibrate the twist for nozzle probes.
So, I guess, for now, it is easier to disable that.
I tried to do that through SampleAveragingHelper() average helper, so it would be “more readable/obvious” what it does/why.

Regards,
-Timofey