?
在學(xué)習(xí) PID 算法的參數(shù)整定的時(shí)候,每一個(gè)系統(tǒng)的 PID系數(shù)是不通用的,在不同的系統(tǒng)中運(yùn)用同樣的 PID 系數(shù),其最終所體現(xiàn)的效果可能是相差可能甚遠(yuǎn)的,所以我們需要根據(jù)實(shí)際的系統(tǒng)進(jìn)行 PID 的參數(shù)整定(調(diào)參)。
? ? ?
01
采樣周期選擇
采樣周期指的是 PID 控制中實(shí)際值的采樣時(shí)間間隔,其越短,效果越趨于連續(xù),但對(duì)硬件資源的占用也越高。在實(shí)際的應(yīng)用中,我們可以使用理論或者經(jīng)驗(yàn)方法來(lái)確定采樣周期:
①理論方法:香農(nóng)采樣定理。 這個(gè)定理可以用來(lái)確定采樣周期可選擇的最大值,當(dāng)采樣周期超出了這個(gè)最大的允許范圍,我們所得到的信號(hào)就會(huì)失真,也就無(wú)法較好地還原信號(hào)了。
香農(nóng)采樣定理的具體原理我們不展開(kāi)介紹,感興趣的朋友可以去查找相關(guān)的資料,我們這里重點(diǎn)關(guān)注經(jīng)驗(yàn)方法。
②經(jīng)驗(yàn)方法:根據(jù)控制對(duì)象突變能力選擇。
假設(shè)電機(jī)當(dāng)前轉(zhuǎn)速為 20RPM,我們需要提高它的轉(zhuǎn)速到 30RPM,此電機(jī)的轉(zhuǎn)速在 1s 之內(nèi)最大可以突變 10RPM,如果我們每 1ms 采集一次電機(jī)轉(zhuǎn)速,那么每一次采集到的速度變化量最大為 10RPM / 1000 =0.01RPM。
很明顯,此時(shí)最大的變化量遠(yuǎn)遠(yuǎn)小于當(dāng)前的速度,對(duì)我們的 PID 控制效果并沒(méi)有明顯的提升,但是卻占用了很多的硬件資源,因此,我們需要根據(jù)控制對(duì)象的突變能力來(lái)選擇采樣周期。
02
PID參數(shù)整定方法
?
理論計(jì)算整定法:依據(jù)系統(tǒng)的數(shù)學(xué)模型,經(jīng)過(guò)理論計(jì)算確定 PID 參數(shù)。
這種方法是建立在理想化條件下的,其得到的參數(shù)不一定能夠直接使用,還需要結(jié)合經(jīng)驗(yàn)以及實(shí)際的系統(tǒng)進(jìn)行調(diào)整。
工程整定法:依靠工程經(jīng)驗(yàn),直接在控制系統(tǒng)的試驗(yàn)中進(jìn)行整定,此方法易于掌握,在實(shí)際調(diào)參中被廣泛采用。工程整定法包括:試湊法、臨界比例法和一般調(diào)節(jié)法。
注意:無(wú)論采用哪一種方法所得到的 PID 參數(shù),都需要在實(shí)際運(yùn)行中進(jìn)行最后調(diào)整與完善,因此,在 PID 參數(shù)整定中,最重要的就是經(jīng)驗(yàn)的積累。
①比例系數(shù):調(diào)節(jié)作用快,系統(tǒng)一出現(xiàn)偏差,調(diào)節(jié)器立即將偏差放大輸出
②積分系數(shù):積分系數(shù)的調(diào)節(jié)會(huì)改變輸入偏差對(duì)于系統(tǒng)輸出的影響程度。積分系數(shù)越大,消除靜差的時(shí)間越短,但是過(guò)大的積分系數(shù)則會(huì)導(dǎo)致系統(tǒng)出現(xiàn)超調(diào)現(xiàn)象,這在具有慣性的系統(tǒng)中尤為明顯。
③微分系數(shù):微分系數(shù)的調(diào)節(jié)是偏差變化量對(duì)于系統(tǒng)輸出的影響程度。微分系數(shù)越大,系統(tǒng)對(duì)于偏差量的變化越敏感,越能提前響應(yīng),進(jìn)而抑制超調(diào),但是過(guò)大的微分系數(shù)則會(huì)讓整個(gè)系統(tǒng)出現(xiàn)振蕩。
03
試湊法
3.1 內(nèi)容
結(jié)合系統(tǒng)的具體情況以及經(jīng)驗(yàn),先試湊幾組合理的 PID 系數(shù),同時(shí)需要觀察系統(tǒng)的曲線變化,確定每一個(gè)系數(shù)對(duì)于整個(gè)系統(tǒng)曲線的大致影響,然后再根據(jù)具體的曲線進(jìn)行調(diào)整。
3.2 調(diào)節(jié)思路
① 先是比例(P),再積分(I),最后是微分(D)
②按純比例系統(tǒng)整定比例系數(shù),使其得到比較理想的調(diào)節(jié)過(guò)程曲線,然后再把比例系數(shù)縮小 1.2 倍左右,將積分系數(shù)從小到大改變,使其得到較好的調(diào)節(jié)過(guò)程曲線
③ 在這個(gè)積分系數(shù)下重新改變比例系數(shù),再看調(diào)節(jié)過(guò)程曲線有無(wú)改善
④ 如果有改善,可將原整定的比例系數(shù)減少,改變積分系數(shù),這樣多次的反復(fù),就可得到合適的比例系數(shù)和積分系數(shù)
⑤ 如果存在外界的干擾,系統(tǒng)的穩(wěn)定性不好,可把比例、積分系數(shù)適當(dāng)減小,使系統(tǒng)足夠穩(wěn)定
⑥ 如果系統(tǒng)存在小幅度超調(diào),可以將整定好的比例系數(shù)和積分系數(shù)適當(dāng)減小,增大微分系數(shù),以得到超調(diào)量最小、調(diào)節(jié)作用時(shí)間最短的系統(tǒng)曲線。
04
臨界比例法
4.1 內(nèi)容
在閉環(huán)的控制系統(tǒng)里,將調(diào)節(jié)器置于純比例作用下,從小到大逐漸調(diào)節(jié)比例系數(shù),直到系統(tǒng)曲線出現(xiàn)等幅振蕩,再根據(jù)經(jīng)驗(yàn)公式計(jì)算參數(shù)。
4.2 調(diào)節(jié)思路
①將積分、微分系數(shù)置零,比例度取適當(dāng)值,平衡操作一段時(shí)間,使控制系統(tǒng)按純比例作用的方式投入運(yùn)行
②慢慢地增大比例系數(shù),細(xì)心觀察曲線的變化情況。如果控制過(guò)程的曲線波動(dòng)是衰減的,則把比例系數(shù)繼續(xù)增大;如果曲線波動(dòng)是發(fā)散的,則應(yīng)把比例系數(shù)減小,直至曲線波動(dòng)呈等幅振蕩,此時(shí)記下臨界比例系數(shù) δK 和臨界振蕩周期 Tk 的值
③根據(jù)記下的比例系數(shù)和周期,采用經(jīng)驗(yàn)公式,計(jì)算調(diào)節(jié)器的參數(shù)
? ?
05
一般調(diào)節(jié)法
5.1 內(nèi)容
這種方法針對(duì)一般的 PID 控制系統(tǒng)所以稱(chēng)之為一般調(diào)節(jié)法。
5.2 調(diào)節(jié)思路
①首先將積分、微分系數(shù)置零,使系統(tǒng)為純比例控制??刂茖?duì)象的值設(shè)定為系統(tǒng)允許的最大值的 60%~70%,接著逐漸增大比例系數(shù),直至系統(tǒng)出現(xiàn)振蕩; 此時(shí)再逐漸減小比例系數(shù),直至系統(tǒng)振蕩消失,然后記錄此時(shí)的比例系數(shù),并設(shè)定系統(tǒng)的比例系數(shù)為當(dāng)前值的 60%~70%
②確定比例系數(shù)后,設(shè)定一個(gè)較小的積分系數(shù),然后逐漸增大積分系數(shù),直至系統(tǒng)出現(xiàn)振蕩;此時(shí)在逐漸減小積分系數(shù),直至系統(tǒng)振蕩消失,然后記錄此時(shí)的積分系數(shù),并設(shè)定系統(tǒng)的積分系數(shù)為當(dāng)前值的 55%~65%
③微分系數(shù)一般不用設(shè)定,為 0 即可。若系統(tǒng)出現(xiàn)小幅度振蕩,并且通過(guò) PI 環(huán)節(jié)無(wú)法優(yōu)化,這可以采用與確定比例、積分系數(shù)相同的方法,微分系數(shù)取系統(tǒng)不振蕩時(shí)的 30%左右。
④ 系統(tǒng)空載、帶載聯(lián)調(diào),再對(duì) PID 參數(shù)進(jìn)行微調(diào),直至滿足要求 在使用PID時(shí),如果只使用一個(gè)參數(shù)是沒(méi)有意義,至少使用兩個(gè)參數(shù),并且P(比例項(xiàng))是必須要有的 雖然PID有三個(gè)參數(shù),但大多數(shù)情況下PID三個(gè)參數(shù)并不是都使用上的,一般會(huì)其中兩個(gè)來(lái)組合使用,比如PI組合用于追求穩(wěn)定的系統(tǒng),PD組合用于追求快速響應(yīng)的系統(tǒng) 當(dāng)然PID用于即追求穩(wěn)定又追求快速響應(yīng)的系統(tǒng),但是實(shí)際上PID參數(shù)越多越難調(diào),而且許多情況下兩個(gè)參數(shù)的效果已經(jīng)足夠了,所以我一般根據(jù)情況使用前兩個(gè)。
06
實(shí)際調(diào)參
從實(shí)際的 PID 系統(tǒng)曲線來(lái)理解 PID 各個(gè)系數(shù)的調(diào)節(jié)效果。
①先調(diào)整比例系數(shù),積分、微分系數(shù)設(shè)置為0,此時(shí)的系統(tǒng)只有比例環(huán)節(jié)參與控制,此時(shí)系統(tǒng)的曲線出現(xiàn)大幅振蕩。
?
首先確定硬件上是否出現(xiàn)了故障,例如電壓不穩(wěn)定、電機(jī)堵轉(zhuǎn)等,排除了這些之后,那就說(shuō)明比例系數(shù)調(diào)節(jié)的過(guò)大了,這個(gè)時(shí)候我們可以把比例系數(shù)慢慢地減小,并同時(shí)觀察曲線的變化。
②當(dāng)我們調(diào)小比例系數(shù)之后,曲線的大幅度振蕩現(xiàn)象消失,但是曲線依舊存在小幅度的超調(diào)現(xiàn)象,并且此時(shí)通過(guò)調(diào)節(jié)比例系數(shù)已經(jīng)無(wú)法優(yōu)化曲線。
?
此時(shí),我們可以慢慢地增大微分系數(shù),并同時(shí)觀察曲線的變化,從而找到最合適的參數(shù)。
增大微分系數(shù)之后,如果系統(tǒng)的曲線已經(jīng)較為理想,則說(shuō)明這個(gè)系統(tǒng)只需要比例和微分環(huán)節(jié)的控制。
③如果在純比例環(huán)節(jié)的控制下,系統(tǒng)的實(shí)際值始終達(dá)不到目標(biāo)值,存在靜態(tài)誤差。
?
?
此時(shí),可以逐漸增大積分系數(shù),并同時(shí)觀察曲線的變化,如果消除靜差的時(shí)間過(guò)長(zhǎng),則可以再適當(dāng)增大積分系數(shù),但是需要注意兼顧系統(tǒng)的超調(diào)量。
經(jīng)過(guò)調(diào)整之后,如果系統(tǒng)的曲線已經(jīng)較為理想,則說(shuō)明這個(gè)系統(tǒng)只需要比例和積分環(huán)節(jié)的控制。
④如果系統(tǒng)在比例和積分環(huán)節(jié)的控制下出現(xiàn)小幅度的超調(diào)現(xiàn)象,可以慢慢地增大微分系數(shù),并同時(shí)觀察曲線的變化,從而找到最合適的參數(shù)。
以上就是在實(shí)際調(diào)參中經(jīng)常遇到的一些問(wèn)題以及解決方法。在實(shí)際應(yīng)用中,控制系統(tǒng)是多樣且復(fù)雜的,這一些方法只能作為參考,并不是通用的,因此在 PID 調(diào)參過(guò)程中,要注意經(jīng)驗(yàn)的積累。
07
參考Code
PID初始化代碼 定義一個(gè)新的PID參數(shù)時(shí),就是建立一個(gè)新的結(jié)構(gòu)體,運(yùn)算和初始化時(shí)直接調(diào)用對(duì)應(yīng)的成員變量就行,十分方便簡(jiǎn)潔,具體定義的結(jié)構(gòu)體如下:
typedef struct{ //PID運(yùn)算模式 uint8_t mode; //PID 三個(gè)基本參數(shù) __IO float Kp; __IO float Ki; __IO float Kd; __IO float max_out; //PID最大輸出 __IO float max_iout; //PID最大積分輸出 __IO float2 set; //PID目標(biāo)值 __IO float2 fdb; //PID當(dāng)前值 __IO float out; //三項(xiàng)疊加輸出 __IO float Pout; //比例項(xiàng)輸出 __IO float Iout; //積分項(xiàng)輸出 __IO float Dout; //微分項(xiàng)輸出 //微分項(xiàng)最近三個(gè)值 0最新 1上一次 2上上次 __IO float Dbuf[3]; //誤差項(xiàng)最近三個(gè)值 0最新 1上一次 2上上次 __IO float error[3]; } pid_type_def;初始運(yùn)行時(shí)調(diào)用一次,初始化各個(gè)參數(shù)
void Own_PID_init(pid_type_def *pid, uint8_t mode, const __IO float PID[3], __IO float max_out, __IO float max_iout){ if (pid == NULL || PID == NULL){ return; } pid->mode = mode; pid->Kp = PID[0]; pid->Ki = PID[1]; pid->Kd = PID[2]; pid->max_out = max_out; pid->max_iout = max_iout; pid->Dbuf[0] = pid->Dbuf[1] = pid->Dbuf[2] = 0.0f; pid->error[0] = pid->error[1] = pid->error[2] = pid->Pout = pid->Iout = pid->Dout = pid->out = 0.0f; }? PID運(yùn)算代碼
__IO float PID_calc(pid_type_def *pid, __IO float ref, __IO float set){ //判斷傳入的PID指針不為空 if (pid == NULL){ return 0.0f; } //存放過(guò)去兩次計(jì)算的誤差值 pid->error[2] = pid->error[1]; pid->error[1] = pid->error[0]; //設(shè)定目標(biāo)值和當(dāng)前值到結(jié)構(gòu)體成員 pid->set = set; pid->fdb = ref; //計(jì)算最新的誤差值 pid->error[0] = set - ref; //判斷PID設(shè)置的模式 if (pid->mode == PID_POSITION) { //位置式PID //比例項(xiàng)計(jì)算輸出 pid->Pout = pid->Kp * pid->error[0]; //積分項(xiàng)計(jì)算輸出 pid->Iout += pid->Ki * pid->error[0]; //存放過(guò)去兩次計(jì)算的微分誤差值 pid->Dbuf[2] = pid->Dbuf[1]; pid->Dbuf[1] = pid->Dbuf[0]; //當(dāng)前誤差的微分用本次誤差減去上一次誤差來(lái)計(jì)算 pid->Dbuf[0] = (pid->error[0] - pid->error[1]); //微分項(xiàng)輸出 pid->Dout = pid->Kd * pid->Dbuf[0]; //對(duì)積分項(xiàng)進(jìn)行限幅 LimitMax(pid->Iout, pid->max_iout); //疊加三個(gè)輸出到總輸出 pid->out = pid->Pout + pid->Iout + pid->Dout; //對(duì)總輸出進(jìn)行限幅 LimitMax(pid->out, pid->max_out); } else if (pid->mode == PID_DELTA) { //增量式PID //以本次誤差與上次誤差的差值作為比例項(xiàng)的輸入帶入計(jì)算 pid->Pout = pid->Kp * (pid->error[0] - pid->error[1]); //以本次誤差作為積分項(xiàng)帶入計(jì)算 pid->Iout = pid->Ki * pid->error[0]; //迭代微分項(xiàng)的數(shù)組 pid->Dbuf[2] = pid->Dbuf[1]; pid->Dbuf[1] = pid->Dbuf[0]; //以本次誤差與上次誤差的差值減去上次誤差與上上次誤差的差值作為微分項(xiàng)的輸入帶入計(jì)算 pid->Dbuf[0] = (pid->error[0] - 2.0f * pid->error[1] + pid->error[2]); pid->Dout = pid->Kd * pid->Dbuf[0]; //疊加三個(gè)項(xiàng)的輸出作為總輸出 pid->out += pid->Pout + pid->Iout + pid->Dout; //對(duì)總輸出做一個(gè)先限幅 LimitMax(pid->out, pid->max_out); } return pid->out;}
#define LimitMax(input, max) { if (input > max) { input = max; } else if (input < -max) ? ?{ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?input = -max; ? ? ? ? ?} ? ? ? ? ? ? ? ? ? ? ? }PID數(shù)據(jù)清空代碼
有時(shí)候需要清除中間變量,例如目標(biāo)值和中間變量清零。
void PID_clear(pid_type_def *pid) { if (pid == NULL) { return; } //當(dāng)前誤差清零 pid->error[0] = pid->error[1] = pid->error[2] = 0.0f; //微分項(xiàng)清零 pid->Dbuf[0] = pid->Dbuf[1] = pid->Dbuf[2] = 0.0f; //輸出清零 pid->out = pid->Pout = pid->Iout = pid->Dout = 0.0f; //目標(biāo)值和當(dāng)前值清零 pid->fdb = pid->set = 0.0f; } 處理PID算法還有很多算法,例如lqr算法等,項(xiàng)目這個(gè)開(kāi)源項(xiàng)目就是lqr實(shí)現(xiàn)的。后面會(huì)詳細(xì)介紹制作過(guò)程和算法。 審核編輯:劉清
-
控制系統(tǒng)
+關(guān)注
關(guān)注
41文章
6604瀏覽量
110576 -
PID算法
+關(guān)注
關(guān)注
2文章
172瀏覽量
24301 -
調(diào)節(jié)器
+關(guān)注
關(guān)注
5文章
847瀏覽量
46411
原文標(biāo)題:快速調(diào)試PID參數(shù)的3種方法。
文章出處:【微信號(hào):All_best_xiaolong,微信公眾號(hào):大魚(yú)機(jī)器人】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論