00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "PIDsmoothedValue.h"
00011 #include "Tools/Debugging/DebugDrawings.h"
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 PIDsmoothedValue::PIDsmoothedValue():value(0.0),p(0.5),i(0.5),d(0.5),min(-10000),max(10000),maxaction(5000)
00022 {
00023 }
00024
00025
00026
00027
00028
00029
00030
00031 PIDsmoothedValue::PIDsmoothedValue(double value, double p, double i, double d, double min, double max, double maxaction):
00032 lastDifference(0.0),
00033 lastTargetVal(0.0),
00034 value(value),
00035 lastValue(0.0),
00036 started(false),
00037 integralError(0.0),
00038 lastTime(0.0),
00039 p(p), i(i), d(d),
00040 min(min), max(max),
00041 maxaction(maxaction)
00042 {}
00043
00044
00045
00046
00047
00048
00049 void PIDsmoothedValue::setMin(double m)
00050 {
00051 PIDsmoothedValue::min = m;
00052 }
00053
00054
00055
00056
00057
00058
00059 void PIDsmoothedValue::setMax(double m)
00060 {
00061 PIDsmoothedValue::max = m;
00062 }
00063
00064
00065
00066
00067
00068
00069 void PIDsmoothedValue::setWeightP(double p)
00070 {
00071 PIDsmoothedValue::p = p;
00072 }
00073
00074
00075
00076
00077
00078
00079 void PIDsmoothedValue::setWeightI(double i)
00080 {
00081 PIDsmoothedValue::i = i;
00082 }
00083
00084
00085
00086
00087
00088
00089 void PIDsmoothedValue::setWeightD(double d)
00090 {
00091 PIDsmoothedValue::d = d;
00092 }
00093
00094
00095
00096
00097
00098
00099
00100
00101 double PIDsmoothedValue::approximateVal(double targetVal)
00102 {
00103
00104 double diff = targetVal - value;
00105
00106
00107
00108 double dDiff = diff - lastDifference;
00109
00110 if (!started)
00111 {
00112 dDiff = 0;
00113 started = true;
00114 }
00115
00116
00117
00118 integralError += diff;
00119
00120
00121
00122 lastValue = value;
00123
00124
00125 value += p*diff + i*integralError + d*dDiff;
00126
00127
00128
00129 if (value < min)
00130 {
00131 value = min;
00132 }
00133
00134
00135 if (value > max)
00136 {
00137 value = max;
00138 }
00139
00140
00141
00142 if ((value - lastValue) > maxaction) { value = lastValue + maxaction; }
00143 else if ((lastValue - value) > maxaction) { value = lastValue - maxaction; }
00144
00145
00146
00147 lastDifference = diff;
00148
00149 return value;
00150
00151 }
00152
00153
00154
00155
00156
00157
00158 double PIDsmoothedValue::apprDiscrVal(double targetVal, double time, double maxIteration) {
00159
00160
00161 if (time >= lastTime + maxIteration)
00162 {
00163 resetTo(targetVal);
00164 return value;
00165 }
00166
00167 if (time < lastTime + 1)
00168 {
00169 return value;
00170 }
00171
00172
00173 while (time >= lastTime + 1)
00174 {
00175 value = approximateVal(lastValue + 1/(time-lastTime)*(targetVal-lastValue));
00176
00177
00178
00179 ++lastTime;
00180 }
00181 return value;
00182 }
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 double PIDsmoothedValue::approximateValNew(double targetVal)
00194 {
00195
00196 double diff = targetVal - value;
00197
00198
00199 double tDiff = targetVal - lastTargetVal;
00200 if (!started) {
00201 tDiff = 0;
00202 started = true;
00203 }
00204
00205
00206
00207
00208 integralError += diff;
00209
00210
00211 lastTargetVal = targetVal;
00212
00213
00214 value += p*diff + i*integralError + d*tDiff;
00215
00216
00217
00218
00219 return value;
00220
00221 }
00222
00223
00224
00225
00226
00227 double PIDsmoothedValue::apprContVal(double targetVal, double time)
00228 {
00229 double diff = targetVal - value;
00230 double dDiff = diff - lastDifference;
00231 double timeDiff = time - lastTime;
00232 double diffQuot = 0;
00233
00234 if (!started)
00235 {
00236 dDiff = 0;
00237 started = true;
00238 }
00239
00240 integralError += diff*timeDiff*timeDiff;
00241
00242 if (timeDiff != 0)
00243 {
00244 diffQuot = dDiff;
00245 }
00246
00247 lastValue = value;
00248 lastDifference = diff;
00249 lastTime = time;
00250
00251 value += p*diff*timeDiff + i*integralError + d*diffQuot;
00252
00253 if (value < min)
00254 {
00255 value = min;
00256 }
00257
00258
00259 if (value > max)
00260 {
00261 value = max;
00262 }
00263
00264
00265
00266 if ((value - lastValue) > maxaction)
00267 {
00268 value = lastValue + maxaction;
00269 }
00270
00271 if ((lastValue - value) > maxaction)
00272 {
00273 value = lastValue - maxaction;
00274 }
00275
00276
00277
00278
00279 return value;
00280 }
00281
00282
00283
00284
00285
00286
00287 double PIDsmoothedValue::getVal() { return value; }
00288
00289
00290
00291 double PIDsmoothedValue::getWeightP() { return p; }
00292
00293
00294 double PIDsmoothedValue::getWeightI() { return i; }
00295
00296
00297 double PIDsmoothedValue::getWeightD() { return d; }
00298
00299 double PIDsmoothedValue::getMin() { return min; }
00300 double PIDsmoothedValue::getMax() { return max; }
00301
00302
00303
00304
00305
00306
00307 void PIDsmoothedValue::reset()
00308 {
00309
00310 lastTargetVal = 0;
00311 value = 0;
00312 integralError = 0;
00313 started = false;
00314 lastTime = 0;
00315
00316 }
00317
00318 void PIDsmoothedValue::resetTo(double val)
00319 {
00320 reset();
00321 value = val;
00322 approximateVal(val);
00323 }
00324
00325 double PIDsmoothedValue::addOffset(double offset)
00326 {
00327 value += offset;
00328 lastValue += offset;
00329 return value;
00330 }
00331
00332 double PIDsmoothedValue::setTo(double val)
00333 {
00334 double offset = val - value;
00335 return addOffset(offset);
00336 }
00337