|
之前章節已經把PID從理論到時間基本上講完了,剩下一個位置式PID就能收尾了。趕緊更完,就開始平衡小車下一步制作了。最近也是比較忙,更貼慢了很多。不過,這個零基礎教程我還是要堅持寫完的。
位置式PID部分主要代碼
/********************位置式 PID 控制設計************************************/unsigned int LocPIDCalc(int NextPoint){ int iError,dError; iError = SetPoint - NextPoint; //求出當前偏差 SumError += iError; //對偏差進行積分 dError = iError - LastError; //對偏差求微分 LastError = iError; //轉換賦值 //返回位置式PID計算結果 return(Proportion * iError //比例項 + Integral * SumError //積分項 + Derivative * dError); //微分項}
注釋已經很詳細了,看了之前我的帖子應該能看的懂代碼的。推導過程不明白的在往前看看吧。
之后在中斷中直接調用公式即可,計算出來的結果直接賦值給PWM(計算結果既是PWM,計算出來是0,PWM就是0)
count=(short)(TIM2 -> CNT/4); TIM2 -> CNT=0;/* 計數得到增量式PID的增量數值 */PWM_Duty=LocPIDCalc(count); //將計算的PWM送入寄存器TIM_SetCompare1(TIM3,PWM_Duty);
完事了,是不是很簡單。
位置式PID調參
位置式PID和增量式PID調參還是有點區別的。下面說下具體調參過程和思路。
思路還是將ID系數設為0,先調節單獨的P。
當P = 2時,如下圖:
是不是有點懵逼,怎么趨近一條直線了?不應該是越來越靠近目標值嗎?如果你這樣想的,那真是還沒理解公式呀。仔細看看公式,當ID為0,只有一個P時,是不是應該就是一條直線?下面說下為啥是直線。第一次采樣:假設初始化目標值為100個脈沖,第一次采樣測得脈沖為0個,此時誤差為100,在乘上系數2,最終占空比為200。第二次采樣:假設采樣50個脈沖,誤差為50,乘上系數,2,最終得占空比為100.第三次采樣:假設采樣脈沖為25,誤差為75,乘上系數2,最終占空比為150
以此循環得出結果:誤差越大,占空比越大,誤差越小,占空比越小,也就是說誤差越大輸出越大,誤差越小,輸出越小。在經過N次采樣后,會得到一個平衡值、平衡的條件是計算出來的占空比1所對應的編碼器輸出值被目標值減去之后再乘上P,得出來的占空比2和占空比相同。本例程實際測得當占空比為146,使得編碼器輸出28個脈沖, 目標值100-28=72,72乘上P系數2=144,144和146非常接近,也就相當于平衡了。因此只有P項時,會輸出一條直線。
當P = 5時,如下圖:
此時抖動比較大,不過最終還會趨近直線。這里抖動大,也說明響應速度快,對比增量式PID調節方法,增量式PID調節P時,是將系統在目標值附近抖動兩三下之后迅速穩定下來為最佳,我們這里也可以這樣來調節,只不過增量式是趨近于目標值,而位置式是趨近于一條直線。
這里我們選擇P=3,如下圖:
我們看上圖抖動兩三下就可以趨近于一條直線,說明這個P差不多可以了。
當P = 3時,調節I,當P = 3 ,I = 1時如下圖:
你會發現曲線會越過目標值,因為加入了歷史誤差,在第一次未達到目標值期間,累積誤差都是為正的,再加上P,使得系統超過目標值。當采樣值超過目標之后,累積誤差就會出現負值,將會抵消一部分前面的正值誤差,因此會出現不對稱的情況。之前只有P時,直線上下震動的賦值是對稱的,加入累積誤差之后,圖中橫線是目標值,在目標值上方的誤差值都為正(因為都是小于目標值,誤差=目標值-當前值>0),說明大多數情況都是未能達到目標值。因此系統會慢慢將這些正的誤差值加起來代入到系統,會使得系統慢慢趨近于目標值,而不是像上面一樣形成一條直線。
當P = 3 ,I = 2時如下圖:
你會發現,斜線更抖了,因為I的作用增強了,響應更快了。
加入D,當P = 3 ,I = 2,D = -0.1時如下圖:曲線變得很平順了,沒有上一張圖中的抖動了,這個效果還是不錯的。
加入D,當P = 3 ,I = 2,D = -2時如下圖:D大了會出現回彈,說明D抑制的太過了。
因此當P = 3 ,I = 2,D = -0.1使得整體效果最佳。至此,PID完結。
|
|