Our mice should be driving reasonably straight using only proportional control. This week, we will learn how to correct for long-term error, use the Arduino PID library, and have our mouse follow walls.
Important Before you begin the lab, make sure to download the new lab code here:
Recall our implementation of a proportional controller from last week's lab:
Proportional control works pretty well for making our mouse drive straight, but it doesn’t account for long-term drift. Even if our mouse manages to correct most of the error every timestep, there’s still a little bit of uncorrected error that builds up. What if our mouse kept track of the total error so far?
This is known as a proportional-integral (PI) controller. The integral sums up the total error since we started the controller. As small errors build up, they’ll cause the controller to apply a stronger correction to u(t) and get our mouse back on track.
It might also help to add a term that’s proportional to the derivative of error:
The derivative of error represents how fast the error is changing. If the error is increasing rapidly, we might want to apply a stronger control input u(t). Likewise, we might want to reduce the amount of u(t) we apply if the error is approaching zero quickly.
When we combine these three terms, we get a proportional-integral-derivative (PID) controller.
\(K_p\), \(K_i\) and \(K_d\) are tunable gains that determine how much each term affects the final output power
Let’s break down the terms from left to right:
- The P term (proportional term) increases our correction proportionally to the error: the higher our error, the more power we should apply to correct for it. This is generally considered the most important term.
- The I term (integral term) compensates for long-term error & drift by integrating the error over time. While a small tendency for our mouse to veer to the right might have little effect on the P term, it’ll cause the I term to build up until the system reaches the setpoint perfectly.
- The D term (derivative term) takes the derivative of the error with respect to time. Systems often have inertia: the faster our error is already decreasing, the less power we need to apply to correct for it. This dampens our controller and decreases overshooting.
- We only have individual measurements of the error, and not a continuous function. How could we estimate the integral of the error? (You don’t need to write code for this part.)
- How could we estimate the derivative of the error? (You don’t need to write code for this part.)
- One potential issue with PID control is integral windup. You can read about it on Wikipedia. What are some ways of preventing integral windup?
Now we’re going to implement the integral part of the PID and add it to the proportional control we made in Controls 1 lab. You're going to add the integral coefficient, the integral of the mouse’s error over time and a solution to integral windup. You may want to start around the Ki values, Angular Ki = 0.05, and Linear Ki = 0.0005. Try some values larger and smaller than the Ki values given and notice the effect on your mouse.
- Explain what you changed from the code of Controls 1 lab.
- What effect does increasing Ki have? What happens if Ki is too large?
- Demonstrate your working code!
Now we’re going to implement turning in place. We’re going to take advantage of the fact that have implemented the PI of PID for going straight. To go straight you set linear velocity to some number and angular velocity to zero, to turn, we just do the opposite. We’ll have two functions that will change the values of the setpoints for linear and angular velocity. You’ll need your code from controls 1 to set up your PID.
- Show us turning in place and then have the mouse go straight.
- Since we can go straight or turn, what are some ideas of how to control how far we turn or go straight?
No matter how well our mouse can drive straight, there will always be some drift. Since our mouse will be driving through a maze with straight walls, we can use the walls as a reference to correct any remaining error. For this section we will be adding a P controller to our mouse that will use our distance sensors as an input. Make sure you make your code be able wall follow from the right or the left, and a bonus if your mouse can choose which side to wall follow. As you discuss how to implement this wall following controller remember that a controller needs an input, setpoint, and what value the controller is changing. Hint: How can our controller affect the Ωangle the robot wants to go, what have we implemented that controls the direction or angle the robot is moving? If you are very confused don’t hesitate to ask for help! We recommend having an if statement based on the value of the side sensor, to have two different sets of PID coefficients. One set of PID coefficients when the distance sensor readings are small, and one set of coefficients when the sensor reading is large. Later on you’ll have to choose the left or right wall to follow, so write your code in a way that will allow you to easily switch from one wall to another later when we have the wall switching logic implemented.
- Explain what you’re using for input, setpoint, and controllable value.
- Walk through the code you wrote for this wall following controller.
- Demonstrate wall following with the wall on the right of your mouse then with the wall on the left of your mouse.
- Bonus: Add an integral constant!