This project is to use Model Predictive Control (MPC) to drive a car in a simulator. The server provides reference waypoints 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.
Yellow line - polynomial reference way points Green line - MPC trajectory path
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:
x: cars x position y: cars y position ψ (psi): vehicle's angle in radians from the x-direction (radians) ν: vehicle's velocity cte: cross track error eψ : orientation error
Actuator values:
δ (delta): steering angle a : acceleration (including throttle and break)
Update loop:
- N = 10
- dt = 0.1 s
The time horizon (T) is the duration over which future predictions are made.
T = N * dt
T should be as large as possible. However, the smaller dt is preferred for finer resolution. And larger N isn't always better due to computational time. Hence it is a trade-off.
The reference way points are given in the map global coordinate, and they are transferred into the car's coordinate. And then a 3rd order polynomial is fitted to way points.
In reality, no actuctor could execute command instaly - there will be a delay as the command propagates through the system. A realistic delay might be 100 milliseconds, as set into the project. The following codes deal with the latency issue.
const double latency = 0.1; // 100 ms
const double px_act = v * latency;
const double py_act = 0;
const double psi_act = - v * steering_angle * latency / Lf;
const double v_act = v + throttle * latency;
const double cte_act = cte + v * sin(epsi) * latency;
const double epsi_act = epsi + psi_act;
// State in vehicle coordinate.
Eigen::VectorXd state(6);
state << px_act, py_act, psi_act, v_act, cte_act, epsi_act;
-
cmake >= 3.5
-
All OSes: click here for installation instructions
-
make >= 4.1(mac, linux), 3.81(Windows)
- Linux: make is installed by default on most Linux distros
- Mac: install Xcode command line tools to get make
- Windows: Click here for installation instructions
-
gcc/g++ >= 5.4
- Linux: gcc / g++ is installed by default on most Linux distros
- Mac: same deal as make - [install Xcode command line tools]((https://developer.apple.com/xcode/features/)
- Windows: recommend using MinGW
-
- Run either
install-mac.sh
orinstall-ubuntu.sh
. - If you install from source, checkout to commit
e94b6e1
, i.e.Some function signatures have changed in v0.14.x. See this PR for more details.git clone https://github.com/uWebSockets/uWebSockets cd uWebSockets git checkout e94b6e1
- Run either
-
Ipopt and CppAD: Please refer to this document for installation instructions.
-
Eigen. This is already part of the repo so you shouldn't have to worry about it.
-
Simulator. You can download these from the releases tab.
-
Not a dependency but read the DATA.md for a description of the data sent back from the simulator.
- Clone this repo.
- Make a build directory:
mkdir build && cd build
- Compile:
cmake .. && make
- Run it:
./mpc
.