天天看點

MATLAB/simulink_S函數基礎知識S-Function建立S函數模闆檔案詳解執行個體

S函數是simulink動态系統的核心,可以采用m代碼,C,C++等語言編寫S函數,由一種特定的文法構成,用來描述并實作連續系統,離散系統以及複合系統等動态系統。S函數可以接收來自simulink求解器的相關資訊,并對求解器發出的指令做出适當的響應

基礎知識

simulink

simulink是MATLAB中的可視化仿真工具,基于MATLAB采用框圖方式實作動态系統模組化、仿真和分析的過程。每個simulink子產品都有三個基本元素:輸入向量,狀态向量和輸出向量。分别用u,x,y表示。

MATLAB/simulink_S函數基礎知識S-Function建立S函數模闆檔案詳解執行個體

其中狀态向量最為重要,可以分為連續狀态,離散狀态或兩者混合狀态,實際運用中多用離散狀态。

MATLAB/simulink_S函數基礎知識S-Function建立S函數模闆檔案詳解執行個體

simulink的仿真過程包含兩個主要階段:初始化和運作階段,初始化主要是設定一些基本參數,如系統輸入輸出個數,狀态初值,采樣時間等;運作階段主要是計算輸出,更新離散狀态,計算連續狀态等;

對系統仿真控制是通過系統模型與求解器之間建立對話的方式進行,simulink将系統模型、子產品參數和系統方程傳遞給simulink求解器,求解器将計算出的系統狀态與仿真時間通過simulink傳遞給系統模型本身,通過這樣的互動作用方式完成動态系統仿真。

MATLAB/simulink_S函數基礎知識S-Function建立S函數模闆檔案詳解執行個體

S函數

過零

動态系統仿真過程中,過零是指系統模型中的信号或系統模型特征的某種改變,包括:1)信号在上一個仿真時間步長之内改變了符号。2)系統子產品在上個仿真時間步長改變了模式。對于離散子產品及其産生的離散信号不需要進行過零檢測

直接饋通(direct feedthrough)

直接饋通:表示系統的輸出或可變采樣時間是否受輸入控制

在編寫S-函數時,初始化函數中需要對sizes.DirFeedthrough 進行設定,如果輸出函數mdlOutputs或者對于變采樣時間的(mdlGetTimeOfNextVarHit)是輸入u的函數,則子產品具有直接饋通的特性sizes.DirFeedthrough=1;否則為0。

S-Function建立

1.通過在simulink中輕按兩下空白處輸入s function,回車确認,添加s函數,打開空白檔案

MATLAB/simulink_S函數基礎知識S-Function建立S函數模闆檔案詳解執行個體

2.通過library Browser打開,找到s-function examples,打開模闆檔案,更改函數名字與檔案名字一緻,另存為xiuMS

MATLAB/simulink_S函數基礎知識S-Function建立S函數模闆檔案詳解執行個體

S函數模闆檔案詳解

function [sys,x0,str,ts,simStateCompliance] = sfuntmpl(t,x,u,flag)
%主函數
%主函數包含四個輸出:
%                 sys數組包含某個子函數傳回的值(根據flag不同而不同)
%                 x0為所有狀态的初始化向量
%                 str是保留參數,總是一個空矩陣(一般置空即可)
%                 Ts傳回系統采樣時間(是一個1x2的向量,ts(1)是采樣周期,ts(2)是偏移量
%函數的四個輸入分别為采樣時間t、狀态x、輸入u和仿真流程控制标志變量flag(判斷目前狀态)
%輸入參數後面還可以接續一系列的附帶參數simStateCompliance
%% 
switch flag,
  case 0,
      [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes;
  % flag=0,表示目前處于初始化狀态,此時調用函數mdlInitializeSizes進行初始化,具體見下面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));
 
end
%主函數結束
%下面是各個子函數,即各個回調過程
function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes %初始化回調子函數
%提供狀态、輸入、輸出、采樣時間數目和初始狀态的值
%初始化階段,标志變量flag首先被置為0,S-function首次被調用時
%該子函數首先被調用,且為S-function子產品提供下面資訊
%該子函數必須存在
sizes = simsizes;%生成sizes資料結構,資訊被包含在其中
sizes.NumContStates  = 0;%連續狀态數,預設為0
sizes.NumDiscStates  = 0;%離散狀态數,預設為0
sizes.NumOutputs     = 0;%輸出個數,預設為0
sizes.NumInputs      = 0;%輸入個數,預設為0
sizes.DirFeedthrough = 1;%是否存在直饋通道,1存在,0不存在
sizes.NumSampleTimes = 1;%采樣時間個數,至少是一個
sys = simsizes(sizes);%傳回size資料結構所包含的資訊
x0  = [];%設定初始狀态
str = [];%保留變量,置空即可
ts  = [0 0];%設定采樣時間,若采樣周期設為0,則為連續系統
simStateCompliance = 'UnknownSimState';

function sys=mdlDerivatives(t,x,u)%計算導數回調子函數(計算連續狀态的微分)
%給定t,x,u計算連續狀态的導數,可以在此給出系統的連續狀态方程
%該子函數可以不存在
sys = [];%sys表示狀态導數,即dx

function sys=mdlUpdate(t,x,u)%狀态更新回調子函數(計算下一個離散狀态)
%給定t、x、u計算離散狀态的更新
%每個仿真步内必然調用該子函數,不論是否有意義
%除了在此描述系統的離散狀态方程外,還可以在此添加其他每個仿真步内都必須執行的代碼
sys = [];%sys表示下一個離散狀态,即x(k+1)

function sys=mdlOutputs(t,x,u)%計算輸出回調函數,給定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 = [];
           

s函數控制流程圖

MATLAB/simulink_S函數基礎知識S-Function建立S函數模闆檔案詳解執行個體

執行個體

以S函數完成對輸入信号運算:   y = 2 u \ y=2 u  y=2u

在模闆檔案中隻需将輸入輸出改為1,在回調函數mdlOutputs中輸入狀态方程   s y s = 2 ∗ u \ sys=2*u  sys=2∗u即可

function [sys,x0,str,ts,simStateCompliance] = xiuMS(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));
end
function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes
sizes = simsizes;
sizes.NumContStates  = 0;
sizes.NumDiscStates  = 0;
sizes.NumOutputs     = 1;
sizes.NumInputs      = 1;
sizes.DirFeedthrough = 1;
sizes.NumSampleTimes = 1;   % at least one sample time is needed
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 = 2*u;
function sys=mdlGetTimeOfNextVarHit(t,x,u)
sampleTime = 1;    %  Example, set the next hit to be one second later.
sys = t + sampleTime;
function sys=mdlTerminate(t,x,u)
sys = [];


           

建立如圖所示simulink框圖,得到仿真結果

MATLAB/simulink_S函數基礎知識S-Function建立S函數模闆檔案詳解執行個體

繼續閱讀