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