Nebula
Loading...
Searching...
No Matches
pidfeedbackloop.h
Go to the documentation of this file.
1#ifndef Math_PIDFEEDBACKLOOP_H
2#define Math_PIDFEEDBACKLOOP_H
3//------------------------------------------------------------------------------
13#include "core/types.h"
14#include "timing/time.h"
15
16namespace Math
17{
19{
20public:
24 void SetState(double value);
26 void SetGoal(double wantedValue);
28 void SetConstants(double pConst, double iConst, double dConst, double acceleration = 0.0);
30 const double& GetState() const;
32 const double& GetGoal() const;
34 double GetLastError() const;
36 double GetLastDelta() const;
38 void Update(Timing::Time time);
40 void ResetError();
42 void SetIsAngularValue(bool val);
43
44private:
45 double value; // current value of the controller
46 double goal; // the value the controller is trying to achieve
47
48 double pConst; // proportional constant (Kp)
49 double iConst; // integral constant (Ki)
50 double dConst; // derivative constant (Kd)
51 double maxAcceleration; // limits how fast the control can accelerate the value
52
53 double lastError; // previous error
54 double lastDelta; // amount of change during last adjustment
55 double runningError; // summed errors (using as the integral value)
56 bool validError; // prevents numerical problems on the first adjustment
58
61
62 Timing::Time maxAllowableDeltaTime; // if more time (in seconds) than this has passed, no PID adjustments will be made
63};
64
65//------------------------------------------------------------------------------
68inline
70 value(0.0),
71 goal(0.0),
72 pConst(1.0),
73 iConst(0.0),
74 dConst(0.0),
75 maxAcceleration(0.0),
76 lastError(0.0),
77 lastDelta(0.0),
78 runningError(0.0),
79 validError(false),
80 isAngularValue(false),
81 lastTime(0.0),
82 lastDeltaTime(0.0),
83 maxAllowableDeltaTime(0.03)
84{
85}
86
87//------------------------------------------------------------------------------
90inline
91void
93{
94 this->value = value;
95 lastError = 0.0;
96 lastDelta = 0.0;
97}
98
99//------------------------------------------------------------------------------
102inline
103void
104PIDFeedbackLoop::SetGoal(double wantedValue)
105{
106 this->goal = wantedValue;
107}
108
109//------------------------------------------------------------------------------
112inline
113void
114PIDFeedbackLoop::SetConstants(double pConst, double iConst, double dConst, double acceleration)
115{
116 this->pConst = pConst;
117 this->iConst = iConst;
118 this->dConst = dConst;
119 maxAcceleration = acceleration;
120}
121
122//------------------------------------------------------------------------------
125inline
126const double&
128{
129 return this->value;
130}
131
132
133//------------------------------------------------------------------------------
136inline
137double
139{
140 return this->lastError;
141}
142
143//------------------------------------------------------------------------------
146inline
147const double&
149{
150 return this->goal;
151}
152
153//------------------------------------------------------------------------------
156inline
157double
159{
160 return this->lastDelta;
161}
162
163//------------------------------------------------------------------------------
166inline
167void
169{
170 this->isAngularValue = val;
171}
172
173//------------------------------------------------------------------------------
176inline
177void
179{
180 Timing::Time frameTime = time - this->lastTime;
181 // if too much time has passed, do nothing
182 if (frameTime != 0.0f)
183 {
184 if (frameTime > maxAllowableDeltaTime)
185 frameTime = maxAllowableDeltaTime;
186
187 // compute the error and sum of the errors for the integral
188 double difference;
189 if (this->isAngularValue)
190 {
191 difference = (double)n_angulardistance((float)value, (float)goal);
192 }
193 else
194 {
195 difference = goal - value;
196 }
197 double error = difference * frameTime;
198 runningError += error;
199
200 // proportional
201 double dP = pConst * error;
202
203 // integral
204 double dI = iConst * runningError * frameTime;
205
206 // derivative
207 double dD(0.0f);
208 if (validError)
209 dD = dConst * (lastError - error) * frameTime;
210 else
211 validError = true;
212
213 // remember the error for derivative
214 lastError = error;
215
216 // compute the adjustment
217 double thisDelta = dP + dI + dD;
218
219 // clamp the acceleration
220 if (maxAcceleration != 0.0f)
221 {
222 double timeRatio(1.0);
223 if (lastDeltaTime != 0.0)
224 timeRatio = frameTime / lastDeltaTime;
225 lastDeltaTime = frameTime;
226
227 lastDelta *= timeRatio;
228 double difference = (thisDelta - lastDelta);
229 double accl = maxAcceleration * frameTime * frameTime;
230
231 if (difference < -accl)
232 thisDelta = lastDelta - accl;
233 else if (difference > accl)
234 thisDelta = lastDelta + accl;
235 }
236
237 // modify the value
238 value += thisDelta;
239 if (this->isAngularValue)
240 {
241 value = (double)n_modangle((float)value);
242 }
243 lastDelta = thisDelta;
244 }
245 this->lastTime = time;
246}
247
248//------------------------------------------------------------------------------
251inline
252void
254{
255 runningError = 0.0f;
256 validError = false;
257}
258} // namespace Math
259//------------------------------------------------------------------------------
260#endif
A PID feedback loop (proportional integral derivative feedback loop)
Definition pidfeedbackloop.h:19
double goal
Definition pidfeedbackloop.h:46
double iConst
Definition pidfeedbackloop.h:49
double lastDelta
Definition pidfeedbackloop.h:54
const double & GetGoal() const
get the goal
Definition pidfeedbackloop.h:148
bool validError
Definition pidfeedbackloop.h:56
void SetGoal(double wantedValue)
set the goal
Definition pidfeedbackloop.h:104
Timing::Time maxAllowableDeltaTime
Definition pidfeedbackloop.h:62
double value
Definition pidfeedbackloop.h:45
double GetLastDelta() const
last delta of error
Definition pidfeedbackloop.h:158
double dConst
Definition pidfeedbackloop.h:50
Timing::Time lastTime
Definition pidfeedbackloop.h:59
const double & GetState() const
get current value
Definition pidfeedbackloop.h:127
double runningError
Definition pidfeedbackloop.h:55
bool isAngularValue
Definition pidfeedbackloop.h:57
double maxAcceleration
Definition pidfeedbackloop.h:51
double pConst
Definition pidfeedbackloop.h:48
void SetState(double value)
set value of loop
Definition pidfeedbackloop.h:92
void ResetError()
reset running error
Definition pidfeedbackloop.h:253
Timing::Time lastDeltaTime
Definition pidfeedbackloop.h:60
void Update(Timing::Time time)
update current value
Definition pidfeedbackloop.h:178
void SetIsAngularValue(bool val)
set IsAngularValue
Definition pidfeedbackloop.h:168
double GetLastError() const
get last computed error
Definition pidfeedbackloop.h:138
void SetConstants(double pConst, double iConst, double dConst, double acceleration=0.0)
set the propotional, integral and derivative constants, and maximum acceleration (how fast the value ...
Definition pidfeedbackloop.h:114
double lastError
Definition pidfeedbackloop.h:53
PIDFeedbackLoop()
constructor
Definition pidfeedbackloop.h:69
Half precision (16 bit) float implementation.
Definition angularpfeedbackloop.h:17
double Time
the time datatype
Definition time.h:18
Typedefs for the Timing subsystem.