PID控制器改进笔记之二:改进PID控制器之手自动切换
前面我們發(fā)布了一系列PID控制器相關(guān)的文章,包括經(jīng)典PID控制器以及參數(shù)自適應(yīng)的PID控制器。這一系列PID控制器雖說實現(xiàn)了主要功能,也在實際使用中取得了良好效果,但還有很多的細節(jié)部分可以改進以提高性能和靈活性。所以在這篇中我們來討論改進PID控制器以實現(xiàn)手自動的方便切換。
1、提出問題
PID控制器的效果是眾所周知的,但有些時候我們希望強制輸出某個值以查看執(zhí)行機構(gòu)的響應(yīng),或者有些時候我們希望直接指定執(zhí)行機構(gòu)的行為而不需要它隨時調(diào)整,在這些情況下我們該怎么做呢?
這個時候我們需要說明兩個定義。當(dāng)使用PID控制器自動調(diào)節(jié)時,我們稱之為自動操作;而如上述情況下我們直接指定控制器的輸出時,或者說直接指定執(zhí)行機構(gòu)的行為時,我們稱之為手動。很顯然為了實現(xiàn)前述的相應(yīng)操作,我們需要為PID控制器添加上手自動轉(zhuǎn)換功能。在這一篇中我們就來討論這個問題。
2、分析設(shè)計
現(xiàn)在我們需要考慮怎么來實現(xiàn)手自動轉(zhuǎn)換功能。首先我們需要在PID對象中添加一個屬性,這個屬性用于標(biāo)識PID控制器究竟是處于手動模式還是自動模式。為了方便在外部修改PID對象的手自動模式,我們設(shè)計一個指向uint16_t的指針類型。所以我們設(shè)計PID對象如下:
/*定義PID對象類型*/ typedef struct CLASSIC {float *pPV;?????????????????? //測量值指針float *pSV;?????????????????? //設(shè)定值指針float *pMV;?????????????????? //輸出值指針float *pKp;?????????????????? //比例系數(shù)指針float *pKi;?????????????????? //積分系數(shù)指針float *pKd;?????????????????? //微分系數(shù)指針uint16_t *pMA;??????????????? //手自動操作指針float setpoint;?????????????? //設(shè)定值float lasterror;????????????? //前一拍偏差float preerror;?????????????? //前兩拍偏差float deadband;?????????????? //死區(qū)float result;???????????????? //PID控制器計算結(jié)果float output;???????????????? //輸出值0-100%float maximum;??????????????? //輸出值上限float minimum;??????????????? //輸出值下限float errorabsmax;??????????? //偏差絕對值最大值float errorabsmin;??????????? //偏差絕對值最小值float alpha;????????????????? //不完全微分系數(shù)float deltadiff;????????????? //微分增量float integralValue;????????? //積分累計量float gama;?????????????????? //微分先行濾波系數(shù)float lastPv;???????????????? //上一拍的過程測量值float lastDeltaPv;??????????? //上一拍的過程測量值增量 }CLASSICPID;對于手自動操作,我們需要通過外部變量來賦值外,在初始化時我們將其默認初始化為自動模式,畢竟我們使用PID控制器的目的不是為了手動操作它。
3、軟件實現(xiàn)
我們?yōu)镻ID對象添加了手自動操作屬性,那么根據(jù)這個屬性我們需要對PID控制器進行哪些修改呢?我們考慮一下在自動狀態(tài)下和手動狀態(tài)下都需要做什么工作。
在自動狀態(tài)下沒有什么需要做的,就是讓PID控制器正常輸出就可以了。而在手動狀態(tài)下,我們要讓PID控制器的輸出為我們?nèi)藶榻o定的輸出。僅僅如此,自然是不行的。我們考慮一下,PID控制器由自動轉(zhuǎn)為手動時,可能會給系統(tǒng)有什么影響。事實上,我們由自動轉(zhuǎn)為手動時,只要不修改輸出,整個系統(tǒng)的狀態(tài)不會發(fā)生變化。但由手動切換到自動時,由于我們修改了輸出值,測量值也會跟著發(fā)生變化,在原有設(shè)定值的情況下,由手動轉(zhuǎn)為自動時必然會出現(xiàn)階躍干擾,為了避免這種情況我們在手動狀態(tài)下讓設(shè)定值跟隨到測量值以達到無擾動切換。據(jù)此,我們修改PID控制器代碼為:
/* 通用PID控制器,采用增量型算法,具有變積分,梯形積分和抗積分飽和功能,微分項采用不完全微分,一階濾波,alpha值越大濾波作用越強??????????????????? */ void PIDRegulator(CLASSICPID *vPID) {float thisError;float result;float factor;float increment;float pError,dError,iError;if(*vPID->pMA<1)????? //手動模式{vPID->output=*vPID->pMV;//設(shè)置無擾動切換vPID->result=(vPID->maximum-vPID->minimum)*vPID->output/100.0+-vPID->minimum;*vPID->pSV=*vPID->pPV;vPID->setpoint=*vPID->pSV;}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);//計算微分項增量帶不完全微分vPID->deltadiff=(*vPID->pKd)*(1-vPID->alpha)*dError+vPID->alpha*vPID->deltadiff;increment=(*vPID->pKp)*pError+(*vPID->pKi)*factor*iError+vPID->deltadiff;?? //增量計算}else{if((fabs(vPID->setpoint-vPID->minimum)<vPID->deadband)&&(fabs((*vPID->pPV)-vPID->minimum)<vPID->deadband)){result=vPID->minimum;}increment=0.0;}result=result+increment;/*對輸出限值,避免超調(diào)和積分飽和問題*/if(result>=vPID->maximum){result=vPID->maximum;}if(result<=vPID->minimum){result=vPID->minimum;}?vPID->preerror=vPID->lasterror;? //存放偏差用于下次運算vPID->lasterror=thisError;vPID->result=result;vPID->output=(vPID->result-vPID->minimum)/(vPID->maximum-vPID->minimum)*100.0;*vPID->pMV=vPID->output;} }4、總結(jié)
我們添加了手自動轉(zhuǎn)換功能,并在手動轉(zhuǎn)為自動時,做了無擾動切換的預(yù)置。經(jīng)測試效果與我們的預(yù)期一致。當(dāng)我們將PID控制器置為自動狀態(tài)時,我們通過修改設(shè)定值(SV)來實現(xiàn)對系統(tǒng)的影響。而當(dāng)我們將PID控制器置為手動狀態(tài)時,我們通過修改輸出值(MV)來實現(xiàn)對系統(tǒng)的影響。
歡迎關(guān)注:
總結(jié)
以上是生活随笔為你收集整理的PID控制器改进笔记之二:改进PID控制器之手自动切换的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AutoML 与 Bayesian Op
- 下一篇: wxPython做界面的适用性