There's still some work to be done on this homing accuracy business. Let's see if we can crack it finally. The decision to use the Claude Code extension within Visual Studio Code has certainly allowed me to do stuff I'd never have been able to figure out myself, it's true - but the experience is pretty trying at times. If Claude has a personality it's that of an excitable junior engineer - tends to sound very pleased with itself and jumps to conclusions that aren't backed up with evidence. I guess we can hope that Claude will develop over the coming years to the point that it is a lot more dependable and less fallible.
Let's look at the homing moves. It seems to me that the movements are rather jerky, whereas a servo system should be capable of smooth, quiet movement. Let's log some moves and see if there's anything to be learned.
All 10 index-clear events from the final switch position, velocity-derived from the raw position samples and aligned to each cycle's own capture instant (t=0, dashed green). Commanded (blue) is what the trajectory planner is asking for; feedback (orange) is what the axis is actually doing. Faint lines are individual cycles; overlap (or lack of it) at t=0 shows how consistently the capture lands on the velocity profile.
This doesn't look ideal - what's all that sinusoidal wobble about? Looks like marginal stability to me.
Here's the same data plotted as distance rather than velocity. Velocity is simply the derivative of distance.
±1mm step transient (no homing involved)
All 10 dwell events from the z_backlash_check.ngc +/-1mm relative-jog test (no switch, no homing, no index involved at all -- a plain commanded stop), aligned to each move's own stop instant (t=0, dashed green). Commanded (blue) is what the trajectory planner is asking for; feedback (orange) is what the axis is actually doing. Faint lines are individual cycles.
Nasty lumpy movement is still visible. Homing in on the transient portions of the +/-1mm backlash test, shows some unauthorised wobbling:
Cruise-phase velocity ripple
Z velocity during the constant-speed middle portion of a single +/-1mm move (200mm/min commanded) -- not the stop/settle transient, the actual translation. Commanded (blue) should be a flat line; feedback (orange) swings from near zero to more than double the commanded speed, cyclically, roughly every 40ms (~24-25Hz).
Fundamental frequency is ~26Hz. Is this caused by the Linuxcnc controller or is it caused by the Lichuan servo driver? That's worth establishing before trying to optimise the wrong PID loop. IIRC, the Lichuan servo driver is actually pretty well set up for the matching motor.
Ripple: LinuxCNC's own commanded output vs. actual
Same +/-1mm cruise-phase window as before, but now including pid.z.output -- the actual velocity command LinuxCNC's PID sends downstream to the stepgen, before it ever reaches the drive. It shows the same ~26Hz ripple as the feedback, and at far larger amplitude than the nominal -3.33mm/s command -- meaning LinuxCNC's own loop output is actively oscillating, not just passing through a clean signal that gets corrupted later.
Setting D=0 in the INI file makes quite a difference:
Ripple fixed: pid.z.Dgain set to 0
Same +/-1mm cruise-phase window and signals as the previous capture, but with pid.z.Dgain set to 0 (was 3). pid.z.output now ramps smoothly and holds steady instead of oscillating between roughly -17 and +14mm/s -- suggests that the ~26Hz ripple was mostly the D-term amplifying quantization noise from the 5µm scale, not a real mechanical resonance.
Looks to me like too much Kp term. Reduce Kp to 35 from 50 and Kd to 0 from 3, I unchanged.
PID tuning progress
pid.z.output (the velocity command LinuxCNC sends to the stepgen) across three tuning stages, same +/-1mm cruise window each time. This is the clearest single signal for the whole investigation -- how hard the loop is working to hold a supposedly constant speed.
PID tuning progress - Z axis
pid.z.output (the velocity command LinuxCNC sends to the stepgen) across three tuning stages, same +/-1mm cruise window each time. This is the clearest single signal for the whole investigation -- how hard the loop is working to hold a supposedly constant speed.
Looking a lot better now:
Let's look at the X axis now:
pid.x.output across the X-axis tuning sequence -- same diagnostic process as Z, but a different root cause: X's weak feedforward (FF1=0.4) meant Kp was carrying too much of the tracking burden, so raising FF1 (not cutting Kp or Kd) was the fix here.
Servo homing results, Z and X
Each dot is one homing cycle's resting position (raw linear-scale feedback, not the DRO -- unaffected by the homing offset reset), shown as deviation from that group's own mean so spreads are directly comparable across groups measured in different sessions. Same jog-away and settle protocol throughout.
The Z axis is looking pretty good:
But the X axis is still pretty crap, even if it has improved a bit:
Final X axis backlash tests:
Clean before/after: original X gains (P=60 I=40 D=1 FF1=0.4) vs. the final tuned config (P=100 I=40 D=0 FF1=0.85). Mean peak position error went from ~41µm to 5.0µm (one encoder increment) on every single cycle.
And as for the X homing - has that finally improved? I'm close to losing the will to live here but I want to get this thing cracked.
Servo homing results, Z and X
Each dot is one homing cycle's resting position (raw linear-scale feedback, not the DRO -- unaffected by the homing offset reset), shown as deviation from that group's own mean so spreads are directly comparable across groups measured in different sessions. Same jog-away and settle protocol throughout.
Woohoo - finally looking half decent. I need to convince myself the effort was worth it - perhaps that conviction will come with time.
One key difference is that the Z axis is still using index mark. we don't know how it would behave without that, as many changes happened since we implemented it. Is the x axis just as good as the z would be without index? In other words, has all this messing about with index marks been a waste of time?
Let's compare index mark homing vs the original proximity switch to double check....
Z axis homing - with index and without:
Conclusion: using the index mark from the servo driver makes sod all difference. So I had no need to bugger about with connections from the servo driver to the 7i85 interface and all the buggerage that it entailed. Instead, careful setup of the homing and PID parameters delivered the same results.
- X axis homing accuracy - typically +/- 5-10um on radius (+/- 20um on diameter).
- Z axis homing accuracy - typically +/- 5-10um.
No comments:
Post a Comment