In this project Model predictive control (MPC) is used to drive the car around the track, there's a 100 millisecond latency between actuations commands on top of the connection latency.
The goals / steps of this project are the following:
- Step 1: converting the map's coordinate system to the car's coordinate system for easier CTE and Epsi calculation
- Step 2: fitting a 3rd order polynomial to the converted x and y coordinates
- Step 3: using coefficients to predict car's state (px,py,psi, v) at t+dt (considering latency)
- Step 4: feeding states to the model to solve and optimize the costs and thereby calculate the state and actuator values at t+1
- Step 5: adjusting throttle & steering values based on predictions
Vehicle can't have steering angle of 90 degrees, such conditions can be fixed by setting a lower and upper bound for actuators:
The prediction horizon is the duration over which future predictions are made.
N dt are the hyperparameters to tune for each model predictive controller. The general guidelines is to have N as large as possible, while dt should be as small as possible.
I tested my model with dt= 0.01 and N=5, which was not enough input for the model to control the vehicle. I then increased dt to 0.05 and N to 10 which significanlty improved my model.
For dealing with latency, I used coefficients to predict car's state (px,py,psi, v) at t+dt (dt=0.05) before passing it to the model.
Model's goal is to minimize errors:
- cte: distance of vehicle from trajectory
- epsi: difference of vehicle orientation and trajectory
This model also considers additional costs to penalize vehicle:
- for not maintaining the reference velocity (75mph)
- control-input magnitude & change rate as well as th3e differences from the next control-input state
However I added more weights to some of the costs to add more penalty to the model for a smoother driving:
Here are the cte, v & steering_angle diagrams that I collected for 1000 iterations, as depicted below majority of cte-values are around 0 which shows model is trying to stay in track & valocity is maintaining 50mph, steering-angle-values are very similar to cte-values and it's to stay around 0 to avoid sharp changes:
CTE | Velocity | Steering Anlge |
![]() |
![]() |
![]() |
- cmake >= 3.5
- All OSes: click here for installation instructions
- make >= 4.1
- 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
- uWebSockets
- 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
- Fortran Compiler
- Mac:
brew install gcc
(might not be required) - Linux:
sudo apt-get install gfortran
. Additionall you have also have to install gcc and g++,sudo apt-get install gcc g++
. Look in this Dockerfile for more info.
- Mac:
- Ipopt
- Mac:
brew install ipopt
- Some Mac users have experienced the following error:
This error has been resolved by updrading ipopt withListening to port 4567 Connected!!! mpc(4561,0x7ffff1eed3c0) malloc: *** error for object 0x7f911e007600: incorrect checksum for freed object - object was probably modified after being freed. *** set a breakpoint in malloc_error_break to debug
brew upgrade ipopt --with-openblas
per this forum post. - Linux
- You will need a version of Ipopt 3.12.1 or higher. The version available through
apt-get
is 3.11.x. If you can get that version to work great but if not there's a scriptinstall_ipopt.sh
that will install Ipopt. You just need to download the source from the Ipopt releases page. - Then call
install_ipopt.sh
with the source directory as the first argument, ex:sudo bash install_ipopt.sh Ipopt-3.12.1
.
- You will need a version of Ipopt 3.12.1 or higher. The version available through
- Windows: TODO. If you can use the Linux subsystem and follow the Linux instructions.
- Mac:
- CppAD
- Mac:
brew install cppad
- Linux
sudo apt-get install cppad
or equivalent. - Windows: TODO. If you can use the Linux subsystem and follow the Linux instructions.
- Mac:
- 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
.