CarND-Controls-PID

Self-Driving Car Engineer Nanodegree Program


Dependencies

Fellow students have put together a guide to Windows set-up for the project here if the environment you have set up for the Sensor Fusion projects does not work for this project. There's also an experimental patch for windows in this PR.

Basic Build Instructions

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

Tips for setting up your environment can be found here

Project Instructions and Rubric

Note: regardless of the changes you make, your project must be buildable using cmake and make!

More information is only accessible by people who are already enrolled in Term 2 of CarND. If you are enrolled, see the project page for instructions and the project rubric.

Project overview

Introduce of the PID controller

PID control is a technique to correct vehicle steering Angle, throttle threshold and other behaviors according to loss components of P(proportion), I(integral) and D(differential) given vehicle crossing trajectory error.

In the Udacity automotive simulator, the CTE value is read from the data message sent by the simulator, and the PID controller updates the error value and predicts the steering angle based on the total error.

PID formula and process (image from Wikipedia)

P : Proportional — This item applies to correcting steering wheel scale errors.If we get too far from the target, we turn the wheel in the other direction.

D : Derivative —The purpose of item D is to suppress this oscillation effect by adding a damping term to the formula.This term is the change in error.The PD controller find that the error is reduced and slightly reduces the angle to approache the smooth path.

I : Integral — The term of I is used to correct a mechanical error that causes us to turn the wheel more or less strong depending on the vehicle to stay upright. So we add a last term to penalize the sum of cumulative errors. The Twiddle PID curve corresponds to the use of an algorithm to find the coefficients more rapidly and thus to converge more quickly towards the reference trajectory.

The PID controller is the simplest and most common in the world. It has the advantage of being implemented quickly and operating in simple situations. But it is impossible to model the physics of the vehicle. When we drive, we naturally adjust our maneuvers according to the size, mass and dynamics of the vehicle. A PID controller can not do it.

Implementation of the PID controller

  1. Update PID

     PID::PID() {}
     
     PID::~PID() {}
     
     void PID::Init(double Kp, double Ki, double Kd) {
         /**
        * TODO: Initialize PID coefficients (and errors, if needed)
        */
     
         this->Kp = Kp;
         this->Ki = Ki;
         this->Kd = Kd;
         this->p_error = 0.0;
         this->i_error = 0.0;
         this->d_error = 0.0;
         this->prev_cte=0.0;
     
     }
     
     void PID::UpdateError(double cte) {
         /**
       * TODO: Update PID errors based on cte.
       */
         this->p_error=cte;
         this->d_error=cte-this->prev_cte;
         this->i_error+=cte;
         this->prev_cte=cte;
     
     }
     
     
     double PID::TotalError() {
         /**
       * TODO: Calculate and return the steer-angle
       */
         double steer_angle=-this->Kp * this->p_error-this->Kd*this->d_error-this->Ki*this->i_error;
         return steer_angle;
     }
    
  2. manual turnning

The most important part of the project is to tune the hyperparameters. This can be done by different methods such as manual tuning, Zieglor-Nichols tuning, SGD, Twiddle. I have done manual tuning. After that I have used twiddle to optimize the parameter-combination. The following table summerizes the effect of each parameter on the system.

The result of manual turning is {0.15000, 0.00100,1.70000}

  1. Twiddle

The twist algorithm is a correct parameter selection technique and can minimize the error.The key idea is to adjust each parameter by increasing and decreasing the value of each parameter, and to see how the error changes.If either direction is conducive to error minimization, the change rate in that direction should be amplified; otherwise, the change rate should be reduced.

Pseudocode for implementing the Twiddle algorithm is as follows:

function(tol=0.2) {
	p = [0, 0, 0]
	dp = [1, 1, 1]
	best_error = move_robot()
	loop untill sum(dp) > tol
	        loop until the length of p using i
				p[i] += dp[i]
				error = move_robot()

				if err < best_err
				        best_err = err
						dp[i] *= 1.1
				else
					p[i] -= 2 * dp[i]
					error = move_robot()

					if err < best_err
				        best_err = err
						dp[i] *= 1.1
					else
						p[i] += dp[i]
						dp[i] *= 0.9
	return p
}

After each run of the 600-point loop, the PID error is updated to make the twiddle algorithm better finetuned.

The result of twiddle turning is {0.155, 0.0011, 1.691}

Discussion

  1. The less tolerance is set, the more simulator loops are needed and the more time is required. Considering the time factor, I didn't set the tolerance to 0.1, which could be lower than 0.001, but udacity's GPU doesn't have enough usable time. Is there any way to save time?

  2. In the future, the speed can also be added to PID control.