I did a deep dive on what Prusa is doing in InterpolateFinalZCoordinate:
float InterpolateFinalZCoordinate(Features &features) {
float zDecompressionEnd = features.riseLine.GetY(features.decompressionEndTime);
float loadAtDecompressionEnd = features.decompressionLine.GetY(features.decompressionEndTime);
float middleTimestamp = features.decompressionLine.GetTime(loadAtDecompressionEnd - 120 + 70);
float zDecompressionMiddle = features.riseLine.GetY(middleTimestamp);
return (zDecompressionEnd + zDecompressionMiddle) / 2;
}
They are working out the time at the elbow and the time at -50g from the elbow and averaging the two. The elbow time is taken directly from the elbow sample. The -50g time is taken from a linear regression line that has all points before the elbow. This seems weird, they have the linear regression line but they are not solving for y=0. Maybe they have overshoot as the toolhead lifts up and they are compensating for this? Maybe this is some sort of extra “squish” factor? In my testing it seems to move the collision time by about 0.02-0.03mm. It also slightly improves the range over linear regression to y=0.
Whats more interesting is the dedicated move they have for collecting the riseLine
/decompressionLine
data. Its only 0.09mm long at 0.33mm/s. I think you can see it in some of the videos, the toolhead looks like it pauses and I thought it was a hiccup in their movement queue. But this is where they are waiting for data from the toolhead boards and doing all the computation causing the pause. The move takes 270ms and the pause is another 140ms on the MK4, 20ms longer for canbus communication delay on the XL. No one is going to sit still for their printer to do an entire probe at 0.33mm/s. But because this move is short its hardly noticeable.
0.33mm/s / 320sps = 0.001mm per sample of resolution
I’m going to try and replicate this in klipper. I’m just going to hard code the move into the endstop for now. If that works well and the data I collect improves things we can discuss where the movement code should go (homing.py?). I can pick the movement speed such that it always results in 0.001mm per sample with any sensor chip. On the HX711 you would be looking at 0.08mm/s and a glacially slow 1.1s move time. The 0.09mm is going to be related to the overshoot. Its going to be less at 2mm/s vs 10mm/s. Maybe there is a way to scale that length value based on the homing speed to save some time.
Its possible this technique would improve switch probes as well. You could just invert the trigger condition of the endstop and do a slow move back until it triggered. Other probe technology might not benefit due to hysteresis.