2020-12-28 Matlab自动化控制-Adrc自抗扰控制
Matlab自動化控制-Adrc自抗擾控制
想要初步了解ADRC,可以從韓京清教授的一篇文獻和一本書看起
1.文獻:?從PID技術到“自抗擾控制”技術(《控制工程》,2002)
2.書:?自抗擾控制技術——估計補償不確定因素的控制技術
ADRC控制中包含三個主要的部分:
跟蹤微分器,非線性狀態反饋(非線性組合),擴張觀測器。
ADRC特點:
繼承了經典PID控制器的精華,對被控對象的數學模型幾乎沒有任何要求,又在其基礎上引入了基于現代控制理論的狀態觀測器技術,將抗干擾技術融入到了傳統PID控制當中去,最終設計出了適合在工程實踐中廣泛應用的全新控制器。
一、跟蹤微分器(TD)
這是一個單輸入雙輸出的模塊,作用有兩個:
-
避免輸入量不要有跳變,便于實際系統實時跟蹤。因為傳統的pid有個問題,就是當跟蹤像階躍信號這種突變信號時超調和上升時間共存的現象,所以我們的思路就是對輸入的信號進行平滑處理,也就是避免其出現突變。
-
過濾高頻噪聲
所以輸出1就是處理過的信號,第二個信號是輸出1的微分,輸出1和2都將用于下一環節,這里不介紹。
先擺出他的輸出效果圖,輸入為階躍信號:
說明:藍色為處理后的階躍信號,顯然就好很多,沒有那么突變。黃色為微分。
TD公式:
Simulink仿真模型:
?
友情提示:離散差分方程建模和連續系統微分方程建模一樣,先找準輸出y(k),再找準y(k-1)…,然后他們之間用單位延遲連接,最后在這基礎上連其他東西。
hfst函數模塊:
function out = hfst(u1,u2,r,h)
d=r*h;d0=h*d;y=u1+h*u2;a0=sqrt(d*d+8*r*abs(y));a=0;out1=0;if abs(y)>d0 a=u2+(a0-d)/2*sign(y);end if abs(y)<=d0 a=u2+y/h;end if abs(a)>d out1=-r*sign(a);end if abs(a)<=d out1=-r*a/d;endout=out1;end或者,不用像上面的simulink+m,整個td都可以直接用m腳本寫也可以,已經過驗證效果一樣:
function [y1k,y2k] = fcn(u)persistent y1k_1 y2k_1h=0.01;delta=10;if isempty(y1k_1) y1k_1=0;end if isempty(y2k_1) y2k_1=0;end y1k=y1k_1+h*y2k_1; % hfst計算內容d=delta*h;d0=h*d;y=y1k_1-u+h*y2k_1;a0=sqrt(d*d+8*delta*abs(y));a=0;out1=0;if abs(y)>d0 a=y2k_1+(a0-d)/2*sign(y);end if abs(y)<=d0 a=y2k_1+y/h;end if abs(a)>d out1=-delta*sign(a);end if abs(a)<=d out1=-delta*a/d;endout=out1;% 更新變量y2k=y2k_1+h*out; y1k_1=y1k;y2k_1=y2k; end驗證效果:
t = 0:0.01:2;u = zeros(length(t), 1);u (t >=1) = 1;figureplot(t,u)y1k = zeros(length(t), 1);y2k = zeros(length(t), 1);for i = 1:length(t) [y1k(i),y2k(i)] = fcn(u(i));endfigureplot(t,y1k)figureplot(t,y2k)說明:TD模型涉及兩個調參:δ和h,h為采樣周期,delta決定跟蹤快慢(δ越大,過濾后的輸出越接近輸入),一般的仿真模型r可以盡量大一些,在100~500范圍內基本相同,即使再大效果也基本不會有大的提升,我這里delta為50,h=0.001。
二、非線性組合
這一部分對應第一張圖中的非線性組合模塊,這一模塊為雙輸入單輸出,輸入的是兩個誤差,分別是指令信號差和指令信號微分的差,參考指令信號和參考指令信號的微分均由TD產生。
傳統的pid或者pd控制就是比例、積分、微分的線性加權之和,但這種線性的組合不是最佳的,后來發現三者的非線性組合效果更好。最常用的就是pd形式的非線性組合:
這里面涉及的調參有三個:β1,β2,δ,δ為h的整數倍。
對比一下傳統PID和非線性PID
sys = tf([133],[1,25,0])dsys = c2d(sys,0.001,'z');[num,den]=tfdata(dsys,'v');效果:
非線性pd控制:
函數模塊代碼:
function y =nonlinear_pd(e1,e2)alfa1=0.75;alfa2=1.5;delta=0.002;beta1=150;beta2=1;fal1=1;fal2=1; if abs(e1)<=delta fal1=e1/(delta^(1-alfa1));end if abs(e1)>delta fal1=(abs(e1))^(alfa1)*sign(e1);end if abs(e2)<=delta fal2=e2/(delta^(1-alfa2));end if abs(e2)>delta fal2=(abs(e2))^(alfa2)*sign(e2);end y=beta1*fal1+beta2*fal2;end效果:
可見效果好多了,因此非線性pid有效果!!!!!!
三、ESO擴張觀測器
ESO是一個雙輸入單輸出模塊,輸入的值為對象的輸出以及對象的控制輸入,見第一張圖,而輸出有三個,分別是對象輸出的估計值、對象輸出的估計值的一階導數、對象輸出的估計值的二階導數。而對象輸出的估計值、對象輸出的估計值的一階導數將反饋給最開始的跟蹤微分器(TD),而對象輸出的估計值的二階導數將反饋給非線性組合的輸出上用于彌補擾動。
一般觀測器僅觀測系統的狀態,只有輸出和輸出的導數(速度)。但是這里對輸出的導數的導數(加速度)也進行了觀測,這里也就是所謂的擾動(即第一張圖中的w),對擾動進行了觀測。觀測器的狀態量也由此擴張了一維,因此叫做擴張觀測器。
ESO的公式見下圖:
Simulink fcn模型:
里面的代碼如下:
function [z1_k,z2_k,z3_k] = ESO(yk,uk)%%參數初始化persistent z1_k_1 z2_k_1 z3_k_1bata01=30;beta02=300;beta03=1000;b=5;h=0.001;alfa1=0.25;alfa2=0.5;delta=0.002;fal1=1;fal2=1;if isempty(z1_k_1) z1_k_1=0;endif isempty(z2_k_1) z2_k_1=0;endif isempty(z3_k_1) z3_k_1=0;end e1=z1_k_1-yk;z1_k=z1_k_1+h*z2_k_1-bata01*e1;z1_k_1=z1_k; %%迭代更新z1_k_1 %%計算fal函數if abs(e1)<=delta fal1=e1/(delta^(1-alfa1));endif abs(e1)>delta fal1=(abs(e1))^(alfa1)*sign(e1);endif abs(e1)<=delta fal2=e1/(delta^(1-alfa2));endif abs(e1)>delta fal2=(abs(e1))^(alfa2)*sign(e1);end z2_k=z2_k_1+h*(z3_k_1+b*uk)-beta02*fal1;z2_k_1=z2_k;%%迭代更新z2_k_1 z3_k=z3_k_1-h*beta03*fal2;z3_k_1=z3_k;%%迭代更新z3_k_1 end但要注意:因為ESO的公式里面已經加入了b*u,所以在搭最后的模型時第一張圖中的b0就不要了,即不用再乘上b0,直接將補償后的u輸入ESO。同理,如果你要在similink模型里要顯示用上b0這個比例系數,那么ESO里的公式里就要改為:z2_k=z2_k_1+h*(z3_k_1-beta02*fal1+uk);即去掉最后的uk前的系數b
四、完整的ADRC
這一節將把前面的組合起來構成一個完整的ADRC,也就是第一張圖中的形式。搭好的結構如下:
注意點:
1.因為這是一個離散的模型,所以確保所有模塊的采樣時間一致
2.注意檢查所有的求和模塊的正負
3.注意上面第三節的黑色注意部分
開始仿真,報錯了:
翻譯過來就是說存在代數環的原因
這個問題很很好理解,我們知道,我們在求解反饋環的時候,首先反饋的初始值是為o的,也就是反饋系統的順序是:我們先根據主路輸入計算得到主路的輸出(即得到反饋路的輸入),在根據反饋路的輸入計算出反饋路的輸出(即反饋值),然后進行下一次循環。而在simulink中,他不像我們之前寫的m腳本(我們自己寫腳本就是從主路開始),他不知道首先應該計算主路還是首先計算反饋路,所以我們需要告訴他,解決辦法就是在反饋路的輸出端加上單位延遲,也就是告訴反饋路你等等,別太急,等主路先走。
其實我們還可以這樣去理解代數環,將其理解為初始狀態時反饋量沒有初始值,我們以前的控制模型比如pid啥的,我們反饋的反饋量都會有一個初始值,而這個模型的ESO的輸出作為反饋量是沒有初始值的,所以他報錯的原因還可以理解為反饋量沒有初始值,所以我們就去給反饋量設一個初始值,我們就可以用memory模塊(這個模塊的作用就是有輸入時輸出=輸入,沒輸入時輸出保持原先狀態,且當輸入改變時輸出才改變,否則一直保持輸出不變),在memory模塊里設置一個初始值,這樣反饋量就有初始值了。而上面我們用的單位延遲模塊就是一個memory模塊,二者本來就是一樣的。所以上面用單位延遲模塊也可以這樣理解。
修改后的simulink為:
或者(兩者等價):
仿真后結果沒報錯,且結果令人滿意:
其中黃色為初始階躍信號,紅色為經過TD的信號,藍色為控制輸出。
總結
以上是生活随笔為你收集整理的2020-12-28 Matlab自动化控制-Adrc自抗扰控制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python 深度学习目标检测评价指标
- 下一篇: 2020-12-29 Matlab自动化