Self-Driving Car Engineer Nanodegree Program
- I used the kinetmatic model taught in the lectures. The model describes how the state vector [x,y,psi,v, cte, epsi] changes over time. Where x, y is the cars position, psi is the orientation and v is the velocity. The cte is the cross track error and is the difference between the center of the road and the vehicles position. The epsi is the orientation error and its the difference between the vehicle orientation and the trajectory orientation. For control inputs I use the steering wheel [delta] and throttle/brake [a] giving a actuator input of [delta,a].
The update equations for this model are:
- x' = x + v * cos(psi) * dt
- y' = y + v * sin(psi) * dt
- psi' = psi + v/L * delta * dt
- v' = v + a * dt
- cte' = cte + v * sin(epsi) * dt
- epsi' = epsi + v/L * delta * dt
- Where dt is the change in time, and L is the distance from the front of the vehicle to its center of gravity.
For MPC you must decide the time over which future predictions are made, or T.
T = N * dt
To choose N and dt I used trial and error to find numbers that worked. I started with N = 10 and dt = 0.1 , therefore T=1, these numbers worked good if you did not take into account latency, but once a 100ms latency was added, the controller became unstable. How I was able to deal with it was I increased dt so that it was larger than latency: 0.125. N I kept at 10, as I found making changes to N drastically changed the controller, and required that you then had to change dt. When experimenting with dt I chose values between 0.1 and 0.15 until I found one that I thought worked the best.
To start I followed the project walkthrough and the cars position is subtracted from the waypoints position, so that the reference origin for the car is a (0,0) in addtion the waypoint points are rotated by (0 - cars orientation) so that the cars reference orientation is 0 also. This simplifies things when calculating the inital state and made doing the polynomial fit easier since the cars reference orientation is always 0, therfore we will mostly be fitting a horizontal line and not a vertical line.
With the intial positions and orientation set to zero the intial state is [0,0,0,v,cte,epsi]
The initial cte in the state above is calculated by first fitting a 3rd degree polynomial to the waypoints and because the cars reference orientation is zero you just evaluate the polynomial at x = 0 and that is the cte. Also the epsi is calculated by finding the difference between the calculated lines orienation and the cars orientation and is again simplified because of the initial transformation. These calculations are at line 123 in main.cpp.
As discussed above I handled latency by increasing the dt so that it was greater than the latency. This way you don't have to worry about the cars state being much different then the one you predicted the actuations for.
- 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
- 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 or the Github releases page. - Then call
install_ipopt.sh
with the source directory as the first argument, ex: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
.