s function
s function
S Function
定义
S-functions (system-function) provide a mechanism for extending the capability of simulink environment using the mex utility.
S-function 定义了在仿真环境中一个 block 是如何执行的,包含:initialization, update, derivates, output 和 termination. 在其中的每一个步骤,simulink engine 都会调用一个 method 去实现具体的细节。
首先,为了理解 s function 怎么工作的,可以参考 simulink 执行细节 。
Simulink 模块的数学表述
一个 Simulink 模块可以认为有以下成分组成:
- 输入集合
- 状态集合
- 参数集合
- 输出集合
可以表示成下面的数学形式:
其中 是系统状态, 是系统输入, 是系统输出。
仿真阶段分析
可以参考 simulink 执行细节 。
S Function 回调函数
在 simulink 仿真过程中,会执行不同的回调函数,可以分类为下列部分:
- 编译阶段: Simulink engine 初始化 s function
- 将库块合并到模型中,并传播信号宽度、数据类型和样本时间
- 设置输入输出端口数量和维度
- 计算模块参数,分配模块内存
- 计算输出阶段
- 计算系统输出,满足所有输出端口的条件,使得下次仿真正常执行
- 更新离散状态
- 更新系统的模块状态
- 初始化和终止方法
- 这些可选方法只执行一次 S-function 所需的初始化和终止活动。初始化活动可能包括设置用户数据,或在 s 函数中初始化状态向量。终止方法执行诸如在终止仿真或从模型中删除 S-function 块时所需的内存释放等任何操作
- 集成部分
- 这适用于具有连续状态和/或非抽样零交叉的模型。如果你的 s 函数有连续的状态,引擎在小的时间步上调用你的 s 函数的输出和导数部分。这样求解器就可以计算 s 函数的状态。如果您的 s 函数具有非采样的零交叉点,引擎也会在较小的时间步骤中调用 s 函数的输出和零交叉点部分,以便它可以定位零交叉点。
更细致的结构可以参考 S-Function Concepts 。
此外,需要注意 s function 与其余实现方式的区别,参考下表:
Compare and contrast features supported by different types of S-function implementations.
S-Function Features
The following tables give overviews of the features supported by different types of S-functions. The first table focuses on handwritten S-functions. The second table compares the features of S-functions automatically generated by the S-Function Builder or Legacy Code Tool.
Features of Hand-Written S-Functions
Feature | Level-1 MATLAB S-Function | Level-2 MATLAB S-Function | Handwritten C MEX S-Function |
---|---|---|---|
Data types | Supports signals with a data type of double . | Supports any data type supported by Simulink® software, including fixed-point types. | Supports any data type supported by Simulink software, including fixed-point types. |
Numeric types | Supports only real signals. | Supports real and complex signals. | Supports real and complex signals. |
Frame support | Does not support frame-based signals. | Supports framed and unframed signals. | Supports framed and unframed signals. |
Port dimensions | Supports vector inputs and outputs. Does not support multiple input and output ports. | Supports scalar, 1-D, and multidimensional input and output signals. | Supports scalar, 1-D, and multidimensional input and output signals. |
S-function API | Supports only mdlInitializeSizes , mdlDerivatives , mdlUpdate , mdlOutputs , mdlGetTimeOfNextVarHit , and mdlTerminate . | Supports a larger set of the S-function API. See Level-2 MATLAB S-Function Callback Methods for a list of supported methods. | Supports the entire S-function API. |
Code generation support | Does not support code generation. | Requires a handwritten TLC file to generate code. | Natively supports code generation. Requires a handwritten TLC file to inline the S-function during code generation. |
Simulink Accelerator mode | Runs interpretively and is, therefore, not accelerated. | Provides the option to use a TLC file in Accelerator mode, instead of running interpretively. | Provides the option to use a TLC or MEX file in Accelerator mode. |
Model reference | Cannot be used in a referenced model. | Supports Normal and Accelerator mode simulations when used in a referenced model. Requires a TLC file for Accelerator mode. | Provides options for sample time inheritance and Normal mode support when used in a referenced model. See Model Reference Requirements and Limitations |
Simulink. and Simulink. support | Does not support these classes. | Supports Simulink. NumericType and Simulink. AliasType classes (see Configure Custom Data Types). | Supports all of these classes (see Configure Custom Data Types). |
Bus input and output signals | Does not support bus input or output signals. | Does not support bus input or output signals. | Supports nonvirtual bus input or output signals. |
Tunable and run-time parameters | Supports tunable parameters during simulation. Does not support run-time parameters. | Supports tunable and run-time parameters. | Supports tunable and run-time parameters. |
Work vectors | Does not support work vectors. | Supports DWork vectors (see Using DWork Vectors in Level-2 MATLAB S-Functions). | Supports all work vector types (see Types of DWork Vectors). |
Features of Automatically Generated S-Functions
Feature | S-Function Builder | Legacy Code Tool |
---|---|---|
Data types | Supports any data type supported by Simulink software, including fixed-point types. | Supports all built-in data types. To use a fixed-point data type, you must specify the data type as a Simulink.NumericType . You cannot use a fixed-point type with unspecified scaling. |
Numeric types | Supports real and complex signals. | Supports complex signals only for built-in data types. |
Frame support | Supports framed and unframed signals. | Does not support frame-based signals. |
Port dimensions | Supports scalar, 1-D, and multidimensional input and output signals. | Supports scalar, 1-D, and multidimensional input and output signals. |
S-function API | Supports creation of custom mdlInitializeSizes , mdlInitializeSampleTimes , mdlDerivatives , mdlUpdate , and mdlOutputs . Also allows for automatic generation of mdlStart and mdlTerminate . | Supports mdlInitializeSizes , mdlInitializeSampleTimes , mdlStart , mdlInitializeConditions , mdlOutputs , and mdlTerminate . |
Code generation support | Natively supports code generation. Also, automatically generates a TLC file for inlining the S-function during code generation. | Natively supports code generation optimized for embedded systems. Also, automatically generates a TLC file that supports expression folding for inlining the S-function during code generation. |
Simulink Accelerator™ mode | Uses a TLC file in Accelerator mode, if the file was generated. Otherwise, uses the MEX file. | Provides the option to use a TLC or MEX file in Accelerator mode. |
Model reference | Uses default behaviors when used in a referenced model. | Uses default behaviors when used in a referenced model. |
Simulink.AliasType and Simulink.NumericType | Does not support these classes. | Supports Simulink.AliasType and Simulink.NumericType . |
Bus input and output signals | Supports bus input and output signals. See sfbuilder_bususage for an example. | Supports bus input and output signals. You must define a Simulink.Bus object in the MATLAB® workspace that is equivalent to the structure of the input or output used in the legacy code. Does not support bus parameters. |
Tunable and run-time parameters | Supports tunable parameters only during simulation. Supports run-time parameters. | Supports tunable and run-time parameters. |
Work vectors | Does not provide access to work vectors. | Supports DWork vectors with the usage type SS_DWORK_USED_AS_DWORK . See Types of DWork Vectors for a discussion on the different DWork vector usage types. |
S-Function Limitations
The following table summarizes the major limitations of the different types of S-functions.
Implementation | Limitations |
---|---|
Level-1 MATLAB S-function | Does not support the majority of S-function features. See the S-Function Features and Limitations section for information on what features a Level-1 MATLAB S-function does support. |
Level-2 MATLAB S-functions |
|
Handwritten C MEX S-function | Supports model reference with some limitations. See S-Functions in Referenced Models. |
S-Function Builder |
NoteS-functions with one input and one output port can have dynamically-sized signals |
Legacy Code Tool |
|
可以发现,建议使用 level-2 s-function。
实现 S-function
基本介绍
参考: Write Level-2 MATLAB S-Functions - MATLAB & Simulink (mathworks.com)
需要注意,实现 s-function (level-2) 在细节上有很多和实现 C MEX s-function 接近,因此也可以参考 C MEX 的实现方式。
为了实现 s-function (level-2) 的功能,matlab 将一个运行时对象作为参数传送到回调方法中。运行时对象实际上充当了 matlab 的 s-function 模块代理,使其能够在仿真期间设置、访问模型属性。
在 simulink engine 调用 level-2 的 s-function 回调函数时,它将一个 Simulink.MSFcnRunTimeBlock
类的实例作为运行时对象传递给回调函数 (和 CMEX s function 的 SimStruct 结构体作用类似)。注意,运行时对象不支持 matlab sparse matrices,因此 speye
等函数不支持使用。
note
collapse: open title: Note Other MATLAB programs besides MATLAB S-functions can use run-time objects to obtain information about a MATLAB S-function in a model that is simulating. See Access Block Data During Simulation in Using Simulink for more information.
从模板开始
使用 Level-2 MATLAB S-function template `msfuntmpl_basic ,其中带有较多的注释。
参考 Level-2 MATLAB S-Function Callback Methods 后,逐步介绍如何完成一个 s function。
模型可以参考 [msfcndemo_sfundsc2
](assets/msfcndemo_sfundsc2](./assets/msfcn_unit_delay.m) :
模型 Setup
修改运行时对象的属性:
NumInputPorts
和NumOutputPorts
为 1 来实现 1 in 1 out。调用运行时对象的方法: SetPreCompInpPortInfoToDynamic 和 SetPreCompOutPortInfoToDynamic SetPreCompOutPortInfoToDynamic 来表明输入输出 ports 从模型继承编译的属性,比如数据类型,数据维度,采样率等。
设置运行时对象的
InputPort
的DirectFeedthrough
属性为 false,表明输入 port 没有直接的反馈输入。为所有其余的输入输出 port 的属性保留原样,并为 Dimensions、DatatypeID 和 Complexity 属性设置的值覆盖使用 SetPreCompInpPortInfoToDynamic 和 SetPreCompOutPortInfoToDynamic 方法继承的值。设置
NumDialogPrms
属性为 1 来初始化 s function 的的 dialog parameter。设置
SampleTimes
属性为 [-1, 0] 来继承采样时间。关于采样时间,可以参考 采样时间类型。调用
RegBlockMethod
方法来注册下列回调函数PostPropagationSetup
InitializeConditions
Outputs
Update
将模板中其余注册的回调函数删除。此外,在调用
RegBlockMethod
方法时,第一个参数是 s function API method 的名字,第二个输入参数是对应本地处理这些函数的名字,比如block.RegBlockMethod('PostPropagationSetup',@DoPostPropSetup);
下面这是一个初始化的例子,来源于 `msfcn_unit_delay :
function setup(block) %% Register a single dialog parameter block.NumDialogPrms = 1; %% Register number of input and output ports block.NumInputPorts = 1; block.NumOutputPorts = 1; %% Setup functional port properties to dynamically %% inherited. block.SetPreCompInpPortInfoToDynamic; block.SetPreCompOutPortInfoToDynamic; %% Hard-code certain port properties(choose from this and upper one) block.InputPort(1).Dimensions = 1; block.InputPort(1).DirectFeedthrough = false; block.OutputPort(1).Dimensions = 1; %% Set block sample time to [0.1 0] block.SampleTimes = [0.1 0]; %% Register methods block.RegBlockMethod('PostPropagationSetup',@DoPostPropSetup); block.RegBlockMethod('InitializeConditions',@InitConditions); block.RegBlockMethod('Outputs', @Output); block.RegBlockMethod('Update', @Update);
如果 s function 需要连续状态,使用
NumContStates
知名连续状态的数目,离散状态不需要这个。
需要注意,如果使用的s function 作为源信号输出,那么需要指定其输出模式,是采样信号输出还是帧输出。可以参考 Sample- and Frame-Based Concepts - MATLAB & Simulink (mathworks.com)。
具体代码参考如下:
block.OutputPort(1).SamplingMode = 'Sample'; % sample mode
block.OutputPort(1).SamplingMode = 'Frame'; % frame mode
关于 Frame
模式参考 sfundemos
下 matlab s fucntion 中的 Frame signals
。
我自己实现的输出常值信号的代码如下:
function msfuntmpl_basic(block)
%MSFUNTMPL_BASIC A Template for a Level-2 MATLAB S-Function
% The MATLAB S-function is written as a MATLAB function with the
% same name as the S-function. Replace 'msfuntmpl_basic' with the
% name of your S-function.
% Copyright 2003-2018 The MathWorks, Inc.
%%
%% The setup method is used to set up the basic attributes of the
%% S-function such as ports, parameters, etc. Do not add any other
%% calls to the main body of the function.
%%
setup(block);
%endfunction
%% Function: setup ===================================================
%% Abstract:
%% Set up the basic characteristics of the S-function block such as:
%% - Input ports
%% - Output ports
%% - Dialog parameters
%% - Options
%%
%% Required : Yes
%% C MEX counterpart: mdlInitializeSizes
%%
function setup(block)
% Register number of ports
block.NumInputPorts = 0;
block.NumOutputPorts = 1;
% Setup port properties to be inherited or dynamic
block.SetPreCompInpPortInfoToDynamic;
block.SetPreCompOutPortInfoToDynamic;
% Override input port properties
% block.InputPort(1).Dimensions = 1;
% block.InputPort(1).DatatypeID = 0; % double
% block.InputPort(1).Complexity = 'Real';
% block.InputPort(1).DirectFeedthrough = true;
% Override output port properties
block.OutputPort(1).Dimensions = 1;
block.OutputPort(1).DatatypeID = 0; % double
block.OutputPort(1).Complexity = 'Real';
block.OutputPort(1).SamplingMode = 'Sample';
% Register parameters
block.NumDialogPrms = 1;
% Register sample times
% [0 offset] : Continuous sample time
% [positive_num offset] : Discrete sample time
%
% [-1, 0] : Inherited sample time
% [-2, 0] : Variable sample time
block.SampleTimes = [0 0];
% Specify the block simStateCompliance. The allowed values are:
% 'UnknownSimState', < The default setting; warn and assume DefaultSimState
% 'DefaultSimState', < Same sim state as a built-in block
% 'HasNoSimState', < No sim state
% 'CustomSimState', < Has GetSimState and SetSimState methods
% 'DisallowSimState' < Error out when saving or restoring the model sim state
block.SimStateCompliance = 'DefaultSimState';
%% -----------------------------------------------------------------
%% The MATLAB S-function uses an internal registry for all
%% block methods. You should register all relevant methods
%% (optional and required) as illustrated below. You may choose
%% any suitable name for the methods and implement these methods
%% as local functions within the same file. See comments
%% provided for each function for more information.
%% -----------------------------------------------------------------
% block.RegBlockMethod('PostPropagationSetup', @DoPostPropSetup);
% block.RegBlockMethod('InitializeConditions', @InitializeConditions);
% block.RegBlockMethod('Start', @Start);
block.RegBlockMethod('Outputs', @Outputs); % Required
% block.RegBlockMethod('Update', @Update);
% block.RegBlockMethod('Derivatives', @Derivatives);
% block.RegBlockMethod('Terminate', @Terminate); % Required
%end setup
%%
%% PostPropagationSetup:
%% Functionality : Setup work areas and state variables. Can
%% also register run-time methods here
%% Required : No
%% C MEX counterpart: mdlSetWorkWidths
%%
% function DoPostPropSetup(block)
% block.NumDworks = 1;
% block.Dwork(1).Name = 'x1';
% block.Dwork(1).Dimensions = 1;
% block.Dwork(1).DatatypeID = 0; % double
% block.Dwork(1).Complexity = 'Real'; % real
% block.Dwork(1).UsedAsDiscState = true;
%%
%% InitializeConditions:
%% Functionality : Called at the start of simulation and if it is
%% present in an enabled subsystem configured to reset
%% states, it will be called when the enabled subsystem
%% restarts execution to reset the states.
%% Required : No
%% C MEX counterpart: mdlInitializeConditions
%%
% function InitializeConditions(block)
%end InitializeConditions
%%
%% Start:
%% Functionality : Called once at start of model execution. If you
%% have states that should be initialized once, this
%% is the place to do it.
%% Required : No
%% C MEX counterpart: mdlStart
%%
% function Start(block)
% block.Dwork(1).Data = 0;
%end Start
%%
%% Outputs:
%% Functionality : Called to generate block outputs in
%% simulation step
%% Required : Yes
%% C MEX counterpart: mdlOutputs
%%
function Outputs(block)
block.OutputPort(1).Data = block.DialogPrm(1).Data;
%end Outputs
%%
%% Update:
%% Functionality : Called to update discrete states
%% during simulation step
%% Required : No
%% C MEX counterpart: mdlUpdate
%%
% function Update(block)
% block.Dwork(1).Data = block.InputPort(1).Data;
%end Update
%%
%% Derivatives:
%% Functionality : Called to update derivatives of
%% continuous states during simulation step
%% Required : No
%% C MEX counterpart: mdlDerivatives
%%
% function Derivatives(block)
%end Derivatives
%%
%% Terminate:
%% Functionality : Called at the end of simulation for cleanup
%% Required : Yes
%% C MEX counterpart: mdlTerminate
%%
% function Terminate(block)
%end Terminate
离散状态属性设置
对应 PostPropagationSetup
回调函数进行实现。注意 level 2 s function 将离散状态信息存储在 DWork Vector 中,参考 Use DWork Vectors in S-Functions - MATLAB & Simulink (mathworks.com)。
If multiple instances of your S-function can occur in a model, your S-function must use DWork vectors instead of global or static memory to store instance-specific values of S-function variables.
下面是对应上面代码中 DoPostPropSetup
的实现部分:
function DoPostPropSetup(block)
%% Setup Dwork
block.NumDworks = 1;
block.Dwork(1).Name = 'x0';
block.Dwork(1).Dimensions = 1;
block.Dwork(1).DatatypeID = 0;
block.Dwork(1).Complexity = 'Real';
block.Dwork(1).UsedAsDiscState = true;
这将 DWork 的名字设定为了 x0
。
初始化初始条件
初始化初始条件对应的 InitConditions
。这里有两种初始化方式:
Start
回调函数适用于在仿真开始仅调用一次的情形InitializeConditions
回调函数适用于这个 s function 包含于一个子系统 (subsystem) 中,且这个子系统会被重启的情形。会对重启的子系统中的对应变量重新初始化。
对下面例子,其使用了了 InitializeConditions
来设置离散状态的初值为使用的 dialog parameter 值。
function InitConditions(block)
%% Initialize Dwork
block.Dwork(1).Data = block.DialogPrm(1).Data;
这里 DialogPrm
属性可以参考 Pass Dialog Parameters to S-Functions - MATLAB & Simulink (mathworks.com),多输入的 Parameters 类似 1.0,2.0,3.0
对应三个输入参数。
note
collapse: open title: Note 注意这里1.0,2.0,3.0
不能写成[1.0,2.0,3.0]
,后者被认为是一个变量
对连续状态而言,使用类似 block.ContStates.Data(1) = 1.0;
的代码来初始化。
计算输出
对应 Outputs
回调函数的实现,这里输出为:
function Output(block)
block.OutputPort(1).Data = block.Dwork(1).Data;
计算微分
对连续状态而言,使用 Derivatives
回调函数对应的函数,计算连续的微分状态,其结果存储在 Derivatives
的属性中,比如下面这个就将第一个状态的微分设为了第一个输入信号:
block.Derivatives.Data(1) = block.InputPort(1).Data;
注意例子中并没有连续的状态,因此没有实现这一回调函数。
刷新状态
对应 Update
回调函数,实现刷新离散状态的代码。这里就将当前输入的数据付给离散状态的值:
function Update(block)
block.Dwork(1).Data = block.InputPort(1).Data;
结束程序
Perform any cleanup, such as clearing variables or memory, in the Terminate
method. Unlike C MEX S-functions, Level-2 MATLAB S-function are not required to have a Terminate
method.
进阶
对于可变 size 的输入输出,参考下面代码实现:
function setup(block)
% Register the properties of the output port
block.OutputPort(1).DimensionsMode = 'Variable';
block.RegBlockMethod('SetInputPortDimensionsMode', @SetInputDimsMode);
function DoPostPropSetup(block)
%Register dependency rules to update current output size of output port a depending on
%input ports b and c
block.AddOutputDimsDependencyRules(a, [b c], @setOutputVarDims);
%Configure output port b to have the same dimensions as input port a
block.InputPortSameDimsAsOutputPort(a,b);
%Configure DWork a to have its size reset when input size changes.
block.DWorkRequireResetForSignalSize(a,true);
function SetInputDimsMode(block, port, dm)
% Set dimension mode
block.InputPort(port).DimensionsMode = dm;
block.OutputPort(port).DimensionsMode = dm;
function setOutputVarDims(block, opIdx, inputIdx)
% Set current (run-time) dimensions of the output
outDimsAfterReset = block.InputPort(inputIdx(1)).CurrentDimensions;
block.OutputPort(opIdx).CurrentDimensions = outDimsAfterReset;
For information on additional callback methods, see Level-2 MATLAB S-Function Callback Methods. For a list of run-time object properties, see the reference page for Simulink.MSFcnRunTimeBlock
and the parent class Simulink.RunTimeBlock
.
更多例子
参考 S-Function Examples - MATLAB & Simulink (mathworks.com)
个人觉得这个限制积分器比较不错:
我自己写了一个倒立摆的模型,使用了连续状态,constates,可以参考一下:
模型物理模式参考:动力学建模-拉格朗日方程 - 知乎 (zhihu.com)
问题
DWork 目前只能存储向量,如何在 s function 中存储矩阵状态?
注意
- s function 中支持中间变量,比如下面代码 ok
function Outputs(block)
y = block.Dwork(1).Data;
block.OutputPort(1).Data = 0.2*sin(y(1));
end
- 连续状态没有维数的概念,只能为单维度的。