diff --git a/firmware/drivers/pid_controller/.pid_controller.cpp.swp b/firmware/drivers/pid_controller/.pid_controller.cpp.swp new file mode 100644 index 0000000000000000000000000000000000000000..23cc8998492688172b9c42322ffacccc4822b9fe Binary files /dev/null and b/firmware/drivers/pid_controller/.pid_controller.cpp.swp differ diff --git a/firmware/drivers/pid_controller/pid_controller.cpp b/firmware/drivers/pid_controller/pid_controller.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3ed79ba8f2fb578b6c8e1ee0b9752bd6ae35a805 --- /dev/null +++ b/firmware/drivers/pid_controller/pid_controller.cpp @@ -0,0 +1,83 @@ +#include <pid_controller.hpp> +#include <algorithm> +#include <ltc6992.hpp> + +//define statics +double Pid_controller::setpoint_=0.; //target temperature in °C +double Pid_controller::output_=0.05; //output to LTC6992 +std::vector<double> Pid_controller::pid_vec_ = {0.,0.,0.}; //current values of P I D +std::vector<double> Pid_controller::kpid_vec_ = {0., 0., 0.}; //coefficients Kp Ki Kd +double Pid_controller::I_reset_ = 0.; //reset value of I +double Pid_controller::I_reset_errsq_ = 0.; //value of error*error above which the I-term is held in reset + + +Pid_controller:: + + +void Pid_controller::init(double setpoint, std::vector<double> kpid, double I_reset, double I_reset_errsq){ + setpoint_ = setpoint; + kpid_ = kpid; + I_reset_ = I_reset; + I_reset_errsq_ = I_reset_errsq; +} + +void Pid_controller::update_pid(double temperature){ + //calculate error from setpoint + double error = setpoint_ - temperature; + //update P,I,D + pid_vec_[2] = error - pid_vec_[0]; + (error*error < I_reset_errsq_) ? pid_vec_[1] += error : pid_vec_[1] = I_reset_; + pid_vec_[0] = error; + //calculate output + output_ = kpid_vec_[0]*pid_vec_[0] + kpid_vec_[1]*pid_vec_[1] + kpid_vec_[2]*pid_vec_[2]; + //clamp output to rails + output_ = std::max(output_, 0.1); + output_ = std::min(output_, 0.9); + //send value to controller + Ltc6992::set_level(output_); +} + +void Pid_controller::set_Kp(double Kp){ + kpid_vec_[0] = Kp; +} + +void Pid_controller::set_Ki(double Ki){ + kpid_vec_[1] = Ki; +} + +void Pid_controller::set_Kd(double Kd){ + kpid_vec_[2] = Kd; +} + +void Pid_controller::set_I_reset(double I_reset){ + I_reset_ = I_reset; + pid_vec_[1] = I_reset; +} + +void Pid_controller::set_I_reset_errsq(double I_reset_errsq){ + I_reset_errsq_ = I_reset_errsq; +} + +void Pid_controller::set_setpoint(double temperature){ + setpoint_ = temperature; +} + +std::vector<double> Pid_controller::get_kpid() const{ + return kpid_vec_; +} + +std::vector<double> Pid_controller::get_pid() const{ + return pid_vec_; +} + +double Pid_controller::get_output() const{ + return output_; +} + +double Pid_controller::get_I_reset() const{ + return I_reset_; +} + +double Pid_controller::get_setpoint() const{ + return setpoint_; +} diff --git a/firmware/drivers/pid_controller/pid_controller.hpp b/firmware/drivers/pid_controller/pid_controller.hpp new file mode 100644 index 0000000000000000000000000000000000000000..95a89c5845e2b9455744dd26abf16b4a0a02482d --- /dev/null +++ b/firmware/drivers/pid_controller/pid_controller.hpp @@ -0,0 +1,33 @@ +#ifndef PID_CONTROLLER_HPP_INCLUDED +#define PID_CONTROLLER_HPP_INCLUDED +#include <ltc6992.hpp> +#include <vector> + +class Pid_controller{ +public: + static void init(double setpoint, std::vector<double> kpid, double I_reset, double I_reset_errsq); + static void update_pid(double temperature); + + static void set_Kp(double Kp); + static void set_Ki(double Ki); + static void set_Kd(double Kd); + static void set_I_reset(double I_reset); + static void set_I_reset_errsq(double I_reset_errsq); + static void set_setpoint(double temperature); + + static std::vector<double> get_kpid() const; + static std::vector<double> get_pid() const; + static double get_output() const; + static double get_I_reset() const; + static double get_setpoint() const; + +private: + static double setpoint_; //target temperature in °C + static double output_; //output to LTC6992 + static std::vector<double> pid_vec_; //current values of P I D + static std::vector<double> kpid_vec_; //coefficients Kp Ki Kd + static double I_reset_; //reset value of I + static double I_reset_errsq_; //value of error*error above which the I-term is held in reset +}; + +#endif