PID, state-feedback, LQR, and MPC controllers — plus EKF-SLAM — for a self-driving buggy on a track inspired by CMU's buggy competition.

Objective. In CMU's control-theory course I was tasked with designing an efficient controller and estimator for a small self-driving vehicle, drawing track inspiration from CMU's annual buggy competition.

Bicycle model of the vehicle
Bicycle model used for the vehicle dynamics.

Solution. I approximated the car with a simple bicycle model — two wheels, two degrees of freedom, described by longitudinal and lateral dynamics — and designed a two-part controller that outputs steering angle δ and longitudinal force f. Given a desired trajectory of waypoints, I implemented:

  1. PID controller
  2. State-feedback controller
  3. LQR controller
  4. MPC controller

For the PID controller I tuned the proportional, derivative, and integral gains. For the static LQR I discretized the continuous error dynamics of the nonlinear system with a zero-order hold and designed an infinite-horizon LQR. For MPC I ran an iterative finite-horizon LQR over a tunable horizon N. The controller accelerated on straights and slowed appropriately for turns.

Track

When GPS localization is unavailable, autonomous cars often rely on CV/LIDAR for obstacle avoidance. I implemented EKF-SLAM, a sensor-fusion method that augments the position estimate with local measurements. Using range and bearing measurements to the next waypoint, the buggy maintained a stable estimate of position and heading over the whole track.

Results. I tested the model on a track modeled after CMU's buggy course using Webots. The buggy completed the track in under 120 seconds with an average deviation of under 3 meters from the optimal path — substantially better than the real-world buggy raced each year at CMU. Every controller cleared the target performance metrics.

LQR results
Results figure
Applied skills Python · Webots · Extended Kalman Filter SLAM · MPC · LQR · State Feedback · PID