PID算法 是控制算法中的經典算法,特別是在一個閉環控制系統中更為常用。自己曾是第十三屆全國大學生“恩智浦”杯智能汽車競賽的參賽選手,相信所有的選手在電機控制算法上大多都是用PID算法,本想好好使用這種算法,卻無奈沒有學過。而網上查閱資料卻又是基本都是一些苦澀難懂數學公式和膾炙人口的一些PID語句,對于剛接觸PID算法的人而言無異于天書。所以寫此文章,意在用于分享自己對于PID算法的理解,希望可以幫助同樣與我曾經有相同困惑的人排除困惑。注:本文是自己通過查閱書籍和觀看視頻學習而得,若有錯誤,歡迎批評指正。
- PS:感謝評論區的大佬指出我畫的PID的圖都有些小問題,但是我還畫不好一個比較好的圖來替代它們,所以大家可以根據自己所學,結合評論區大佬的建議看看。(QAQ我盡量早些畫出比較好的圖來替代。)
- 2020.4.8:隨著這篇文章的點贊數越來越多,首先感謝大家對我的肯定,其次,不好意思,我的圖還沒畫出來,?大家一定要帶著懷疑的心態看我的圖片啊.?? 期待各位看官可以再給我提出新的問題和改進思路。?
一、簡介
1.1控制系統 :開環控制系統與閉環控制系統
控制系統有幾種分類方法,其中,按控制原理的不同,自動控制系統分為開環控制系統
和閉環控制系統
。
- 開環控制系統
在開環控制系統中,系統輸出只受輸入的控制,控制精度和抑制干擾的特性都比較差。

- 閉環控制系統
閉環控制系統利用輸出量同期望值的偏差對系統進行控制,可獲得比較好的控制性能。閉環控制系統又稱反饋控制系統。

由圖中可以很明顯的看出,此控制系統比開環系統多了一個環節——傳感器,通過傳感器進行 采集和反饋 到控制算法中,形成一個 閉合的回環 這也就是閉環控制系統中的閉環。
1.2PID算法介紹
PID算法
是將偏差
的比例( P roportion)
、積分( I ntegral)
和 微分( D ifferential)
通過線性組合構成控制量,用這一控制量對被控對象進行控制,這樣的控制器稱PID控制器。

簡單來說,偏差
= 用戶設定的期望值
— 傳感器采集回來的當前值
,將偏差進行P、I、D
三個環節的計算,再進行求和、輸出
。
二、二位式控制算法
2.1 為什么要解釋二位式控制算法
二位式控制算法在某種程度上可謂是PID算法的前身,了解原理便可更好的理解PID算法。
2.2 以實例理解二位式控制
二位式控制算法輸出的控制量只有高 \ 低 電平
2種狀態。我們以燒水為例:假設我們要求此控制系統要將水加熱到100℃,當傳感器采集反饋回的當前值 沒有達到期望值
(100℃),便全高/低電平加熱;當傳感器采集反饋回的當前值達到期望值
(100℃),便停止加熱。

2.3 引入慣性環節
一個簡單的控制系統這么設計看似毫無問題,然而,由于我們的控制對象具有慣性
,例如我們控制加熱絲燒水,當我們達到指定溫度停止加熱
的時候,加熱絲不會馬上冷卻下來
,水溫還會繼續升高,超過指定溫度;而過了一會兒,水溫冷卻下來低于指定溫度時,給加熱絲通電,加熱絲也無法立刻把溫度升上去
。由于我們的控制對象(加熱絲、電感、電容、電機等)具有慣性
,而二位式控制算法的輸出量只于當前狀態有關
,故很難達到精確控制
。
eg:電機就是一個 具有慣性的對象,給他施加電壓,不能馬上轉到對應的速度;撤去電壓,電機也不能馬上停下。

