Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: Encoder_Nucleo_16_bits
Dependents: FRC_2018 FRC2018_Bis 0hackton_08_06_18 lib_FRC_2019 ... more
PID.cpp
00001 #include "PID.h" 00002 00003 PID::PID (TIM_TypeDef *LTIM, TIM_TypeDef *RTIM, PinName LPWM, PinName RPWM, PinName LDIRA, PinName LDIRB, PinName RDIRA, PinName RDIRB) : _Lencoder(LTIM), _Rencoder(RTIM), _Lpwm(LPWM), _Rpwm(RPWM), _LdirA(LDIRA), _LdirB(LDIRB), _RdirA(RDIRA), _RdirB(RDIRB) 00004 { 00005 _tick.attach(callback(this, &PID::controlLoop), 0.001); 00006 00007 _Lpwm.period_us(50); 00008 _Lpwm = 0; 00009 00010 _Rpwm.period_us(50); 00011 _Rpwm = 0; 00012 00013 _Kp = 2.0; 00014 _Ki = 0.4; 00015 _Kd = 1.0; 00016 } 00017 00018 float PID::setProportionnalValue (float KpValue) 00019 { 00020 _Kp = KpValue; 00021 return _Kp; 00022 } 00023 00024 float PID::setintegralValue (float KiValue) 00025 { 00026 _Ki = KiValue; 00027 return _Ki; 00028 } 00029 00030 float PID::setDerivativeValue (float KdValue) 00031 { 00032 _Kd = KdValue; 00033 return _Kd; 00034 } 00035 00036 void PID::setSpeed (double left, double right) 00037 { 00038 _SpeedG = left; 00039 _SpeedD = right; 00040 } 00041 00042 void PID::getSpeed (double *vG, double *vD) 00043 { 00044 *vG = _measSpeedG; 00045 *vD = _measSpeedD; 00046 } 00047 00048 void PID::getPosition (double *x, double *y, double *theta) 00049 { 00050 *x = _X; 00051 *y = _Y; 00052 *theta = _THETA; 00053 } 00054 00055 void PID::resetPosition (void) 00056 { 00057 _X = 0; 00058 _Y = 0; 00059 _THETA = 0; 00060 } 00061 00062 void PID::controlLoop() 00063 { 00064 long PositionG, PositionD; 00065 static float integralErrorG = 0, integralErrorD = 0; 00066 static float oldErrorG, oldErrorD; 00067 double errorG, commandeG; 00068 double errorD, commandeD; 00069 double meanDist, diffDist, deltaX, deltaY, deltaTheta; 00070 static long oldPositionG=0, oldPositionD=0; 00071 00072 PositionG = _Lencoder.GetCounter(); 00073 PositionD = -_Rencoder.GetCounter(); 00074 00075 // As we use mm/s for speed unit and we convert all mesure to this unit 00076 00077 // Converting step to millimeters 00078 _measDistG = ((double)PositionG - (double)oldPositionG) / 54.881; 00079 _measDistD = ((double)PositionD - (double)oldPositionD) / 54.881; 00080 00081 // Converting position to speed 00082 _measSpeedG = 1000.0 * _measDistG; 00083 _measSpeedD = 1000.0 * _measDistD; 00084 00085 // Computing errors 00086 errorG = _SpeedG - _measSpeedG; 00087 errorD = _SpeedD - _measSpeedD; 00088 integralErrorG += errorG; 00089 integralErrorD += errorD; 00090 00091 // Limiting integral error 00092 if (integralErrorG > 10000) { 00093 _WheelStuckG = 1; 00094 integralErrorG = 10000; 00095 } else { 00096 if (integralErrorG < -10000) { 00097 _WheelStuckG = 1; 00098 integralErrorG = -10000; 00099 } else { 00100 _WheelStuckG = 0; 00101 } 00102 } 00103 00104 if (integralErrorD > 10000) { 00105 _WheelStuckD = 1; 00106 integralErrorD = 10000; 00107 } else { 00108 if (integralErrorD < -10000) { 00109 _WheelStuckD = 1; 00110 integralErrorD = -10000; 00111 } else { 00112 _WheelStuckD = 0; 00113 } 00114 } 00115 00116 // Correcting system (empiric test tells me that Kp = 4, Ki = 1 and Kd = 2, but this is probably not the good setting) 00117 commandeG = _Kp * errorG + _Ki * integralErrorG + _Kd * (errorG - oldErrorG); 00118 commandeD = _Kp * errorD + _Ki * integralErrorD + _Kd * (errorD - oldErrorD); 00119 00120 // Convert to PWM 00121 _PwmValueG = commandeG / 1300.0; 00122 if (_PwmValueG > 1) _PwmValueG = 1; 00123 if (_PwmValueG < -1) _PwmValueG = -1; 00124 00125 if (_PwmValueG < 0) { 00126 _Lpwm = -_PwmValueG; 00127 _LdirA = 0; 00128 _LdirB = 1; 00129 } else { 00130 _Lpwm = _PwmValueG; 00131 _LdirA = 1; 00132 _LdirB = 0; 00133 } 00134 00135 _PwmValueD = commandeD/1300.0; 00136 if (_PwmValueD > 1) _PwmValueD = 1; 00137 if (_PwmValueD < -1) _PwmValueD = -1; 00138 00139 if (_PwmValueD < 0) { 00140 _Rpwm = -_PwmValueD; 00141 _RdirA = 1; 00142 _RdirB = 0; 00143 } else { 00144 _Rpwm = _PwmValueD; 00145 _RdirA = 0; 00146 _RdirB = 1; 00147 } 00148 00149 //odometry (segments approx.) 00150 meanDist = (_measDistG + _measDistD) / 2.0; 00151 diffDist = _measDistD - _measDistG; 00152 00153 deltaX = meanDist * cos (_THETA); 00154 deltaY = meanDist * sin (_THETA); 00155 deltaTheta = atan2(diffDist,230.0); 00156 00157 _X += deltaX; 00158 _Y += deltaY; 00159 _THETA += deltaTheta; 00160 //if (_THETA > 3.141592653589793) _THETA -= 6.283185307179586; 00161 //if (_THETA < -3.141592653589793) _THETA += 6.283185307179586; 00162 00163 oldPositionG = PositionG; 00164 oldPositionD = PositionD; 00165 oldErrorG = errorG; 00166 oldErrorD = errorD; 00167 }
Generated on Sat Jul 16 2022 09:22:10 by
1.7.2