Fork of PID by Kamil Foryszewski

Committer:
HangL
Date:
Tue Nov 08 21:19:04 2016 +0000
Revision:
3:7f0ed54318df
Parent:
2:0fff4827f3b6

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
aberk 0:6e12a3e5af19 1 #include "PID.h"
aberk 0:6e12a3e5af19 2
HangL 2:0fff4827f3b6 3
HangL 3:7f0ed54318df 4 float Stand_Kc=86.4/*84.0*//*120.0*/;float Stand_tauI=0.0288/*0.0028*//*0.004 and if times 10 is better!*/;float Stand_tauD=0.000504/*0.000504*//*0.0007*/;
HangL 3:7f0ed54318df 5 float Speed_Kc=/*3.0*/40.0;float Speed_tauI=/*0.015*/0.20;float Speed_tauD=0.0;//20,0.1better than 26.0,0.13
HangL 2:0fff4827f3b6 6 //PID::PID(float Kc, float tauI, float tauD, float interval)
HangL 2:0fff4827f3b6 7 PID::PID(float interval)
HangL 2:0fff4827f3b6 8 {
aberk 0:6e12a3e5af19 9
aberk 0:6e12a3e5af19 10 usingFeedForward = false;
aberk 0:6e12a3e5af19 11 inAuto = false;
aberk 0:6e12a3e5af19 12
kfforex 1:0ffb635770b3 13 setInputLimits(-90.0,90.0 );
kfforex 1:0ffb635770b3 14 setOutputLimits(-3500.0, 3500.0);
aberk 0:6e12a3e5af19 15
aberk 0:6e12a3e5af19 16 tSample_ = interval;
aberk 0:6e12a3e5af19 17
HangL 2:0fff4827f3b6 18 // setTunings(float Kc,float tauI,float tauD);
HangL 2:0fff4827f3b6 19 /*****************after modifying**********************/
HangL 2:0fff4827f3b6 20 setStandTunings(Stand_Kc,Stand_tauI,Stand_tauD);
HangL 2:0fff4827f3b6 21 // setSpeedTunings(Speed_Kc,Speed_tauI,Speed_tauD);
HangL 2:0fff4827f3b6 22 /******************************************************/
aberk 0:6e12a3e5af19 23 setPoint_ = 0.0;
aberk 0:6e12a3e5af19 24 processVariable_ = 0.0;
aberk 0:6e12a3e5af19 25 prevProcessVariable_ = 0.0;
aberk 0:6e12a3e5af19 26 controllerOutput_ = 0.0;
aberk 0:6e12a3e5af19 27 prevControllerOutput_ = 0.0;
aberk 0:6e12a3e5af19 28
aberk 0:6e12a3e5af19 29 accError_ = 0.0;
aberk 0:6e12a3e5af19 30 bias_ = 0.0;
aberk 0:6e12a3e5af19 31
aberk 0:6e12a3e5af19 32 realOutput_ = 0.0;
aberk 0:6e12a3e5af19 33 }
aberk 0:6e12a3e5af19 34
aberk 0:6e12a3e5af19 35 void PID::setInputLimits(float inMin, float inMax) {
aberk 0:6e12a3e5af19 36
aberk 0:6e12a3e5af19 37 //Make sure we haven't been given impossible values.
aberk 0:6e12a3e5af19 38 if (inMin >= inMax) {
aberk 0:6e12a3e5af19 39 return;
aberk 0:6e12a3e5af19 40 }
aberk 0:6e12a3e5af19 41
aberk 0:6e12a3e5af19 42 //Rescale the working variables to reflect the changes.
aberk 0:6e12a3e5af19 43 prevProcessVariable_ *= (inMax - inMin) / inSpan_;
aberk 0:6e12a3e5af19 44 accError_ *= (inMax - inMin) / inSpan_;
aberk 0:6e12a3e5af19 45
aberk 0:6e12a3e5af19 46 //Make sure the working variables are within the new limits.
aberk 0:6e12a3e5af19 47 if (prevProcessVariable_ > 1) {
aberk 0:6e12a3e5af19 48 prevProcessVariable_ = 1;
aberk 0:6e12a3e5af19 49 } else if (prevProcessVariable_ < 0) {
aberk 0:6e12a3e5af19 50 prevProcessVariable_ = 0;
aberk 0:6e12a3e5af19 51 }
aberk 0:6e12a3e5af19 52
aberk 0:6e12a3e5af19 53 inMin_ = inMin;
aberk 0:6e12a3e5af19 54 inMax_ = inMax;
aberk 0:6e12a3e5af19 55 inSpan_ = inMax - inMin;
aberk 0:6e12a3e5af19 56
aberk 0:6e12a3e5af19 57 }
aberk 0:6e12a3e5af19 58
aberk 0:6e12a3e5af19 59 void PID::setOutputLimits(float outMin, float outMax) {
aberk 0:6e12a3e5af19 60
aberk 0:6e12a3e5af19 61 //Make sure we haven't been given impossible values.
aberk 0:6e12a3e5af19 62 if (outMin >= outMax) {
aberk 0:6e12a3e5af19 63 return;
aberk 0:6e12a3e5af19 64 }
aberk 0:6e12a3e5af19 65
aberk 0:6e12a3e5af19 66 //Rescale the working variables to reflect the changes.
aberk 0:6e12a3e5af19 67 prevControllerOutput_ *= (outMax - outMin) / outSpan_;
aberk 0:6e12a3e5af19 68
aberk 0:6e12a3e5af19 69 //Make sure the working variables are within the new limits.
aberk 0:6e12a3e5af19 70 if (prevControllerOutput_ > 1) {
aberk 0:6e12a3e5af19 71 prevControllerOutput_ = 1;
aberk 0:6e12a3e5af19 72 } else if (prevControllerOutput_ < 0) {
aberk 0:6e12a3e5af19 73 prevControllerOutput_ = 0;
aberk 0:6e12a3e5af19 74 }
aberk 0:6e12a3e5af19 75
aberk 0:6e12a3e5af19 76 outMin_ = outMin;
aberk 0:6e12a3e5af19 77 outMax_ = outMax;
aberk 0:6e12a3e5af19 78 outSpan_ = outMax - outMin;
aberk 0:6e12a3e5af19 79
aberk 0:6e12a3e5af19 80 }
aberk 0:6e12a3e5af19 81
HangL 2:0fff4827f3b6 82 //void PID::setTunings(float Kc, float tauI, float tauD) {
HangL 2:0fff4827f3b6 83 void PID::setStandTunings(float Kc,float tauI,float tauD){
aberk 0:6e12a3e5af19 84 //Verify that the tunings make sense.
aberk 0:6e12a3e5af19 85 if (Kc == 0.0 || tauI < 0.0 || tauD < 0.0) {
aberk 0:6e12a3e5af19 86 return;
aberk 0:6e12a3e5af19 87 }
aberk 0:6e12a3e5af19 88
aberk 0:6e12a3e5af19 89 //Store raw values to hand back to user on request.
aberk 0:6e12a3e5af19 90 pParam_ = Kc;
aberk 0:6e12a3e5af19 91 iParam_ = tauI;
aberk 0:6e12a3e5af19 92 dParam_ = tauD;
aberk 0:6e12a3e5af19 93
aberk 0:6e12a3e5af19 94 float tempTauR;
aberk 0:6e12a3e5af19 95
aberk 0:6e12a3e5af19 96 if (tauI == 0.0) {
aberk 0:6e12a3e5af19 97 tempTauR = 0.0;
aberk 0:6e12a3e5af19 98 } else {
aberk 0:6e12a3e5af19 99 tempTauR = (1.0 / tauI) * tSample_;
aberk 0:6e12a3e5af19 100 }
aberk 0:6e12a3e5af19 101
aberk 0:6e12a3e5af19 102 //For "bumpless transfer" we need to rescale the accumulated error.
aberk 0:6e12a3e5af19 103 if (inAuto) {
aberk 0:6e12a3e5af19 104 if (tempTauR == 0.0) {
aberk 0:6e12a3e5af19 105 accError_ = 0.0;
aberk 0:6e12a3e5af19 106 } else {
aberk 0:6e12a3e5af19 107 accError_ *= (Kc_ * tauR_) / (Kc * tempTauR);
aberk 0:6e12a3e5af19 108 }
aberk 0:6e12a3e5af19 109 }
aberk 0:6e12a3e5af19 110
aberk 0:6e12a3e5af19 111 Kc_ = Kc;
aberk 0:6e12a3e5af19 112 tauR_ = tempTauR;
aberk 0:6e12a3e5af19 113 tauD_ = tauD / tSample_;
aberk 0:6e12a3e5af19 114
aberk 0:6e12a3e5af19 115 }
HangL 2:0fff4827f3b6 116 //setSpeedTunings(SpeedKc,SpeedtauI,SpeedtauD)
HangL 2:0fff4827f3b6 117 /*void setSpeedTunings(float Kc,float tauI,float tauD)
HangL 2:0fff4827f3b6 118 {
aberk 0:6e12a3e5af19 119
HangL 2:0fff4827f3b6 120 Speed_Kc_ = Kc;
HangL 2:0fff4827f3b6 121 //Speed_tauI_ = tauI;
HangL 2:0fff4827f3b6 122
HangL 2:0fff4827f3b6 123 }
HangL 2:0fff4827f3b6 124 */
aberk 0:6e12a3e5af19 125 void PID::reset(void) {
aberk 0:6e12a3e5af19 126
aberk 0:6e12a3e5af19 127 float scaledBias = 0.0;
aberk 0:6e12a3e5af19 128
aberk 0:6e12a3e5af19 129 if (usingFeedForward) {
aberk 0:6e12a3e5af19 130 scaledBias = (bias_ - outMin_) / outSpan_;
aberk 0:6e12a3e5af19 131 } else {
aberk 0:6e12a3e5af19 132 scaledBias = (realOutput_ - outMin_) / outSpan_;
aberk 0:6e12a3e5af19 133 }
aberk 0:6e12a3e5af19 134
aberk 0:6e12a3e5af19 135 prevControllerOutput_ = scaledBias;
aberk 0:6e12a3e5af19 136 prevProcessVariable_ = (processVariable_ - inMin_) / inSpan_;
aberk 0:6e12a3e5af19 137
aberk 0:6e12a3e5af19 138 //Clear any error in the integral.
aberk 0:6e12a3e5af19 139 accError_ = 0;
aberk 0:6e12a3e5af19 140
aberk 0:6e12a3e5af19 141 }
aberk 0:6e12a3e5af19 142
aberk 0:6e12a3e5af19 143 void PID::setMode(int mode) {
aberk 0:6e12a3e5af19 144
aberk 0:6e12a3e5af19 145 //We were in manual, and we just got set to auto.
aberk 0:6e12a3e5af19 146 //Reset the controller internals.
aberk 0:6e12a3e5af19 147 if (mode != 0 && !inAuto) {
aberk 0:6e12a3e5af19 148 reset();
aberk 0:6e12a3e5af19 149 }
aberk 0:6e12a3e5af19 150
aberk 0:6e12a3e5af19 151 inAuto = (mode != 0);
aberk 0:6e12a3e5af19 152
aberk 0:6e12a3e5af19 153 }
aberk 0:6e12a3e5af19 154
aberk 0:6e12a3e5af19 155 void PID::setInterval(float interval) {
aberk 0:6e12a3e5af19 156
aberk 0:6e12a3e5af19 157 if (interval > 0) {
aberk 0:6e12a3e5af19 158 //Convert the time-based tunings to reflect this change.
aberk 0:6e12a3e5af19 159 tauR_ *= (interval / tSample_);
aberk 0:6e12a3e5af19 160 accError_ *= (tSample_ / interval);
aberk 0:6e12a3e5af19 161 tauD_ *= (interval / tSample_);
aberk 0:6e12a3e5af19 162 tSample_ = interval;
aberk 0:6e12a3e5af19 163 }
aberk 0:6e12a3e5af19 164
aberk 0:6e12a3e5af19 165 }
aberk 0:6e12a3e5af19 166
aberk 0:6e12a3e5af19 167 void PID::setSetPoint(float sp) {
aberk 0:6e12a3e5af19 168
aberk 0:6e12a3e5af19 169 setPoint_ = sp;
aberk 0:6e12a3e5af19 170
aberk 0:6e12a3e5af19 171 }
aberk 0:6e12a3e5af19 172
aberk 0:6e12a3e5af19 173 void PID::setProcessValue(float pv) {
aberk 0:6e12a3e5af19 174
aberk 0:6e12a3e5af19 175 processVariable_ = pv;
aberk 0:6e12a3e5af19 176
aberk 0:6e12a3e5af19 177 }
aberk 0:6e12a3e5af19 178
aberk 0:6e12a3e5af19 179 void PID::setBias(float bias){
aberk 0:6e12a3e5af19 180
aberk 0:6e12a3e5af19 181 bias_ = bias;
aberk 0:6e12a3e5af19 182 usingFeedForward = 1;
aberk 0:6e12a3e5af19 183
aberk 0:6e12a3e5af19 184 }
aberk 0:6e12a3e5af19 185
aberk 0:6e12a3e5af19 186 float PID::compute() {
aberk 0:6e12a3e5af19 187
aberk 0:6e12a3e5af19 188 //Pull in the input and setpoint, and scale them into percent span.
aberk 0:6e12a3e5af19 189 float scaledPV = (processVariable_ - inMin_) / inSpan_;
aberk 0:6e12a3e5af19 190
aberk 0:6e12a3e5af19 191 if (scaledPV > 1.0) {
aberk 0:6e12a3e5af19 192 scaledPV = 1.0;
aberk 0:6e12a3e5af19 193 } else if (scaledPV < 0.0) {
aberk 0:6e12a3e5af19 194 scaledPV = 0.0;
aberk 0:6e12a3e5af19 195 }
aberk 0:6e12a3e5af19 196
aberk 0:6e12a3e5af19 197 float scaledSP = (setPoint_ - inMin_) / inSpan_;
aberk 0:6e12a3e5af19 198 if (scaledSP > 1.0) {
aberk 0:6e12a3e5af19 199 scaledSP = 1;
aberk 0:6e12a3e5af19 200 } else if (scaledSP < 0.0) {
aberk 0:6e12a3e5af19 201 scaledSP = 0;
aberk 0:6e12a3e5af19 202 }
aberk 0:6e12a3e5af19 203
aberk 0:6e12a3e5af19 204 float error = scaledSP - scaledPV;
aberk 0:6e12a3e5af19 205
aberk 0:6e12a3e5af19 206 //Check and see if the output is pegged at a limit and only
aberk 0:6e12a3e5af19 207 //integrate if it is not. This is to prevent reset-windup.
aberk 0:6e12a3e5af19 208 if (!(prevControllerOutput_ >= 1 && error > 0) && !(prevControllerOutput_ <= 0 && error < 0)) {
aberk 0:6e12a3e5af19 209 accError_ += error;
aberk 0:6e12a3e5af19 210 }
aberk 0:6e12a3e5af19 211
aberk 0:6e12a3e5af19 212 //Compute the current slope of the input signal.
aberk 0:6e12a3e5af19 213 float dMeas = (scaledPV - prevProcessVariable_) / tSample_;
aberk 0:6e12a3e5af19 214
aberk 0:6e12a3e5af19 215 float scaledBias = 0.0;
aberk 0:6e12a3e5af19 216
aberk 0:6e12a3e5af19 217 if (usingFeedForward) {
aberk 0:6e12a3e5af19 218 scaledBias = (bias_ - outMin_) / outSpan_;
aberk 0:6e12a3e5af19 219 }
aberk 0:6e12a3e5af19 220
aberk 0:6e12a3e5af19 221 //Perform the PID calculation.
aberk 0:6e12a3e5af19 222 controllerOutput_ = scaledBias + Kc_ * (error + (tauR_ * accError_) - (tauD_ * dMeas));
aberk 0:6e12a3e5af19 223
aberk 0:6e12a3e5af19 224 //Make sure the computed output is within output constraints.
aberk 0:6e12a3e5af19 225 if (controllerOutput_ < 0.0) {
HangL 2:0fff4827f3b6 226 controllerOutput_ = 0.0;
aberk 0:6e12a3e5af19 227 } else if (controllerOutput_ > 1.0) {
aberk 0:6e12a3e5af19 228 controllerOutput_ = 1.0;
aberk 0:6e12a3e5af19 229 }
aberk 0:6e12a3e5af19 230
aberk 0:6e12a3e5af19 231 //Remember this output for the windup check next time.
aberk 0:6e12a3e5af19 232 prevControllerOutput_ = controllerOutput_;
aberk 0:6e12a3e5af19 233 //Remember the input for the derivative calculation next time.
aberk 0:6e12a3e5af19 234 prevProcessVariable_ = scaledPV;
aberk 0:6e12a3e5af19 235
aberk 0:6e12a3e5af19 236 //Scale the output from percent span back out to a real world number.
aberk 0:6e12a3e5af19 237 return ((controllerOutput_ * outSpan_) + outMin_);
aberk 0:6e12a3e5af19 238
aberk 0:6e12a3e5af19 239 }
HangL 2:0fff4827f3b6 240 float PID::Speedcompute(double Stepper,double Target)
HangL 2:0fff4827f3b6 241 {
HangL 3:7f0ed54318df 242 static double Bias,PWM,/*Last_bias,*/Integral_bias;
HangL 3:7f0ed54318df 243 Stepper=Stepper/10;
HangL 2:0fff4827f3b6 244 Bias=Stepper-Target;
HangL 3:7f0ed54318df 245 /////////////////////////////////////
HangL 3:7f0ed54318df 246 Stepper*=0.7;
HangL 3:7f0ed54318df 247 Stepper+=Bias*0.3;
HangL 3:7f0ed54318df 248 Integral_bias+=Stepper;
HangL 3:7f0ed54318df 249 // Integral_bias+=Bias;
HangL 3:7f0ed54318df 250 // PWM+=Speed_Kc*(Bias-Last_bias)+Speed_tauI*Bias;
HangL 3:7f0ed54318df 251 PWM=Stepper*Speed_Kc+Integral_bias*Speed_tauI;
HangL 3:7f0ed54318df 252 // Last_bias=Bias;
HangL 2:0fff4827f3b6 253 return PWM;
HangL 2:0fff4827f3b6 254 }
HangL 3:7f0ed54318df 255
aberk 0:6e12a3e5af19 256 float PID::getInMin() {
aberk 0:6e12a3e5af19 257
aberk 0:6e12a3e5af19 258 return inMin_;
aberk 0:6e12a3e5af19 259
aberk 0:6e12a3e5af19 260 }
aberk 0:6e12a3e5af19 261
aberk 0:6e12a3e5af19 262 float PID::getInMax() {
aberk 0:6e12a3e5af19 263
aberk 0:6e12a3e5af19 264 return inMax_;
aberk 0:6e12a3e5af19 265
aberk 0:6e12a3e5af19 266 }
aberk 0:6e12a3e5af19 267
aberk 0:6e12a3e5af19 268 float PID::getOutMin() {
aberk 0:6e12a3e5af19 269
aberk 0:6e12a3e5af19 270 return outMin_;
aberk 0:6e12a3e5af19 271
aberk 0:6e12a3e5af19 272 }
aberk 0:6e12a3e5af19 273
aberk 0:6e12a3e5af19 274 float PID::getOutMax() {
aberk 0:6e12a3e5af19 275
aberk 0:6e12a3e5af19 276 return outMax_;
aberk 0:6e12a3e5af19 277
aberk 0:6e12a3e5af19 278 }
aberk 0:6e12a3e5af19 279
aberk 0:6e12a3e5af19 280 float PID::getInterval() {
aberk 0:6e12a3e5af19 281
aberk 0:6e12a3e5af19 282 return tSample_;
aberk 0:6e12a3e5af19 283
aberk 0:6e12a3e5af19 284 }
aberk 0:6e12a3e5af19 285
aberk 0:6e12a3e5af19 286 float PID::getPParam() {
aberk 0:6e12a3e5af19 287
aberk 0:6e12a3e5af19 288 return pParam_;
aberk 0:6e12a3e5af19 289
aberk 0:6e12a3e5af19 290 }
aberk 0:6e12a3e5af19 291
aberk 0:6e12a3e5af19 292 float PID::getIParam() {
aberk 0:6e12a3e5af19 293
aberk 0:6e12a3e5af19 294 return iParam_;
aberk 0:6e12a3e5af19 295
aberk 0:6e12a3e5af19 296 }
aberk 0:6e12a3e5af19 297
aberk 0:6e12a3e5af19 298 float PID::getDParam() {
aberk 0:6e12a3e5af19 299
aberk 0:6e12a3e5af19 300 return dParam_;
aberk 0:6e12a3e5af19 301
aberk 0:6e12a3e5af19 302 }