Understanding Robot Motion: PID Control
This is part of a series of articles related to working through the AI for Robotics course on Udacity. This write-up is about Lesson 5.
Self-driving cars and robots in general don’t move with perfect precision. Their trajectory can be affected by its environment (such as non-flat surfaces), and slight mis-alignments in its mechanics (such as mis-aligned wheels wheels).
A human driving a car with imprecisely aligned tires can constantly self-correct to make sure they are driving straight. How can we teach a self-driving car to do the same?
Assuming we have a desired path for the car to drive along, we can implement an algorithm known as PID Control to ensure that the car will re-align itself to the target.
Open vs Closed Loop
To understand why systems use PID Control (or Control Systems in general), it’s helpful to understand basic open and closed loop control theory.
If a car were to adhere to an open loop system, the output of that system would have no effect on the control action of the input signal. Instead, the car would faithfully follow the instructions from the input command regardless of the final result. Therefore, if we instruct a car’s computer to move five meters, it will always move five meters even if ends up stopping short or ahead of the target position.
In a closed loop system, the output is fed back as input to reduce errors and increase stability. Its forward-pass architecture is similar to an open loop system, but differs in that part of the output provides feedback to the input. This is known as feedback control. In such a system, the reference signal (which represents the desired goal) can be compared with the measured value, subsequently providing an error term.
The process variable is a system parameter than needs to be controlled. Sensors are used to measure the process variable and provide feedback to the control system.
The set point is the desired value of the process variable. The controller or compensator uses the difference between the process variable and set point to determine the actuator output to drive the system or plant.
Forcing the actuator to turn the wheel left will cause the car the turn left, and will result in the process variable changing as the the distance between the car and the boundary will also change.
In real life, turning and velocity will not be the only affect on the distance from the boundary, as the conditions of the wheels and road will also influence the eventual position of the car. These external influences are known as disturbances.
Steady-state error is the final difference between the process variable and the set point.
PID Explained
PID stands for Proportional Integral Derivative, different methods of treating the error between the process variable and reference signal, which will be used to drive the system. One way to look at PID is to break it down in terms of looking at error using past information (Integral), present information (Proportional), and future information (Derivative).
Notice in the mathematical expression for PID that each response has a K gain coefficient that tunes how sensitive the system is to each of the paths. The paths can be negated by setting the gains to 0. We could for example create a P controller by setting I and D to zero.
Proportional Response
The proportional response examines an error in the present, as it evaluates the distance error proportionately from a given time step. In other words, if the amount of error is low, there is a small correction. Conversely, if there is a lot of error, there is a much larger correction.
Think about a pendulum that’s held in someones hand. When its not at rest, it will swing back and forth, as gravity will ultimately always pull the pendulum back into the start position, with a force that depends on how far it is from the start position. When it’s far from the starting position, the pendulum will swing with a large amount of force.
The issue with using Proportional Control is overshoot, whereby an object overcorrects it’s position. It’s akin to a pendulum swinging past the resting position. On its own, Proportional Control can have issues when an object has mass or inertia, because they will affect the speed of the object regardless of decreasing influence from whatever is accelerating the object, such as gravity or a cars engine. It doesn’t anticipate it’s going back to the target position, so it tends to overshoot and oscillate.
If PC has too high a gain, the controller will constantly over-compensate in either direction, resulting in noticeable oscillation. It’s akin to full throttling a car from a resting a position and then hard braking when the car invariably exceeds the speed limit.
Integral Response
The integral helps looks at data from the past as it sums past errors. Even a small error will result in an progressive increase in the integral response, taking into account the fact that something hasn’t been properly corrected over time.
It’s useful in removing constant errors in a control system, since no matter how small the constant error, eventually the summation of that error will be significant enough to adjust the controller output. It has the effect of driving the steady-state error to zero.
If the gain is too large, the controller might become unstable because normal controller fluctuations will be exaggerated. If it’s too small, it can take too long to respond to dynamic changes.
Derivative Response
The derivative response anticipates the future by examining the rate of the change of the error that contributes at a given time step. The derivative response is proportional to the rate of the change of the process variable. When the change of the error is moving is slowly, the derivative path is small. The faster the error changes, the larger the derivative path. It is sometimes called anticipatory control.
Unlike the Proportionate and Integral response, the Derivative Response has no impact on the steady-state error. Its role is largely to reduce overshoot.
Applying PID Control
Putting all three together can be effective as they can compensate for one another’s deficiencies.
With the provided Udacity project code, the goal was to have a robot walk along the set point by adjusting its rotation as it walks a consistent pace forward every time step. Programming-wise, all we had to do was create a run method that calculated the steering angle using PID Control.
We’re aiming for the robot to reposition itself to a y position of 0. This means the cross-track error is y.
The integral is the sum of the all the observed errors. And the derivative is the current y position minus the previously observed y position, divided by the unit of time (in this projects case, it’s 1.0).
The robot starts off at (x,y) position (0, 1). The target y position is 0.
With hyperparameters provided within the problem, the algorithm nearly converges on the correct set point but we can see that it has a hovers around a y position of -0.03 instead of 0.
If we use a longer timeframe of 500 time steps instead of the default 200 steps, we can see that the provided hyper-parameters will eventually result in the process variable settling around the set point.
Curious, I wanted to try see to see if I could tweak the hyper parameters in a way that would push the algorithm closer to the set point quicker. One of my attempts was to boost the effect of the integral, as it could help reduce the residual error. While I was able to converge to zero much quicker, the side effect of boosting the integral response was more lag in course correction, resulting in an increase in overshoot.
This was an interesting toy exercise, but unsurprisingly applying it to self-driving cars is significantly more difficult, as there is no known true function that gets steering wheel angles and speed as inputs and outputs the car movement. Engineers instead hand-tune PID controls to get the car to drive well enough.
Helpful Resources: