Matlab之S-Function例項解析

S-Function是系統函式(System Function)的簡稱,可以十分方便地用來描述各種動態系統,尤其是複雜的動態系統,屬於Simulink動態系統的核心。我們常用的Simulink工具箱都是透過S-Function實現的,如果想開發一個新的模組或工具箱,S-Function可能是最好的選擇。

今天,將分兩部分內容來介紹S-Function。

1)S-Function簡介

:簡要介紹S-Function的關鍵資訊,理解S-Function的工作過程。

2)電機模型的S-Function實現

:以直流電機這一物理物件作為代表,透過S-Function實現電機的動態過程設計。

之前寫過一篇文章《Simulink中4種電機建模方式》,有朋友留言比較完美但缺少S-Function,今天藉著這個機會一併補上。

1、S-Function簡介

學習S-Function的最佳方式是先熟悉Matlab自帶的模板sfuntmpl。m,一般在以下路徑:C:\Program Files\MATLAB\toolbox\simulink\blocks。

一共40多行程式碼,主要包括1個主函式和6個子函式,模板程式碼如下:

function [sys,x0,str,ts,simStateCompliance] = sfuntmpl(t,x,u,flag)switch flag,  case 0,    [sys,x0,str,ts,simStateCompliance]=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    DAStudio。error(‘Simulink:blocks:unhandledFlag’, num2str(flag));endfunction [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizessizes = simsizes;sizes。NumContStates  = 0;sizes。NumDiscStates  = 0;sizes。NumOutputs     = 0;sizes。NumInputs      = 0;sizes。DirFeedthrough = 1;sizes。NumSampleTimes = 1;  sys = simsizes(sizes);x0  = [];str = [];ts  = [0 0];simStateCompliance = ‘UnknownSimState’;function sys=mdlDerivatives(t,x,u)sys = [];function sys= mdlUpdate (t,x,u)sys = [];function sys=mdlOutputs(t,x,u)sys = [];function sys=mdlGetTimeOfNextVarHit(t,x,u)sampleTime = 1;  sys = t + sampleTime;function sys=mdlTerminate(t,x,u)sys = [];

主函式:

透過flag來選擇執行對應的子函式。

mdlInitializeSizes:

定義系統的初始條件、取樣時間等。

mdlDerivatives:

計算連續狀態的微分,即dx/dt。

mdlUpdate:

計算離散狀態x(K+1)。

mdlOutputs:

計算輸出y。

mdlGetTimeOfNextVarHit:

計算離散狀態的下一次取樣時間。

mdlTerminate:

結束函式。

需要注意的是,對於特定的系統可能僅需要排程部分子函式即可完成系統的設計。例如,對於僅存在連續狀態的系統,只需要排程mdlInitializeSizes、mdlDerivatives、mdlOutputs、mdlTerminate等4個子函式。這些都是S-Function透過flag去自動實現的。

2、電機模型的S-Function實現

在介紹以前,先回顧一下前面介紹的狀態空間搭建電機模型的方法。

選取電流I、轉速w作為狀態變數,轉速w作為輸出,直流電機的狀態方程和輸出方程可表達為:

Matlab之S-Function例項解析

Matlab之S-Function例項解析

式中紅色部分分別對應系統矩陣A、b、C。使用State-Space模組,完成以上的狀態方程搭建,模型如下圖。

Matlab之S-Function例項解析

使用S-Function搭建電機模型時,會借用到上面的引數A、b、C。具體搭建步驟如下:

1)把模板sfuntmpl。m改為motor。m,並新建一個空的mdl檔案,也可以命名為motor。mdl。

Matlab之S-Function例項解析

兩個檔案放在一起並置於當前目錄下,不然m檔案後面無法被mdl檔案引用。

2)在工具箱中找到S-Function模組,並拖入模型中。

Matlab之S-Function例項解析

雙擊開啟,將S-Function name設定為motor,S-Function parameter設定為A、b、C。

Matlab之S-Function例項解析

3)點選Edit,即可開啟motor。m檔案,進行電機模型設計,修改部分程式碼,如下面註釋。

function [sys,x0,str,ts,simStateCompliance] = sfuntmpl(t,x,u,flag,A,b,C)  %%增加參變數switch flag,  case 0,    [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes;  case 1,    sys=mdlDerivatives(t,x,u,A,b); %%增加參變數  case 2,    sys=mdlUpdate(t,x,u);  case 3,    sys=mdlOutputs(t,x,u,C); %%增加參變數  case 4,    sys=mdlGetTimeOfNextVarHit(t,x,u);  case 9,    sys=mdlTerminate(t,x,u);  otherwise    DAStudio。error(‘Simulink:blocks:unhandledFlag’, num2str(flag));endfunction [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizessizes = simsizes;sizes。NumContStates  = 2; %%2個狀態變數sizes。NumDiscStates  = 0;sizes。NumOutputs     = 1; %%單輸入sizes。NumInputs      = 1; %%單輸出sizes。DirFeedthrough = 1;sizes。NumSampleTimes = 1; sys = simsizes(sizes);x0  = [0 0]; %%初始狀態為0str = [];ts  = [0 0];simStateCompliance = ‘UnknownSimState’;function sys=mdlDerivatives(t,x,u,A,b) %%增加參變數sys = A*x + b*u; %%計算狀態變數的導數function sys=mdlUpdate(t,x,u)sys = [];function sys=mdlOutputs(t,x,u,C) %%增加參變數sys = C*x; %%計算輸出function sys=mdlGetTimeOfNextVarHit(t,x,u)sampleTime = 1;  sys = t + sampleTime;function sys=mdlTerminate(t,x,u)sys = [];

4)在mdl模型中新增對應的輸入,並與狀態空間的建模方式對比,如下圖。

Matlab之S-Function例項解析

模擬結果如下圖所示,可以看出,兩種方法的電機轉速曲線完全一致,S-Function的電機建模正確。

Matlab之S-Function例項解析

以上,以電機模型為例,介紹了利用S-Function的方式來描述系統動態過程的方法。