The use of s function in Matlab

Table of contents

0. Write in front

1. Writing the s-function

2. Continuous system model

3. sfuntmpl with Chinese annotations

0. Write in front

Recently, I used the s function of [matlab] in my final project. I will share my gains here. Welcome to correct me

Some concepts about the s-function are not described, and a lot of them are searched on the Internet. This article mainly shares the steps of writing the s function and some understanding of the code

(The first article, please take care)

1. Writing the s-function

First, open the template function and copy the code in sfuntmpl to your own m file

%case 0: initialization
function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes

sizes = simsizes; % structure used to set module parameters

sizes.NumContStates = 0; % number of continuous variables
sizes.NumDiscStates = 0; % number of discrete variables
sizes.NumOutputs = 0; % number of outputs
sizes.NumInputs = 0; % number of inputs
sizes.DirFeedthrough = 1; % whether the input directly affects the output
sizes.NumSampleTimes = 1; % at least one sample time

sys = simsizes(sizes);

% initialize initial conditions
x0 = [];

% Reserved
str = [];

% Initialize sample time
ts = [0 0]; %[0 0] continuous sampling
             %[0 1] Continuous sampling with small steps
             %[PERIOD OFFSET] discrete adoption time [sample time step]
             %[-2 0] When the sampling time of variable step size FLAG=4, get the next sampling time

% Specify simStateCompliance block value
simStateCompliance = 'UnknownSimState'; %'UnknownSimState' default setting
                                        %'DefaultSimState' is the same as the built-in block's simulation state
                                        %'HasNoSimState' has no simulation state
                                        %'DisallowSimState' Error saving or restoring model simulation state

②Then , modify the function name ( the name must be the same as the file name , here I use systemP.m)

sfuntmpl code:

switch flag
  case 0   
    [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes;

  case 1   
    sys=mdlDerivatives(t,x,u,name1,name2,name3);

  case 2    
    sys=mdlUpdate(t,x,u);

  case 3   
    sys=mdlOutputs(t,x,u,name1,name3);

  case 4  
    sys=mdlGetTimeOfNextVarHit(t,x,u);

  case 9   
    sys=mdlTerminate(t,x,u);

  otherwise 
    DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag));

end

Modified code: (no module parameters)

function sys=mdlDerivatives(t,x,u,name1,name2,name3)
sys = [];

function sys=mdlUpdate(t,x,u)
sys = [];

function sys=mdlOutputs(t,x,u,name1,name3)
sys = [];

Modified code: (with three module parameters)

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

switch  flag 
  case  0 %initialize 
    [sys,x0,str,ts,simStateCompliance] = mdlInitializeSizes;

  case  1 % Calculate the derivative of the continuous state 
    sys = mdlDerivatives(t,x,u);

  case  2 % Calculate the next discrete state   
    sys = mdlUpdate(t,x,u);

  case  3 % calculation output 
    sys = mdlOutputs(t,x,u);

  case  4 % Calculate the next sampling time 
    sys = mdlGetTimeOfNextVarHit(t,x,u);

  case  9 % system end 
    sys = mdlTerminate(t,x,u);

  otherwise  % other cases 
    DAStudio.error('Simulink : blocks:unhandledFlag', num2str(flag));

end

