ichinoseki_Bteam_2019 / PID

Dependents:   MR_example 2019_AR_Itsuki

Committer:
soyooo
Date:
Tue Sep 11 01:33:20 2018 +0000
Revision:
4:64ae90ccf8d8
Parent:
2:493370c3e206
Child:
5:ceb7cbed26f3
????????????;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
soyooo 0:da83c97448bf 1 #include "mbed.h"
soyooo 0:da83c97448bf 2 #include "PID.h"
soyooo 0:da83c97448bf 3
soyooo 0:da83c97448bf 4 /*p,i,d:ゲイン設定 t:制御ループ時間 max:ourputの最大値*/
soyooo 2:493370c3e206 5 PID::PID(float p, float i, float d, float t, float max, Timer *T)
soyooo 0:da83c97448bf 6 {
soyooo 2:493370c3e206 7 timer = T;
soyooo 0:da83c97448bf 8 kp = p; ki = i; kd = d; delta_t = t;
soyooo 0:da83c97448bf 9 abs_max_output = max;
soyooo 0:da83c97448bf 10 integral = 0;
soyooo 0:da83c97448bf 11 pid_type = PID_LOCATE;
soyooo 2:493370c3e206 12 allowable_error = 0;
soyooo 2:493370c3e206 13
soyooo 0:da83c97448bf 14 }
soyooo 0:da83c97448bf 15 void PID::setParameter(float p, float i, float d, float t, float max)
soyooo 0:da83c97448bf 16 {
soyooo 0:da83c97448bf 17 kp = p; ki = i; kd = d; delta_t = t;
soyooo 0:da83c97448bf 18 abs_max_output = max;
soyooo 0:da83c97448bf 19 integral = 0;
soyooo 0:da83c97448bf 20 }
soyooo 0:da83c97448bf 21
soyooo 0:da83c97448bf 22 /*計算のための割り込み開始*/
soyooo 0:da83c97448bf 23 void PID::start()
soyooo 0:da83c97448bf 24 {
soyooo 0:da83c97448bf 25 pidTimer.attach(this, &PID::_compute, delta_t);
soyooo 0:da83c97448bf 26 }
soyooo 0:da83c97448bf 27
soyooo 0:da83c97448bf 28 /*計算のための割り込み停止*/
soyooo 0:da83c97448bf 29 void PID::stop()
soyooo 0:da83c97448bf 30 {
soyooo 1:4906167d1263 31 reset();
soyooo 0:da83c97448bf 32 pidTimer.detach();
soyooo 0:da83c97448bf 33 }
soyooo 0:da83c97448bf 34
soyooo 0:da83c97448bf 35 /*現在保持している計算データをリセット*/
soyooo 0:da83c97448bf 36 void PID::reset()
soyooo 0:da83c97448bf 37 {
soyooo 0:da83c97448bf 38 integral = 0;
soyooo 0:da83c97448bf 39 error[0] = 0;
soyooo 0:da83c97448bf 40 error[1] = 0;
soyooo 0:da83c97448bf 41 }
soyooo 0:da83c97448bf 42
soyooo 0:da83c97448bf 43 /*計算する タイマーで回される*/
soyooo 0:da83c97448bf 44 void PID::_compute()
soyooo 0:da83c97448bf 45 {
soyooo 0:da83c97448bf 46 float proportion, differential;
soyooo 0:da83c97448bf 47 static float _output = 0;
soyooo 0:da83c97448bf 48
soyooo 0:da83c97448bf 49 error[0] = *target - *sensor;
soyooo 0:da83c97448bf 50
soyooo 0:da83c97448bf 51 proportion = kp * error[0];
soyooo 0:da83c97448bf 52 integral += ki * error[0] * delta_t;
soyooo 0:da83c97448bf 53 differential = kd * (error[0] - error[1]) / delta_t;
soyooo 0:da83c97448bf 54
soyooo 0:da83c97448bf 55 error[1] = error[0];
soyooo 0:da83c97448bf 56
soyooo 0:da83c97448bf 57 integral = _gurd(integral, abs_max_output);
soyooo 2:493370c3e206 58
soyooo 0:da83c97448bf 59 if(pid_type == PID_LOCATE)
soyooo 0:da83c97448bf 60 _output = proportion + integral + differential;
soyooo 0:da83c97448bf 61 else if(pid_type == PID_SPEED)
soyooo 0:da83c97448bf 62 _output += proportion + integral + differential;
soyooo 0:da83c97448bf 63 else _output = 0;
soyooo 0:da83c97448bf 64
soyooo 0:da83c97448bf 65 _output = _gurd(_output, abs_max_output);
soyooo 0:da83c97448bf 66 output = _output;
soyooo 2:493370c3e206 67
soyooo 4:64ae90ccf8d8 68 last_target = *target;
soyooo 4:64ae90ccf8d8 69
soyooo 2:493370c3e206 70 if(_abs(error[0]) <= allowable_error)
soyooo 2:493370c3e206 71 timer->start();
soyooo 2:493370c3e206 72 else start_time = timer->read();
soyooo 0:da83c97448bf 73 }
soyooo 0:da83c97448bf 74
soyooo 0:da83c97448bf 75 float PID::_gurd(float val, float abs_max)
soyooo 0:da83c97448bf 76 {
soyooo 0:da83c97448bf 77 if(val > abs_max)
soyooo 0:da83c97448bf 78 return abs_max;
soyooo 0:da83c97448bf 79 else if(val < -abs_max)
soyooo 0:da83c97448bf 80 return -abs_max;
soyooo 0:da83c97448bf 81 else return val;
soyooo 0:da83c97448bf 82 }
soyooo 2:493370c3e206 83 float PID::_abs(float val)
soyooo 2:493370c3e206 84 {
soyooo 2:493370c3e206 85 if(val >= 0)
soyooo 2:493370c3e206 86 return val;
soyooo 2:493370c3e206 87 else return -val;
soyooo 2:493370c3e206 88 }
soyooo 2:493370c3e206 89
soyooo 2:493370c3e206 90 bool PID::isConvergence(float time_range)
soyooo 4:64ae90ccf8d8 91 {
soyooo 4:64ae90ccf8d8 92 if(last_target != *target)
soyooo 4:64ae90ccf8d8 93 return 0;
soyooo 2:493370c3e206 94 if(timer->read() - start_time > time_range)
soyooo 2:493370c3e206 95 return 1;
soyooo 2:493370c3e206 96 else return 0;
soyooo 2:493370c3e206 97 }