Simulink之——S函數
在電氣工程專業的畢業設計,碩士論文以及課程報告中都少不了simulink模型模擬。而除了直接使用simulink模型庫中的元器件之外,還有一種比較看起來高大上的S函數法來建造屬於自己的模型。今天打算簡單的介紹一下simulink中的S-函數相關內容,主要是以下幾點:
- 什麼是S函數?
- S-函數的工作方式
- 如何在模型中使用S函數
- 一個例子分析
一.什麼是S函數?
S-函數是系統函數(System Function)的簡稱,在Simulink中用非圖形化的方式來描述一個模塊。一個完整的S-函數結構體系包含了描述一個動態系統所需要的全部能力。使用S-函數用戶可以向Simulink模型中添加自己的模塊,可以自由選擇使用MATLAB、C、C++等語言來創建自己的模塊。
二. S-函數的工作方式
若要創建屬於自己的S-函數,必須先知道S-函數的工作方式,而要理解S-函數的工作方式,先得了解simulink模擬模型的過程。
Simulink 中的每個模塊都有三個基本元素:輸入向量、狀態向量和輸出向量。分別表示為u ,x 和 y 。它們的關係如下所示:
在 Simulink 模塊的三個元素中,狀態向量是最重要的,也是三者之中最靈活的一個概念。在 Simulink 中狀態向量可以分為連續狀態、離散狀態或兩者的結合。輸入、輸出及狀態的關係可以用狀態方程描述:
Simulink 在模擬時,將上述方程對應不同的模擬階段,它們分別是計算模塊的輸出、更新離散狀態、計算連續狀態的微分。在模擬開始和結束,還包括初始化和結束模擬兩個階段。在每個階段,Simulink都反覆地調用模塊。
為了深入了解 S-函數的工作原理,還需了解一個概念:模擬循環(Simulation loop)。
一個模擬循環就是由模擬階段按一定順序組成的執行序列。對於每個模塊,經過一次模擬循環就是一個模擬步長, 而在同一個模擬步長中, 模型中各模塊的模擬按照事先排好的順序依次執行。
在模擬開始時Simulink 首先對模型進行初始化,此階段不屬於模擬循環的部分。在所有模塊都初始化後,模塊進入模擬循環,在模擬循環的每個階段,Simulink 都要調用模塊或者 S函數。
在調用模型中的S函數時,Simulink會調用用戶定義的S函數的常式來實現每個模擬階段要完成的任務。這些任務包括:
一、初始化:模擬開始前,Simulink 在這個階段初始化S函數,完成的主要工作包括:
1 、初始化包含S函數所有信息的結構體SimStruct;2、確定輸入輸出埠的數目和大小;3、確定模塊的採樣時間;4、分配內存和 Sizes 數組。二、計算下一個採樣時刻。如果模型使用變步長求解器,那麼就需要在當前模擬步長內確定下一個採樣點的時間,也即下一個模擬步長的大小;三、計算輸出:計算所有輸出埠的輸出值。四、更新離散狀態:此常式在每個模擬步長處都要執行一次,為當前時間的模擬循環更新離散狀態;五、數值積分:這個階段只有模塊具有連續狀態和非採樣過零點時才會存在。如果S函數存在連續狀態,Simulink 就在細化的小時間步長中調用S函數的輸出 mdlOutputs和微分 (mdlDerivatives)常式。如果存在非採樣過零點,Simulink將調用 S函數中的輸出 (mdlOutputs)和過零檢測(mdlZeroCrossngs)常式,以定位過零點。
三. 如何在模型中使用S函數?
在編寫M文件的S函數時,可以使用M文件的S函數模板 sfuntmpl.m 文件。該文件包含了所有的S函數的常式, 包含1個主函數和6個子函數。 在主函數程序使用一個多分支語句 (Switch-case)根據標誌將執行流程轉移到相應的常式函數。主函數的參數 Flag 標誌值是由系統(Simulink 引擎)調用時給出的。
打開模板文件的方法由兩種,用戶可以在 MATLAB 命令窗口中鍵入:
>> edit sfuntmpl或者雙擊 User-defined Function S-function ExamplesM-file S-functionsLeveal-1 M-fileS-functions1 Leveal-1 M-file template 模塊。%主函數
function [sys,x0,str,ts] = sfuntmpl(t,x,u,flag)switch flag,case 0,[sys,x0,str,ts]=mdlInitializeSizes;case 1,
sys=mdlDerivatives(t,x,u);case 2,sys=mdlUpdate(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 % 主函數結束,下面是各個子函數,即各個模擬常式% 初始化常式子函數:提供狀態、輸入、輸出、採樣時間數目和初始狀態的值。function [sys,x0,str,ts]=mdlInitializeSizessizes = simsizes; % 生成 sizes 數據結構sizes.NumContStates = 0; % 連續狀態數,預設為 0sizes.NumDiscStates = 0; % 離散狀態數,預設為 0sizes.NumOutputs = 0; % 輸出量個數,預設為 0sizes.NumInputs = 0; % 輸入量個數,預設為 0
sizes.DirFeedthrough = 1; % 有無直接饋入,有取 1,無取 0,預設為 1sizes.NumSampleTimes = 1; % 採樣時間個數,至少取 1sys = simsizes(sizes); % 返回 sizes 數據結構所包含的信息x0 = []; % 設置初始狀態的值str = []; % 保留變數,置為空矩陣,請忽略ts = [0 0]; % 採樣時間:[採樣周期 偏移量],採樣時間取 0 表示為連續系統% 計算導數常式子函數:計算連續狀態的導數,用戶需在此常式輸入連續狀態方程。% 該子函數可以不存在。function sys=mdlDerivatives(t,x,u)
sys = []; % sys 表示連續狀態導數% 狀態更新常式子函數:計算離散狀態的更新。% 用戶除了需在此輸入離散狀態方程外,還可以輸入其它每個模擬步長都有必要執行的代碼。% 該子函數可以不存在。function sys=mdlUpdate(t,x,u)sys = []; % sys 表示下一個離散狀態,即 x(k+1)% 計算輸出常式子函數: 計算模塊輸出。該子函數必須存在,用戶在此輸入系統的輸出方程。function sys=mdlOutputs(t,x,u)
sys = []; % sys 表示系統輸出 y% 計算下一個採樣時間, 只有變採樣時間系統才調用此模擬常式。function sys=mdlGetTimeOfNextVarHit(t,x,u)sampleTime = 1; % 設置下一次的採樣時間是 1s 以後sys = t + sampleTime; % sys 表示下一個採樣時間點% 模擬結束調用的常式函數:用戶需在此輸入結束模擬所需要的必要工作。function sys=mdlTerminate(t,x,u)sys = [];
我們可以看到主函數包含四個輸出參數:
sys 數組返回某個子函數,它的含義隨著調用子函數的不同而不同;
x0為所有狀態的初始化向量;
str 是保留參數,總是一個空矩陣;
Ts 是返回系統採樣時間。
主函數的四個輸入參數分別是採樣時間 t,狀態 x,輸入 u 和模擬流程式控制制標誌變數 flag。輸入參數後面還可以附加一系列用戶模擬需要的參數。編寫用戶自己的S函數時,應將函數名sfuntmpl 改為 S-function 模塊中設置的函數名。可能大家已經發現一個令人困惑的問題:不論在哪個模擬階段,常式子函數的返回變數都是 sys。要搞清楚這個問題,還要回到 Simulink 如何調用S函數上來。前面講過,Simulink 在每個模擬步長的模擬循環中的每個模擬階段都要調用S函數。在調用時,Simulink 不但根據所處的模擬階段為 flag 傳入不同的值,還會為返回變數 sys 指定不同的角色。即是說儘管是相同的 sys 變數,但在不同的模擬階段其意義是不相同的,這種變化由 Simulink 自動完成。四.一個例子分析
光說不練假把式,下面就具體舉個例子。
對於一個積分器,狀態方程為:
為了驗證模擬結果,先用數學知識解出
當u(t)=2時,y=2t+y(0)
在這個例子中有一個輸入,一個輸出,一個連續狀態變數。需要編寫mdlDeruvatives子函數,目的是把狀態變數x的導數通過sys返回。simulink模擬模型如下:

將MATLAB工作當前路徑改為積分器m函數和模所在路徑下,點擊運行。此時會出現一個錯誤:告訴我們沒有定義函數或者變數:initial_state

查看我們的S函數的m文件:

變數:initial_state是我們自己定義的一個變數,是一個額外的參數,這些參數必須在S函數的第一行的輸入參數中列出。此時雙擊S函數模塊,在參數表中寫入初值y(0)=5。


這裡只是舉了一個很簡單的例子,實際的課題研究中可能涉及到的研究對象要更加複雜,這裡只是拋磚引玉,希望給初學者一些幫助。
推薦閱讀:
※使用基於模型設計開發AUTOSAR軟體組件
※細節和效率,哪個更重要?
※simulink 里如何搭建運放?求指導
※半實物平台模擬和simulink模擬有何異同?
※如何在(matlab simulink)simpowersystem里連接一個可變電阻?