%case  0: Initialize 
function  [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes

sizes = simsizes; % structure used to set module parameters

sizes.NumContStates   = 2; %Number of continuous variables 
sizes.NumDiscStates   = 0; %Number of discrete variables 
sizes.NumOutputs      = 1; %Number of outputs 
sizes.NumInputs       = 2; %Number of inputs 
sizes.DirFeedthrough = 0; %Input Whether to directly affect the output 
sizes.NumSampleTimes = 1; % at least one sample time

sys = simsizes(sizes);

%Initialize initial conditions 
x0   = [0;0];

% reserved item 
str = [];

%  Initial sampling time 
ts   = [0 0]; %[0 0] Continuous sampling 
             %[0  1] Continuous sampling in small steps 
             %[PERIOD  OFFSET] Discrete adoption time [sampling time step] 
             %[-2  0] change The next sampling time is obtained when the sampling time of the step size is FLAG=4

% Specify simStateCompliance block value 
simStateCompliance = 'UnknownSimState'; %'UnknownSimState' default setting 
                                        %'DefaultSimState'   is the same as the simulation state of the built-in block 
                                        %'HasNoSimState'     has no simulation state 
                                        %'DisallowSimState'  Error saving or restoring model simulation state


%case 1: Calculate the differential  function of continuous state 
sys=mdlDerivatives(~,x,u) ut = u(2); Ml = u(1); sys = [0 1;0 1]*x+[1;0] *ut-[0;1]*Ml; 




%case  2: Calculate the next discrete state   
%sys = AX+BU 
function  sys=mdlUpdate(~,~,~) 
sys = [];

%case  3: Calculate output            
function  sys=mdlOutputs(~,x,~) 
sys = [1 0]*x;

%case  4: Use this function when calculating the next sampling time [-2 0] 
function  sys=mdlGetTimeOfNextVarHit(t,~,~) 
sampleTime = 1; % For example, after setting the next sampling time to 1s, 
sys = t + sampleTime ;

%case  9: System end 
function  sys=mdlTerminate(~,~,~) 
sys = [];

When using parameters with modules, you need to pass parameters in simulink. For example, in the figure below, pass parameters 1, 2, 3, corresponding to name1, name2, name3

Parameter meaning:

output enter
sys: Generic return value t: time
x0: state initial value x: status
str: reserved item (currently not used)  u: input
ts: sampling time setting

flag: flag bit

simStateCompliance: Simulation state settings Inputs that can add any number of simulink block parameters

Modify the initialization parameters (that is, flag is equal to 0)

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

switch  flag 
  case  0 %initialize 
    [sys,x0,str,ts,simStateCompliance] = mdlInitializeSizes;

  case  1 % Calculate the derivative of the continuous state 
    sys = mdlDerivatives(t,x,u);

  case  2 % Calculate the next discrete state   
    sys = mdlUpdate(t,x,u);

  case  3 % calculation output 
    sys = mdlOutputs(t,x,u);

  case  4 % Calculate the next sampling time 
    sys = mdlGetTimeOfNextVarHit(t,x,u);

  case  9 % system end 
    sys = mdlTerminate(t,x,u);

  otherwise  % other cases 
    DAStudio.error('Simulink : blocks:unhandledFlag', num2str(flag));

end

%case  0: Initialize 
function  [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes

sizes = simsizes; % structure used to set module parameters

sizes.NumContStates   = 0; %Number of continuous variables 
sizes.NumDiscStates   = 0; %Number of discrete variables 
sizes.NumOutputs      = 0; %Number of outputs 
sizes.NumInputs       = 0; %Number of inputs 
sizes.DirFeedthrough = 1; %Input Whether to directly affect the output 
sizes.NumSampleTimes = 1; % at least one sample time

sys = simsizes(sizes);

%Initialize initial conditions 
x0   = [];

% reserved item 
str = [];

%  Initial sampling time 
ts   = [0 0]; %[0 0] Continuous sampling 
             %[0  1] Continuous sampling in small steps 
             %[PERIOD  OFFSET] Discrete adoption time [sampling time step] 
             %[-2  0] change The next sampling time is obtained when the sampling time of the step size is FLAG=4

% Specify simStateCompliance block value 
simStateCompliance = 'UnknownSimState'; %'UnknownSimState' default setting 
                                        %'DefaultSimState'   is the same as the simulation state of the built-in block 
                                        %'HasNoSimState'     has no simulation state 
                                        %'DisallowSimState'  Error saving or restoring model simulation state


%case  1: Calculate the derivative of continuous state 
%sys = AX+BU 
function  sys=mdlDerivatives(t,x,u) 
sys = [];

%case  2: Calculate the next discrete state   
%sys = AX+BU 
function  sys=mdlUpdate(t,x,u) 
sys = [];

%case  3: Calculated output            
%sys = CX+DU 
function  sys=mdlOutputs(t,x,u) 
sys = [];

%case  4: Use this function when calculating the next sampling time [-2 0] 
function  sys=mdlGetTimeOfNextVarHit(t,x,u) 
sampleTime = 1; % For example, after setting the next sampling time to 1s, 
sys = t + sampleTime ;

%case  9: System end 
function  sys=mdlTerminate(t,x,u) 
sys = [];

There are three main situations in this step:

  • continuous system

Continuous system modification: number of continuous variables, number of inputs, number of outputs, x0 initial condition

  • discrete system

Discrete system modification: number of discrete variables, number of inputs, number of outputs, x0 initial condition, sampling time

  • pure mathematics

Modified by the function that calculates the output from the input: the number of inputs, the number of outputs

Selection of simStateCompliance: There is no problem using the ‘default settings’ here in general. When I was doing the final design, I only encountered a state problem when matlab ran the simulink simulation program. I changed the default setting to ‘the same as the simulation state of the built-in block’.

Modify ‘case 1+case 3’, ‘case 2+case 3’, ‘case 3’ according to the three situations mentioned in ‘step ③’

In most cases, the parameters are used here

(If you want to use parameters in initialization, it is not impossible, the precautions are the same)

In addition to the position modification mentioned in ‘step ②’, the parameters should also be modified in two places

First, in the function of switch-case, if you need to pass parameters when calling the function, you need to add parameters after the corresponding function

switch flag
  case 0   
    [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes;

  case 1   
    sys=mdlDerivatives(t,x,u,name1,name2,name3);

  case 2    
    sys=mdlUpdate(t,x,u);

  case 3   
    sys=mdlOutputs(t,x,u,name1,name3);

  case 4  
    sys=mdlGetTimeOfNextVarHit(t,x,u);

  case 9   
    sys=mdlTerminate(t,x,u);

  otherwise 
    DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag));

end

Second, when the parameters are defined

function sys=mdlDerivatives(t,x,u,name1,name2,name3)
sys = [];

function sys=mdlUpdate(t,x,u)
sys = [];

function sys=mdlOutputs(t,x,u,name1,name3)
sys = [];

The above two places must be used together

⑤Create a simulink module

After the s function is written, save it, open simulink, and search for s-function

Drag the s-function module into the workspace, double-click the module, add the s-function just saved in the s-function name, and enter the parameters in the s-function parameter.

2. Continuous system model case

Since I mainly use the continuous model, here I share the continuous system model and code

The continuous model is mainly a state space equation:

x is a continuous variable and u is the input

In the s-function module is single input, single output, we can use Mux and Dmux to increase input and output

The input n signals are distinguished by u(1), u(2)….u(n), and when the output m signals are in ‘case 3’, sys=[output 1; output 2;…; output m]

Continuous system model:

Code:

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

switch  flag 
  case  0 %initialize 
    [sys,x0,str,ts,simStateCompliance] = mdlInitializeSizes;

  case  1 % Calculate the derivative of the continuous state 
    sys = mdlDerivatives(t,x,u);

  case  2 % Calculate the next discrete state   
    sys = mdlUpdate(t,x,u);

  case  3 % calculation output 
    sys = mdlOutputs(t,x,u);

  case  4 % Calculate the next sampling time 
    sys = mdlGetTimeOfNextVarHit(t,x,u);

  case  9 % system end 
    sys = mdlTerminate(t,x,u);

  otherwise  % other cases 
    DAStudio.error('Simulink : blocks:unhandledFlag', num2str(flag));

end

%case  0: Initialize 
function  [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes

sizes = simsizes; % structure used to set module parameters

sizes.NumContStates   = 2; %Number of continuous variables 
sizes.NumDiscStates   = 0; %Number of discrete variables 
sizes.NumOutputs      = 1; %Number of outputs 
sizes.NumInputs       = 2; %Number of inputs 
sizes.DirFeedthrough = 0; %Input Whether to directly affect the output 
sizes.NumSampleTimes = 1; % at least one sample time

sys = simsizes(sizes);

%Initialize initial conditions 
x0   = [0;0];

% reserved item 
str = [];

%  Initial sampling time 
ts   = [0 0]; %[0 0] Continuous sampling 
             %[0  1] Continuous sampling in small steps 
             %[PERIOD  OFFSET] Discrete adoption time [sampling time step] 
             %[-2  0] change The next sampling time is obtained when the sampling time of the step size is FLAG=4

% Specify simStateCompliance block value 
simStateCompliance = 'UnknownSimState'; %'UnknownSimState' default setting 
                                        %'DefaultSimState'   is the same as the simulation state of the built-in block 
                                        %'HasNoSimState'     has no simulation state 
                                        %'DisallowSimState'  Error saving or restoring model simulation state


%case 1: Calculate the differential  function of continuous state 
sys=mdlDerivatives(~,x,u) ut = u(2); Ml = u(1); sys = [0 1;0 1]*x+[1;0] *ut-[0;1]*Ml; 




%case  2: Calculate the next discrete state   
%sys = AX+BU 
function  sys=mdlUpdate(~,~,~) 
sys = [];

%case  3: Calculate output            
function  sys=mdlOutputs(~,x,~) 
sys = [1 0]*x;

%case  4: Use this function when calculating the next sampling time [-2 0] 
function  sys=mdlGetTimeOfNextVarHit(t,~,~) 
sampleTime = 1; % For example, after setting the next sampling time to 1s, 
sys = t + sampleTime ;

%case  9: System end 
function  sys=mdlTerminate(~,~,~) 
sys = [];

3. sfuntmpl with Chinese annotations

Finally, here is a complete version of sfuntmpl with Chinese annotations

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

switch  flag 
  case  0 %initialize 
    [sys,x0,str,ts,simStateCompliance] = mdlInitializeSizes;

  case  1 % Calculate the derivative of the continuous state 
    sys = mdlDerivatives(t,x,u);

  case  2 % Calculate the next discrete state   
    sys = mdlUpdate(t,x,u);

  case  3 % calculation output 
    sys = mdlOutputs(t,x,u);

  case  4 % Calculate the next sampling time 
    sys = mdlGetTimeOfNextVarHit(t,x,u);

  case  9 % system end 
    sys = mdlTerminate(t,x,u);

  otherwise  % other cases 
    DAStudio.error('Simulink : blocks:unhandledFlag', num2str(flag));

end

%case  0: Initialize 
function  [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes

sizes = simsizes; % structure used to set module parameters

sizes.NumContStates   = 0; %Number of continuous variables 
sizes.NumDiscStates   = 0; %Number of discrete variables 
sizes.NumOutputs      = 0; %Number of outputs 
sizes.NumInputs       = 0; %Number of inputs 
sizes.DirFeedthrough = 1; %Input Whether to directly affect the output 
sizes.NumSampleTimes = 1; % at least one sample time

sys = simsizes(sizes);

%Initialize initial conditions 
x0   = [];

% reserved item 
str = [];

%  Initial sampling time 
ts   = [0 0]; %[0 0] Continuous sampling 
             %[0  1] Continuous sampling in small steps 
             %[PERIOD  OFFSET] Discrete adoption time [sampling time step] 
             %[-2  0] change The next sampling time is obtained when the sampling time of the step size is FLAG=4

% Specify simStateCompliance block value 
simStateCompliance = 'UnknownSimState'; %'UnknownSimState' default setting 
                                        %'DefaultSimState'   is the same as the simulation state of the built-in block 
                                        %'HasNoSimState'     has no simulation state 
                                        %'DisallowSimState'  Error saving or restoring model simulation state


%case  1: Calculate the derivative of continuous state 
%sys = AX+BU 
function  sys=mdlDerivatives(t,x,u) 
sys = [];

%case  2: Calculate the next discrete state   
%sys = AX+BU 
function  sys=mdlUpdate(t,x,u) 
sys = [];

%case  3: Calculated output            
%sys = CX+DU 
function  sys=mdlOutputs(t,x,u) 
sys = [];

%case  4: Use this function when calculating the next sampling time [-2 0] 
function  sys=mdlGetTimeOfNextVarHit(t,x,u) 
sampleTime = 1; % For example, after setting the next sampling time to 1s, 
sys = t + sampleTime ;

%case  9: System end 
function  sys=mdlTerminate(t,x,u) 
sys = [];

Leave a Comment

Your email address will not be published. Required fields are marked *