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