主要内容

维护 1 级 MATLAB S-Function

关于 1 级 MATLAB S-Function 的维护

注意

本节提供的信息仅用于维护现有 1 级 MATLAB® S-Function。请使用更强大的 2 级 API 开发新的 MATLAB S-Function(请参阅编写 2 级 MATLAB S-Function)。与 2 级 MATLAB S-Function 相比,1 级 MATLAB S-Function 支持的 S-Function API 子集要小得多,并且与内置模块相比,其功能受限。

1 级 MATLAB S-Function 是以下形式的 MATLAB 函数:

[sys,x0,str,ts]=f(t,x,u,flag,p1,p2,...)

其中,f 是 S-Function 的名称。在模型仿真期间,Simulink® 引擎重复调用 f,使用 flag 参量指示特定调用要执行的任务。S-Function 执行任务并以输出向量形式返回结果。

1 级 MATLAB S-Function 参量

Simulink 引擎将以下参量传递给 1 级 MATLAB S-Function:

t当前时间
x状态向量
u输入向量
flag指示 S-Function 要执行的任务的整数值

下表描述 flag 可以采用的值,并列出每个值对应的 2 级 MATLAB S-Function 方法。

标志参量

1 级标志2 级回调方法描述
0setup定义基本 S-Function 模块特性,包括采样时间、连续和离散状态的初始条件以及 sizes 数组(有关 sizes 数组的描述,请参阅定义 S-Function 模块特性)。
1mdlDerivatives计算连续状态变量的导数。
2mdlUpdate更新离散状态、采样时间和主时间步要求。
3mdlOutputs计算 S-Function 的输出。
4mdlOutputs 方法更新运行时对象 NextTimeHit 属性以绝对时间计算下一个采样点的时间。仅当在 setup 方法中指定可变离散采样时间时,才使用此例程。
9mdlTerminate执行任何必要的仿真结束任务。

1 级 MATLAB S-Function 输出

1 级 MATLAB S-Function 返回包含以下元素的输出向量:

  • sys,泛型返回参量。返回值取决于 flag 值。例如,对于 flag = 3sys 包含 S-Function 输出。

  • x0,初始状态值(如果系统中没有状态,则为空向量)。除非 flag = 0,否则忽略 x0

  • str,最初用于将来用途。1 级 MATLAB S-Function 必须将此项设置为空矩阵 []

  • ts,包含模块采样时间和偏移量的一个两列矩阵(有关如何指定采样时间和偏移量的信息,请参阅使用 Simulink 中的指定采样时间)。

    例如,如果希望 S-Function 在每个时间步(连续采样时间)运行,请将 ts 设置为 [0 0]。如果希望 S-Function 以与所连接模块相同的速率运行(继承的采样时间),请将 ts 设置为 [-1 0]。如果希望 S-Function 在仿真开始时间后 0.1 秒处开始每 0.25 秒运行一次(离散采样时间),请将 ts 设置为 [0.25 0.1]

    您可以创建执行多个任务的 S-Function,每个任务以不同采样率执行(即多速率 S-Function)。在这种情况下,ts 应按采样时间升序指定 S-Function 使用的所有采样率。例如,假设 S-Function 从仿真开始时间执行一项任务,每 0.25 秒执行一次,另一项任务在仿真开始时间后 0.1 秒处开始执行,每 1 秒执行一次。在这种情况下,S-Function 应将 ts 设置为等于 [.25 0; 1.0 .1]。这将导致 Simulink 引擎在以下时间执行 S-Function:[0 0.1 0.25 0.5 0.75 1 1.1 ...]。S-Function 必须在每个采样时间决定该时间要执行的任务。

    您还可以创建一个 S-Function,它连续(即在每个时间步)执行某些任务,而以离散间隔执行其他任务。

定义 S-Function 模块特性

为了让 Simulink 引擎识别 1 级 MATLAB S-Function,您必须向其提供有关 S-Function 的特定信息。这些信息包括输入数、输出数、状态数和其他模块特性。

要提供此信息,请在 S-Function 开头调用 simsizes 函数。

sizes = simsizes;

此函数返回未初始化的 sizes 结构体。您必须加载具有有关 S-Function 的信息的 sizes 结构体。下表列出了 sizes 结构体的字段并描述每个字段包含的信息。

sizes 结构体中的字段

字段名称描述
sizes.NumContStates连续状态的数量
sizes.NumDiscStates离散状态的数量
sizes.NumOutputs输出数目
sizes.NumInputs输入数目
sizes.DirFeedthrough直接馈通标志
sizes.NumSampleTimes采样时间数

在初始化 sizes 结构体后,再次调用 simsizes

sys = simsizes(sizes);

这会将 sizes 结构体中的信息传递给 sys,它是保留信息供 Simulink 引擎使用的向量。

处理 S-Function 参数

调用 1 级 MATLAB S-Function 时,Simulink 引擎始终将标准模块参数 txuflag 作为函数参量传递给 S-Function。引擎可以将用户指定的其他特定于模块的参数传递给 S-Function。用户在 S-Function 的“模块参数”对话框的 S-Function 参数字段中指定参数(请参阅向 S-Function 传递参数)。如果模块对话框指定其他参数,引擎会将这些参数作为附加函数参量传递给 S-Function。排列在 S-Function 参量列表中标准参量之后的其他参量按对应的参数在模块对话框中出现的顺序列出。您可以使用此特定于模块的 S-Function 参数能力,允许同一 S-Function 实现各种处理选项。

将 1 级 MATLAB S-Function 转换为 2 级

您可以通过将与每个 1 级 S-Function 标志相关联的代码映射到对应的 2 级 S-Function 回调方法,将 1 级 MATLAB S-Function 转换为 2 级 MATLAB S-Function。有关 1 级标志到 2 级回调方法的映射,请参阅标志参量表。此外:

  • PostPropagationSetup 方法中初始化的 DWork 向量中存储 2 级 MATLAB S-Function 的离散状态信息。

  • 使用 DialogPrm 运行时对象属性访问 2 级 MATLAB S-Function 对话框参数,而不是将其作为函数参量传递到 S-Function 中。

  • 对于具有可变采样时间的 S-Function,在 Outputs 方法中更新 NextTimeHit 运行时对象属性,为 2 级 MATLAB S-Function 设置下一个采样时间命中点。

例如,下表显示如何将 1 级 MATLAB S-Function sfundsc2.m 转换为 2 级 MATLAB S-Function。该示例在转换 1 级 MATLAB S-Function 时使用 2 级 MATLAB S-Function 模板 msfuntmpl_basic.m 作为起点。表中的行号对应 sfundsc2.m 中的代码行。

 sfundsc2_level2.m

行号sfundsc2.m 中的代码2 级 MATLAB 文件 (sfundsc2_level2.m) 中的代码
1
function [sys,x0,str,ts]= ...
  sfundsc2(t,x,u,flag)
function sfundsc2(block)
  setup(block);
function 行的语法更改为接受一个输入参量 block,即 2 级 MATLAB S-Function 模块的运行时对象。2 级 MATLAB S-Function 的主体包含调用局部 setup 函数的单行代码。
13 - 19
switch flag,

case 0,
[sys,x0,str,ts] = ...
   mdlInitializeSizes;
function setup(block)
flag 值为零对应调用 setup 方法。2 级 MATLAB S-Function 不使用 switch 语句调用回调方法。相反,局部 setup 函数注册在仿真期间直接调用的回调方法。
24 - 31
case 2,
   sys = mdlUpdate(t,x,u);

case 3,
   sys = mdlOutputs(t,x,u);
setup 函数注册与 flag23 关联的两个局部函数。
block.RegBlockMethod('Outputs' ,@Output);
block.RegBlockMethod('Update'  ,@Update);
53 - 66
sizes = simsizes;

sizes.NumContStates  = 0;
sizes.NumDiscStates  = 1;
sizes.NumOutputs     = 1;
sizes.NumInputs      = 1;
sizes.DirFeedthrough = 0;
sizes.NumSampleTimes = 1;

sys = simsizes(sizes);

x0  = 0;
str = [];
ts  = [.1 0];
setup 函数还初始化 2 级 MATLAB S-Function 的属性:
block.NumInputPorts  = 1;
block.NumOutputPorts = 1;
block.InputPort(1).Dimensions        = 1;
block.InputPort(1).DirectFeedthrough = false;
block.OutputPort(1).Dimensions       = 1;
block.NumDialogPrms     = 0;
block.SampleTimes = [0.1 0];
由于此 S-Function 具有离散状态,setup 方法注册 PostPropagationSetup 回调方法以初始化 DWork 向量,并注册 InitializeConditions 回调方法以设置初始状态值。
block.RegBlockMethod('PostPropagationSetup',...
 @DoPostPropSetup);
block.RegBlockMethod('InitializeConditions', ...
 @InitConditions);
56
sizes.NumDiscStates  = 1;
PostPropagationSetup 方法初始化存储单个离散状态的 DWork 向量。
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;
64
x0  = 0;
InitializeConditions 方法初始化离散状态值。
function InitConditions(block)

%% Initialize Dwork 
block.Dwork(1).Data = 0
77 - 78
function sys = ...
   mdlUpdate(t,x,u)

sys = u;    
Update 方法计算离散状态的下一个值。
function Update(block)
block.Dwork(1).Data = block.InputPort(1).Data;
88 - 89
function sys = ...
   mdlOutputs(t,x,u)
sys = x;
Outputs 方法计算 S-Function 的输出。
function Outputs(block)
block.OutputPort(1).Data = block.Dwork(1).Data;