## Saturday, October 17, 2015

### Fun with PIDs

PID?  What the heck is a PID?

According to Wikipedia, PID is a Proportional-Integral-Derivative controller (PID controller) which is any kind of control loop feedback mechanism.  These controllers find common usage in industrial control systems.

What a PID controller does is continuously calculate an error value as the difference between the measured value of something that is changing and the desired value.

Perhaps a simple example is in order.  Let's say you want to fill a pan of water at a specific temperature from the tap.  You have two sources of water, cold and hot.  You will need to control the mix of hot and cold water to obtain the desired temperature which you are going to measure with your finger.  So you start with a guess of the hot and cold water settings, measure the result and adjust the hot and cold flow until satisfied.  Making a change that is too big may result in overshooting or undershooting the desired temperature.

Lets call the water temperature sensed by your finger the "process variable" or PV.  The temperature that is desired, let's call the "set point" or SP.  The amount of change of the water flow mix of hot and cold, let's call the "control variable" or CV.  And lastly, the difference between the measured temperature and the desired temperature is the "error" or e.

The most obvious way to change the water flow is in proportion to the current error.  The bigger the error, the bigger the change.  A slightly more complex methodology might want consider the rate of change of the error adding more water flow control depending on how fast the error is approaching zero (a derivative action).  Another refinement might be to consider some historical accumulated error information to detect whether the temperature is settling out too low or too high and make the appropriate corrections (an integral action).  Another way to perform this integral action would be change the current water tap position in steps proportional the current error.

When making changes that result in overshoot or undershoot of the desired set point, continuing to do so will result in oscillations around the desired set point that either grow or decay with time.  If the oscillations decay, the system is stable.  If they grow, the system is unstable.  If they remain at a constant amplitude, the system is marginally stable.  The desired goal is a gradual convergence to the desired set point, so the controller may try to dampen future oscillations by tempering its adjustments by a process called reducing the loop gain.

When the controller starts from a stable state with no error (PV = SP), any changes made by the controller will be in response to changes in other inputs to the process that affect it.  These changes are known as disturbances.  An example of a disturbance in our simple system described above would be a change in the tap water temperature caused by an external event such as the water heater deciding to turn on its heating element.

In theory, a PID controller can be used to control any process which has a measurable output (PV), a known ideal for that output (SP) and an input to the process (CV) that will affect the PV.  So, as you can see PID controllers find uses in any problem domain that needs to regulate temperature, force, speed, pressure, flow rate, weight, position and just about any other variable for which a measurement exists.

So, now just a little bit about the theory of PID controllers.  The name as we have seen above comes from its three terms (Proportional, Integral and Derivative) which are summed to calculate the output of the controller.

The clasasic formula for the algorithm (from Wikipedia) is:

where:
Kp - Proportional gain.  These first three are algorithm tuning parameters
Ki  - Integral gain
Kd - Derivative gain

e   - Error = SP - PV

t   - Time or instantaneous time (the present)
T  - Variable of integration (takes values from time 0 to present time t)

What is desired is a controller that will smoothly make adjustments to the desired set point with minimal over-shoot and under-shoot.  Directly implementing this formula in code would lead to some simple solutions that would most likely suffer from a number of short-comings such as the following:

• Sample Time - The formula requires recalculation at a regular interval since both integration and derivatives are a function of time.
• Derivative Kick - Any time the set point (SP) is changed, the error is changed (SP-PV) and the derivative of this change is infinity.  In practice however, since the change in time is never zero, it ends up being a very big number which when fed into the calculation results is an undesirable spike in the output.
• On the fly Tuning Changes - Changes in the three tuning parameters affect the integration of the error value over time.  Any change in Ki will be multiplied by the entire error sum that has been accumulating when we really only want it to affect the result going forward.
• Reset Wind-up - Most controllers have some limit on operational ranges.  For example a water valve can only be set in the range of completely closed to completely open.  If the PID controller does not know about these ranges, it may calculate an output value that is out of range.  Over time when it tries to continue to add more water flow beyond maximum, only to have it clamped by the physical size of the pipe, the algorithm will continue to ask for more and more beyond the limit.  The result is that the output gets "wound up" way beyond the maximum limit.  Where the problem reveals itself is when the set point (SP) is dropped, the algorithm needs to wind back down again to the maximum before it will even affect the output.  This results in what looks like a lag in response of the controller to the new set point.
• Switching the PID Controller on/off - This occurs when you validly decide that regardless of what the PID controller is doing, you want to override its decision for a period of time.  Now, when you stop overriding it's decision, you get a sudden, huge change in the output.  The controller keeps trying to adjust the output to get the desired result, but it doesn't see any change, so it adjusts the output a little more and so on.  It would be like externally overriding a volume control of a stereo system while trying to adjust the volume internally.  No change internally has any effect.  Then you switch off the external override and suddenly you have a huge volume change.
• Initialization - While it is useful to be able to turn off the PID and set your own override, when you turn it back on, the PID jumps back to the last output value it had set resulting in another spike in the output.  These transitions need to be seamless.
• Changing Direction - The PID algorithm may be used to drive a system that is either "direct acting" (an increase in the output causes an increase in the input) or "reverse acting" (an increase in the output causes a decrease in the input).  A refrigeration system for example is a reverse acting system as an increase in the cooling results in a decrease in temperature.  Changing the sign of Kp, Ki and Kd allows proper control of a reverse acting systems.
Rather than detail the solutions for all of these potential issues, let me refer you to a most excellent blog by Brett Beauregard detailing the improvements one-by-one starting with the most basic code example.  It is a great read and not one I could not improve upon.

There is a great PID implementation for the Arduino also available at the Arduino Playground which will be the subject of my next posting.