日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > 循环神经网络 >内容正文

循环神经网络

matlab中S函数的概念及使用

發布時間:2023/12/9 循环神经网络 61 豆豆
生活随笔 收集整理的這篇文章主要介紹了 matlab中S函数的概念及使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

??S函數即系統函數System Function的意思,為什么要使用S函數呢?是因為在研究中,有時需要用到復雜的算法設計等,而這些算法因為其復雜性不適合用普通的Simulink模塊來搭建,即matlab所提供的Simulink模塊不能滿足用戶的需求,需要用編程的形式設計出S函數模塊,將其嵌入到系統中。如果恰當地使用S函數,理論上,可以在Simulink下對任意復雜的系統進行仿真。

??? S函數具有固定的程序格式,用matlab語言可以編寫S函數,此外還允許用戶使用C、C++、Fortran和Ada等語言進行編寫,用非matlab語言進行編寫時,需要采用編譯器生成動態鏈接庫DLL文件。

在主窗口中輸入sfundemos,或者點擊Simulink->User-Defined Functions->S-Function Examples,即可出現如圖1所示的界面,可以選擇對應的編程語言查看演示文件。

圖1 S函數范例庫

Matlab為了用戶使用方便,有一個S函數的模板sfuntmpl.m,一般來說,我們僅需要在sfuntmpl.m的基礎上進行修改即可。在主窗口輸入edit sfuntmpl即可出現模板函數的內容,可以詳細地觀察其幫助說明以便更好地了解S函數的工作原理。模板函數的定義形式為function[sys,x0,str,ts]=sfuntmpl(t,x,u,flag),一般來說,S函數的定義形式為[sys,x0,str,ts]=sfunc(t,x,u,flag,p1,…Pn),其中的sfunc為自己定義的函數名稱,以上參數中,t、x、u分別對應時間、狀態、輸入信號,flag為標志位,其取值不同,S函數執行的任務和返回的數據也是不同的,pn為額外的參數,sys為一個通用的返回參數值,其數值根據flag的不同而不同,x0為狀態初始數值,str在目前為止的matlab版本中并沒有什么作用,一般str=[]即可,ts為一個兩列的矩陣,包含采樣時間和偏移量兩個參數,如果設置為[0 0],那么每個連續的采樣時間步都運行,[-1 0]則表示按照所連接的模塊的采樣速率進行,[0.25 0.1]表示仿真開始的0.1s后每0.25s運行一次,采樣時間點為TimeHit=n*period+offset。

S函數的使用過程中有2個概念值得注意:1、direct feedthrough,系統的輸出是否直接和輸入相關聯,即輸入是否出現在輸出端的標志,若是為1,否則為0,一般可以根據在flag=3的時候,mdlOutputs函數是否調用輸入u來判斷是否直接饋通。2、dynamically sized inputs,主要給出連續狀態的個數、離散狀態的個數、輸入數目、輸出數目和直接饋通否。

S函數中目前支持的flag選擇有0、1、2、3、4、9等幾個數值,下面說一下在不同的flag情況下S函數的執行情況。1)flag=0。進行系統的初始化過程,調用mdlInitializeSizes函數,對參數進行初始化設置,比如離散狀態個數、連續狀態個數、模塊輸入和輸出的路數、模塊的采樣周期個數、狀態變量初始數值等。2)flag=1。進行連續狀態變量的更新,調用mdlDerivatives函數。3)flag=2。進行離散狀態變量的更新,調用mdlUpdate函數。4)flag=3。求取系統的輸出信號,調用mdlOutputs函數。5)flag=4。調用mdlGetTimeOfNextVarHit函數,計算下一仿真時刻,由sys返回。6)flag=9。終止仿真過程,調用mdlTerminate函數。

圖2 不同flag情況下S函數執行情況

在實際仿真過程中,Simulink會自動將flag設置為0,進行初始化過程,然后將flag的數值設置為3,計算模塊的輸出,一個仿真周期后,Simulink將flag的數值先后設置為1和2,更新系統的連續和離散狀態,再將其設置為3,計算模塊的輸出,如此循環直至仿真結束條件滿足。?

在S函數的編寫過程中,首先需要搞清楚模塊中有多少個連續和離散狀態,離散模塊的采樣周期是如何的,同時需要了解模塊的連續和離散的狀態方程分別是什么,輸出如何表示。下面以實例說明S函數的具體應用。

實例一:在進行BLDC的速度電流雙閉環控制時候,如果電流采用滯緩控制,那么速度環的輸出作為參考電流的輸入IsABC三相的參考電流分別為I_arI_brI_cr,轉子的位置記為Pos,那么轉子位置和三相參考電流之間的關系表如圖3所示。

圖3 轉子位置和三相參考電流的關系表

分析系統情況:輸入為兩路,一是角度Angle,通過mod(angle,2*pi)轉化為Pos,二是參考電流輸入Is,輸出為三路,分別為A、B、C的三相參考電流,離散和連續的狀態均為0,輸入端出現在輸出端,將S函數命名為given_current,其程序代碼如下所示:

%參考電流模塊

%Author:dingqian12345@126.com

%很明顯:2個輸入分別為角度和速度控制器的輸出、3個輸出為三相電流的參考電流、為直通模型

function [sys,x0,str,ts]=cemf(t,x,u,flag)

clc;

switch flag

??? case 0

??????? [sys,x0,str,ts]=mdlInitializeSizes;???? %初始化

??? case 1

??????? sys=[];???????????????????????????????? %連續狀態的更新

??? case 2

??????? sys=[];????????????? %離散狀態的更新

??? case 3

??????? sys=mdlOutputs(u);??????????? ??????????%求取系統的輸出信號

??? case 4

??????? sys=[];???????????????????????????????? %計算下一時刻的仿真時間

??? case 9

??????? sys=[];???????????????????????????????? %終止仿真

??? otherwise

??????? error(['Unhandled flag=',num2str(flag)]);

end

%%%%%在flag=0的時候進行整個系統的初始化

function [sys,x0,str,ts]=mdlInitializeSizes

sizes = simsizes;??????????? %讀入初始化參數模板

sizes.NumContStates? = 0;??? %連續狀態個數

sizes.NumDiscStates? = 0;??? %離散狀態個數

sizes.NumOutputs???? = 3;??? %輸出變量個數

sizes.NumInputs????? = 2;??? %輸入信號個數

sizes.DirFeedthrough = 1;? ??%輸入直接傳入輸出信號否

sizes.NumSampleTimes = 1;??? % at least one sample time is neededWO? 一般來說為1個

sys = simsizes(sizes);

x0=[];??? %狀態初始化

str=[];

ts=[-1 0];??? %采樣周期若寫成-1表示繼承其輸入信號

%%%%%%在flag=1的時候進行連續系統狀態的更新

function sys=mdlDerivatives(t,x,u)

sys = [];

%%%%%%在flag=2的時候進行離散系統狀態的更新

function sys=mdlUpdates

%sys(1,1)=x(1)+T*x(2);??????????????? %為什么會寫成這樣呢

%sys(2,1)=x(2)+T*fst2(x,u,r,h);

%%%%%%在flag=3的時候進行系統輸出信號的求取

function sys=mdlOutputs(u)

m=current_dq(u(1),u(2));

sys(1,1)=m(1);

sys(2,1)=m(2);

sys(3,1)=m(3);

%%%%%%在flag=4的時候進行下一時刻仿真時間的計算

function sys=mdlGetTimeOfNextVarHit(t,x,u)

%sampleTime = 1;??? %? Example, set the next hit to be one second later.

%sys = t + sampleTime;

%%%%%%在flag=9的時候終止仿真過程

