This project implements controlling application for Udacity self-driving car simulator using PID controller mechanism.
The project implements "twiddle" parameters tuning algorithm as well.
Project objective: No tire may leave the drivable portion of the track surface. The car may not pop up onto ledges or roll over any surfaces that would otherwise be considered unsafe (if humans were in the vehicle).
./pid -p 0.195405 -i 0.004 -d 3.28759 --tKp 0.45372 --tKi 0 --tKd 0.941861
./pid -p 0.195405 -i 0.004 -d 3.28759 -c 0.4
Usage:
pid [options]
Available options:
--tKd throttle PID Kd
--tKi throttle PID Ki
-c, --tC constant throttle
-i, --sKi steering angle PID Ki
-p, --sKp steering angle PID Kp
--tKp throttle PID Kp
-d, --sKd steering angle PID Kd
-t, --twiddle enable twiddle mode
-h, --help print this help screen
./pid -t
In order to activate "twiddle" mode the only -t
option should be passed via
command line.
./pid -p<Kp> -i<Ki> -d<Kd> (-c<C> | --tKp<tp> --tKi<ti> --tKd<kd>)
In order to configure operational mode one might choice between constant
throttle (--tC
) and throttle PID controller (--tKp
, --tKi
, and --tKd
).
Steering angle always controlled by PID (--sKp
, --sKi
, and --sKd
).
cmake
>= 3.5- All OSes: click here for installation instructions
make
>= 4.1 (Linux, Mac), 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, clang- Linux: gcc/g++ is installed by default on most Linux distros
- Mac: same deal as make - install Xcode command line tools
- Windows: recommend using MinGW
uWebSocketIO
== v0.13.0- Ubuntu/Debian: the repository includes
install-ubuntu.sh
that can be used to set up and installuWebSocketIO
- Mac: the repository includes
install-mac.sh
that can be used to set up and installuWebSocketIO
- Windows: use either Docker, VMware, or even Windows 10 Bash on Ubuntu
- Ubuntu/Debian: the repository includes
JSON for Modern C++
- JSON parserCatch2
- Unit-testing frameworkProgramOptions.hxx
- Single-header program options parsing library for C++11
- Clone this repo.
mkdir build
cd build
cmake .. -G "Unix Makefiles"
make
make check # -- optional
The project uses uWebSocketIO
request-response protocol in communicating with the simulator.
INPUT: values provided by the simulator to the c++ program
{
"cte": "current cross track error",
"speed": "current speed",
"steering_angle": "current steering angle"
}
OUTPUT: values provided by the c++ program to the simulator
steer
- instruct simulator to adjust steering angle and speed
{
"steering_angle": "steering angle evaluated on current iteration [-1..1]",
"throttle": "throttle evaluated on current iteration [-1..1]"
}
reset
- forces simulator to reset state
The project uses set of two PID controllers to update steering angle and throttle.
PID (proportional–integral–derivative) is wildly used control technic. PID controller continuously evaluates difference between current state and reference (desired) state and applies a correction which consists of
-
proportional - the main force to achieve convergence to desired state The plot shows how choice of Kp affects the error over time. Choosing smaller value of Kp (orange line) leads to longer convergence. On other hand higher value of Kp gives an opportunity to converge faster (around step 250), but might lead to bigger error (around step 475).
-
integral - fights against potential systematic bias The plot shows there is a systematic bias presents in the system. Blue line (Ki == 0) oscillates around small positive value. Choosing small positive value (green curve) as Ki allows get rid of it. The large value (orange curve) might increase overall error.
-
derivative - fights against oscillation around desired state Proper choice of the Kd allows controller to reduce oscillation.
- Input - pure simulator cross track error value
- Parameters - Kp, Ki, Kd
- Output - truncated to be in range [-1 .. 1]
- Input - magnitude of cross track error shifted by pre-defined value
- Parameters - Kp and Kd (so in fact it's PD-controller)
- Output - truncated to be in range [-1e-2 .. 1]
Magnitude of the cross track error was taken as an input since there is no difference for the controller if the car on the left, or on the right side of the reference path.
The offset defines minimal cross track error magnitude to start braking.
Ki parameter was dropped to reduce the size of parameter space for tuning. PID uses Ki in order to reduce an effect of systematic bias. Since magnitude is used as the input for the controller there is no sense to keep track of systematic bias. It could only be introduced by poor choice of offset value (for now the assumption is the offset value is selected carefully).
Schema for tuning the hyperparameters
- Initial feasible solution was found. Fortunately, the value from lesson worked as a feasible solution at constant throttle of 0.3
- Twiddle approach was used to tune feasible solution from (1).
- Score was calculated from the whole lap
Since twiddling is very time consuming
- simulator provides one measurement each ~0.03 seconds
- the lap is ~0.85 miles long
- simulation time for 1 lap at avg. speed of 45 mph ~60 seconds
- Each set of parameters need to be simulated
The following adjustment was made in scoring routine to achieve keep-feasible and fail-fast goals
- Negative Kp value for both controllers treated as failure
- Score was counted only till currently known best score
- Velocity below threshold for pre-defined number of measurements treated as failure
- Distance below threshold after pre-defined number of measurements treated as failure
- Ki parameter for throttle controller was dropped
- Try to use different parameters tuning technic
- Try to use PID instead of PD to control throttle
- Try different input for throttle controller (ie use current angle and/or speed)
- Normalize parameters to be on the same scale before running twiddle