semf
pidcontroller.cpp
Go to the documentation of this file.
1
12#include <cfloat>
13
14namespace semf
15{
16PidController::PidController(double kp, double ki, double kd, double sampleTime, double yMin, double yMax, double setpoint, double yStart, double deltaMax)
17: m_kp(kp),
18 m_ki(ki),
19 m_kd(kd),
20 m_sampleTime(sampleTime),
21 m_yMin(yMin),
22 m_yMax(yMax),
23 m_deltaMax(deltaMax),
24 m_setpoint(setpoint)
25{
26 calculateQ0();
27 calculateQ1();
28 calculateQ2();
29
30 // if m_ki>0 init the integral with the start value
31 if (m_ki != 0)
32 m_yLast1 = yStart;
33 else
34 m_yLast1 = 0;
35}
36
37void PidController::setKp(double kp)
38{
39 SEMF_INFO("set kp to: %f", kp);
40 m_kp = kp;
41 calculateQ0();
42 calculateQ1();
43}
44
45double PidController::kp() const
46{
47 return m_kp;
48}
49
50void PidController::setKi(double ki)
51{
52 SEMF_INFO("set ki to: %f", ki);
53 m_ki = ki;
54 calculateQ0();
55}
56
57double PidController::ki() const
58{
59 return m_ki;
60}
61
62void PidController::setKd(double kd)
63{
64 SEMF_INFO("set kd to: %f", kd);
65 m_kd = kd;
66 calculateQ0();
67 calculateQ1();
68 calculateQ2();
69}
70
71double PidController::kd() const
72{
73 return m_kd;
74}
75
76void PidController::setSampleTime(double sampleTime)
77{
78 SEMF_INFO("set sample time to: %f", sampleTime);
79 m_sampleTime = sampleTime;
80 calculateQ0();
81 calculateQ1();
82 calculateQ2();
83}
84
86{
87 return m_sampleTime;
88}
89
90void PidController::setSetpoint(double setpoint)
91{
92 SEMF_INFO("set setpoint to: %f", setpoint);
93 m_setpoint = setpoint;
94}
95
97{
98 return m_setpoint;
99}
100
102{
103 SEMF_INFO("set max output to: %f", max);
104 m_yMax = max;
105}
106
108{
109 return m_yMax;
110}
111
113{
114 SEMF_INFO("set min output to: %f", min);
115 m_yMin = min;
116}
117
119{
120 return m_yMin;
121}
122
124{
125 SEMF_INFO("set max delta to: %f", delta);
126 m_deltaMax = delta;
127}
128
130{
131 return m_deltaMax;
132}
133
134void PidController::reset(double yStart)
135{
136 SEMF_INFO("to yStart: %f", yStart);
137 // if m_ki>0 init the integral with the start value
138 if (m_ki != 0)
139 m_yLast1 = yStart;
140 else
141 m_yLast1 = 0;
142 m_eLast1 = 0;
143 m_eLast2 = 0;
144}
145
146double PidController::calculate(double currentValue)
147{
148 double e = m_setpoint - currentValue;
149
150 double y = m_yLast1 + m_q0 * e + m_q1 * m_eLast1 + m_q2 * m_eLast2;
151
152 // limit the min and max value of the output
153 if (y > m_yMax)
154 {
155 SEMF_INFO("y (%f) set to max (%f)", y, m_yMax);
156 y = m_yMax;
157 }
158 else if (y < m_yMin)
159 {
160 SEMF_INFO("y (%f) set to min (%f)", y, m_yMin);
161 y = m_yMin;
162 }
163
164 // limit the delta from the output
165 if ((y - m_yLast1) > m_deltaMax)
166 {
167 SEMF_INFO("limit delta (%f) to max delta (%f)", y - m_yLast1, m_deltaMax);
168 y = m_yLast1 + m_deltaMax;
169 }
170 else if ((m_yLast1 - y) > m_deltaMax)
171 {
172 SEMF_INFO("limit delta (%f) to max delta (%f)", m_yLast1 - y, m_deltaMax);
173 y = m_yLast1 - m_deltaMax;
174 }
175
176 m_yLast1 = y;
177 m_eLast2 = m_eLast1;
178 m_eLast1 = e;
179 SEMF_INFO("current value: %f, y: %f", currentValue, y);
180 return y;
181}
182
183void PidController::calculateQ0()
184{
185 m_q0 = m_kp + m_ki * m_sampleTime + (m_kd / m_sampleTime);
186 SEMF_INFO("q0: %f", m_q0);
187}
188
189void PidController::calculateQ1()
190{
191 m_q1 = -m_kp - 2 * m_kd / m_sampleTime;
192 SEMF_INFO("q1: %f", m_q1);
193}
194
195void PidController::calculateQ2()
196{
197 m_q2 = m_kd / m_sampleTime;
198 SEMF_INFO("q2: %f", m_q2);
199}
200} /* namespace semf */
PidController(double kp, double ki, double kd, double sampleTime, double yMin, double yMax, double setpoint=0, double yStart=0, double deltaMax=DBL_MAX)
Constructor.
double maxOuput() const
Returns the maximum value which the output is allowed to have.
void setKd(double kd)
Set the gain of the derivative.
void setSetpoint(double setpoint)
Set the controller set point.
void reset(double yStart=0)
Resets the past sampled values which will be used for the calculation of the integral and derivative.
void setKp(double kp)
Set the proportional gain.
void setMinOutput(double min)
Set the minimum possible output.
virtual double calculate(double currentValue)
Calculates the output value dependent to the actual value. This method must be called cyclically at t...
void setKi(double ki)
Set the gain of the integral.
double ki() const
Get the gain of the integral.
void setSampleTime(double sampleTime)
Set the sample time of the controller.
double kp() const
Returns the proportional gain.
void setMaxDelta(double delta)
Set the max delta of the output between two samples.
void setMaxOutput(double max)
Limits the maximum value of the output.
double setpoint() const
Returns the current set point.
double kd() const
Returns the gain of the derivative.
double maxDelta() const
Returns Set the max delta of the output between two samples.
double sampleTime() const
Returns the current configured sample time.
double minOutput() const
Returns the minimum possible output.
#define SEMF_INFO(...)
Definition: debug.h:41