■Cancel関数
PID_AutoTune_v0.hライブラリのCancel関数は、PIDオートチューン実行中の場合に実行する事でPIDオートチューンを停止します。
■使用例
Arduino IDEで使用するPID_ATune関数の使用例は以下の通りです。
試しにこのプログラムをArduino UNOで実行すると、DoModel関数で生成したInput値に対してPID関数でPID制御を開始します。
図1の様に開始直後にシリアルモニター送信欄に「1」と入力し送信すると「Kp,Ki,Kd」の値が消え「tuning mode」と表示しPID_ATune関数が実行されます。
※この間にシリアルモニター送信欄に「0」と入力し送信するとCancel関数が実行されオートチューンが停止されます。
しばらく(実験では251秒)待つと最適化された「Kp,Ki,Kd」の値がPID関数に適用され図3の様にPCのシリアルモニタ上に出力されます。
#include <PID_v1.h> #include <PID_AutoTune_v0.h> byte ATuneModeRemember = 2; double input = 80, output = 50, setpoint = 180; double kp = 2, ki = 0.5, kd = 2; double kpmodel = 1.5, taup = 100, theta[50]; double outputStart = 5; double aTuneStep = 50, aTuneNoise = 1, aTuneStartValue = 100; unsigned int aTuneLookBack = 20; boolean tuning = false; unsigned long modelTime, serialTime; PID myPID(&input, &output, &setpoint, kp, ki, kd, DIRECT); PID_ATune aTune(&input, &output); //set to false to connect to the real world boolean useSimulation = true; void AutoTuneHelper(boolean start) { if (start) ATuneModeRemember = myPID.GetMode(); else myPID.SetMode(ATuneModeRemember); } void changeAutoTune() { if (!tuning) { //Set the output to the desired starting frequency. output = aTuneStartValue; aTune.SetNoiseBand(aTuneNoise); aTune.SetOutputStep(aTuneStep); aTune.SetLookbackSec((int)aTuneLookBack); AutoTuneHelper(true); tuning = true; } else { //cancel autotune aTune.Cancel(); tuning = false; AutoTuneHelper(false); } } void SerialSend() { Serial.print("setpoint: "); Serial.print(setpoint); Serial.print(" "); Serial.print("input: "); Serial.print(input); Serial.print(" "); Serial.print("output: "); Serial.print(output); Serial.print(" "); if (tuning) { Serial.println("tuning mode"); } else { Serial.print("kp: "); Serial.print(myPID.GetKp()); Serial.print(" "); Serial.print("ki: "); Serial.print(myPID.GetKi()); Serial.print(" "); Serial.print("kd: "); Serial.print(myPID.GetKd()); Serial.println(); } } void SerialReceive() { if (Serial.available()) { char b = Serial.read(); Serial.flush(); if ((b == '1' && !tuning) || (b != '1' && tuning))changeAutoTune(); } } void DoModel() { //cycle the dead time for (byte i = 0; i < 49; i++) { theta[i] = theta[i + 1]; } //compute the input input = (kpmodel / taup) * (theta[0] - outputStart) + input * (1 - 1 / taup) + ((float)random(-10, 10)) / 100; } void setup() { if (useSimulation) { for (byte i = 0; i < 50; i++) { theta[i] = outputStart; } modelTime = 0; } //Setup the pid myPID.SetMode(AUTOMATIC); if (tuning) { tuning = false; changeAutoTune(); tuning = true; } serialTime = 0; Serial.begin(9600); } void loop() { unsigned long now = millis(); if (!useSimulation) { //pull the input in from the real world input = analogRead(0); } if (tuning) { byte val = (aTune.Runtime()); if (val != 0) { tuning = false; } if (!tuning) { //we're done, set the tuning parameters kp = aTune.GetKp(); ki = aTune.GetKi(); kd = aTune.GetKd(); myPID.SetTunings(kp, ki, kd); AutoTuneHelper(false); } } else myPID.Compute(); if (useSimulation) { theta[30] = output; if (now >= modelTime) { modelTime += 100; DoModel(); } } else { analogWrite(0, output); } //send-receive with processing if it's time if (millis() > serialTime) { SerialReceive(); SerialSend(); serialTime += 500; } }
図1:プログラム例
図2:Arduino IDE シリアルモニター(オートチューニング開始)
図3:Arduino IDE シリアルモニター(オートチューニング中)
図4:Arduino IDE シリアルモニター(251秒でオートチューニング終了)
■構文
Cancel()
■パラメータ・戻り値
Cancel()関数にパラメータと戻り値は有りません。
励みになりますのでよければクリック下さい(^o^)/