Matlab仿真PID控制(帶M文件、simulink截圖和參數分析)

0.符號說明

  1. y(k)——系統響應輸出的離散值
  2. u(k)——數字PID控制輸出的離散值
  3. r(k)——期望輸出的離散值(事先已知),在本例中爲常數(即階躍輸入)
  4. e(k)——e(k)=r(k)-y(k),爲期望值-實際值,是單位負反饋的誤差比較信號
    圖片來源於百度百科
    注:圖片來源於百度百科

1.如何根據連續系統建立差分方程

1.1.獲取連續系統的傳遞函數

線性定常系統的控制中,PID是個非常常見的控制方式,如果可以通過Matlab仿真出PID的控制效果圖,那麼對系統設計時的實時調試將會容易得多。在這裏我們將會以一個利用系統辨識參數的PID設計爲爲例展示Matlab仿真PID的過程。
首先需要對一個未知的系統的參數進行辨識,以延遲環節可以忽略不計的電機調速系統爲例。將時間戳導入xdata向量,對應的時刻轉速導入ydata向量,進行系統辨識

鏈接:Matlab的系統辨識

我們就以上文鏈接中辨識的系統傳遞函數爲例:
G(s)=0.9980.021s+1G(s)=\frac{0.998}{0.021s+1}因此通過tf函數建立系統結構體如下:

sys=tf(0.998,[0.021,1]);   %建立被控對象傳遞函數,即式4.1

1.2.獲取離散系統的傳遞函數

由於是數字PID仿真,我們需要選取一個採樣時間,本案例選用的是0.005s(注意,採樣週期應該小於系統純滯後時間的0.1倍)。在對其進行數字PID控制前,我們需要將這個系統離散化:

ts=0.005;  %採樣時間=0.005s
dsys=c2d(sys,ts,'z');      %離散化

dsys即我們根據採樣週期離散化的Z變換系統。首先我們需要提取這個Z變化d那系統的參數方便後面的計算:

[num,den]=tfdata(dsys,'v');%'v'代表強制以向量的格式(默認爲元胞數組)輸出num和den

1.3.轉換爲差分方程

求解出的Z變換表達式爲dsys=num(1)z+num(2)den(1)z+den(2)=0.2114z0.7881dsys=\frac{num(1)\cdot z +num(2)}{den(1)\cdot z+den(2)}=\frac{0.2114}{z-0.7881}
在PID仿真的過程中我們需要求解出時域表達式 ,因此需要藉助差分方程解決,對於以下的Z變換:

\begin{equation}
Y(z)=dsys\cdot U(z)=\frac{num(2)}{den(1)\cdot z+den(2)}\cdot U(z)
\label{eq:Sample1}
\end{equation}

\begin{equation}
zY(z)+den(2)Y(z)=num(1)zU(z)+num(2)U(z)
\label{eq:Sample2}
\end{equation}
對上式進行反Z變換,可以得到以下的差分方程:

\begin{equation}
y(k+1)+den(2)y(k)=num(1)u(k+1)+num(2)u(k)
\label{eq:Sample3}
\end{equation}

\begin{equation}
y(k+1)=-den(2)y(k)+num(1)u(k+1)+num(2)u(k)
\label{eq:Sample4}
\end{equation}
位置型PID仿真時實際上可以不需要保存前一個數據(u(k)和y(k)),增量型PID必須要保存前一個數據。這裏我們使用了位置型PID,但仍然利用u1u_1y1y_1保存了上一個數據,僅僅是爲了演示這一過程。\begin{equation}
y(k+1)=-den(2)y(k)+num(1)u(k+1)+num(2)u(k)
\end{equation}
可以轉換爲下面的式子:
\begin{equation}
y(k)=-den(2)y_1+num(1)u(k)+num(2)u_1
\label{eq:Sample5}
\end{equation}
我們的差分方程就這樣建立完畢。注意,此差分方程僅僅是描述系統模型的運算規律的,和我們的控制無關。因此是y(k)和u(k)的映射關係。我們下面的控制則是利用負反饋信號e(k)導出u(k)的輸出,求解的是控制器u(k)的序列值。

2.基本PID控制原理

以位置型PID控制爲例。將連續的PID控制轉換爲數字式時,微分環節被用差分代替,積分環節被累加和代替,比例環節則保持不變。差分的實現非常簡單,只需要用e(k+1)e(k)e(k+1)-e(k)e(k)e1e(k)-e_1等效即可。積分的實現在每一次運算的後面都累加原來的誤差,即Ee=Ee+e_1;即可。PID的控制器輸出u(k)=Kpe(k)+Kd(e(k)e1)+KiEeu(k)=Kp\cdot e(k)+Kd\cdot (e(k)-e_1)+Ki\cdot Ee
PID控制器構造完畢,我們需要通過r(k)和y(k)得到e(k),再通過e(k)得出u(k),進而再求解出y(k),再結合r(k)求解出e(k),…以此循環,求解出離散的響應點。
詳細的代碼如下:

