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.
Diff: PID.cpp
- Revision:
- 2:c8ab3e8d4c51
- Parent:
- 1:4705d8930670
- Child:
- 3:c690a8974246
diff -r 4705d8930670 -r c8ab3e8d4c51 PID.cpp --- a/PID.cpp Sun Apr 07 13:52:44 2019 +0000 +++ b/PID.cpp Sun Apr 14 14:03:46 2019 +0000 @@ -1,78 +1,112 @@ #include "PID.h" #include "mbed.h" -PID::PID(Timer *_timer){ - integral = 0; - prev_hensa = 0; - nowtime = 0; - prev_time = 0; - lateD = 0; - timer = _timer; -} +PID::PID(double* _Input, double* _Output, double* _Setpoint, double _Kp, double _Ki, double _Kd, PID_Mode _mode, Timer *_timer) +{ + + Input = _Input; + Output = _Output; + Setpoint = _Setpoint; -float PID::control(float target, float nowrpm){ - //timer->start(); - nowtime =timer->read(); - float hensa = target - nowrpm; - float dt = 1000000 / (nowtime - prev_time); - integral += (hensa + prev_hensa) / 2 * dt; - float differential = (hensa - prev_hensa) / dt; - float sousaryou = Kp*hensa + Ki*integral + Kd*differential; - prev_hensa = hensa; - prev_time =timer->read(); - return sousaryou; -} - -float PID::PI_lateD(float target, float nowrpm){ - nowtime = (*timer).read(); - float hensa = target - nowrpm; - float dt = nowtime - prev_time; - integral += (hensa + prev_hensa) / 2 *dt; - float sousaryou = Kp*hensa + Ki*integral + Kd*lateD; - prev_hensa = hensa; - prev_time = timer->read(); - lateD = (hensa - prev_hensa) / dt; - return sousaryou; + timer = _timer; + + SampleTime = 100; + lastTime = timer->read_ms(); + setOutputLimits(-1,1); + setParameter_pid(_Kp,_Ki,_Kd); + setPIDMode(_mode); + Initialize(); } -float PID::control_P(float target, float nowrpm, float new_Kp){ - float hensa = target - nowrpm; - float sousaryou = new_Kp*hensa; - return sousaryou; -} - -float PID::control_PI(float target, float nowrpm){ - Kp = 0.45 * Ku; - Ti = 0.83 * Pu; - Ki = (1 / Ti) * Kp; - nowtime = timer->read(); - float hensa = target - nowrpm; - float dt = nowtime -prev_time; - integral += (hensa + prev_hensa) / 2 * dt; - float sousaryou = Kp*hensa + Ki*integral; - prev_hensa = hensa; - prev_time = timer->read(); - return sousaryou; +void PID::control() +{ + //timer->start(); + double nowtime =timer->read_ms(); + double input = *Input; + + if((nowtime - lastTime) > SampleTime) + { + double error = *Setpoint - input; + double dInput = input - lastInput; + double derror = error - lastError; + outputSum += (Ki*error); + double output = 0; + + if(outputSum > outMax) outputSum= outMax; + else if(outputSum < outMin) outputSum= outMin; + + switch(mode) + { + case pos_PID: + output = outputSum + Kp*error + Kd*derror; + break; + + case P_D: + output = Kp*error - Kd*dInput; + break; + + case PI_D: + output = outputSum + Kp*error - Kd*dInput; + break; + + case I_PD: + output = outputSum - Kp*input - Kd*dInput; + break; + + } + + *Output = output; + lastTime = nowtime; + lastInput = input; + } } -void PID::setParameter_pid(float new_Kp, float new_Ki, float new_Kd){ - Kp = new_Kp; - Ki = new_Ki; - Kd = new_Kd; +void PID::setParameter_pid(double new_Kp, double new_Ki, double new_Kd) +{ + Kp = new_Kp; + Ki = new_Ki; + Kd = new_Kd; +} + +void PID::setParameter_KuPu(double new_Ku, double new_Pu) +{ + Ku = new_Ku; + Pu = new_Pu; + Kp = 0.60 * Ku; + Ti = 0.50 * Pu; + Td = 0.125 * Pu; + Ki = (1 / Ti) * Kp; + Kd = Td * Kp; +} + +void PID::setPIDMode(PID_Mode _mode) +{ + mode = _mode; + Initialize(); } -void PID::setParameter_KuPu(float new_Ku, float new_Pu){ - Ku = new_Ku; - Pu = new_Pu; - Kp = 0.60 * Ku; - Ti = 0.50 * Pu; - Td = 0.125 * Pu; - Ki = (1 / Ti) * Kp; - Kd = Td * Kp; +void PID::setOutputLimits(double Min, double Max) +{ + if(Min >= Max) return; + outMin = Min; + outMax = Max; + + if(*Output > outMax) *Output = outMax; + else if(*Output < outMin) *Output = outMin; + if(outputSum > outMax) outputSum = outMax; + else if(outputSum < outMin) outputSum = outMin; } -void PID::reset(float target){ - integral = 0; - prev_hensa = target; - prev_time = timer->read(); +void PID::reset(double target) +{ + outputSum = 0; } + +void PID::Initialize() +{ + outputSum = *Output; + lastInput = *Input; + lastError = *Setpoint - lastInput; + if(outputSum > outMax) outputSum = outMax; + else if(outputSum < outMin) outputSum = outMin; +} \ No newline at end of file