PID控制器改进笔记之六:改进PID控制器之参数设定
??前面我們發(fā)布了一系列PID控制器相關(guān)的文章,包括經(jīng)典PID控制器以及參數(shù)自適應(yīng)的PID控制器。這一系列PID控制器雖說(shuō)實(shí)現(xiàn)了主要功能,也在實(shí)際使用中取得了良好效果,但還有很多的細(xì)節(jié)部分可以改進(jìn)以提高性能和靈活性。這篇中我們來(lái)討論改進(jìn)PID控制器參數(shù)設(shè)置的問(wèn)題。
1、問(wèn)題提出
??在前面的文章中我們?cè)茖?dǎo)過(guò)PID控制器的公式,并且對(duì)其進(jìn)行了離散化以適用于程序?qū)崿F(xiàn),具體的離散化公式如下:
??在編寫程序時(shí),我們將比例項(xiàng)的系數(shù)設(shè)定為Kp、積分項(xiàng)的系數(shù)設(shè)定為Ki、微分項(xiàng)的系數(shù)設(shè)定為Kd,其中:
??這其中T是采樣周期,Ti是積分時(shí)間,Td是微分時(shí)間。所以在設(shè)置參數(shù)的時(shí)候我們需要先去頂比例系數(shù)Kp,然后在根據(jù)采樣周期和積分微分時(shí)間來(lái)計(jì)算Ki和Kd。這么做雖然是公式變得簡(jiǎn)單了,但與我們傳統(tǒng)的參數(shù)設(shè)置相比就顯得不那么直觀,所以有些使用者希望還是以傳統(tǒng)的比例帶PB、積分時(shí)間Ti、微分時(shí)間Td來(lái)配置相應(yīng)的參數(shù),這一篇中就來(lái)分析并解決這個(gè)問(wèn)題。
2、分析設(shè)計(jì)
??對(duì)于上述這個(gè)問(wèn)題,我們需要搞清楚Kp、Ki、Kd與PB、Ti、Td之間的關(guān)系。事實(shí)上,它們之間的關(guān)系并不復(fù)雜。首先比例系數(shù)Kp與比例帶之間是互為倒數(shù)的關(guān)系,所以我們知道了其中一個(gè)就可以得到另一個(gè)。而Ti和Ki的關(guān)系以及Td和Kd的關(guān)系我們前面已經(jīng)給出了。
接下來(lái)我們需要做的事,實(shí)際上就是讓我們的PID控制器在不同的應(yīng)用需求下呈現(xiàn)出不同的參數(shù)設(shè)置就可以設(shè)置不同的參數(shù)形式了。
3、軟件實(shí)現(xiàn)
??我們已經(jīng)分析了需要實(shí)現(xiàn)的內(nèi)容,接下來(lái)我們就來(lái)考慮怎么實(shí)現(xiàn)。關(guān)于這一點(diǎn),我們考慮我們的PID控制器的設(shè)計(jì)形式,需要修改的主要是三個(gè)方面的內(nèi)容。第一個(gè)需要修改的地方就是PID控制器對(duì)象的定義。我們定義一個(gè)宏來(lái)實(shí)現(xiàn)條件編譯,以實(shí)現(xiàn)在不同的需求下實(shí)現(xiàn)不同的參數(shù)定義,所以我們實(shí)現(xiàn)PID控制器的對(duì)象類型定義如下:
/*定義PID對(duì)象類型*/ typedef struct CLASSIC {float *pPV; //測(cè)量值指針float *pSV; //設(shè)定值指針float *pMV; //輸出值指針uint16_t *pMA; //手自動(dòng)操作指針\#if PID_PARAMETER_STYLE > (0)float *pKp; //比例系數(shù)指針float *pKi; //積分系數(shù)指針float *pKd; //微分系數(shù)指針 \#elsefloat *pPb; //比例帶float *pTi; //積分時(shí)間,單位為秒float *pTd; //微分時(shí)間,單位為秒float ts; //采樣周期,單位為秒 \#endiffloat setpoint; //設(shè)定值float lasterror; //前一拍偏差float preerror; //前兩拍偏差float deadband; //死區(qū)float result; //PID控制器計(jì)算結(jié)果float output; //輸出值0-100%float maximum; //輸出值上限float minimum; //輸出值下限float errorabsmax; //偏差絕對(duì)值最大值float errorabsmin; //偏差絕對(duì)值最小值float alpha; //不完全微分系數(shù)float deltadiff; //微分增量float integralValue; //積分累計(jì)量float gama; //微分先行濾波系數(shù)float lastPv; //上一拍的過(guò)程測(cè)量值float lastDeltaPv; //上一拍的過(guò)程測(cè)量值增量ClassicPIDDRType direct; //正反作用ClassicPIDSMType sm; //設(shè)定值平滑ClassicPIDCSType cas; //串級(jí)設(shè)定}CLASSICPID;??我們定義了對(duì)象類型,可以得到我們需要的對(duì)象變量,但這個(gè)對(duì)象變量需要初始化才能使用。所以第二個(gè)需要修改的地方就是PID控制器對(duì)象初始化函數(shù)。我們使用條件編譯,在不同的應(yīng)用需求下我們初始化不同的對(duì)象參數(shù),具體實(shí)現(xiàn)如下:
/* PID初始化操作,需在對(duì)vPID對(duì)象的值進(jìn)行修改前完成 */ /* CLASSICPID vPID,普通PID對(duì)象變量,實(shí)現(xiàn)數(shù)據(jù)交換與保存 */ /* float vMax,float vMin,過(guò)程變量的最大最小值(量程范圍) */ void PIDParaInitialization(CLASSICPID *vPID, //PID控制器對(duì)象float *pPV, //測(cè)量值指針float *pSV, //設(shè)定值指針float *pMV, //輸出值指針\#if PID_PARAMETER_STYLE > (0)float *pKp, //比例系數(shù)指針float *pKi, //積分系數(shù)指針float *pKd, //微分系數(shù)指針 \#elsefloat *pPb; //比例帶float *pTi; //積分時(shí)間float *pTd; //微分時(shí)間float ts, //采樣周期,單位為秒 \#endifuint16_t *pMA, //手自動(dòng)操作指針float vMax, //控制變量量程float vMin, //控制變量的零點(diǎn)ClassicPIDDRType direct, //正反作用ClassicPIDSMType sm, //設(shè)定值平滑ClassicPIDCSType cas //串級(jí)設(shè)定) {if((vPID==NULL)||(pPV==NULL)||(pSV==NULL)||(pMV==NULL)||(pMA==NULL)){return;}vPID->pPV=pPV;vPID->pSV=pSV;vPID->pMV=pMV;vPID->pMA=pMA;\#if PID_PARAMETER_STYLE > (0)if((pKp==NULL)||(pKi==NULL)||(pKd==NULL)){return;}vPID->pKp=pKp;vPID->pKi=pKi;vPID->pKd=pKd;if(*vPID->pKp<=0.00001){*vPID->pKp=1.0; //比例系數(shù)*vPID->pKi=0.01; //積分系數(shù)*vPID->pKd=0.01; //微分系數(shù)} \#elseif((pPb==NULL)||(pTi==NULL)||(pTd==NULL)){return;}vPID->pPb=pPb;vPID->pTi=pTi;vPID->pTd=pTd;vPID->ts=ts;if(*vPID->pPb<=0.00001){*vPID->pPb=1.0; //比例帶*vPID->pTi=1.0; //積分時(shí)間,單位為秒*vPID->pTd=0.0001; //微分時(shí)間,單位為秒} \#endifvPID->maximum=vMax; //控制變量的量程vPID->minimum=vMin; //控制變量的零點(diǎn)*vPID->pSV=*pPV; //設(shè)定值vPID->setpoint=*pPV; //設(shè)定值*vPID->pMA=1; //初始化為自動(dòng)模式vPID->direct=direct; //設(shè)定PID對(duì)象的正反作用vPID->cas=cas; //設(shè)定是否啟用串級(jí)vPID->sm=sm; //設(shè)定是否啟用設(shè)定值平滑if(vPID->cas==CASCADE){vPID->sm=SMOOTH_DISABLE;}vPID->lasterror=0.0; //前一拍偏差vPID->preerror=0.0; //前兩拍偏差vPID->result=vMin; //PID控制器結(jié)果vPID->output=0.0; //輸出值,百分比*vPID->pMV=vPID->output; //輸出值,百分比vPID->errorabsmax=(vMax-vMin)*0.9;vPID->errorabsmin=(vMax-vMin)*0.1;vPID->deadband=(vMax-vMin)*0.001; //死區(qū)vPID->alpha=0.2; //不完全微分系數(shù)vPID->deltadiff=0.0; //微分增量vPID->integralValue=0.0;}??第三個(gè)需要修改的是PID控制器對(duì)象的實(shí)現(xiàn)。在前面我們已經(jīng)描述PB、Ti、Td與Kp、Ki、Kd之間的數(shù)學(xué)關(guān)系。為了方便處理,我們通過(guò)條件編譯在不同應(yīng)用需求下將參數(shù)均轉(zhuǎn)化為統(tǒng)一的Kp、Ki、Kd來(lái)進(jìn)行計(jì)算。具體的實(shí)現(xiàn)方式如下:
/* 通用PID控制器,采用增量型算法,具有變積分,梯形積分和抗積分飽和功能 */ /* 微分項(xiàng)采用不完全微分,一階濾波,alpha值越大濾波作用越強(qiáng) */ /* CLASSICPID vPID,PID對(duì)象變量,實(shí)現(xiàn)數(shù)據(jù)交換與保存 */ /* float pv,過(guò)程測(cè)量值,對(duì)象響應(yīng)的測(cè)量數(shù)據(jù),用于控制反饋 */ void PIDRegulator(CLASSICPID *vPID) {float thisError;float result;float factor;float increment;float pError,dError,iError;float kp,ki,kd;\#if PID_PARAMETER_STYLE > (0)kp=*vPID->pKp;ki=*vPID->pKi;kd=*vPID->pKd; \#elseif((*vPID->pTi)<vPID->ts){*vPID->pTi=vPID->ts;}kp=1/(*vPID->pPb);ki=kp*(vPID->ts/(*vPID->pTi));kd=kp*((*vPID->pTd)/vPID->ts); \#endifif(*vPID->pMA<1) //手動(dòng)模式{vPID->output=*vPID->pMV;//設(shè)置無(wú)擾動(dòng)切換vPID->result=(vPID->maximum-vPID->minimum)*vPID->output/100.0+vPID->minimum;*vPID->pSV=*vPID->pPV;vPID->setpoint=*vPID->pSV;}else //自動(dòng)模式{if(vPID->sm==SMOOTH_ENABLE) //設(shè)定值平滑變化{SmoothSetpoint(vPID);}else{if(vPID->cas==CASCADE) //串級(jí)處理{vPID->setpoint=(vPID->maximum-vPID->minimum)*(*vPID->pSV)/100.0+vPID->minimum;}else{vPID->setpoint=*vPID->pSV;}}thisError=vPID->setpoint-(*vPID->pPV); //得到偏差值result=vPID->result;if (fabs(thisError)>vPID->deadband){pError=thisError-vPID->lasterror;iError=(thisError+vPID->lasterror)/2.0;dError=thisError-2*(vPID->lasterror)+vPID->preerror;//變積分系數(shù)獲取factor=VariableIntegralCoefficient(thisError,vPID->errorabsmax,vPID->errorabsmin);//計(jì)算微分項(xiàng)增量帶不完全微分vPID->deltadiff=kd*(1-vPID->alpha)*dError+vPID->alpha*vPID->deltadiff;increment=kp*pError+ki*factor*iError+vPID->deltadiff; //增量計(jì)算}else{if((fabs(vPID->setpoint-vPID->minimum)<vPID->deadband)&&(fabs((*vPID->pPV)-vPID->minimum)<vPID->deadband)){result=vPID->minimum;}increment=0.0;}//正反作用設(shè)定if(vPID->direct==DIRECT){result=result+increment;}else{result=result-increment;}/*對(duì)輸出限值,避免超調(diào)和積分飽和問(wèn)題*/if(result>=vPID->maximum){result=vPID->maximum;}if(result<=vPID->minimum){result=vPID->minimum;} vPID->preerror=vPID->lasterror; //存放偏差用于下次運(yùn)算vPID->lasterror=thisError;vPID->result=result;vPID->output=(vPID->result-vPID->minimum)/(vPID->maximum-vPID->minimum)*100.0;*vPID->pMV=vPID->output;} }4、總結(jié)
??在這一篇中,我們只是為了實(shí)現(xiàn)不同使用者的需求,將PID控制器的參數(shù)定義做了相應(yīng)的修改,而控制器本身的功能并沒(méi)有什么變化。這樣既保證原有的應(yīng)用不會(huì)受到影響,新的應(yīng)用也可以根據(jù)需要定義參數(shù),使用Kp、Ki、Kd或是PB、Ti、Td由應(yīng)用設(shè)計(jì)的需要選擇。
??這里需要說(shuō)一下,不論我們?nèi)绾味x參數(shù),采樣周期的選擇都需要認(rèn)真考慮。即使我們采用相同的參數(shù)整定,當(dāng)采樣周期不同時(shí),效果可能會(huì)有較大差異,所以在整定參數(shù)前應(yīng)根據(jù)系統(tǒng)的特性采用合適的采樣周期。
歡迎關(guān)注:
總結(jié)
以上是生活随笔為你收集整理的PID控制器改进笔记之六:改进PID控制器之参数设定的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: cad里面f命令用不了_CAD出现命令无
- 下一篇: 一文带你读懂计算机进制