function sys=mdlTerminate(t,x,u)

%sys = [];

??? 如果某個flag對應的函數不起作用,我們將其所調用的函數設為空或者sys=[],為了保持模塊化以便思路清晰和方便擴充,一般不要使用case {1,4,9 }的形式,而是一個一個的列出。在以上代碼中,在flag=3的時候調用了自編的子程序m=current_dq(u(1),u(2))current_dq的代碼如下:

%%%%%%用戶自定義子程序

function x=current_dq(angle,current)

pos=mod(angle,2*pi);

x(1)=current;

x(2)=-current;

x(3)=0;

if 0<=pos && pos<pi/3

???? x(1)=current;

???? x(2)=-current;

???? x(3)=0;

end

if pi/3<=pos && pos<2*pi/3

???? x(1)=current;

???? x(2)=0;

???? x(3)=-current;

end

if 2*pi/3<=pos && pos<pi

??? x(1)=0;

??? x(2)=current;

??? x(3)=-current;

end

if pi<=pos && pos<4*pi/3

??? x(1)=-current;

??? x(2)=current;

??? x(3)=0;

end

if 4*pi/3<=pos && pos<5*pi/3

??? x(1)=-current;

??? x(2)=0;

??? x(3)=current;

end

if 5*pi/3<=pos && pos<2*pi

?? x(1)=0;

?? x(2)=-current;

?? x(3)=current;

end

??? S函數的代碼完成后,下面進行Simulink模塊的搭建,如圖4所示,其中的S-Function模塊提取路徑為Simulink->User-Defined Functions->S-Function,雙擊S-Function模塊,在name行中輸入函數名稱given_current即可,仿真結果如圖5所示。

圖4 參考電流模塊Simulink測試圖

圖5 參考電流模塊測試結果

????實例二:我覺得對于不做理論研究的我來說,如果用到S函數的話,一般的情況就如實例一的情況那樣,沒有離散和連續的狀態,只需要對輸入做某些運算或者判斷就可。上學期學的一門交流調速的課程,問題稍微復雜一點,在此也說一下。

??? 對于含有齒隙環節的閉環系統,系統控制量反映了系統運動方向的變化,可以對系統控制量U加一個補償量Ucomp以縮短系統在齒隙內的運行時間,補償控制系統框圖如圖6所示。具體的補償規則為:

if U(k)>0 and U(k-1)<=0 then flag=1
if U(k)<0 and U(k-1)>=0 then flag=1 Ucomp=flag*const*exp(-t/T0)

圖6 補償控制系統框圖

??? 分析系統情況:需離散狀態變量,系統狀態方程X1(k+1)=U(k)、X2(k+1)=f(X1(k),U(k)),其中f代表一個如上等式所示的關系,輸出Y= flag*const*exp(-t/T0),因此得到如下的信息,輸入為一路,即為圖6中的u,輸出為一路,連續狀態個數為0,離散狀態個數為2,輸入端不出現在輸出端,將S函數命名為comp,根據以上分析,其程序代碼如下所示:

%Author:dingqian12345@126.com

%Note:實現基于規則的補償算法

%2個離散狀態、0個連續狀態、1個輸入信號、1個輸出信號、輸出不涉及輸入信號

function [sys,x0,str,ts]=comp(t,x,u,flag)

clc;

global Cflag;

global Cont;

global T0;

Cont=20;

T0=1.5;

switch flag

??? case 0

??????? [sys,x0,str,ts]=mdlInitializeSizes; %初始化

??? case 1

??????? sys=mdlDerivatives(t,x,u);????????? %連續狀態的更新

??? case 2

??????? sys=mdlUpdates(t,x,u);???? ?????????%離散狀態的更新

??? case 3

??????? sys=mdlOutputs(t,x,u);????????????????? %求取系統的輸出信號

??? case 4

??????? sys=mdlGetTimeOfNextVarHit(t,x,u);????? %計算下一時刻的仿真時間

