12#include <promeki/config.h>
13#if PROMEKI_ENABLE_CORE
18PROMEKI_NAMESPACE_BEGIN
39template <
typename ValueType =
double,
typename TimeType =
double>
class PIDController {
42 using CurrentTimeFunc = Function<TimeType()>;
44 using CurrentValueFunc = Function<ValueType()>;
51 PIDController(CurrentValueFunc currentValueFunc, CurrentTimeFunc currentTimeFunc)
52 : _gainP(1), _gainI(0), _gainD(0), _integral(0), _prevError(0), _setPoint(0),
53 _currentValue(currentValueFunc), _currentTime(currentTimeFunc), _prevUpdate(_currentTime()) {}
56 ValueType getGainP()
const {
return _gainP; }
62 void setGainP(
const ValueType &val) { _gainP = val; }
65 ValueType getGainI()
const {
return _gainI; }
71 void setGainI(
const ValueType &val) { _gainI = val; }
74 ValueType getGainD()
const {
return _gainD; }
80 void setGainD(
const ValueType &val) { _gainD = val; }
86 void updateSetPoint(
const ValueType &val) { _setPoint = val; }
98 TimeType now = _currentTime();
99 TimeType dt = now - _prevUpdate;
102 ValueType pv = _currentValue();
103 ValueType error = _setPoint - pv;
104 _integral += error * dt;
105 ValueType derivative = (error - _prevError) / dt;
108 return _gainP * error + _gainI * _integral + _gainD * derivative;
115 _prevUpdate = _currentTime();
120 ValueType _gainP = 1;
121 ValueType _gainI = 1;
122 ValueType _gainD = 1;
123 ValueType _integral = 0;
124 ValueType _prevError = 0;
125 ValueType _setPoint = 0;
126 CurrentValueFunc _currentValue;
127 CurrentTimeFunc _currentTime;
128 TimeType _prevUpdate = 0;