Model-Predictive-Control

This project is to use Model Predictive Control (MPC) to drive a car in a game simulator. The server provides reference waypoints (yellow line in the demo video) via websocket, and we use MPC to compute steering and throttle commands to drive the car. The solution must be robust to 100ms latency, since it might encounter in real-world application.

View the Project on GitHub

Autonomous driving with Model Predictive Control

1. Objective

This project is to use Model Predictive Control (MPC) to drive a car in a game simulator. The server provides reference waypoints (yellow line in the demo video) via websocket, and we use MPC to compute steering and throttle commands to drive the car. The solution must be robust to 100ms latency, since it might encounter in real-world application.

In this project, the MPC optimize the actuators (steering and throttle), simulate the vehicle trajactory, and minimize the cost like cross-track error.

A max speed of 80 MPH is achieved in this project.

Demo: Autonomous driving with MPC (click to see the full video)

demo_gif1


2. System in brief

2.1 Kinematic model

A kinematic model is implemented to control the vehicle around the track. Kinematic models are simplifications of dynamic models that ignore tire forces, gravity, and mass. This simplification reduces the accuracy of the models, but it also makes them more tractable.

States:

Actuator values

Update equations

state_update

2.2 Timestep Length and Elapsed Duration (N & dt)

The prediction horizon is the duration over which future predictions are made. We’ll refer to this as T. T is the product of two other variables, T = N * dt. In the case of driving a car, T should be a few seconds, at most. Beyond that horizon, the environment will change enough that it won’t make sense to predict any further into the future. N and dt are hyperparameters you will need to tune for each model predictive controller you build. However, there are some general guidelines: T should be as large as possible, while dt should be as small as possible. These guidelines create tradeoffs.

These following dt has been tested 0.3, 0.12, 0.1, 0.08, and I found that the dt should be greater than the latency in order to make the MPC work. So, I choose 0.12 as dt in the end.

The goal of Model Predictive Control is to optimize the control inputs: [δ,a]. An optimizer will tune these inputs until a low cost vector of control inputs is found.

2.3 Polynomial Fitting and MPC Preprocessing

Since the reference waypoints are given in the map global coordinate, and I transfer them into the car’s coordinate by a funciton called map2car (see line 117 in main.cpp), then a 3rd order polynomial is fitted to waypoints.

2.4 Model Predictive Control with Latency

In a real car, an actuation command won’t execute instantly - there will be a delay as the command propagates through the system. A realistic delay might be on the order of 100 milliseconds, so in this project 100 millisecond latency is handled by Model Predictive Controller.

The latency is handled by using kinematic equations to predict the states for after 100ms before sending them to MPC (see code in line 126-134 in main.cpp).


Code & Files

1. Dependencies & environment

2. How to run the code

  1. Clone this repo.
  2. Clean the project: $./clean.sh
  3. Build the project: $./build.sh
  4. Run the project: $./run.sh
  5. Start the simulator v1.45, select the MPC Controller.

3. My project files

4. Code Style

5. Release History