PID Tuning - Sector67/router-conversion GitHub Wiki
This page describes the process for PID tuning the router. PID tuning this machine will be a bit different than our experience with the Anilam-converted routers. The ~$800 per-axis servo drivers on those machines were velocity mode, meaning the analog input to the drive specified a velocity target, and the drives themselves had tachometer feedback and a PID loop to control the motor to the specified velocity. In that case, tuning can be done with P, FF1 and FF2.
For the motors on this machine, LinuxCNC is driving a PWM that drives an H bridge controller that is wired to the motors, turning current on and off at high speed. This approach is significantly less expensive for the four servos we are driving, but means tuning is done differently than many of the PID tuning tutorials, which are intended to be used with velocity-mode drives. The thread at https://www.forum.linuxcnc.org/27-driver-boards/26558-brushed-closed-loop-using-encoders-and-h-bridge provides some details, and we'll be walking through the process we use in this case for achieving a tuned PID loop.
Some comments:
Velocity mode drives basically handle the 'D' term themselves so they mainly use P and FF1 (and typically 1KHz sample rate is fine for machine tool
type mechanical bandwidths)
Torque mode drives need P and D and some FF2. Because LinuxCNC closes the velocity loop, the sample rate may need to be higher (say 2-5 KHz)
Voltage mode drives (a bare H-bridge for example) are somewhere in between velocity mode and torque mode and will need P, D, and FF1
Straight PWM is the simplest. It is like the etch-a-sketch, but uses hardware so that
reasonable PWM frequencies can be had at the same time as good duty cycle
resolution. The direct PWM scheme effectively commands the VOLTAGE to the motor.
Torque mode gives slightly better stability, but generally requires analog command
to the servo amp. The improvement is that instead of sending a voltage to the motor,
it is commanding the motor current, which is proportional to torque. It is a minor
introduction to control systems theory to explain why. But, it moves part of the
control loop out to the drive, and attempts to remove the delay incurred by motor
inductance from the CNC control and makes the drive handle this.
Velocity servos move another part of the control loop out to the drive, by having
the drive measure velocity with a tachometer and force the motor to match
the commanded velocity. Especially in the old days with 60 Hz or 100 Hz
servo loop update rates, only the analog velocity servo could have the
bandwidth to keep up with a dynamic machine with cutting tools taking bites
out of the workpiece at several hundred teeth per second. They can still
have a bigger margin of stability than involving a CPU in the loop, due to the
delay of the CPU response. However, with high resolution encoders,
the PWM scheme can work well.
We'll first want a faster servo control loop than the default configuration provides. Before tuning, we've made to sure to have the machine encoders wired and scaled properly and the motor drives working in coordination with the controllers so that the machine can move very slowly under closed-loop control with the default PID parameters.
Then we determine the machine max velocity and acceleration by running the axis in open loop mode and applying a step input of the maximum control voltage. For this machine, that meant disconnecting a motor from the Mesa control card and directly wiring it to +48V, being very careful to drive the machine in a safe direction. HAL scope can be used to capture the information you need to determine max velocity and acceleration, with signals such as x-vel-fb
or y-vel-fb
. For the X gantry axis, this was a bit more complicated, so we used the values from the Y axis (same motors) as a starting point for the X axis.
We set the servo period to 500,000 ns (we had intermittent real time errors at 250,000 ns on our current PC) to provide a faster PC-side control loop.
For tuning, we set large following errors in the config file, an 1.5 and 1.05 inches, instead of 0.5 and 0.05.
We had issues tuning initially related to backlash in the rack and pinion, so we made sure the backlash in the system is was as small as possible. It is very difficult to tune a system with significant backlash. In addition to tightening the rack and pinions, we made sure the belts were tight.
To actually tune an axis, start LinuxCNC and open Machine -> Halscope
with the following signals:
joint.2.f-error
joint.2.pos-fb
y-vel-fb
trigger on v-vel-fb
rising
Then use a simple gcode program to run the axis through a step motion. Something like:
TODO: get this from the machine
Then open up the Machine -> Calibration
settings to tune specific values. You can test new tuning values for each joint. For the gantry axis, it makes most sense to set both X joints the same.
The tuning cycle is then:
- Enter new tuning values and click test.
- Enable the a single trigger in halscope
- Run the gcode program
- Observe the following error
You can use this procedure to get a better sense how individual tuning changes effect the system. Depending on the type of control system you have, you can take different approaches. For this brushed DC h-bridge system, the following worked well:
- Adjust P until the axis is stiff (in our case 60 for Y)
- Adjust D to reduce oscillation but not so much that the axis buzzes (in our case 0.1 for Y)
- Add FF1 to reduce stead state error (in our case ~0.0345 for Y)
- Add FF2 to reduce acceleration error (in our case, 0.0 for Y)
We then started with these values for X.
For these settings, the OUTPUT_SCALE was set to 1.0, to match the 0.0-1.0 expected for the PWMGen input. You can choose different scales, and your tuning terms will adjust appropriately.
The Z axis can be somewhat more difficult to tune since it has a constant weight in one direction only. You can view the output of the PID command under this load and use that value as a bias to try and keep the PID loop a bit more symmetric.