-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Vehicle Steering Control using PID. Adding files for project submission
- Loading branch information
AhmedDesoky91
committed
Sep 5, 2018
1 parent
27eea76
commit 4a4e164
Showing
12 changed files
with
13,515 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage"> | ||
<storageModule moduleId="org.eclipse.cdt.core.settings"> | ||
<cconfiguration id="0.1570756881"> | ||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.1570756881" moduleId="org.eclipse.cdt.core.settings" name="Default"> | ||
<externalSettings/> | ||
<extensions> | ||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> | ||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> | ||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> | ||
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> | ||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> | ||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> | ||
</extensions> | ||
</storageModule> | ||
<storageModule moduleId="cdtBuildSystem" version="4.0.0"> | ||
<configuration buildProperties="" description="" id="0.1570756881" name="Default" parent="org.eclipse.cdt.build.core.prefbase.cfg"> | ||
<folderInfo id="0.1570756881." name="/" resourcePath=""> | ||
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.1160039664" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain"> | ||
<targetPlatform id="org.eclipse.cdt.build.core.prefbase.toolchain.1160039664.1518819301" name=""/> | ||
<builder id="org.eclipse.cdt.build.core.settings.default.builder.1499869261" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/> | ||
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.677009479" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/> | ||
<tool id="org.eclipse.cdt.build.core.settings.holder.1640990166" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder"> | ||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1951982531" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/> | ||
</tool> | ||
<tool id="org.eclipse.cdt.build.core.settings.holder.663409044" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder"> | ||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1873477790" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/> | ||
</tool> | ||
<tool id="org.eclipse.cdt.build.core.settings.holder.1012831861" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder"> | ||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1627184704" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/> | ||
</tool> | ||
</toolChain> | ||
</folderInfo> | ||
</configuration> | ||
</storageModule> | ||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> | ||
</cconfiguration> | ||
</storageModule> | ||
<storageModule moduleId="cdtBuildSystem" version="4.0.0"> | ||
<project id="Vehicle-Steering-Control-using-PID-Controller.null.983217834" name="Vehicle-Steering-Control-using-PID-Controller"/> | ||
</storageModule> | ||
<storageModule moduleId="scannerConfiguration"> | ||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> | ||
<scannerConfigBuildInfo instanceId="0.1570756881"> | ||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> | ||
</scannerConfigBuildInfo> | ||
</storageModule> | ||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/> | ||
</cproject> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<projectDescription> | ||
<name>Vehicle-Steering-Control-using-PID-Controller</name> | ||
<comment></comment> | ||
<projects> | ||
</projects> | ||
<buildSpec> | ||
<buildCommand> | ||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name> | ||
<triggers>clean,full,incremental,</triggers> | ||
<arguments> | ||
</arguments> | ||
</buildCommand> | ||
<buildCommand> | ||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name> | ||
<triggers>full,incremental,</triggers> | ||
<arguments> | ||
</arguments> | ||
</buildCommand> | ||
</buildSpec> | ||
<natures> | ||
<nature>org.eclipse.cdt.core.cnature</nature> | ||
<nature>org.eclipse.cdt.core.ccnature</nature> | ||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature> | ||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature> | ||
</natures> | ||
</projectDescription> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
project(PID) | ||
|
||
cmake_minimum_required (VERSION 3.5) | ||
|
||
add_definitions(-std=c++11) | ||
|
||
set(CXX_FLAGS "-Wall") | ||
set(CMAKE_CXX_FLAGS "${CXX_FLAGS}") | ||
|
||
set(sources src/PID.cpp src/main.cpp) | ||
|
||
include_directories(/usr/local/include) | ||
link_directories(/usr/local/lib) | ||
|
||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") | ||
|
||
include_directories(/usr/local/opt/openssl/include) | ||
link_directories(/usr/local/opt/openssl/lib) | ||
link_directories(/usr/local/Cellar/libuv/1*/lib) | ||
|
||
endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") | ||
|
||
|
||
add_executable(pid ${sources}) | ||
|
||
target_link_libraries(pid z ssl uv uWS) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,107 @@ | ||
# Vehicle-Steering-Control-using-PID-Controller | ||
In this project, I have worked on a PID controller to control the vehicle's steering angle | ||
# **Vehicle Control Using PID Controller** | ||
--- | ||
|
||
**In this project, I have worked on a PID controller to control the vehicle's steering angle .** | ||
|
||
## Project Introduction: | ||
--- | ||
In this project, we are controlling the vehicle's steering angle to be within the road using one of the most common and fundamental controllers which is the PID (Proportional, Integral, Differtial) controller. For doing this, we use the Cross Track Error (CTE) which the lateral distance between the vehicle and the reference trajectory provided from the simulator to control the steering angle and have the vehicle in the road. | ||
|
||
|
||
## Environment: | ||
--- | ||
* Ubuntu 16.04 LTS | ||
* Udacity Self-Driving Car Nano-Degree Term2 Simulator | ||
* cmake >= 3.5 | ||
* make >= 4.1 | ||
* gcc/g++ >= 5.4 | ||
|
||
## Parameters Discussion | ||
--- | ||
### Proportional Term (Kp) | ||
The proportional term is simply multiplying a factor (constant) by the error value (CTE in our case) to compensate the drift happened in the steering angle due to this error (CTE). | ||
|
||
The following equation summerizes the proportional term: | ||
` steering_angle = - Kp * CTE` | ||
|
||
Applying the proportional term (P-Controller) to the vehicle, it will act like this: | ||
 | ||
