積分作用的引入是為了消除系統的靜差,提高控制精度。但是如果一個系統總是存在統一個方向的偏差,就可能無限累加而進而飽和,極大影響系統性能。抗積分飽和就是用以解決這一問題的方法之一。這一節我們就來實現抗積分飽和的PID算法。
1、抗積分飽和的基本思想
所謂積分飽和就是指系統存在一個方向的偏差,PID控制器的輸出由於積分作用的不斷累加而擴大,從而導致控制器輸出不斷增大超出正常范圍進入飽和區。當系統出現反響的偏差時,需要首先從飽和區退出,而不能對反向的偏差進行快速的響應。
為了解決積分飽和的問題,人們引入了抗積分飽和的PID算法。所謂抗積分飽和算法,其思路是在計算U(k)的時候,先判斷上一時刻的控制量U(k-1)是否已經超出了限制范圍。若U(k-1)>Umax,則只累加負偏差;若U(k-1)<Umin,則只累加正偏差。從而避免控制量長時間停留在飽和區。
2、算法實現
抗積分飽和的思想很簡單,解釋在控制器輸出的最大最小值附近限制積分的累積情況,以防止在恢復時沒有響應。根據前面得分系我們可以得到如下的流程圖:
(1)位置型PID算法實現
對於位置型PID的抗積分飽和算法其實就是在基本的PID基礎上加上抗積分飽和的操作,增加量個機鋒的極限值。首先定義PID對象的結構體:
1 /*定義結構體和公用體*/ 2 3 typedef struct 4 5 { 6 7 float setpoint; //設定值 8 9 float proportiongain; //比例系數 10 11 float integralgain; //積分系數 12 13 float derivativegain; //微分系數 14 15 float lasterror; //前一拍偏差 16 17 float result; //輸出值 18 19 float integral;//積分值 20 21 float maximum;//最大值 22 23 float minimum;//最小值 24 25 }PID;
接下來實現PID控制器:
1 void PIDRegulation(PID *vPID, float processValue) 2 3 { 4 5 float thisError; 6 7 thisError=vPID->setpoint-processValue; 8 9 if(vPID->result>vPID->maximum) 10 11 { 12 13 if(thisError<=0) 14 15 { 16 17 vPID->integral+=thisError; 18 19 } 20 21 } 22 23 else if(vPID->result<vPID->minimum) 24 25 { 26 27 if(thisError>=0) 28 29 { 30 31 vPID->integral+=thisError; 32 33 } 34 35 } 36 37 else 38 39 { 40 41 vPID->integral+=thisError; 42 43 } 44 45 46 47 vPID->result=vPID->proportiongain*thisError+vPID->integralgain*vPID->integral+vPID->derivativegain*(thisError-vPID->lasterror); 48 49 vPID->lasterror=thisError; 50 51 }
(2)增量型PID算法實現
增量型PID的抗積分飽和的實現也是一樣在最基本的增量型PID算法中引入極大極小的限值,並在算法中通過比較限值實現抗飽和的操作。
首先定義PID對象的結構體:
1 /*定義結構體和公用體*/ 2 3 typedef struct 4 5 { 6 7 float setpoint; //設定值 8 9 float proportiongain; //比例系數 10 11 float integralgain; //積分系數 12 13 float derivativegain; //微分系數 14 15 float lasterror; //前一拍偏差 16 17 float preerror; //前兩拍偏差 18 19 float deadband; //死區 20 21 float result; //輸出值 22 23 float maximum;//最大值 24 25 float minimum;//最小值 26 27 }PID;
接下來實現PID控制器:
1 void PIDRegulation(PID *vPID, float processValue) 2 3 { 4 5 float thisError; 6 7 float increment; 8 9 float pError,dError,iError; 10 11 12 13 thisError=vPID->setpoint-processValue; //得到偏差值 14 15 pError=thisError-vPID->lasterror; 16 17 iError=0; 18 19 dError=thisError-2*(vPID->lasterror)+vPID->preerror; 20 21 22 23 if(vPID->result>vPID->maximum) 24 25 { 26 27 if(thisError<=0) 28 29 { 30 31 iError=thisError; 32 33 } 34 35 } 36 37 else if(vPID->result<vPID->minimum) 38 39 { 40 41 if(thisError>=0) 42 43 { 44 45 iError=thisError; 46 47 } 48 49 } 50 51 else 52 53 { 54 55 iError=thisError; 56 57 } 58 59 increment=vPID->proportiongain*pError+vPID->integralgain*iError+vPID->derivativegain*dError; //增量計算 60 61 vPID->preerror=vPID->lasterror; //存放偏差用於下次運算 62 63 vPID->lasterror=thisError; 64 65 vPID->result+=increment; 66 67 }
3、總結
所謂抗積分飽和就是防止由於長期存在一個方向的偏差而對相反方向的偏差遲滯響應。本文的方法是在達到極值后將不再對這一方向的偏差做出反應相反只對另一方向的偏差做出反應。事實上由於偏差的存在有可能造成輸出值超限的情況,所以還需要對輸出值作出限制。
歡迎關注: