RSeries astromech firmware
PID.h
Go to the documentation of this file.
1 #ifndef PID_h
2 #define PID_h
3 
4 #include "ReelTwo.h"
5 
13 template<typename T> class PID
14 {
15 public:
16  enum Direction
17  {
20  };
21  enum {
22  kManual = 0,
23  kAuto = 1,
24  };
25 
31  PID( T& input,
32  T& output,
33  T& setpoint,
34  T kp,
35  T ki,
36  T kd,
37  Direction direction = kDirect,
38  bool proportialOnError = true) :
39  fAuto(false),
40  fInput(input),
41  fOutput(output),
42  fSetpoint(setpoint),
43  fSampleTime(100)
44  {
45  setOutputLimits(0, 255);
46 
47  setDirection(direction);
48  setTunings(kp, ki, kd, proportialOnError);
49 
50  fLastTime = millis() - fSampleTime;
51  }
52 
53  bool process()
54  {
55  uint32_t now = millis();
56  uint32_t diff = (now - fLastTime);
57  if (fAuto && diff >= fSampleTime)
58  {
59  /* Compute all the working error variables */
60  T input = fInput;
61  T error = fSetpoint - input;
62  T dInput = (input - fLastInput);
63  fOutputSum += (fKi * error);
64 
65  /* Add Proportional on Measurement if specified */
67  fOutputSum-= fKp * dInput;
68  if (fOutputSum > fOutMax)
69  fOutputSum = fOutMax;
70  else if (fOutputSum < fOutMin)
71  fOutputSum = fOutMin;
72 
73  T output = (getProportialOnError()) ? fKp * error : 0;
74  output += fOutputSum - fKd * dInput;
75 
76  if (output > fOutMax)
77  output = fOutMax;
78  else if (output < fOutMin)
79  output = fOutMin;
80  fOutput = output;
81 
82  fLastInput = input;
83  fLastTime = now;
84  return true;
85  }
86  return false;
87  }
88 
89  void setAutomatic(bool automatic)
90  {
91  if (automatic && !fAuto)
92  init();
93  fAuto = automatic;
94  }
95 
96  inline T getOutputMin() const
97  {
98  return fOutMin;
99  }
100 
101  inline T getOutputMax() const
102  {
103  return fOutMax;
104  }
105 
106  void setOutputLimits(T outputMin, T outputMax)
107  {
108  fOutMin = outputMin;
109  fOutMax = outputMax;
110 
111  if (fAuto)
112  {
113  if (fOutput > fOutMax)
114  fOutput = fOutMax;
115  else if (fOutput < fOutMin)
116  fOutput = fOutMin;
117 
118  if (fOutputSum > fOutMax)
119  fOutputSum = fOutMax;
120  else if (fOutputSum < fOutMin)
121  fOutputSum = fOutMin;
122  }
123  }
124 
125  void setTunings(T Kp, T Ki, T Kd, bool pOnError)
126  {
127  if (Kp < 0 || Ki < 0 || Kd < 0)
128  return;
129 
130  fPOnError = pOnError;
131 
132  fKpOrg = Kp;
133  fKiOrg = Ki;
134  fKdOrg = Kd;
135 
136  T sampleTimeInSec = ((T)fSampleTime) / 1000;
137  fKp = Kp;
138  fKi = Ki * sampleTimeInSec;
139  fKd = Kd / sampleTimeInSec;
140 
141  if (fDirection == kReverse)
142  {
143  fKp = (0 - fKp);
144  fKi = (0 - fKi);
145  fKd = (0 - fKd);
146  }
147  }
148 
149  void setTunings(T Kp, T Ki, T Kd)
150  {
151  setTunings(Kp, Ki, Kd, fPOnError);
152  }
153 
154  void setDirection(Direction direction)
155  {
156  if (fAuto && fDirection != direction)
157  {
158  fKp = (0 - fKp);
159  fKi = (0 - fKi);
160  fKd = (0 - fKd);
161  }
162  fDirection = direction;
163  }
164 
165  void setSampleTime(unsigned sampleTime)
166  {
167  T ratio = (T)sampleTime / (T)fSampleTime;
168  fKi *= ratio;
169  fKd /= ratio;
170  fSampleTime = (unsigned long)sampleTime;
171  }
172 
173  inline bool getProportialOnMeasurement() const { return !fPOnError; }
174  inline bool getProportialOnError() const { return fPOnError; }
175 
176  inline T getKp() const { return fKpOrg; }
177  inline T getKi() const { return fKiOrg; }
178  inline T getKd() const { return fKdOrg; }
179  inline int getAutomatic() const { return fAuto; }
180  inline int getDirection() const { return fDirection; }
181 
182 private:
183  T fKpOrg;
184  T fKiOrg;
185  T fKdOrg;
186 
187  T fKp;
188  T fKi;
189  T fKd;
190 
191  bool fAuto;
192  bool fPOnError;
193  Direction fDirection;
194 
195  T& fInput;
196  T& fOutput;
197  T& fSetpoint;
198 
199  uint32_t fLastTime;
200  T fOutputSum;
201  T fLastInput;
202 
203  uint32_t fSampleTime;
204  T fOutMin;
205  T fOutMax;
206 
207  void init()
208  {
209  fOutputSum = fOutput;
210  fLastInput = fInput;
211  if (fOutputSum > fOutMax)
212  fOutputSum = fOutMax;
213  else if (fOutputSum < fOutMin)
214  fOutputSum = fOutMin;
215  }
216 };
217 #endif
PID::Direction
Direction
Definition: PID.h:16
PID::getKi
T getKi() const
Definition: PID.h:177
ReelTwo.h
PID::process
bool process()
Definition: PID.h:53
PID::getProportialOnMeasurement
bool getProportialOnMeasurement() const
Definition: PID.h:173
PID::kManual
@ kManual
Definition: PID.h:22
PID::getKp
T getKp() const
Definition: PID.h:176
PID::setOutputLimits
void setOutputLimits(T outputMin, T outputMax)
Definition: PID.h:106
PID::setTunings
void setTunings(T Kp, T Ki, T Kd)
Definition: PID.h:149
PID::kAuto
@ kAuto
Definition: PID.h:23
PID::kDirect
@ kDirect
Definition: PID.h:18
PID::getOutputMin
T getOutputMin() const
Definition: PID.h:96
PID::setDirection
void setDirection(Direction direction)
Definition: PID.h:154
PID::setAutomatic
void setAutomatic(bool automatic)
Definition: PID.h:89
PID::setTunings
void setTunings(T Kp, T Ki, T Kd, bool pOnError)
Definition: PID.h:125
PID
Definition: PID.h:13
PID::getDirection
int getDirection() const
Definition: PID.h:180
PID::setSampleTime
void setSampleTime(unsigned sampleTime)
Definition: PID.h:165
PID::getOutputMax
T getOutputMax() const
Definition: PID.h:101
PID::getAutomatic
int getAutomatic() const
Definition: PID.h:179
PID::getProportialOnError
bool getProportialOnError() const
Definition: PID.h:174
PID::PID
PID(T &input, T &output, T &setpoint, T kp, T ki, T kd, Direction direction=kDirect, bool proportialOnError=true)
Constructor.
Definition: PID.h:31
PID::kReverse
@ kReverse
Definition: PID.h:19
PID::getKd
T getKd() const
Definition: PID.h:178