ts=0.005;  %採樣時間=0.005s
sys=tf(0.998,[0.021,1]);   %建立被控對象傳遞函數,即式4.1
dsys=c2d(sys,ts,'z');      %離散化
[num,den]=tfdata(dsys,'v');   %
e_1=0;      %前一時刻的偏差      
Ee=0;       %累積偏差
u_1=0.0;    %前一時刻的控制量
y_1=0;       %前一時刻的輸出
%PID參數
kp=0.22;    
ki=0.13;
kd=0;
u=zeros(1,1000);%預先分配內存
time=zeros(1,1000);%時刻點(設定1000個)
for k=1:1:1000
    time(k)=k*ts;   %時間參數
    r(k)=1500;      %期望值
    y(k)=-1*den(2)*y_1+num(2)*u_1+num(1)*u(k);%系統響應輸出序列
    e(k)=r(k)-y(k);   %誤差信號
    u(k)=kp*e(k)+ki*Ee+kd*(e(k)-e_1); %系統PID控制器輸出序列
    Ee=Ee+e(k);    %誤差的累加和
    u_1=u(k);    	%前一個的控制器輸出值
    y_1=y(k);    	%前一個的系統響應輸出值
    e_1=e(k);		%前一個誤差信號的值
end
%(僅繪製過渡過程的曲線,x座標限制爲[0,1])
p1=plot(time,r,'-.');xlim([0,1]);hold on;%指令信號的曲線(即期望輸入)
p2=plot(time,y,'--');xlim([0,1]);%不含積分分離的PID曲線
hold on;

輸出的PID控制曲線如下:
PID控制

3.比較PID輸出,分析參數產生的影響

一個基本的PID就完成了。下面如果我們想要知道修改PID的三個參數kp,ki,kd會帶來什麼效果,只需要在程序中修改即可。爲了方便起見,我們建立一個PID的數組,kp,ki,kd每次都取數組的一個值,然後設定一個大循環開始循環仿真。再利用subplot輸出子圖的方式將所有的PID效果都輸出到一個圖進行對比。該代碼根據上述代碼修改已經很容易,PID比較圖的代碼如下:

close all
PID=[0.22,0.13,0;
    0.4,0.13,0;
    0.4,0.25,0;
    0.8,0.23,0.4;
    0.8,0.2,1;
    0.7,0.2,0.9];%初始化PID參數
for pid=1:1:6
ts=0.005;  %採樣時間=0.005s
sys=tf(0.998,[0.021,1]);   %建立被控對象傳遞函數,即式4.1
dsys=c2d(sys,ts,'z');      %離散化
[num,den]=tfdata(dsys,'v');   %
e_1=0;      %前一時刻的偏差      
Ee=0;       %累積偏差
u_1=0.0;    %前一時刻的控制量
y_1=0;       %前一時刻的輸出
%PID參數
kp=PID(pid,1);    
ki=PID(pid,2);
kd=PID(pid,3);
u=zeros(1,1000);
time=zeros(1,1000);
for k=1:1:1000
    time(k)=k*ts;   %時間參數
    r(k)=1500;      %給定量
    y(k)=-1*den(2)*y_1+num(2)*u_1+num(1)*u(k);
    e(k)=r(k)-y(k);   %偏差
    u(k)=kp*e(k)+ki*Ee+kd*(e(k)-e_1);   
    Ee=Ee+e(k);    
    u_1=u(k);    
    y_1=y(k);    
    e_1=e(k);
end
subplot(2,3,pid);
p1=plot(time,r,'-.');xlim([0,1]);hold on;
p2=plot(time,y,'--');xlim([0,1]);
title(['Kp=',num2str(kp),' Ki=',num2str(ki),' Kd= ',num2str(kd)]);
hold on;
end

