Ground Embedded KO Subscribe

Notes / Control Engineering

PID control: present, past and future error

P responds to the present error, I to the accumulated error and D to the rate at which the error changes. The effect of each term and the tuning order.

GROUND EMBEDDED · NOTEControl Engineering 06PID controlTargetKpKiKd

u = Kp·e + Ki·∫e dt + Kd·de/dt

Role of each term

Term Responds to Raising it
P The error right now Faster, but more overshoot and oscillation. Steady-state error remains
I Accumulated error Removes steady-state error; too much gives slow swinging
D Rate of change of error Suppresses overshoot (a brake); amplifies noise

Code

float pid_step(pid_t *p, float target, float meas, float dt) {
    float e = target - meas;
    p->integ += p->ki * e * dt;
    p->integ = clamp(p->integ, -p->imax, p->imax);       // anti-windup
    float deriv = -(meas - p->prev_meas) / dt;             // derivative of the measurement (no kick when the target jumps)
    p->prev_meas = meas;
    return clamp(p->kp * e + p->integ + p->kd * deriv, -p->umax, p->umax);
}

Tuning order (the field method)

  1. With I and D at 0, raise P until the response is fast but just short of oscillating
  2. Lower P a little and raise I to remove the steady-state error
  3. If the overshoot is large, add a little D (with a low-pass filter in front of D)
  4. Apply a disturbance (push by hand, add weight) and check the recovery

Try changing the gains in the lab's PID 3D simulation and see the effect of each term for yourself.

In a picture: response for different gains

TargetP too high: ringsRight: fast, stableGain too low: slowTime
Step responses of the same system with only the gain changed. A high gain is fast but rings; a low gain is stable but slow.

What the three terms do

Term Looks at Raise it and Overdo it and
P The error right now The response gets faster Ringing, divergence
I Accumulated error The remaining error disappears Overshoot, slow swinging
D How fast the error is changing Ringing decreases It shakes on noise

With P alone, a little error remains near the target. When the error is 0 the output is 0 too, but output is needed to overcome the load. I removes this remaining error over time.

3D labRun what you have read so far→

Code as actually used

typedef struct { float kp, ki, kd, integ, prev_meas, out_min, out_max; } pid_t;

float pid_update(pid_t *p, float target, float meas, float dt) {
    float err = target - meas;
    float d   = -(meas - p->prev_meas) / dt;          // differentiate the measurement (no kick on target jumps)
    p->prev_meas = meas;

    float out = p->kp * err + p->integ + p->kd * d;

    if (out > p->out_max)      out = p->out_max;      // output limit
    else if (out < p->out_min) out = p->out_min;
    else p->integ += p->ki * err * dt;                // integrate only when not saturated

    return out;
}

There are two differences from the textbook equation.

  • Integral windup prevention: if the integral keeps accumulating while the output is stuck at its limit, then even after the error reverses the output is pushed to one side for a long time until the accumulated value unwinds. Stop integrating while saturated.
  • Derivative on measurement: differentiating the error makes the derivative term spike the moment the target changes suddenly. Differentiating only the measurement avoids this kick.

Order for tuning by hand

  1. With I and D at 0, raise P. When it starts to ring, bring it down to about half.
  2. Raise I a little at a time until the remaining error disappears within a reasonable time.
  3. If the overshoot bothers you, add a little D. If it shakes, reduce it or add a low-pass filter to the derivative.

It is quicker to change one thing at a time, in big steps of double or half, and find the trend first.

The period must be constant

If dt jitters, the response changes even with the same gains. Run the control loop from a timer interrupt at a fixed period, not from the main loop. Choose a period at least 10 times faster than the system responds. Tens of μs for a current loop, 1 ms for a speed loop and about 100 ms for temperature control are common values.

Problems that come up in practice

  • The sign is connected the wrong way round: positive feedback that pushes harder the larger the error gets
  • Sensor noise amplified by the D term, making the motor audible
  • Differentiating a sensor value that updates more slowly than the control period
  • Mixed units changing what the gains mean (rad and deg, seconds and ms)
3D LABPID ControlRun what this note explains and watch it respond.Open the lab →FREE PDFGet the 3 free ebooksIf you want to keep reading this topic as one book: BLDC motor control, serial communication and sensors at book length. PDFs are in Korean.Get them free →