Advanced PID tuning in LinuxCNC

Previously I described PID tuning in LinuxCNC. Here I want to go deeper and explain more parameters impacting the PID behavior. This should help if you can’t tweak the PID properly with only P, I, D and FF* parameters. Also, this might help to better understand relation between PID and mechanical limitations.

tl;rd: DEADBAND, MAX_ACCELERATION, STEPGEN_MAXACCEL, maxerror are drastically impact the PID. If they are not aligned with mechanical parts, then PID will not work after a week of tuning.

DEADBAND

PID ignores any error smaller than this value. E.g. if error is less than DEADBAND PID does nothing. You might want to set it to the scale of the encoder (me too). But this is not always a good idea.

Low value and PID will chaise a noice. High value and the overall precision will be low. x2-x3 from the encoder scale, usually, a good for start.

Another use case: if DEADBAND is smaller than the typical post-move overshoot, then PID will continuously try to correct the overshoot that can’t be mechanically corrected. Pay attention to your mechanical part if you see an overshoot.

maxerror

This is a part of HAL, not INI. But it impacts PID a lot and related with the previous point. If the real error is higher than maxerror the PID uses maxerror instead.

Starting point: set maxerror value x2-x3 greater than DEADBAND.

Here is an example to better understand the case: if your linear scale has 0.005mm resolution (200 counts/mm). The PID’s maxerror=0.0127mm is only 2.54 encoder counts wide. This means the P-term operates on an almost binary signal - either fully saturated positive or fully negative - rather than providing smooth proportional correction. As a result - no smooth movement independent of PID parameters.

MAX_ACCELERATION and STEPGEN_MAXACCEL

If the machine is rigid enough you want to set it as high as possible (me definitely want). But this is not always a good idea. Lower acceleration means smaller transient errors during ramps, and thus less energy to dissipate as overshoot at the end. Nothing can start/stop immediately. And this is the case. You might pay for the acceleration with a measurable spike in the beginning and/or end of the trajectory.

Also, here we have many cross-relations. Most important is MAX_ACCELERATION and STEPGEN_MAXACCEL. If servo physical acceleration is equal to MAX_ACCELERATION then there is no room for PID to correct the error. Need to keep MAX_ACCELERATION at least 2 times smaller than STEPGEN_MAXACCEL. 4+ times is better. Depends, from your machine and requirements.

In my case x2 was not enough. There were oscillations unable to fix with PID. x4 fixed this easily. But this is not a rule, just an example.

Machine configuration

It’s always matter. Spikes in the beginning/end of the trajectory might be related with mechanical limitations. For example, physical friction might require an additional energy to start movement. This leads to spike in the beginning. No way to fix it with any PID. Sometimes, this is around 0.01mm, another times it’s more than 0.1mm. Depends on the machine.

The same about backlash. BACKLASH parameter is not a silver bullet. It just partially mitigate the problem. Not fix it.

All that cases are not about PID. This is about the machine. Need to understand hardware limits and do not try to fix it with PID.

What to do?

Try a simple approach from the previous article. Spend a dozen of iterations. If no luck - look at the above parameters.

Feed AI with CSV log from HAL-scope. If you’ll do it with a context of your installation (all files from LinuxCNC project), it might bring a valuable insights… or not :)