日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

PID控制器改进笔记之一:改进PID控制器之参数动态调整

發(fā)布時(shí)間:2024/7/23 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PID控制器改进笔记之一:改进PID控制器之参数动态调整 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前面我們發(fā)布了一系列PID控制器相關(guān)的文章,包括經(jīng)典PID控制器以及參數(shù)自適應(yīng)的PID控制器。這一系列PID控制器雖說實(shí)現(xiàn)了主要功能,也在實(shí)際使用中取得了良好效果,但還有很多的細(xì)節(jié)部分可以改進(jìn)以提高性能和靈活性。所以在這篇中我們來討論改進(jìn)PID控制器以實(shí)現(xiàn)動態(tài)調(diào)整參數(shù)的目的。

1、提出問題

在我們一開始開發(fā)PID控制器時(shí),我們主要是關(guān)注于其算法的實(shí)現(xiàn)而沒有過多的關(guān)心其使用過程。但在我們的使用過程中發(fā)現(xiàn)有些不夠靈活的地方。

在原有的PID控制器中,設(shè)定值是通過在外部給PID對象的參數(shù)賦值實(shí)現(xiàn)的,雖然說并不影響使用,但我們?nèi)粝雽ID控制器中的參數(shù)設(shè)定值進(jìn)行某些處理就不是很方便了。而在原有的PID控制器中,輸出值在外部是不可見的,只能通過PID對象查看且不可更改。這些使得對這些參數(shù)的操作顯得不夠靈活。

而且在原有的PID控制器中3個(gè)調(diào)節(jié)參數(shù)也不能在外部隨時(shí)調(diào)整,這顯然不符合很多應(yīng)用的需要,因?yàn)镻ID參數(shù)的調(diào)整是很常見的工作。所以在這篇中我們來考慮實(shí)現(xiàn)這些參數(shù)的動態(tài)調(diào)整。

2、分析設(shè)計(jì)

為了使得PID控制器使用起來更為靈活,我們需要將PID對象作必要的改動。關(guān)于PID對象我們考慮將測量值、設(shè)定值、輸出值作為對象的屬性。但我們不是直接將這幾個(gè)變量作為對象屬性,因?yàn)檫@樣達(dá)不到我們從外部靈活操作的目的,我們將幾個(gè)指向浮點(diǎn)變量的指針作為對象的屬性,而初始化后這幾個(gè)指針將指向我們的測量值、設(shè)定值、輸出值變量。

同樣的三個(gè)PID參數(shù)我們想要在外部修改它,我們也將其在外部定義為變量,而在PID對象中定義為指向這三個(gè)變量的浮點(diǎn)數(shù)指針。在對對象進(jìn)行初始化時(shí),我們將變量地址賦值給這幾個(gè)指針。據(jù)此我們定義PID對象類型為:

/*定義結(jié)構(gòu)體和公用體*/ typedef struct CLASSIC {float *pPV;?????????????????? //測量值指針float *pSV;?????????????????? //設(shè)定值指針float *pMV;?????????????????? //輸出值指針float *pKp;?????????????????? //比例系數(shù)指針float *pKi;?????????????????? //積分系數(shù)指針float *pKd;?????????????????? //微分系數(shù)指針float setpoint;?????????????? //設(shè)定值float lasterror;????????????? //前一拍偏差float preerror;?????????????? //前兩拍偏差float deadband;?????????????? //死區(qū)float result;???????????????? //PID控制器計(jì)算結(jié)果float output;???????????????? //輸出值0-100%float maximum;??????????????? //輸出值上限float minimum;??????????????? //輸出值下限float errorabsmax;??????????? //偏差絕對值最大值float errorabsmin;??????????? //偏差絕對值最小值float alpha;????????????????? //不完全微分系數(shù)float deltadiff;????????????? //微分增量float integralValue;????????? //積分累計(jì)量float gama;?????????????????? //微分先行濾波系數(shù)float lastPv;???????????????? //上一拍的過程測量值float lastDeltaPv;??????????? //上一拍的過程測量值增量 }CLASSICPID;

3、軟件實(shí)現(xiàn)

我們計(jì)劃將PID參數(shù)和過程變量改成指向浮點(diǎn)型變量的指針,那么代碼上需要做哪些修改呢?需要修改的主要是兩個(gè)函數(shù):PID調(diào)節(jié)函數(shù)和PID對象初始化函數(shù)。

首先,我們來看一看PID對象的初始化函數(shù)。我們知道將這些變量修改為指向浮點(diǎn)變量法的指針后,我們就必須在初始化時(shí)指定具體的變量地址,否則指向的將是不可預(yù)知的位置。所以我們修改初始化函數(shù)如下:

/* PID初始化操作,需在對vPID對象的值進(jìn)行修改前完成 */ void PIDParaInitialization(CLASSICPID *vPID,??? //PID控制器對象float *pPV,????????? //測量值指針float *pSV,????????? //設(shè)定值指針float *pMV,????????? //輸出值指針float *pKp,????????? //比例系數(shù)指針float *pKi,???????? ?//積分系數(shù)指針float *pKd,????????? //微分系數(shù)指針float vMax,????????? //控制變量量程float vMin,????????? //控制變量的零點(diǎn)) {if((vPID==NULL)||(pPV==NULL)||(pSV==NULL)||(pMV==NULL)||(pKp==NULL)||(pKi==NULL)||(pKd==NULL)){return;}vPID->pPV=pPV;vPID->pSV=pSV;vPID->pMV=pMV;vPID->pKp=pKp;vPID->pKi=pKi;vPID->pKd=pKd;vPID->maximum=vMax;??????????????? /*輸出值上限*/vPID->minimum=vMin;??????????????? /*輸出值下限*/vPID->setpoint=*pPV;?????????????? /*設(shè)定值*/vPID->lasterror=0.0;????????????? /*前一拍偏差*/vPID->preerror=0.0;?????????????? /*前兩拍偏差*/vPID->result=vMin;??????????????? /*PID控制器結(jié)果*/vPID->output=0.0;???????????????? /*輸出值,百分比*/vPID->errorabsmax=(vMax-vMin)*0.8;vPID->errorabsmin=(vMax-vMin)*0.2;vPID->deadband=(vMax-vMin)*0.0005;?????????????? /*死區(qū)*/vPID->alpha=0.2;????????????????? /*不完全微分系數(shù)*/vPID->deltadiff=0.0; ?????????????? /*微分增量*/vPID->integralValue=0.0;vPID->mode=mode; }

其次,我們還需要修改PID調(diào)節(jié)函數(shù)。在原來的PID調(diào)節(jié)器中過程值是作為函數(shù)的參數(shù)輸入的,而且PID參數(shù)是作為變量存在于對象內(nèi)部的,所以要針對這兩個(gè)方面做相應(yīng)的修改:

/* 通用PID控制器,采用增量型算法,具有變積分,梯形積分和抗積分飽和功能,微分項(xiàng)采用不完全微分,一階濾波,alpha值越大濾波作用越強(qiáng)??????????????????? */ void PIDRegulator(CLASSICPID *vPID) {float thisError;float result;float factor;float increment;float pError,dError,iError;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=(*vPID->pKd)*(1-vPID->alpha)*dError+vPID->alpha*vPID->deltadiff;increment=(*vPID->pKp)*pError+(*vPID->pKi)*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;}result=result+increment;/*對輸出限值,避免超調(diào)和積分飽和問題*/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é)

我們將PID參數(shù)和過程變量都改為了對象所包含的指針,這樣當(dāng)我們從上位機(jī)或者其他進(jìn)程修改變量的值時(shí),也同步修改了PID對象中的值。測試的結(jié)果比原來的方式操作更為方便。

歡迎關(guān)注:

總結(jié)

以上是生活随笔為你收集整理的PID控制器改进笔记之一:改进PID控制器之参数动态调整的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。