輸出的子圖矩陣如下:
PID子圖矩陣
可以發現,修改Kp會造成上升時間的縮短,但是有可能也會帶來較大的超調。積分的增加是一個嚴重的滯後環節,會減小相位裕度,也會帶來超調(超調量並不是絕對的,相對於較小的Kp可能會產生較大的超調,而Kp較大時超調會減小(例如第一行的1圖和2圖的對比))。然而積分的引入也是必要的,否則將會很長時間無法削弱誤差e(k)(例如第二行第二個圖)。微分的引入相當於一個超前校正,會減少超調,但是過渡的微分很可能會造成尾部振盪,系統逐漸變得不穩定。因此微分和積分之間需要一個平衡,當滿足這個平衡的時候,系統幾乎沒有振盪,同時響應速度也較快。(第一行的圖3是積分過多,產生超調,第二行的圖1和圖3就比較理想)
綜合上述,PID的調節經驗可以歸結爲以下幾點:

  • Kp較小時,系統對微分和積分環節的引入較爲敏感,積分會引起超調,微分可能會引起振盪,而振盪劇烈的時候超鐵也會增加。
  • Kp增大時,積分環節由於滯後產生的超調逐漸減小,此時如果想要繼續減少超調可以適當引入微分環節。繼續增大Kp系統可能會不太穩定,因此在增加Kp的同時引入Kd減小超調,可以保證在Kp不是很大的情況下也能取得較好的穩態特性和動態性能。
  • Kp較小時,積分環節不宜過大,Kp較大時積分環節也不宜過小(否則調節時間會非常地長),在下面這個例子中我們還會介紹到,當使用分段PID,在恰當的條件下分離積分,可以取得更好的控制效果。原因在於在穩態誤差即將滿足要求時,消除了系統的滯後。因此係統超調會明顯減少。本例中採樣的抗積分飽和的方法是遇限削弱積分法。

4.改進PID算法(遇限削弱積分法)

遇限削弱積分法的原理是
u(k)>umaxu(k)>u_{max}時,若e(k)>0即輸出值還未到達指定值,則認爲積分會帶來滯後,不再積分。
u(k)<0u(k)<0時,若e(k)<0即輸出值超過了指定值,則認爲積分會帶來滯後,不再積分。
在本案例中認爲umax=r(k)u_{max}=r(k)
改進PID算法如下(需要些兩個循環,當然也可以用一個循環,將其中的PID設爲一個子過程調用):

close all
ts=0.005;  %採樣時間=0.005s
sys=tf(0.998,[0.021,1]);   %建立被控對象傳遞函數,即式4.1
dsys=c2d(sys,ts,'z');      %離散化
[num,den]=tfdata(dsys,'v');   %
e_1=0;      %前一時刻的偏差      
Ee=0;       %累積偏差
u_1=0.0;    %前一時刻的控制量
y_1=0;       %前一時刻的輸出
%PID參數
kp=0.22;    
ki=0.13;
kd=0;
u=zeros(1,1000);
time=zeros(1,1000);
for k=1:1:1000
    time(k)=k*ts;   %時間參數
    r(k)=1500;      %給定量
    y(k)=-1*den(2)*y_1+num(2)*u_1+num(1)*u(k);
    e(k)=r(k)-y(k);   %偏差
    u(k)=kp*e(k)+ki*Ee+kd*(e(k)-e_1);   
    Ee=Ee+e(k);    
    u_1=u(k);    
    y_1=y(k);    
    e_1=e(k);
end
p1=plot(time,r,'-.');xlim([0,1]);hold on;
p2=plot(time,y,'--');xlim([0,1]);
hold on;
a=1;%控制積分分離的二值數
e_1=0;Ee=0;u_1=0.0;y_1=0;%重新初始化       
for k=1:1:1000
    time(k)=k*ts;   %時間參數
    r(k)=1500;      %給定量
    y(k)=-1*den(2)*y_1+num(2)*u_1;
    e(k)=r(k)-y(k);   %偏差
    u(k)=kp*e(k)+ki*Ee+kd*(e(k)-e_1);   
     if ((u(k)>r(k)) && (e(k)>0))||((u(k)<0) && (e(k)<0))
         a=0;
     else 
         a=1;
     end     
    Ee=Ee+a*e(k);    
    u_1=u(k);    
    y_1=y(k);    
    e_1=e(k);
end
p3=plot(time,y,'-');xlim([0,1]);
title('含積分分離與不含積分分離的對比');
legend([p1,p2,p3],'指令信號','不含積分分離','含積分分離');

輸出的曲線對比圖如下:
積分分離之後的改進PID
可以發現,系統的超調量明顯減少了,調節時間也減少了一點。原因在於我們採用了分段PID的手段,既消除了穩態誤差還削弱了積分環節帶來的滯後影響。

5.simulink仿真

需要的模塊名稱(不區分大小寫)如下:

  • gain(參數分別爲0.22和0.13/0.005)
  • sum(參數分別爲"|±"和"|++")
  • integrator
  • scope
    注意:本文使用的是離散PID仿真,而simulink使用的是連續系統仿真,轉換PID參數時P參數不變,I參數應該除以仿真間隔Ts=0.005,D參數應該乘Ts。

以表中第一組PI參數爲例:
在這裏插入圖片描述
得到的示波器曲線如下:
在這裏插入圖片描述

希望本文對您有幫助,謝謝閱讀。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章