It turns out that leaving debugging code in your project can sometimes be a really great thing. I was going to video the axis mechanism and see if I could spot anything odd happening that might explain the drift, when suddenly during moving it into position I got a couple of these though the serial port:
[rogue axis 1 ]This was the warning I put in to check if the servo was overshooting at all (axis 1 is the X axis). It turns out it does overshoot, and my limited earlier tests didn't pick it up because it doesn't happen that often.
I got all excited and put code into the Arduino sketch to track the movement past when it is supposed to be moving, and adjust the internally recorded position accordingly. Then I tried to cut another shape, and there was still drift.
Once I got over the disappointment I decided to record the axis anyway to see what happens in more detail when it drifts. I marked the side of the linkage with a black dot so that I could easily spot when it went out of alignment. Then I set the video recorder going and had it move in tiny circles (2.4mm or 2 complete turns in diameter) over and over again until I spotted the black dot lose alignment. Then I stepped through the frames trying to count along the steps taken and see what happened:
There is this interesting little bit where it backtracks as if it thinks it has overshot by one (when it hasn't). The problem is though that the count on the left and the count on the right should match up and they don't. Even if the extra tick from thinking it has overshot is added it ends up one short. Without it ends up two short (which is the actual physical amount it ends up off by).
The debugging trace for the red bit looks normal, but the blue bit looks like this:
--curved line--- from x: -24 y: 0 z: 0 to x: 0 y: 0 z: 0 center x: -12 y: 0 z: 0 steps 34 c1-132 c0 -100 c0 -117 c1 -173 c1 -129 c0 -98 c0 -113 c0 -155 c1 -152 c1 -112 c0 -75 c1 -143 c0 -62 c0 -120 c1 -75 c0 -93 c0 -83 c1 -107 c1 -60 c1 -103 c1 -111 c1 -90 c1 -124 c0[rogue axis 1 ] -82 c1[rogue axis 1 ]-171 c0 -167 c0 -167 c0 -185 c0 -139 c0 -128 c1 -131 c0 -124 c0 -101 c1 -107 ENDED AT: 0 y: 0 z: 0 DONEWhich is interesting because there are two points where it thought that the servo had overshot (the ones that say "[rogue axis 1]"). I only see one spot where it backtracks on the video though. If the backtrack was the first point we see in the data, the second would be during the backtrack which would put the count off by two. If however the first point it overshoots doesn't backtrack and the second does, that makes the count correct, so is the only theory that makes sense to me unless there is a software bug somewhere.
What is clear from all this though is that the switch is detecting extra presses where none are happening. I think my next step is going to be programming in a way to measure more precisely the interval between switch clicks on a specific axis and when they happen related to servo commands so I can get a better idea exactly what is happening.