A C++ Implementation of Model Predictive Control

Self-Driving Car Engineer Nanodegree Program

This is a project in the course Self-Driving Car Engineer Nanodegree program given by Udacity. Throughout this course I get to learn different concepts that are important learnings for a career within autonomous vehicles. This repo contains a Model Predictive Controler that controls a SDC in the Udacity simulator.

Mdoel

The model of the car is escential to the MPC, as it is used to predict the movement of the car with the input of the actuators. In this controler, a simplified model was used which did not include tire force, gracity, mass and more..

The state is constructed with the position (x,y), direction (ψ) and velocity (v). To control the car, two actuators were used. Stearing angle (δ) and speed actuator (a). The following model was implemented:

Model

This model predicts the next state of the car with the current actuators and state. Actuator input was controled through the minimization of a cost function, and an optimal solution the the problem was used. Lf is a parameter provided by Udacity, which is the distance between the front of the car and its center.

Cross track error (cte) and ψ-error () are used in the MPC cost function. Cost

Timestep Length and Elapsed Duration (N & dt)

At first, I reasoned I wanted to look quite far ahead into the the model to better react to future changes. So I started out with N = 50 and dt = 0.05. This proved to be none-optimal, as I'm running this program on a quite old machine. So my beliefe was that I overextended the max computational time allowed and the controler became very unpredictable. So I increased dt to 0.1 and keep reducing N until I got a sufficient ontroler at 40 mph. In the end, I ended up with dt = 0.11 and N = 10. If I had a faster machine, I believe I could have created a better controller, that could handle higher speeds, if I ran this on a faster cpu.

MPC

The datapoints in map-space were transformed to vehicle-space, and a polynomial was fitted to these points. These points are then project into the future with the vehicle model to handle the latency of 100 ms. These projected points were passed to the state and given to the MPC.Solve function. In this function, and optimizer was uesed to solve for the optimal actuation output to minimize the cost.

Dependencies

Intalling Ipopt and CppAD

Dependencies

At this point in the curriculum students will have set up their SDC Term 2 environment and dependencies, with the exception of Ipopt, Fortran, and CppAD. If you are setting up a fresh environment please refer to setup instructions starting here.

Installation Process

  1. Clone this repository and navigate to the cloned directory
  2. Download the appropriate version of Ipopt (3.12.7 or higher) from the link below. You may also use wget or a similiar command to download the source from the command line (see Linux instructions).
  3. Follow the instructions for your environment
  • Ipopt
    • Mac:
        brew tap udacity/CarND-MPC-Project https://github.com/udacity/CarND-MPC-Project
        brew install ipopt --with-openblas
      
  • For Linux and Windows Ubuntu BASH Please note that for any particular command, including execution of .sh scripts, it may be necessary to add sudo prior to the command. It is also a good practice to run sudo apt-get update prior to installation of new libraries.
  • Linux:

    • sudo apt-get install gfortran
    • apt-get install unzip
    • wget https://www.coin-or.org/download/source/Ipopt/Ipopt-3.12.7.zip && unzip Ipopt-3.12.7.zip && rm Ipopt-3.12.7.zip
    • Call install_ipopt.sh with the source directory as the first argument, ex: ./install_ipopt.sh Ipopt-3.12.7 or bash install_ipopt.sh Ipopt-3.12.7
  • Windows: For Windows environments there are two main options

    • Follow Linux instructions in the Ubuntu Bash environment. Please not that install instructions should be executed from the repository directory. Changing to a Windows directory (ie cd /mnt/c .....) can result in installation issues, particularly for Windows directories that contain spaces.
    • Use the docker container described here, which comes pre-configured with Ipopt.
  • CppAD

    • Mac: brew install cppad
    • Linux sudo apt-get install cppad or equivalent.
    • Windows: For Windows environments there are two main options
      • Follow Linux instructions in the Ubuntu Bash environment
      • Use the docker container described here, which comes pre-configured with CppAD.

Troubleshooting

  • If challenges to installation are encountered (install script fails). Please consult the forums. Please feel free to submit additional tips or forum threads to the issue reports repo, for potential inclusion in this document.
  • Some Mac users have experienced the following error:
    Listening 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
    
    This error has been resolved by updrading ipopt with brew upgrade ipopt --with-openblas per this forum post

Basic Build Instructions

  1. Clone this repo.
  2. Make a build directory: mkdir build && cd build
  3. Compile: cmake .. && make
  4. Run it: ./mpc.