Micromouse Lab 6

Expanding on Controls and PID

In the previous lab, we were able to get our mice driving reasonably straight with just proportional control. This week, we'll learn how to correct for persistent steady state error, turn in place, and follow walls.

For this lab, we'll be using the same starter code as Lab 5. Since this lab is an expansion of the previous one, we recommend just modifying your existing code.

Expanding on Proportional Control

Recall our implementation of a proportional (P) controller from last week.

$$ \begin{align}
e(t) = setp&oint(t) - actual(t) \\
u(t) &= K_p e(t) \\
applyPowerLeft(&u_{linear}(t) + u_{angular}(t)) \\
applyPowerRight(&u_{linear}(t) - u_{angular}(t))
\end{align} $$

Proportional control works pretty well for making our mouse drive straight, but you may have encountered a constant offset error when using it to control linear velocity. If we had zero linear velocity error, we'd apply zero power to our motors, which means they'd stop! How might we fix this? What if we kept track of the total error?

$$ u(t) = K_p e(t) + K_i\int_{0}^{t} e(\tau) d\tau $$

This is called a proportional-integral (PI) controller. The integral keeps track of the total error (both positive and negative) since we first started the controller. Even small errors will cause the integral term to eventually grow large enough and get \(u(t)\) to push our mouse back on track.

In order to dampen oscillations and prevent overshoot, we might want to consider the derivative of our error too. This prevents our error from changing too quickly.

$$ u(t) = K_p e(t) + K_i\int_{0}^{t} e(\tau) d\tau + K_d (de(t)/dt) $$

With these three terms, we have our proportional-integral-derivative (PID) controller. \(K_p\), \(K_i\), and \(K_d\) are tunable gains that determine the behavior of our error (rise time, peak, overshoot, etc.).

Let's go over what each of the terms in PID means.

Note this checkpoint has no code.

Checkpoint #1

Implementing a PI Controller

Now we're going to add the integral term to your proportional controller from last week. Do this for both the angular and linear velocity controller. You're going to need to add a variable for keeping track of the sum of the error, the \(K_i\) coefficient, and the solution to integral windup. We recommend starting with \(K_i=0.05\) for angular and \(K_i=0.0005\) for linear. Try some smaller and larger values and notice the effect on your mouse.

Checkoff #2


Now we're going to implement turning in place. To do this, we can reuse the PI controller you just implemented. Instead of a target angular velocity of 0, we set it to some positive number (8 rad/s is a good start) and set the target linear velocity to 0. You may have to retune your constants, but you should now be turning in place!

To make things interesting, let's have your mouse move straight for a bit and then turn in place for a bit. This is a good time to abstract out the PID computation to another function much like how we did the distance and velocity measurements. Use the millis() function to help switch between the two modes.

Checkoff #3

Wall Following

No matter how straight we drive, there will always be a little drift. Driving in a maze, this may cause our mouse to hit a wall. Using the ToF sensors on our mouse, we can use the distance to the wall as a reference to keep our mouse driving straight relative to the walls. For this section, you'll be implementing a P controller to perform wall following. Since our sensors have limitations, it doesn't need to correct for large angular errors, only smaller ones.

As you discuss how to implement this wall following controller remember that the controller needs an input, setpoint, and changeable value. How can our controller affect the angle the mouse is traveling? Don't be afraid to ask for help!

Checkoff #4