# The use of s function in Matlab

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

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

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

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

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

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:

$\hat{X} = Ax+Bu$

$Y = Cx+Du$

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:

$\begin{bmatrix} \dot{x}1(t)\\ \dot{x}2(t) \end{bmatrix} = \begin{bmatrix} 0 & 1\\ 0 & 1 \end{bmatrix}\begin{bmatrix} x1(t))\\ x2(t)) \end{bmatrix}+\begin{bmatrix} 1\\0 \end{bmatrix} u(t) - \begin{bmatrix} 0\\1 \end{bmatrix} M(t)$

$y = \begin{bmatrix} 1 & 0 \end{bmatrix}\begin{bmatrix} x1(t)\\ x2(t)\end{bmatrix}$

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

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

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 = [];```