diff --git a/.travis.yml b/.travis.yml index 56dece5b..d35eba1f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,6 +22,8 @@ matrix: before_install: - pip install --user cpp-coveralls + - sudo -H pip install --upgrade requests[security] + install: - sudo apt-get install -y -qq lcov script: @@ -35,6 +37,5 @@ script: after_success: - coveralls --root .. -E ".*external.*" -E ".*CMakeFiles.*" -E ".*test/.*.cpp.*" - notifications: email: false diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 7f19e678..683a0ee0 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -8,26 +8,47 @@ "${workspaceRoot}/vendor/boost", "/usr/include" ], - "browse" : { - "limitSymbolsToIncludedHeaders" : true, - "databaseFilename" : "" - } + "browse": { + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + }, + "macFrameworkPath": [ + "/System/Library/Frameworks", + "/Library/Frameworks" + ], + "intelliSenseMode": "clang-x64", + "compilerPath": "/usr/bin/gcc", + "cStandard": "gnu11", + "cppStandard": "gnu++14" }, { "name": "Linux", - "includePath": ["/usr/include"], - "browse" : { - "limitSymbolsToIncludedHeaders" : true, - "databaseFilename" : "" - } + "includePath": [ + "/usr/include" + ], + "browse": { + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + }, + "intelliSenseMode": "gcc-x64", + "compilerPath": "/usr/bin/gcc", + "cStandard": "gnu11", + "cppStandard": "gnu++14" }, { "name": "Win32", - "includePath": ["c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include"], - "browse" : { - "limitSymbolsToIncludedHeaders" : true, - "databaseFilename" : "" - } + "includePath": [ + "c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include" + ], + "browse": { + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + }, + "intelliSenseMode": "msvc-x64", + "compilerPath": "/usr/bin/gcc", + "cStandard": "gnu11", + "cppStandard": "gnu++14" } - ] -} + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 95395d85..c3c3a246 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,6 @@ { // cpp general - "C_Cpp.clang_format_style": "visual studio", + "C_Cpp.clang_format_style": "Google", // cmake "cmake.generator.all": "ninja", @@ -22,5 +22,6 @@ "ms-vscode.cpptools", "RichardHe.you-complete-me", "vector-of-bool.cmake-tools" - ] + ], + "C_Cpp.clang_format_fallbackStyle": "Google" } diff --git a/CMakeLists.txt b/CMakeLists.txt index ccddcaf2..b4881983 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ if (COVERAGE) include(CodeCoverage) set(LCOV_REMOVE_EXTRA "'vendor/*'") setup_target_for_coverage(code_coverage test/cpp-test coverage) - set(COVERAGE_SRCS app/main.cpp include/lib.hpp) + set(COVERAGE_SRCS app/main.cpp app/PID.cpp include/PID.h) SET(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage") SET(CMAKE_C_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage") diff --git a/UML_TDD.pdf b/UML_TDD.pdf new file mode 100644 index 00000000..1d57b7fa Binary files /dev/null and b/UML_TDD.pdf differ diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index c2d13dbe..aa7aceb0 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -1,4 +1,4 @@ -add_executable(shell-app main.cpp) +add_executable(shell-app main.cpp PID.cpp) include_directories( ${CMAKE_SOURCE_DIR}/include ) diff --git a/app/PID.cpp b/app/PID.cpp new file mode 100644 index 00000000..f8bff8bf --- /dev/null +++ b/app/PID.cpp @@ -0,0 +1,53 @@ +/** + * Copyright 2020 + * */ + +/** + * @file: PID.cpp + * @brief: Contains the class definition of PID control + * @author: Part 1 : Aditya Khopkar (driver), Rajeshwar N S (navigator) + * @author: Part 2 - Spencer Elyard (driver), Daniel Sahu (navigator) + * */ + +#include "PID.h" + +// constructor +control::PID::PID() { + kp_ = 1.2; + ki_ = 0.4; + kd_ = 0.2; + dt_ = 1; + prev_error_ = 0.0; + integral_error_ = 0.0; +} + +void control::PID::SetKp(double kp) { this->kp_ = kp; } + +void control::PID::SetKd(double kd) { this->kd_ = kd; } + +void control::PID::SetKi(double ki) { this->ki_ = ki; } + +double control::PID::Compute(double feedback, double setpoint) { + // calculate current error + double current_error = setpoint - feedback; + // Proportional controller portion + double proportional = kp_ * current_error; + // Integral controller portion + double integral = ki_ * (integral_error_ + current_error * dt_); + // Derivative + double derivative = kd_ * ((current_error - prev_error_) / dt_); + // calculate output + double output = proportional + integral + derivative; + // save error as previous prev_error_ + prev_error_ = current_error; + return output; +} + +const double& control::PID::GetKp() { return this->kp_; } + +const double& control::PID::GetKd() { return this->kd_; } + +const double& control::PID::GetKi() { return this->ki_; } + +// destructor +control::PID::~PID() {} diff --git a/app/main.cpp b/app/main.cpp index 74232ade..b43cbe32 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -1,8 +1,28 @@ +/** + * Copyright 2020 + * */ + +/** + * @file: main.cpp + * @brief: Contains the main function of the program + * @author: Part 1 - Aditya Khopkar (driver), Rajeshwar N S (navigator) + * @author: Part 2 - Spencer Elyard (driver), Daniel Sahu (navigator) + * */ + #include -#include +#include + +#include "../include/PID.h" -int main() -{ - dummy(); - return 0; +/** + * @brief: main function + * @param: None + * @return: 0 + * */ +int main() { + control::PID controller; + double new_velocity = controller.Compute(4.0, 8.0); + std::cout << "Actual Velocity: " << 4.0 << " Desired Velocity: " << 8.0 + << " New Velocity: " << new_velocity << std::endl; + return 0; } diff --git a/include/PID.h b/include/PID.h new file mode 100644 index 00000000..610629bc --- /dev/null +++ b/include/PID.h @@ -0,0 +1,89 @@ +/** + * Copyright 2020 + * */ + +/** + * @file: PID.h + * @brief: Contains the class declaration of PID control + * @author: Part 1 : Aditya Khopkar (driver), Rajeshwar N S (navigator) + * @author: Part 2 - Spencer Elyard (driver), Daniel Sahu (navigator) + * */ + +#pragma once + +namespace control { +class PID { + private: + double kp_; + double ki_; + double kd_; + double dt_; + double prev_error_; + double integral_error_; + + public: + /** + * @brief: Setter for kp + * @param: kp: double + * @return: None + * */ + void SetKp(double); + + /** + * @brief: Setter for kd + * @param: kd: double + * @return: None + * */ + void SetKd(double); + + /** + * @brief: Setter for ki + * @param: ki: double + * @return: None + * */ + void SetKi(double); + + /** + * @brief: Computes the new value of velocity given a setpoint and current + * value + * @param: feedback: double, setpoint: double + * @return: new velocity: double + * */ + double Compute(double, double); + + /** + * @brief: Getter for kp + * @param: None + * @return: const double value + * */ + const double& GetKp(); + + /** + * @brief: Getter for kd + * @param: None + * @return: const double value + * */ + const double& GetKd(); + + /** + * @brief: Getter for ki + * @param: None + * @return: const double value + * */ + const double& GetKi(); + + /** + * @brief: Implementation of constructor + * @param: None + * @return: None + * */ + PID(); + + /** + * @brief: Destructor call of class + * @param: None + * @return: None + * */ + virtual ~PID(); +}; +} // namespace control diff --git a/include/lib.hpp b/include/lib.hpp deleted file mode 100644 index 45fd193f..00000000 --- a/include/lib.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include - -void dummy() -{ - std::cout << "HI" << std::endl; -} diff --git a/readme.md b/readme.md index aadd5b41..6894810c 100644 --- a/readme.md +++ b/readme.md @@ -1,19 +1,24 @@ -# C++ Boilerplate -[![Build Status](https://travis-ci.org/dpiet/cpp-boilerplate.svg?branch=master)](https://travis-ci.org/dpiet/cpp-boilerplate) -[![Coverage Status](https://coveralls.io/repos/github/dpiet/cpp-boilerplate/badge.svg?branch=master)](https://coveralls.io/github/dpiet/cpp-boilerplate?branch=master) +# PID Controller (Test Driven Development) +[![Build Status](https://travis-ci.org/akhopkar01/PID_controller.svg?branch=master)](https://travis-ci.org/github/akhopkar01/PID_controller) +[![Coverage Status](https://coveralls.io/repos/github/akhopkar01/PID_controller/badge.svg?branch=master)](https://coveralls.io/github/akhopkar01/PID_controller?branch=master) --- ## Overview -Simple starter C++ project with: +This project is worked in groups to carry out TDD. We have implemented a PID controller with Unit Tests to validate software quality. -- cmake -- googletest +### Authors: +[ Part 1 ] Aditya Khopkar (driver), Rajeshwar N S (navigator) + +[ Part 2 ] Spencer Elyard (driver), Daniel Sahu (navigator) + +### TO-DO for future: +Investigate additional test-cases for compute ## Standard install via command-line ``` -git clone --recursive https://github.com/dpiet/cpp-boilerplate -cd +git clone --recursive https://github.com/akhopkar01/PID_controller +cd PID_controller mkdir build cd build cmake .. @@ -39,16 +44,16 @@ In your Eclipse workspace directory (or create a new one), checkout the repo (an ``` mkdir -p ~/workspace cd ~/workspace -git clone --recursive https://github.com/dpiet/cpp-boilerplate +git clone --recursive https://github.com/danielmohansahu/mobile-pid-controller ``` -In your work directory, use cmake to create an Eclipse project for an [out-of-source build] of cpp-boilerplate +In your work directory, use cmake to create an Eclipse project for an [out-of-source build] of mobile-pid-controller ``` cd ~/workspace mkdir -p boilerplate-eclipse cd boilerplate-eclipse -cmake -G "Eclipse CDT4 - Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug -D CMAKE_ECLIPSE_VERSION=4.7.0 -D CMAKE_CXX_COMPILER_ARG1=-std=c++14 ../cpp-boilerplate/ +cmake -G "Eclipse CDT4 - Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug -D CMAKE_ECLIPSE_VERSION=4.7.0 -D CMAKE_CXX_COMPILER_ARG1=-std=c++14 ../mobile-pid-controller/ ``` ## Import @@ -56,7 +61,7 @@ cmake -G "Eclipse CDT4 - Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug -D CMAKE_ECLI Open Eclipse, go to File -> Import -> General -> Existing Projects into Workspace -> Select "boilerplate-eclipse" directory created previously as root directory -> Finish -# Edit +## Edit Source files may be edited under the "[Source Directory]" label in the Project Explorer. @@ -95,32 +100,3 @@ debugger window. 7. Press Terminate icon to terminate debugging and press C/C++ icon to switch back to C/C++ perspetive view (or Windows->Perspective->Open Perspective->C/C++). - -## Plugins - -- CppChEclipse - - To install and run cppcheck in Eclipse - - 1. In Eclipse, go to Window -> Preferences -> C/C++ -> cppcheclipse. - Set cppcheck binary path to "/usr/bin/cppcheck". - - 2. To run CPPCheck on a project, right click on the project name in the Project Explorer - and choose cppcheck -> Run cppcheck. - - -- Google C++ Sytle - - To include and use Google C++ Style formatter in Eclipse - - 1. In Eclipse, go to Window -> Preferences -> C/C++ -> Code Style -> Formatter. - Import [eclipse-cpp-google-style][reference-id-for-eclipse-cpp-google-style] and apply. - - 2. To use Google C++ style formatter, right click on the source code or folder in - Project Explorer and choose Source -> Format - -[reference-id-for-eclipse-cpp-google-style]: https://raw.githubusercontent.com/google/styleguide/gh-pages/eclipse-cpp-google-style.xml - -- Git - - It is possible to manage version control through Eclipse and the git plugin, but it typically requires creating another project. If you're interested in this, try it out yourself and contact me on Canvas. diff --git a/results/cppcheck b/results/cppcheck new file mode 100644 index 00000000..a645d2dd --- /dev/null +++ b/results/cppcheck @@ -0,0 +1,8 @@ +Checking app/PID.cpp ... +1/4 files checked 41% done +Checking app/main.cpp ... +2/4 files checked 59% done +Checking test/main.cpp ... +3/4 files checked 70% done +Checking test/test.cpp ... +4/4 files checked 100% done diff --git a/results/cpplint b/results/cpplint new file mode 100644 index 00000000..a563a608 --- /dev/null +++ b/results/cpplint @@ -0,0 +1,4 @@ +Done processing ./app/PID.cpp +Done processing ./app/main.cpp +Done processing ./test/main.cpp +Done processing ./test/test.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2b1cd4cb..6e2ba778 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -4,8 +4,10 @@ add_executable( cpp-test main.cpp test.cpp + ../app/PID.cpp ) target_include_directories(cpp-test PUBLIC ../vendor/googletest/googletest/include - ${CMAKE_SOURCE_DIR}/include) + ${CMAKE_SOURCE_DIR}/include + ) target_link_libraries(cpp-test PUBLIC gtest) diff --git a/test/main.cpp b/test/main.cpp index 697a9d70..f4714a7b 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -1,3 +1,14 @@ +/** + * Copyright 2020 + * */ + +/** + * @file: main.cpp (test) + * @brief: This file contains the main function to drive the tests for the + * software + * @author: Part 1 : Aditya Khopkar (driver), Rajeshwar N S (navigator) + * */ + #include int main(int argc, char** argv) { diff --git a/test/test.cpp b/test/test.cpp index 2c5cd069..f0fb763a 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -1,5 +1,55 @@ +/** + * Copyright 2020 + * */ + +/** + * @file: test.cpp + * @brief: This file contains the test functions to Unit test the software + * @author: Part 1 : Aditya Khopkar (driver), Rajeshwar N S (navigator) + * */ + #include -TEST(dummy, should_pass) { - EXPECT_EQ(1, 1); +#include + +#include "../include/PID.h" + +// instance of the class +control::PID pid; + +// temp value +double val = 1.4; + +/** + * @brief: Tests the compute method of the class by returning a double value, + * should pass + * Actual vel = 4.0, Desired vel = 8.0, kp, ki, kd, dt = [1.2, 0.4, + * 0.2, 1] + * */ +TEST(PIDComputeTest, should_pass) { + EXPECT_DOUBLE_EQ(7.2, pid.Compute(4.0, 8.0)); +} + +/** + * @brief: tests setter for kp + * */ +TEST(PIDSetters, check_kp) { + pid.SetKp(val); + EXPECT_DOUBLE_EQ(val, pid.GetKp()); +} + +/** + * @brief: tests setter for kd + * */ +TEST(PIDSetters, check_kd) { + pid.SetKd(val); + EXPECT_DOUBLE_EQ(val, pid.GetKd()); +} + +/** + * @brief: tests setter for ki + * */ +TEST(PIDSetters, check_ki) { + pid.SetKi(val); + EXPECT_DOUBLE_EQ(val, pid.GetKi()); }