matlab/simulink中带参数的S-Function(S函数)的写法
S函數的相關概念與寫法,直接在幫助文件中搜:【MATLAB S-Functions Create custom blocks defined】、【S-Function Concepts】等
?
S函數模塊可以從下圖中拖出來:
圖 1
其中S-Function是正宗的S函數模塊,旁邊還有一個S-Function builder是給新手用的,只要學會了S函數模塊,S builder模塊自然一看就懂。
使用S函數模塊的步驟:①寫S函數的.m文件, 并把m文件所在的文件夾加入搜索路徑,如下圖2所示。②在simulink中拖出S函數,并填上m文件的名字,如果有參數(下文會講到),也把參數名填上,如下圖3所示。然后就可以執行仿真了
圖2
圖3
?
下面是最關鍵的部分,如何寫S函數:
寫S函數的本質就是寫一堆回調函數,C/C++程序員對回調函數應該很熟悉了,既然是回調函數,那寫之前必須要知道形參和返回值的格式,這個格式從哪查?直接在matlab命令行執行:?edit sfuntmpl,就直接打開了官方提供的模板,連格式都不用查了,直接仿照官方模板把函數體改改蓋就行了,方便。
(1)S函數的總函數
把官方模板的代碼拷到一個新文件里,并命名為自定義名稱,我取的名字是oneOrderModule.m,然后把函數名也改成和文件名相同,我的是這樣的:function [sys,x0,str,ts,simStateCompliance] = oneOrderModule(t,x,u,flag, T)
我與官方版不同的是,自己加了一個參數T,如果你還想添加更多參數,直接在形參表里添加就行了。添加的形參的實參值,來自于圖3的第二個輸入框,這個輸入框可填常量,也可以填工作區變量名。
形參:①當前的仿真時間t,單位為秒,該參數可以用來描述變參數系統,例如你想實現【在t>2S時,把系統增益給改掉】這一功能,就可以通過判定t的值來實現;②x為狀態列向量;③輸入列向量u;④flag為當前狀態機的第幾步,例如實參送進來的flag=0代表S函數需要初始化,flag=1代表要更新連續狀態
返回值:在不同的狀態步下(也即flag不同時),返回值的意義是不同的,在模板文件的注釋中都講到了:
例如flag=0時,需要返回:輸入輸出狀態變量等的大小SIZES、狀態變量的初值X0等。。。
又如flag=3時,返回值sys代表輸出向量Y,也即狀態空間表達式第2式,Y=CX+DU
不同flag下返回值得寫法,將在下面的各個函數中依次講解
(2)系統初始化
當我么在函數中檢測到flag=0時,意味著simulnk需要我們返回系統初始化的一些信息。
實際上,我們可以直接把flag=0時需要執行的代碼直接寫在switch-case中,但是為了使程序更清晰,我們也仿照官方模板,在case中調用初始化函數mdlInitializeSizes,我們把代碼寫在初始化函數中。
此函數中,按照回調函數的要求,sys的返回要返回一些成員的尺寸大小,我們可以一個個為sys(1)、sys(2)。。等依次賦值,但我們不會這么做,因為官方模板為我們提供了一個輔助數據結構的實體simsizes,直接把他復制出來把成員值改好,再賦值給返回值sys即可。simsizes的成員有6個,其中有2個需要單獨講一下:
①直接饋通標志DirFeedthrough,這個東西實際上就是看看狀態空間表達式第2式Y=CX+DU中的D矩陣是否為0矩陣,如果不是,那我們必須把饋通標志設為1。從回調函數來看,只要我們把DirFeedthrough設成了1,那么當flag=3時,系統會把t、u兩個參數傳進總函數oneOrderModule中,如果DirFeedthrough設成了0,那么當flag=3時,我們在oneOrderModule函數或者mdlOutputs函數中中將無法讀到t的值(實際讀出來總是0),也無法讀到u的值(實際讀出來總是一個只含Nan元素的向量)。
②采樣時間矩陣的行數NumSampleTimes
這個東西有些復雜,從直觀上看,它決定了【采樣時間矩陣ts】的行數,ts矩陣是NumSampleTimes行2列的矩陣。ts的每一行均包含一個數據對:[ 采樣時間? ?偏移量 ],這些數據對不是亂填的,可選就這么幾種形式:
采樣時間可以理解為采樣周期,真正的采樣時刻=n*周期+偏移量。
對于連續系統,采樣時間應設為0,matlab也提供宏CONTINUOUS_SAMPLE_TIME,該宏的值=0。
對于固定步長的離散系統,可以直接設置采樣間隔和偏移,形如:[ 0.1? ?0.02 ]
對于變步長的離散系統,可以設置為:[VARIABLE_SAMPLE_TIME,? 0.0],這種參數需要同時把simulink求解器solver設置成變步長的。
繼承前一模塊的采樣點,可以設置為:[INHERITED_SAMPLE_TIME, FIXED_IN_MINOR_STEP_OFFSET或0]。
更多知識點,可以搜索這幾個宏名來學習。
?
(3)連續系統更新、離散系統更新
這兩個函數分別為mdlDerivatives和mdlUpdate,如果需要支持自定義的參數,那么直接修改函數的形參表即可,在我的例子中,我附加了一個T參數,那么我的連續系統更新函數是這樣的:
function sys=mdlDerivatives(t,x,u, T) A = [-1/T]; B = [1/T]; sys = A*x+B*u;原理是這樣的,典型一階系統的微分方程:
如果系統中存在離散狀態,那么就在mdlUpdate中寫出離散狀態空間表達式即可,如果沒有離散狀態,就直接sys返回空矩陣。
(4)輸出函數
function sys=mdlOutputs(t,x,u) C = [1 1]; D = [01];sys = C * x + D * u; %sys = [x t];這個也沒啥好說的,描述一下輸出向量即可。不過提醒一下,如果使用了 u或t 參數,不要忘記把饋通標志置1,否則在本函數中收不到t和u的實參值。
這個函數描述了兩個輸出: y(1)=x,y(2)=x+u
?
?
下面看一下仿真結果:
和預想的一樣,沒毛病。
總結
以上是生活随笔為你收集整理的matlab/simulink中带参数的S-Function(S函数)的写法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Shell脚本之sed的使用
- 下一篇: linux怎么看文件状态,linux查看