Manual tuning

In this first section, we'll develop an intuition of what each of the four parameters of our PID controller does by tuning them manually. Later we'll use the heuristic Ziegler─Nichols method to get good starting values for the tuning parameters.

Proportional control

We start by setting ${K}_{i}$ and ${K}_{d}$ to zero, and by disabling the low-pass filter. We'll only vary the proportional gain factor ${K}_{p}$. This means that the control signal we send to the motor is proportional to the distance between the actual fader position and the desired fader position.
For example, if the target position is $512$ and the actual position is $500$, with a gain of ${K}_{p}=10$, this would result in a PWM output of $10\cdot \left(512-500\right)=120$, or a duty cycle of around $47\mathrm{%}$.

The figure above shows the results of four experiments with different values for the proportional gain ${K}_{p}$.
The blue line is the reference or target position, the orange line is the actual position of the fader, and the green line is the control signal sent to the motor.

We can make two main observations based on these experiments:

1. If the proportional gain is too low ─ as is the case in the top graph ─ the controller results in very poor tracking and in a large steady-state error.
2. If the proportional gain is too high ─ such as in the bottom two figures ─ the tracking and steady-state errors are smaller, but the system overshoots the setpoint significantly, with ringing after steep transients, and oscillations while tracking the ramp.

Proportional-derivative control

In order to minimize the overshoot, the derivative gain ${K}_{d}$ is increased. This penalizes the velocity of the fader, so it won't approach the new target position too quickly, which would cause the fader to overshoot.

1. By increasing the derivative gain, the amount of overshoot decreases in the second graph, and is almost completely gone in the third graph.
2. Increasing the derivative gain even further in the fourth graph makes the controller more sluggish, it takes much more time to get close to the target position after a setpoint change.
3. The higher the derivative gain, the higher the noise in the control signal, which is noticeable as buzzing and slight rattling of the fader. This is because the derivative of the position is inherently noisy due to the discrete and quantized nature of the position measurement and the high-pass characteristics of the derivative operator.

Proportional-integral-derivative control

The addition of the derivative component in the previous section worked well to minimize the overshoot, but there is still some constant tracking error while following the ramp. This is addressed by the integral component: if the actual position is consistently below the target position, the integral will sum up those positive errors over time, which increases the control signal and reducing the tracking and steady-state errors.

1. The higher the integral gain, the smaller the tracking error for the ramp reference, and the faster the fader catches up with the reference.
2. If the integral gain is very large, the fader sometimes slightly overshoots the setpoint after steep transients ─ e.g. the rightmost step in the bottom graph. Despite this overshoot, the controller settles to zero steady-state error rather quickly.

Derivative filtering

We'll now address the noisy derivative component by enabling the low-pass filter, tuning the cut-off frequency ${f}_{c}$ (the $-3\mathrm{d}\mathrm{B}$ point). If ${f}_{c}=0$, the filter is disabled. If the filter is enabled, higher values of the cut-off frequency have little effect, because the filter allows frequencies below ${f}_{c}$ to pass through mostly unhindered. Lowering the value of ${f}_{c}$, the filter becomes more and more restrictive, and you can more clearly see the effects.

1. A lower cut-off frequency results in fewer noise in the control signal, which reduces the buzzing and rattling of the fader.
2. If the cut-off frequency is too low ─ as in the bottom figure ─ the filter introduces too much delay into the loop, which causes the derivative component to lag behind the actual velocity of the fader, reducing the effect of ${K}_{d}$, and resulting in higher overshoot.

Proportional fine-tuning

All parameters influence each other, so manual tuning is an iterative process. Now that we have a good baseline controller, we can iteratively fine-tune the parameters until we're satisfied with the results.

Ziegler─Nichols

Manual tuning requires trial-and-error and some knowledge of how the system is affected by each parameter. An alternative is to use a heuristic formula to choose the gains, such as the Ziegler─Nichols method.

Ultimate gain

First, the integral and derivative gains are set to zero and the proportional gain is increased until the system starts oscillating with a constant amplitude, recording the value of ${K}_{p}$ and the period of the oscillations when this happens. This gain is called the “ultimate gain” ${K}_{u}$, and the period of the oscillation period is denoted by ${T}_{u}$.

In this experiment, the ultimate gain was determined to be ${K}_{u}\approx 19$, and the period of oscillation was around 29 cycles, or ${T}_{u}\approx 29\phantom{\rule{thinmathspace}{0ex}}{T}_{s}$, with ${T}_{s}=960\mu s$.

PID gains

These values of ${K}_{u}$ and ${T}_{u}$ are then plugged into the heuristic formula ${K}_{p}=0.6\phantom{\rule{thinmathspace}{0ex}}{K}_{u},\phantom{\rule{1em}{0ex}}\phantom{\rule{1em}{0ex}}{K}_{i}=1.2\phantom{\rule{thinmathspace}{0ex}}{K}_{u}/{T}_{u},\phantom{\rule{1em}{0ex}}\phantom{\rule{1em}{0ex}}{K}_{d}=0.075\phantom{\rule{thinmathspace}{0ex}}{K}_{u}{T}_{u}.$ The results for these parameters are shown in the second graph in the figure below. The top graph shows the best manually tuned controller.

The resulting controller was relatively aggressive and had quite a bit of overshoot, so ${K}_{i}$ was halved (third graph) and ${K}_{d}$ was increased slightly (fourth graph), ${K}_{p}=0.6\phantom{\rule{thinmathspace}{0ex}}{K}_{u},\phantom{\rule{1em}{0ex}}\phantom{\rule{1em}{0ex}}{K}_{i}=0.6\phantom{\rule{thinmathspace}{0ex}}{K}_{u}/{T}_{u},\phantom{\rule{1em}{0ex}}\phantom{\rule{1em}{0ex}}{K}_{d}=0.09\phantom{\rule{thinmathspace}{0ex}}{K}_{u}{T}_{u}.$ The Wikipedia page linked to above also contains some alternative rules that promise less or no overshoot, it might be worth trying these out as well.