??? case 9

??????? sys=mdlTerminate(t,x,u);??????????? %終止仿真

??? otherwise

??????? error(['Unhandled flag=',num2str(flag)]);

end

%%%%%在flag=0的時候進行整個系統的初始化

function [sys,x0,str,ts]=mdlInitializeSizes

sizes = simsizes;??????????? %讀入初始化參數模板

sizes.NumContStates? = 0;??? %連續狀態個數

sizes.NumDiscStates? = 2;??? %離散狀態個數

sizes.NumOutputs???? = 1;??? %輸出變量個數

sizes.NumInputs????? = 1;??? %輸入信號個數

sizes.DirFeedthrough = 0;??? %輸入直接傳入輸出信號否

sizes.NumSampleTimes = 1;??? % at least one sample time is neededWO? 一般來說為1個

sys = simsizes(sizes);

x0=[0;0];??????? %狀態初始化

str=[];

ts=[-1 0];??? %采樣周期若寫成-1表示繼承其輸入信號

%%%%%%在flag=1的時候進行連續系統狀態的更新

function sys=mdlDerivatives(t,x,u)

sys = [];

%%%%%%在flag=2的時候進行離散系統狀態的更新

function sys=mdlUpdates(t,x,u)

global Cflag;

global Cont;

global T0;

Cflag=comp_decide(t,x,u);

sys(1,1)=u;

sys(2,1)=Cflag*Cont*exp(-t/T0);

%%%%%%在flag=3的時候進行系統輸出信號的求取

function sys=mdlOutputs(t,x,u)

sys=x(2);

%%%%%%在flag=4的時候進行下一時刻仿真時間的計算

function sys=mdlGetTimeOfNextVarHit(t,x,u)

%sampleTime = 1;??? %? Example, set the next hit to be one second later.

%sys = t + sampleTime;

%%%%%%在flag=9的時候終止仿真過程

function sys=mdlTerminate(t,x,u)

sys = [];

??? 可以看出,這里的S函數比實例1的S函數多用到了離散狀態更新函數mdlUpdates,注意狀態的更新方程的寫法,sys=x(n+1),可以通過help sfuntmpl查看。在以上代碼中,在flag=2的時候調用了自編的子程序m=comp_decide(t,x,u),comp_decide的代碼如下:

%%%%%%用戶自定義子程序

function cc=comp_decide(t,x,u)

cc=0;

if u>0 && x(1)<=0

??? cc=1;

end;

if u<0 && x(1)>=0

??? cc=-1;

end;

??? 最后,將S函數嵌入到Simulink中,所搭建的補償仿真框圖如圖7所示,我們通過Scope4觀察控制量U和補償Ucomp,其中cont為20,To=1.5。圖8為補償系統中U和Ucomp仿真結果局部放大圖,可見,系統可以捕捉到控制量過零點的時刻并給出相應的補償量。

圖7 補償系統Simulink仿真框圖

圖8 補償系統中U和Ucomp仿真結果局部放大圖

?

參考文獻

[1] 薛定宇 著.控制系統仿真與計算機輔助設計[M].北京:機械工業出版社出版社,2009.

[2] 很好的S函數學習資料-Simulink的S-Function編寫指導[EB/OL].

http://www.ilovematlab.cn/thread-71226-1-1.html.[2010-12-26].

[3] Simulink-s_function使用及應用舉例[EB/OL].

http://www.ilovematlab.cn/thread-62299-1-1.html.[2010-12-26].

[4] 祁麟.交流伺服系統齒隙非線性控制及其網絡化研究[D].碩士論文.南京理工大學,2006.

?

2010年12月26日晚上完成于njust 電工樓 310房間

?

CopyRight:版權所有若需轉載或使用請聯系作者
Email:dingqian12345@126.com

總結

以上是生活随笔為你收集整理的matlab中S函数的概念及使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。