PID Tuning Tutorial for FRC Students

Easy to learn and understand

What is PID?

PID is a control loop that is ideal for most physical and error-prone systems. It is used in robotics very often because of its versatility and straight-forward way of “getting to a setpoint”.

PID is getting from where you are, to where you want to be.

A few very important things to understand:

A setpoint is your desired input. For example, you might have a sensor to detect the position of a rotating arm. Your setpoint is the theoretical input that would be given by that sensor at the rotation that you want to arm to go to.

Your setpoint, and input in general, can be speed, position or boolean. It can be “run a motor at this speed”, “run the system until it is at a specific position, and stay there”. A boolean would simply be a less specific version of a position. (yes or no VS. 4.342cm)

PID is not an ideal system. Well, not entirely true, but in almost all cases it’s not. You will not get “maximum speed to setpoint” using PID - it’s just a physically hard thing to achieve, because things are always changing.

PID, and all control loops in general involves INPUT -> ALGORITHM -> OUTPUT. The algorithm stores old INPUT, and OUTPUT can be (and usually is) a completely different scale and format compared to INPUT. All that matters is that the ALGORITHM uses OUTPUT as a way to adjust INPUT until the setpoint is achieved.

Purposes of the components

PID is an acronym. Ironically, most people who use PID are actually only using P and D, or P and I. Actually, a lot of the time it’s just P.

What do the letters stand for? This is the easiest way to explain PID - by dissecting it into the three components. Be sure to remember through all of this that PID is summing the result of those three components.

Before beginning - a quick note. kP, kI and kD are coefficients used to tune the algorithm. They adjust the three components in different ways, but they are the “key” to changing how your system behaves.

P stands for Proportional. As you can guess, P is for adjusting output in proportion to how close you are to the setpoint. It really is this simple:

        P = (setpoint - input) * kP

I stands for Integral. This is the place where most people get confused. The way I like to explain it is simple code:

error = setpoint - input

potentialIGain = (TotalError + error) * kI

      if (potentialIGain < MaxOutput) {

              if (potentialIGain > MinOutput) {

                TotalError += error

            } else {

                TotalError = MinOutput / kI

            }

      } else {

            TotalError = MaxOutput / kI

      }

        

        I = TotalError * kI

I’ll try to simplify this a little bit. First, look at how TotalError will be equal to the maximum or minimum output if potentialIGain is over the limits. (it is divided then multiplied by kI) So essentially, the output will be the total error. For this reason, kI must usually be very very low, as TotalError adds up very quickly. Some PID algorithms will “reset” the total error sometimes. This usually isn’t necessary with a well tuned system, as the total error will slowly become a much more reasonable value when the system approaches the setpoint.

D stands for derivative. This is in reference to how fast you are progressing to your setpoint. The more of a change in “error”, the more that D contributes. It is as simple as this:

        D = (error - previousError) * kD

Tuning

Tuning really is changing those three P, I and D values. These are floating point decimal numbers.

Of note:

So, the tuning process. First off, I’d like to mention that I am not by any means an expert. There are very fancy papers that explain PID much more in-depth, and show tuning in a seriously complicated way. This guide is much more meant as a practical way of achieving goals.

  1. Set all values to zero.
  2. Increase P until the response to a disturbance is steady oscillation.
  3. Increase D until the the oscillations go away (i.e. it's critically damped).
  4. Repeat steps 2 and 3 until increasing D does not stop the oscillations.
  5. Set P and D to the last stable values.
  6. Increase I until it brings you to the setpoint with the number of oscillations desired (normally zero but a quicker response can be had if you don't mind a couple oscillations of overshoot)

If you set D too high the system will begin to chatter (vibrate at a higher frequency than the normal oscillations). If this happens, reduce the D gain until it stops.

If oscillations grow bigger and bigger, reduce P.

This technique is usually known as the Ziegler-Nichols technique. It’s well understood and should get you where you want to go.

Tips and Tricks

https://www.youtube.com/watch?v=UR0hOmjaHp0&feature=youtu.bec

Implementing

The WPILibJ has a class called PIDController that will do the tough work (including threading and synchronizing settings) for you. Give it the correct settings, make sure it’s running, and you should be good to go.

ATALibJ also has a different, but similar implementation of PID. See it here. There is a lot more documentation for it, so if you’re struggling to implement PID, check it out.