一直以來,pid都是控制領域的經典算法,之前嘗試理解了很久,但還是一知半解,總是不得要領,昨天模仿着別人的代碼寫了一個增量式pid的代碼。
我的理解就是pid其實就是對你設置的預定參數進行跟蹤。在控制領域,他先采集目前的實時參數,與設定的參數進行比較,計算出誤差,然后進行積分微分運算,計算出控制器需要的增量(正負),
然后與實際參數相加,使他盡可能的接近設定值 。沒有D參數的稱為PI控制器,也比較常用。具體公式其實不理解也沒關系,只要對照着差分方程,寫出相應的算法即可,然后上網查查pid調節的經驗。
找到最適的pid參數。
程序中的count為需要計算的次數,有興趣的讀者可以嘗試着修改一下這個數值,當count值為100的時候,你會發現他最后迭代的值並不是設定值200.0.而是一個比他小的數,
這是因為100次計算並不能使他達到設定值,畢竟我們設置的初始實際值為0,要讓0直接跟蹤到200需要一段跳躍時間。這個跳躍時間並不是100計算就能達到的;可以嘗試幾次試試。
當然實際控制領域應用的時候,並沒有這個count,他會一直進行 動態運算,使實際值一直保持在設定值附近。
//實現增量式PID算法 #include "stdio.h" void pid_init();//PID參數初始化 float pid_realise(float speed);//實現PID算法 struct { float set_speed;//設定速度 float actual_speed;//實際速度 float error;//偏差 float error_next;//上一個偏差 float error_last;//上上一個偏差 float kp,ki,kd;//定義比例,積分,微分參數 }pid; int main() { pid_init(); int count = 0; while(count<400)//進行400次 PID 運算,使初始值從0開始接近200.0 { float speed = pid_realise(200.0);//設定值設定為200.0 printf("%f\n",speed);//輸出每一次PID 運算后的結果 count++; } } void pid_init() { pid.set_speed = 0.0; pid.actual_speed = 0.0; pid.error = 0.0; pid.error_next = 0.0; pid.error_last = 0.0; //可調節PID 參數。使跟蹤曲線慢慢接近階躍函數200.0 // pid.kp = 0.2; pid.ki = 0.01; pid.kd = 0.2; } float pid_realise(float speed)//實現pid { pid.set_speed = speed;//設置目標速度 pid.error = pid.set_speed - pid.actual_speed; float increment_speed;//增量 increment_speed = pid.kp*(pid.error-pid.error_next)+pid.ki*pid.error+\ pid.kd*(pid.error-2*pid.error_next+pid.error_last);//增量計算公式 pid.actual_speed+= increment_speed; pid.error_last = pid.error_next;//下一次迭代 pid.error_next = pid.error; return pid.actual_speed; }