由于慣性環節的存在,會使控制對象超出期望值。
三、位置式PID算法
- ①如果我們把二位式控制算法理解為數字量輸出,那么PID算法則就是模擬量輸出。
- ②二位式控制算法只于當前偏差有關,而PID算法則是考慮到過去、現在、和未來的控制算法。
我們規定:用戶期望值為 Expect,每隔一個固定時間對控制對象進行信息采樣Xn,在此基礎上,我們在三個環節中介紹三個序列。
3.1 P環節(現在)
P(比例)環節:對當前時刻的偏差進行比例放大。
- 采樣序列:系統中每個時刻采集回來的當前值 Xn 。
- X1、X2、X3 … Xn-1、Xn; 第k時刻的 偏差:e(k)=Expect — Xk;
- e(k)>0 :控制系統還未達到期望值;
- e(k)=0 :控制系統已經達到期望值;
- e(k)<0 :控制系統已經超過期望值;
- P環節的第k時刻的輸出:
u(k)=Kp * e(k)
。 - Kp:P比例系數,可以理解為放大倍數。
- 單P算法中的缺陷:當系統不存在偏差(e(k)=0)時,執行部件便無輸出,被控對象處于失控狀態。

3.2 I 環節(過去)
I(積分)環節:對過去所有時間的偏差進行積分。
- 偏差序列:e(k)=Expect — Xk
- e1、e2、e3 … en-1、en; ∑ei:對過去所有時間的偏差進行求和;
- ∑ei<0 :控制系統在 過去大部分時間段還未達到期望值;
- ∑ei=0 :控制系統在 過去大部分時間段已經達到期望值;
- ∑ei>0 :控制系統在 過去大部分時間段已經超過期望值;
- I環節的第k時刻的輸出:
u(k)=Ki * ∑ei
。(Ki:i比例系數)
在控制系統剛啟動時,由于I環節的 偏差累積效應,可以 更快的達到期望值。但同時也由于偏差的累積效應,使得系統第一次達到期望值時,過去所有時刻都未達標,即∑ei很大,所以曲線其實會超過期望的那條虛線并持續增長,所以,我們通常會在I環節中除以積分時間Ti,即u(k)=Ki * ∑ei/Ti
另一個解決辦法 我們后面在增量式算法中再進行討論。

3.3 D環節(將來)
D(微分)環節:通過偏差的偏差,對控制系統的輸出走向進行預判,起超前調節的作用。
- 偏差的偏差序列:
△ek=ek-ek-1
; - △e1、△e2、△e3 … △en-1、△en;
- △e(k)很大時,表示控制系統上一刻的輸出很“陡峭”,表明控制系統離目標相差很遠,所以D環節的輸出也很大。
- D環節的第k時刻的輸出:
u(k)=Kd * △e(k)
。 - Kd:D積分系數,除了超前預判,還可理解為阻尼力。

四、增量式PID算法
位置式PID:u(k)=Kp * e(k)+Ki / T * ∫ e(k) dt+Kd*d e(k);
增量式PID:u(k)=Kp * e(k-1)+Ki *e(t) +Kd *(e(k)-2e(k-1)+e(k-2));
很顯然,對位置式PID進行求導(dx = f(x) - f(x-1)),就得到了增量式PID。
對于前面談到的,位置式PID的 I 環節,是對過去所有時間
的偏差進行積分,其輸出與過去所有時間都有關,而增量式的PID只于最近的三個時刻
的偏差有關。
其實,增量式PID我覺得也沒有很多需要理解的,自然而然的代入應用即可。
//電機控制 增量式 P I 算法 Err_speed=Expect_speed-actual_speed; Err_dev_speed=Err_speed-Err_speed_last; Err_speed_last=Err_speed; gradinets=(int) (PID_P*Err_dev_speed+PID_I*Err_speed);
float PID_Cal(float Speed){ pid.SetSpeed = Speed; pid.Err = pid.SetSpeed - pid.ActualSpeed;//誤差的計算,即比例控制 pid.Integral += pid.Err;//誤差相加,即積分控制 pid.Voltage = pid.Kp * pid.Err + pid.Ki * pid.Integral + pid.Kd * (pid.Err - pid.Err_last);//根據位置型PID控制的公式 pid.Err_last = pid.Err; pid.ActualSpeed = pid.Voltage * 1.0; //轉換 return pid.ActualSpeed;//PID控制后的實際輸出值}