重溫經(jīng)典PID算法
2020-3-13新聞
PID算法可以說是在自動控制原理中比較經(jīng)典的一套算法,在現(xiàn)實(shí)生活中應(yīng)用的比較廣泛。
大學(xué)參加過電子競賽的朋友都應(yīng)該玩過電機(jī)(或者說循跡小車),我們要控制電機(jī)按照設(shè)定的速度運(yùn)轉(zhuǎn),PID控制在其中起到了關(guān)鍵的作用。
說來慚愧,大學(xué)這門課程學(xué)的不咋滴,老師講的課基本沒聽進(jìn)去過。直到后面接觸競賽,算是對PID有了很基礎(chǔ)的一點(diǎn)點(diǎn)認(rèn)識,直到現(xiàn)在工作實(shí)際應(yīng)用的比較廣泛才知道它的重要性。所以,這里特地回顧一下。
PID,即比例Proportion、積分Integral和微分Derivative三個單詞的縮寫。
閉環(huán)自動控制技術(shù)是基于反饋的概念以減少不確定性,在閉環(huán)自動控制原理中,我們把它叫做“PID控制器”,拿控制電機(jī)來說,參考下面模型:
下面引用一段網(wǎng)上經(jīng)典的話:
在工業(yè)應(yīng)用中PID及其衍生算法是應(yīng)用最廣泛的算法之一,是當(dāng)之無愧的萬能算法,如果能夠熟練掌握PID算法的設(shè)計(jì)與實(shí)現(xiàn)過程,對于一般的研發(fā)人員來講,應(yīng)該是足夠應(yīng)對一般研發(fā)問題了,而難能可貴的是,在我所接觸的控制算法當(dāng)中,PID控制算法又是最簡單,最能體現(xiàn)反饋思想的控制算法,可謂經(jīng)典中的經(jīng)典。經(jīng)典的未必是復(fù)雜的,經(jīng)典的東西常常是簡單的,而且是最簡單的,想想牛頓的力學(xué)三大定律吧,想想愛因斯坦的質(zhì)能方程吧,何等的簡單!簡單的不是原始的,簡單的也不是落后的,簡單到了美的程度。
常規(guī)的模擬 PID 控制系統(tǒng)原理框圖如下:
該系統(tǒng)由模擬 PID 控制器和被控對象組成。
上面框圖中, r(t) 是給定值, y(t) 是系統(tǒng)的實(shí)際輸出值,給定值與實(shí)際輸出值構(gòu)成控制偏差e(t) = r(t) ? y(t).
e(t) 作為 PID 控制的輸入, u(t)作為 PID 控制器的輸出和被控對象的輸入。 所以模擬 PID 控制器的控制規(guī)律為:
三個重要的參數(shù):
Kp:控制器的比例系數(shù).
Ti:控制器的積分時間,也稱積分系數(shù).
Td:控制器的微分時間,也稱微分系數(shù).
1、P - 比例部分
比例環(huán)節(jié)的作用是對偏差瞬間作出反應(yīng)。偏差一旦產(chǎn)生控制器立即產(chǎn)生控制作用, 使控制量向減少偏差的方向變化。 控制作用的強(qiáng)弱取決于比例系數(shù)Kp, 比例系數(shù)Kp越大,控制作用越強(qiáng), 則過渡過程越快, 控制過程的靜態(tài)偏差也就越??; 但是Kp越大,也越容易產(chǎn)生振蕩, 破壞系統(tǒng)的穩(wěn)定性。 故而, 比例系數(shù)Kp選擇必須恰當(dāng), 才能過渡時間少, 靜差小而又穩(wěn)定的效果。
2、I - 積分部分
從積分部分的數(shù)學(xué)表達(dá)式可以知道, 只要存在偏差, 則它的控制作用就不斷的增加; 只有在偏差e(t)=0時, 它的積分才能是一個常數(shù),控制作用才是一個不會增加的常數(shù)。 可見,積分部分可以消除系統(tǒng)的偏差。
積分環(huán)節(jié)的調(diào)節(jié)作用雖然會消除靜態(tài)誤差,但也會降低系統(tǒng)的響應(yīng)速度,增加系統(tǒng)的超調(diào)量。積分常數(shù)Ti越大,積分的積累作用越弱,這時系統(tǒng)在過渡時不會產(chǎn)生振蕩; 但是增大積分常數(shù)Ti會減慢靜態(tài)誤差的消除過程,消除偏差所需的時間也較長, 但可以減少超調(diào)量,提高系統(tǒng)的穩(wěn)定性。
當(dāng) Ti 較小時, 則積分的作用較強(qiáng),這時系統(tǒng)過渡時間中有可能產(chǎn)生振蕩,不過消除偏差所需的時間較短。所以必須根據(jù)實(shí)際控制的具體要求來確定Ti 。
3、D - 微分部分
實(shí)際的控制系統(tǒng)除了希望消除靜態(tài)誤差外,還要求加快調(diào)節(jié)過程。在偏差出現(xiàn)的瞬間,或在偏差變化的瞬間, 不但要對偏差量做出立即響應(yīng)(比例環(huán)節(jié)的作用), 而且要根據(jù)偏差的變化趨勢預(yù)先給出適當(dāng)?shù)募m正。為了實(shí)現(xiàn)這一作用,可在 PI 控制器的基礎(chǔ)上加入微分環(huán)節(jié),形成 PID 控制器。
微分環(huán)節(jié)的作用使阻止偏差的變化。它是根據(jù)偏差的變化趨勢(變化速度)進(jìn)行控制。偏差變化的越快,微分控制器的輸出就越大,并能在偏差值變大之前進(jìn)行修正。微分作用的引入, 將有助于減小超調(diào)量, 克服振蕩, 使系統(tǒng)趨于穩(wěn)定, 特別對髙階系統(tǒng)非常有利, 它加快了系統(tǒng)的跟蹤速度。但微分的作用對輸入信號的噪聲很敏感,對那些噪聲較大的系統(tǒng)一般不用微分, 或在微分起作用之前先對輸入信號進(jìn)行濾波。
PID 控制算法可以分為位置式 PID 和增量式 PID 控制算法。
兩者的區(qū)別:
(1)位置式PID控制的輸出與整個過去的狀態(tài)有關(guān),用到了誤差的累加值;而增量式PID的輸出只與當(dāng)前拍和前兩拍的誤差有關(guān),因此位置式PID控制的累積誤差相對更大;
(2)增量式PID控制輸出的是控制量增量,并無積分作用,因此該方法適用于執(zhí)行機(jī)構(gòu)帶積分部件的對象,如步進(jìn)電機(jī)等,而位置式PID適用于執(zhí)行機(jī)構(gòu)不帶積分部件的對象,如電液伺服閥。
(3)由于增量式PID輸出的是控制量增量,如果計(jì)算機(jī)出現(xiàn)故障,誤動作影響較小,而執(zhí)行機(jī)構(gòu)本身有記憶功能,可仍保持原位,不會嚴(yán)重影響系統(tǒng)的工作,而位置式的輸出直接對應(yīng)對象的輸出,因此對系統(tǒng)影響較大。
下面給出公式直接體現(xiàn)的C語言源代碼(請結(jié)合項(xiàng)目修改源代碼):
1.位置式PID
typedef struct
{
float Kp; //比例系數(shù)Proportional
float Ki; //積分系數(shù)Integral
float Kd; //微分系數(shù)Derivative
float Ek; //當(dāng)前誤差
float Ek1; //前一次誤差 e(k-1)
float Ek2; //再前一次誤差 e(k-2)
float LocSum; //累計(jì)積分位置
}PID_LocTypeDef;
/************************************************
函數(shù)名稱 : PID_Loc
功 能 : PID位置(Location)計(jì)算
參 數(shù) : SetValue ------ 設(shè)置值(期望值)
ActualValue --- 實(shí)際值(反饋值)
PID ----------- PID數(shù)據(jù)結(jié)構(gòu)
返 回 值 : PIDLoc -------- PID位置
作 者 : strongerHuang
*************************************************/
float PID_Loc(float SetValue, float ActualValue, PID_LocTypeDef *PID)
{
float PIDLoc; //位置
PID->Ek = SetValue - ActualValue;
PID->LocSum += PID->Ek; //累計(jì)誤差
PIDLoc = PID->Kp * PID->Ek + (PID->Ki * PID->LocSum) + PID->Kd * (PID->Ek1 - PID->Ek);
PID->Ek1 = PID->Ek; return PIDLoc;
}
2.增量式PID
typedef struct
{
float Kp; //比例系數(shù)Proportional
float Ki; //積分系數(shù)Integral
float Kd; //微分系數(shù)Derivative
float Ek; //當(dāng)前誤差
float Ek1; //前一次誤差 e(k-1)
float Ek2; //再前一次誤差 e(k-2)
}PID_IncTypeDef;
/************************************************
函數(shù)名稱 : PID_Inc
功 能 : PID增量(Increment)計(jì)算
參 數(shù) : SetValue ------ 設(shè)置值(期望值)
ActualValue --- 實(shí)際值(反饋值)
PID ----------- PID數(shù)據(jù)結(jié)構(gòu)
返 回 值 : PIDInc -------- 本次PID增量(+/-)
作 者 : strongerHuang
*************************************************/
float PID_Inc(float SetValue, float ActualValue, PID_IncTypeDef *PID)
{
float PIDInc; //增量
PID->Ek = SetValue - ActualValue;
PIDInc = (PID->Kp * PID->Ek) - (PID->Ki * PID->Ek1) + (PID->Kd * PID->Ek2);
PID->Ek2 = PID->Ek1;
PID->Ek1 = PID->Ek; return PIDInc;
}