It will be overshooting overtime .. sometimes this overshooting will be slightly small and it may be OK, but even if it is small, it will never really converge, It will be what is called "marginally stable" or "stable" | ||
|
||
We can consider this overshooting as oscillation for our control process. When Kp is large, the oscillation is faster, and vise versa. | ||
|
||
### Differential Term (Kd) | ||
The previous discussion turns to the P-term is usually is not enough due to the overshooting probelm and oscillation. The differential term allow to gracefully approach our target trajectory by having the steering angle not only proportional to the error itself, but also to the difference of the error using another factor (Kd). | ||
|
||
**How we compute the derivative `d/dt CTE` ?** | ||
|
||
`d/dt CTE = ( current_CTE - previosu_CTE ) / delta_t` | ||
|
||
When `delta_t = 1` : | ||
`d/dt CTE = current_CTE - previosu_CTE` | ||
|
||
|
||
The following equation summerizes the PD-Controller: | ||
`steering_agnle = - Kp * CTE - Kd * (CTE - previous_CTE)` | ||
|
||
The following figure from my Udacilty lesson illustrates the impact of the D-term for having more smooth controller rather than P-controller only. | ||
 | ||
|
||
### Integral Term (Ki) | ||
The integral term tackles problems what is called in robotics **Systematic Bias**. To explain this problem with an example related to our case, assume that you receive your car with wheels 100% aligned straight. But in reality due to some mechanical offsets and errors, they are not alighned. When running our controller, this error will accumulate over time turning to a big error in CTE | ||
|
||
The following image illustraces the systematic bias: | ||
 | ||
Even the controller is stable at the end (in blue), it far away from the set point we need to achieve (yellow) | ||
|
||
The I-term solves for this problem by having the sum of all cross track errors you have ever observed. It will evetually correct the vehicle's motion | ||
|
||
The following summerizes how we calculate the integral term: | ||
`integral_CTE += CTE` | ||
|
||
So, the final equation for having a PID controller: | ||
`steering_angle = - Kp * CTE - Kd * (CTE - previous_CTE) - Ki * integral_CTE` | ||
|
||
|
||
## Parameters Tuning (Kp, Ki, Kd) | ||
--- | ||
I followed a manual approach for tuning the PID parameters. | ||
|
||
I have followed the following strategy: | ||
- Firstly and initially, for the integral term, the Systematic bias does not appear in simulation, so I set `Ki = 0.0` | ||
- I started with setting the prortional term `Kp` with low values. I got the feeling that car is not that responsive (oscillation is very slow). | ||
- Then I have increased the `Kp` with trial after another. Here I got to the car keeps oscillating | ||
- Then I started introducing the `Kd` term to have a more smooth and graceful driving | ||
- With many trial, I found the following: | ||
- `Kp` values less than 0.9 get to very poor response to the car specially in curves | ||
- `kp` is very acceptable in 0.1 | ||
- `kd` values less than 0.35 allow the propostional term to have dominant impact so the car still osciallting | ||
- `kd` with high values (2.5, 3.0, .. ) are Ok in sometimes but it gave me the feeling of continuous smooting for steeting so I felt that it is not safe driving | ||
|
||
**Parameters Tuning Conclusion:** | ||
|
||
- I found `Kp = 0.11` and `kd = 0.47` achieves one of the best safe driving for parameters tuning. | ||
- Yes, it may be two times the car touches the ledges, but on the other hand the car was moving very smoothly and gracefully all over the track with very acceptable performace. | ||
- The following video is a demo for my project, [here](https://youtu.be/hOGo_fkgdsE) | ||
|
||
## Running the Code | ||
--- | ||
This project involves the Term 2 Simulator which can be downloaded [here](https://github.com/udacity/self-driving-car-sim/releases) | ||
|
||
|
||
This repository includes two files that can be used to set up and install uWebSocketIO for either Linux or Mac systems. For windows you can use either Docker, VMware, or even Windows 10 Bash on Ubuntu to install uWebSocketIO. | ||
|
||
Once the install for uWebSocketIO is complete, the main program can be built and ran by doing the following from the project top directory. | ||
|
||
1. mkdir build | ||
2. cd build | ||
3. cmake .. | ||
4. make | ||
5. ./pid | ||
|
||
## Conclusion | ||
--- | ||
* The PID controller is on the common and fundametal controllers that can be used in for controlling the vehicle steering and brakes. | ||
* PID parameters tuning needs a lot of intution and understanding of them impact. | ||
* There are some methods to tune these parameters automatically rather than manually, for example the twiddle (or coordinate ascent) algorithm. It may be a furhter improvement for my project to use on of these algorithms for parameters tuning. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
--- CMakeLists.txt 2017-03-23 20:58:47.000000000 +0900 | ||
+++ CMakeListsnew.txt 2017-03-23 20:57:33.000000000 +0900 | ||
@@ -32,10 +32,16 @@ | ||
target_link_libraries (uWS LINK_PUBLIC ${OPENSSL_CRYPTO_LIBRARY}) | ||
target_link_libraries (uWS LINK_PUBLIC ${ZLIB_LIBRARY}) | ||
|
||
-if (UNIX) | ||
+if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") | ||
target_link_libraries (uWS LINK_PUBLIC pthread) | ||
install (TARGETS uWS DESTINATION /usr/lib64) | ||
install (FILES src/Extensions.h src/WebSocketProtocol.h src/Networking.h src/WebSocket.h src/Hub.h src/Group.h src/Node.h src/Socket.h src/HTTPSocket.h src/uWS.h src/uUV.h DESTINATION /usr/include/uWS) | ||
-endif (UNIX) | ||
+endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") | ||
+ | ||
+if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") | ||
+target_link_libraries (uWS LINK_PUBLIC pthread) | ||
+install (TARGETS uWS DESTINATION /usr/local/lib) | ||
+install (FILES src/Extensions.h src/WebSocketProtocol.h src/Networking.h src/WebSocket.h src/Hub.h src/Group.h src/Node.h src/Socket.h src/HTTPSocket.h src/uWS.h src/uUV.h DESTINATION /usr/local/include/uWS) | ||
+endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") | ||
|
||
add_subdirectory(examples) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
brew install openssl libuv cmake | ||
git clone https://github.com/uWebSockets/uWebSockets | ||
cd uWebSockets | ||
git checkout e94b6e1 | ||
patch CMakeLists.txt < ../cmakepatch.txt | ||
mkdir build | ||
export PKG_CONFIG_PATH=/usr/local/opt/openssl/lib/pkgconfig | ||
cd build | ||
OPENSSL_VERSION=`openssl version -v | cut -d' ' -f2` | ||
cmake -DOPENSSL_ROOT_DIR=$(brew --cellar openssl)/$OPENSSL_VERSION -DOPENSSL_LIBRARIES=$(brew --cellar openssl)/$OPENSSL_VERSION/lib .. | ||
make | ||
sudo make install | ||
cd .. | ||
cd .. | ||
sudo rm -r uWebSockets |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#! /bin/bash | ||
sudo apt-get update | ||
sudo apt-get install git libuv1-dev libssl-dev gcc g++ cmake make | ||
git clone https://github.com/uWebSockets/uWebSockets | ||
cd uWebSockets | ||
git checkout e94b6e1 | ||
mkdir build | ||
cd build | ||
cmake .. | ||
make | ||
sudo make install | ||
cd .. | ||
cd .. | ||
sudo ln -s /usr/lib64/libuWS.so /usr/lib/libuWS.so | ||
sudo rm -r uWebSockets |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#!/bin/bash | ||
|
||
# Make sure you have the latest version of the repo | ||
echo | ||
git pull | ||
echo | ||
|
||
# Ask the user for login details | ||
read -p 'Git repository url: ' upstreamVar | ||
read -p 'Git Username: ' userVar | ||
read -p 'Git email: ' emailVar | ||
|
||
echo | ||
echo Thank you $userVar!, we now have your credentials | ||
echo for upstream $upstreamVar. You must supply your password for each push. | ||
echo | ||
|
||
echo setting up git | ||
|
||
git config --global user.name $userVar | ||
git config --global user.email $emailVar | ||
git remote set-url origin $upstreamVar | ||
echo | ||
|
||
echo Please verify remote: | ||
git remote -v | ||
echo | ||
|
||
echo Please verify your credentials: | ||
echo username: `git config user.name` | ||
echo email: `git config user.email` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#include "PID.h" | ||
#include <iostream> | ||
#include <numeric> | ||
#include <math.h> | ||
|
||
|
||
|
||
using namespace std; | ||
|
||
/* | ||
* TODO: Complete the PID class. | ||
*/ | ||
|
||
PID::PID() {} | ||
|
||
PID::~PID() {} | ||
|
||
void PID::Init(double Kp, double Ki, double Kd) { | ||
PID::Kp = Kp; | ||
PID::Ki = Ki; | ||
PID::Kd = Kd; | ||
|
||
p_error = 0.0; | ||
i_error = 0.0; | ||
d_error = 0.0; | ||
} | ||
|
||
void PID::UpdateError(double cte) { | ||
static double previous_cte = cte; | ||
|
||
p_error = cte; | ||
d_error = cte - previous_cte; | ||
i_error += cte; | ||
|
||
previous_cte = cte; | ||
|
||
} | ||
|
||
double PID::TotalError() { | ||
return 0.0; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#ifndef PID_H | ||
#define PID_H | ||
#include <vector> | ||
|
||
class PID { | ||
public: | ||
/* | ||
* Errors | ||
*/ | ||
double p_error; | ||
double i_error; | ||
double d_error; | ||
|
||
/* | ||
* Coefficients | ||
*/ | ||
double Kp; | ||
double Ki; | ||
double Kd; | ||
|
||
|
||
/* | ||
* Constructor | ||
*/ | ||
PID(); | ||
|
||
/* | ||
* Destructor. | ||
*/ | ||
virtual ~PID(); | ||
|
||
/* | ||
* Initialize PID. | ||
*/ | ||
void Init(double Kp, double Ki, double Kd); | ||
|
||
/* | ||
* Update the PID error variables given cross track error. | ||
*/ | ||
void UpdateError(double cte); | ||
|
||
/* | ||
* Calculate the total PID error. | ||
*/ | ||
double TotalError(); | ||
}; | ||
|
||
#endif /* PID_H */ |
Oops, something went wrong.