前言
在剛接觸到PID控制器的時(shí)候,我對(duì)增量式,位置式這些其實(shí)也是很懵的,然后又有什么速度環(huán)啊,位置環(huán)啊,電流環(huán)啊…巴拉巴拉一堆的,但是現(xiàn)在理解起來其實(shí)也就利用一些簡(jiǎn)簡(jiǎn)單單的離散數(shù)據(jù)運(yùn)算出期望罷了。
首先假設(shè)我們已經(jīng)知道了什么是Kp、Ki、Kd了(不知道的話那就看看我上一篇講PID的那個(gè)文章)。
關(guān)于PID的算法可以分為兩大類,一類是位置式,還有一類是增量式,下面就開始說說我對(duì)這兩種算法的理解。
位置式PID
首先是位置式,也是我用得最多的一種算法。位置式PID其實(shí)就是當(dāng)前系統(tǒng)實(shí)際位置,與你期望想要達(dá)到的位置的偏差而進(jìn)行的PID控制。那么一個(gè)用位置式的系統(tǒng)中是什么樣的呢?
看公式來理解:
U k = K p ? e k + K i ∑ j = 0 k e k + K d ( e k ? e k ? 1 ) U_k= K_p*e_k+K_i\sum^k_{j=0}e_k+K_d(e_k-e_{k-1}) Uk?=Kp??ek?+Ki?∑j=0k?ek?+Kd?(ek??ek?1?)
由上式可以看出,PID的每次運(yùn)算的輸出都與過去的狀態(tài)有關(guān),并且積分項(xiàng)的誤差會(huì)進(jìn)行累加。如果偏差一直都是正的或者是負(fù)的,位置式PID在積分項(xiàng)就會(huì)一直累積,當(dāng)偏差開始反向變化的時(shí)候,位置式PID需要一段時(shí)間才能從最大值減下來,會(huì)造成位置PID控制輸出的滯后。所以我們還需要對(duì)積分項(xiàng)進(jìn)行限幅(做一個(gè)最大值max和最小值min),同時(shí)也要對(duì)輸出進(jìn)行限幅。同時(shí),我們輸出的 U k U_k Uk?對(duì)應(yīng)的是執(zhí)行機(jī)構(gòu)的實(shí)際位置,一旦控制輸出出錯(cuò)了,也就是說我們控制的對(duì)象當(dāng)前的狀態(tài)值出現(xiàn)了問題, U k U_k Uk?的大幅度變化就會(huì)影響到系統(tǒng)的大幅度變化。
所以我們?nèi)绻麊螁问褂梦恢檬絇ID的時(shí)候,一般都是直接使用PD控制的,也正因?yàn)檫@樣,位置式PID是用于執(zhí)行機(jī)構(gòu)不帶積分部件的對(duì)象,像平衡車的直立控制呀、溫控系統(tǒng)呀…等等。
下面是代碼實(shí)現(xiàn):
#define HAVE_PID_INTEGRAL
#define LIMIT(TargetValue, LimitValue) \
if (TargetValue > LimitValue)\
{\
TargetValue = LimitValue;\
}\
else if (TargetValue < -LimitValue)\
{\
TargetValue = -LimitValue;\
}\
typedef struct{
float Kp;
float Ki;
float Kd;
#ifdef HAVE_PID_INTEGRAL
int index; // 積分分離系數(shù)
float Integral; // 積分項(xiàng)
float I_outputMax; // 積分限幅
#endif
float Last_Err; // 上次誤差
float Output; // PID輸出
float OutputMax; // 位置式PID輸出限幅
}Position_PID;
void PositionPID_Calculate(Position_PID *pid,const float Target,const float Measure)
{
if(pid == NULL)
return;
float Err;
Err = Target - Measure;
pid->Output = pid->Kp * Err + pid->Kd * (Err - pid->Last_Err)
#ifdef HAVE_PID_INTEGRAL
/* 積分分離 */
if(abs(pid->Err) > Integraldead_zone)
{
pid->index=0;
}else
{
pid->index = 1;
}
pid->Integral += pid->Ki * Err * pid->index;
LIMIT(pid->Integral,I_outputMax);
pid->Output += pid->Integral;
#endif
LIMIT(Output,OutputMax);
pid->Last_Err = Err;
}
優(yōu)點(diǎn):
位置式是一種非遞推式算法,可以直接控制對(duì)象,U(k)的值與對(duì)象的實(shí)際當(dāng)量是一一對(duì)應(yīng)的,所以在不帶積分部件的控制對(duì)象中可以很好應(yīng)用。
缺點(diǎn):文章來源地址http://www.zghlxwxcb.cn/news/detail-849926.html
每次輸出都與之前的狀態(tài)有關(guān),并且還要對(duì)誤差值err進(jìn)行累加,計(jì)算量大。
增量式PID
那么什么是增量式PID呢?增量式PID的輸出只是控制量的增量 Δ U k \Delta U_k ΔUk?。當(dāng)執(zhí)行機(jī)構(gòu)需要的控制量是增量,那么我們就可以采用增量式PID控制算法進(jìn)行控制。(增量式PID的計(jì)算輸出結(jié)果是增量,并不是直接作用到執(zhí)行機(jī)構(gòu))
(增量式PID可以由位置式推導(dǎo)出,感興趣的可以百度,這里就不浪費(fèi)篇幅了。)
看公式來理解:
Δ U k = K p ( e ( k ) ? e ( k ? 1 ) ) + K i e ( k ) + K D [ e ( k ) ? 2 e ( k ? 1 ) + e ( k ? 2 ) ] \Delta U_k=K_p(e(k)-e(k-1))+K_i{e(k)}+K_D[e(k)-2e(k-1)+e(k-2)] ΔUk?=Kp?(e(k)?e(k?1))+Ki?e(k)+KD?[e(k)?2e(k?1)+e(k?2)]
對(duì)于增量式PID來說,給定一個(gè)輸入量,系統(tǒng)反饋回來的量與設(shè)定的量的偏差為Err,系統(tǒng)中保存上一次的偏差Last_Err和上上次的偏差Previous_Err,這三個(gè)輸入量經(jīng)過增量式PID可以計(jì)算得到上述說的控制量增量 Δ U k \Delta U_k ΔUk?。而得出的控制量 Δ U ( k ) \Delta U(k) ΔU(k)對(duì)應(yīng)的是近幾次位置誤差的增量,而不是對(duì)應(yīng)與實(shí)際位置的偏差,也就是說沒有誤差累加。即在上一次的控制量的基礎(chǔ)上需要增加控制量。
以下是代碼實(shí)現(xiàn):
#define LIMIT(TargetValue, LimitValue) \
if (TargetValue > LimitValue)\
{\
TargetValue = LimitValue;\
}\
else if (TargetValue < -LimitValue)\
{\
TargetValue = -LimitValue;\
}\
#define Integraldead_zone 100 // 積分死區(qū) 根據(jù)自己的需求定義
typedef struct{
float Kp;
float Ki;
float Kd;
float p_out;
float i_out;
float d_out;
float Err;
float Last_Err; // 上次誤差
float Previous_Err; // 上上次誤差
float Output;
float OutputMax; // 增量式式PID輸出限幅
}Incremental_PID;
void IncrementalPID_Calculate(Incremental_PID *pid,const float Target,const float Measure)
{
if(pid == NULL)
return;
pid->Err = Target - Measure;
pid->p_out = pid->Kp * (Err - Last_Err);
pid->i_out = pid->Ki * Err;
pid->d_out = pid->Kd * (Err - 2.0f*Last_Err + Previous_Err);
pid->Output += p_out + i_out + d_out;
LIMIT(pid->Output, pid->OutputMax); // 限幅
pid->Previous_Err = pid->Last_Err;
pid->Last_Err = Err;
}
優(yōu)點(diǎn):文章來源:http://www.zghlxwxcb.cn/news/detail-849926.html
- 系統(tǒng)在誤動(dòng)作時(shí)影響小,并且可以利用邏輯判斷來對(duì)錯(cuò)誤數(shù)據(jù)進(jìn)行去除。
- 沖激小,便于實(shí)現(xiàn)無擾動(dòng)切換。
- 不需要累加誤差值,并且控制增量的確定只與最近幾次采樣值有關(guān)。
缺點(diǎn):
- 積分的階段效應(yīng)大,有穩(wěn)態(tài)誤差。
- 溢出的影響大,有的被控對(duì)象用增量式不好。
總結(jié)(增量式與位置式的區(qū)別)
- 增量式算法不需要做累加,增量式PID求出來的是系統(tǒng)需要的增量,并且增量的確定僅與最近幾次偏差采樣值有關(guān),計(jì)算的誤差對(duì)控制量計(jì)算的影響比較小。與位置式相比的話,位置式就需要用到偏差的累加值(Ki*err),容易產(chǎn)生累計(jì)誤差。
- 增量式PID控制輸出的是控制量增量,沒有積分作用,所以該方法適用于帶積分部件的對(duì)象。而位置式PID適用于執(zhí)行機(jī)構(gòu)不帶積分部件的對(duì)象。
- 上面的代碼也很清楚的顯示了,位置式PID需要積分限幅和輸出限幅,而增量式PID只需要輸出限幅。
到了這里,關(guān)于PID的增量式與位置式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!