最新消息: USBMI致力于为网友们分享Windows、安卓、IOS等主流手机系统相关的资讯以及评测、同时提供相关教程、应用、软件下载等服务。

Simulink系列 —— S

IT圈 admin 4浏览 0评论

Simulink系列 —— S

文章目录

    • 为什么使用S-function
    • 函数形式
        • S-function的输入参数
        • S-function的输出参数
        • 信息的传递
    • 标准模板
    • 模块使用


从上图来看,S-function可支持多种语言编写,本文为MATLAB版使用笔记。

为什么使用S-function

博主个人认为,S-function可以看成一个单独的系统,在Simulink中,如果使用MATLAB Function模块,每次执行,仅仅是调用函数而已,无法记录上一次调用后产生的状态,而S-function则可以保存上一时刻状态,因此我认为这种情况下使用S-function能极大程度简化仿真过程。当然,是在不使用Simscape等一些可视化仿真的情况下~

个人使用过程的总结,如有错误还请指出!

S-function,即系统函数(System Function)的简称。S-函数由一种特定的语法构成,用来描述并实现连续系统、离散系统以及复合系统等动态系统;S-函数能够接受来自Simulink求解器的相关信息,并对求解器发出的命令作出适当的响应,这种交互作用非常类似于Simulink系统模块与求解器的交互作用。

函数形式

[sys,x0,str,ts]=functionName(t,x,u,flag,p1,p2,…)
% t为当前时间
% x为相应S-function模块的状态向量
% u是块的输入
% flag 用来指定被需要执行的任务
% p1,p2,...是模块参数

在模型仿真过程中,Simulink反复调用functionName,对于特定的调用使用flag来指示需执行的任务。

MATLAB安装目录R2019b\toolbox\simulink\blocks\sfuntmpl.m给出了S-function的模板。

标准格式如下:

仿真阶段被执行的程序对应的flag
初始化mdlInitializeSizes0
计算下一步的采样步长(仅用于变步长模块)mdlGetTimeOfNextVarHit4
计算输出mdlOutputs3
更新离散状态mdlUpdate2
计算导数mdlDerivatives1
结束仿真时的任务mdlTerminate9

S-function的输入参数

Simulink传递如下参数给S-function:

  • t:当前时间
  • x:状态向量
  • u:输入向量

S-function的输出参数

  • sys:通用的返回参数,返回值取决于flag
  • x0:初始状态值,若没有则为空,只作用于初始化阶段,其余阶段被忽略
  • str:MATLAB的S-function必须设置该元素为空矩阵
  • ts:两列的矩阵,包含块的采样时间和偏移量

对于ts

  1. 设置S-function在每个时间步(连续采样时间)都运行,ts=[0,0]
  2. 设置S-function按其所连接块的速率运行,ts=[-1,0]
  3. 设置其在仿真开始0.1秒后每0.25秒运行一次(离散采样时间),ts=[0.25,0.1]

可创建一个S-function按不同速率执行不同任务!

信息的传递

mdlInitializeSizes子函数开头必须先调用simsizes,将S-function信息加载到sizes中:

sizes = simsizes;

sizes结构说明如下:

结构说明
sizes.NumContStates连续状态的数量
sizes.NumDiscStates离散状态的数量
sizes.NumOutputs输出的数量
sizes.NumInputs输入的数量
sizes.DirFeedthrough直接馈通标志
sizes.NumSampleTimes采样时间的数量

设置完成以上信息后,需要再次调用simsizes,将其传递给保持Simulink所用信息的向量sys

sys = simsizes(sizes);

标准模板

function [sys,x0,str,ts,simStateCompliance] = sfuntmpl(t,x,u,flag)% 主函数switch flag,% Initialization %case 0,[sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes;% Derivatives %case 1,sys=mdlDerivatives(t,x,u);% Update %case 2,sys=mdlUpdate(t,x,u);% Outputs %case 3,sys=mdlOutputs(t,x,u);% GetTimeOfNextVarHit %case 4,sys=mdlGetTimeOfNextVarHit(t,x,u);% Terminate %case 9,sys=mdlTerminate(t,x,u);% Unexpected flags %otherwiseDAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag));end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%                    以下为子函数定义                    %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizessizes = simsizes;% 必须首先调用且必须存在sizes.NumContStates  = 0;% 连续状态数sizes.NumDiscStates  = 0;% 离散状态数sizes.NumOutputs     = 0;% 输出个数sizes.NumInputs      = 0;% 输入个数sizes.DirFeedthrough = 1;% 1为存在直接馈通,0为不存在sizes.NumSampleTimes = 1;% 采样时间个数,至少是1sys = simsizes(sizes);x0  = [];% 初始状态str = [];% str 置空ts  = [0 0];% 初始化采样时间数组function sys=mdlDerivatives(t,x,u)%该函数可无sys = [];%表示状态导数,即dxfunction sys=mdlUpdate(t,x,u)%每个仿真步都会调用该函数,在此描述离散状态方程和其他每个仿真步长必须执行的过程sys = [];function sys=mdlOutputs(t,x,u)%该函数必须存在sys = [];function sys=mdlGetTimeOfNextVarHit(t,x,u)%计算下一个采样时间,仅在系统为变采样时间系统时调用sampleTime = 1;    % 设置下一个采样时间为1s以后sys = t + sampleTime;%function sys=mdlTerminate(t,x,u)%仿真结束时调用,在此完成仿真结束的收尾工作sys = [];

模块使用

  • S-function name:填写Edit中写的M文件中的S-function函数名称
  • S-function parameters:填写需要输入的外部参数,多个变量使用,隔开
  • S-function modules:使用MATLAB写的不需要此参数,其他语言需要

Edit进入编辑模式,以增益模块为例:

function [sys,x0,str,ts,simStateCompliance] = mySfunDemo1(t,x,u,flag,gain)
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,gain);case 4,sys=mdlGetTimeOfNextVarHit(t,x,u);case 9,sys=mdlTerminate(t,x,u);otherwiseDAStudio.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; 
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,gain)
sys =gain*u;
function sys=mdlGetTimeOfNextVarHit(t,x,u)
sampleTime = 1;   
sys = t + sampleTime;
function sys=mdlTerminate(t,x,u)
sys = [];

封装变量输入框到模块:


注意,封装后,双击模块无法再打开设定输入参数的界面,此时按如下操作:
快捷键:Ctrl+U

设置模块输入的变量:


效果:


参考《MATLAB Simulink系统仿真超级学习手册》

Simulink系列 —— S

文章目录

    • 为什么使用S-function
    • 函数形式
        • S-function的输入参数
        • S-function的输出参数
        • 信息的传递
    • 标准模板
    • 模块使用


从上图来看,S-function可支持多种语言编写,本文为MATLAB版使用笔记。

为什么使用S-function

博主个人认为,S-function可以看成一个单独的系统,在Simulink中,如果使用MATLAB Function模块,每次执行,仅仅是调用函数而已,无法记录上一次调用后产生的状态,而S-function则可以保存上一时刻状态,因此我认为这种情况下使用S-function能极大程度简化仿真过程。当然,是在不使用Simscape等一些可视化仿真的情况下~

个人使用过程的总结,如有错误还请指出!

S-function,即系统函数(System Function)的简称。S-函数由一种特定的语法构成,用来描述并实现连续系统、离散系统以及复合系统等动态系统;S-函数能够接受来自Simulink求解器的相关信息,并对求解器发出的命令作出适当的响应,这种交互作用非常类似于Simulink系统模块与求解器的交互作用。

函数形式

[sys,x0,str,ts]=functionName(t,x,u,flag,p1,p2,…)
% t为当前时间
% x为相应S-function模块的状态向量
% u是块的输入
% flag 用来指定被需要执行的任务
% p1,p2,...是模块参数

在模型仿真过程中,Simulink反复调用functionName,对于特定的调用使用flag来指示需执行的任务。

MATLAB安装目录R2019b\toolbox\simulink\blocks\sfuntmpl.m给出了S-function的模板。

标准格式如下:

仿真阶段被执行的程序对应的flag
初始化mdlInitializeSizes0
计算下一步的采样步长(仅用于变步长模块)mdlGetTimeOfNextVarHit4
计算输出mdlOutputs3
更新离散状态mdlUpdate2
计算导数mdlDerivatives1
结束仿真时的任务mdlTerminate9

S-function的输入参数

Simulink传递如下参数给S-function:

  • t:当前时间
  • x:状态向量
  • u:输入向量

S-function的输出参数

  • sys:通用的返回参数,返回值取决于flag
  • x0:初始状态值,若没有则为空,只作用于初始化阶段,其余阶段被忽略
  • str:MATLAB的S-function必须设置该元素为空矩阵
  • ts:两列的矩阵,包含块的采样时间和偏移量

对于ts

  1. 设置S-function在每个时间步(连续采样时间)都运行,ts=[0,0]
  2. 设置S-function按其所连接块的速率运行,ts=[-1,0]
  3. 设置其在仿真开始0.1秒后每0.25秒运行一次(离散采样时间),ts=[0.25,0.1]

可创建一个S-function按不同速率执行不同任务!

信息的传递

mdlInitializeSizes子函数开头必须先调用simsizes,将S-function信息加载到sizes中:

sizes = simsizes;

sizes结构说明如下:

结构说明
sizes.NumContStates连续状态的数量
sizes.NumDiscStates离散状态的数量
sizes.NumOutputs输出的数量
sizes.NumInputs输入的数量
sizes.DirFeedthrough直接馈通标志
sizes.NumSampleTimes采样时间的数量

设置完成以上信息后,需要再次调用simsizes,将其传递给保持Simulink所用信息的向量sys

sys = simsizes(sizes);

标准模板

function [sys,x0,str,ts,simStateCompliance] = sfuntmpl(t,x,u,flag)% 主函数switch flag,% Initialization %case 0,[sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes;% Derivatives %case 1,sys=mdlDerivatives(t,x,u);% Update %case 2,sys=mdlUpdate(t,x,u);% Outputs %case 3,sys=mdlOutputs(t,x,u);% GetTimeOfNextVarHit %case 4,sys=mdlGetTimeOfNextVarHit(t,x,u);% Terminate %case 9,sys=mdlTerminate(t,x,u);% Unexpected flags %otherwiseDAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag));end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%                    以下为子函数定义                    %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizessizes = simsizes;% 必须首先调用且必须存在sizes.NumContStates  = 0;% 连续状态数sizes.NumDiscStates  = 0;% 离散状态数sizes.NumOutputs     = 0;% 输出个数sizes.NumInputs      = 0;% 输入个数sizes.DirFeedthrough = 1;% 1为存在直接馈通,0为不存在sizes.NumSampleTimes = 1;% 采样时间个数,至少是1sys = simsizes(sizes);x0  = [];% 初始状态str = [];% str 置空ts  = [0 0];% 初始化采样时间数组function sys=mdlDerivatives(t,x,u)%该函数可无sys = [];%表示状态导数,即dxfunction sys=mdlUpdate(t,x,u)%每个仿真步都会调用该函数,在此描述离散状态方程和其他每个仿真步长必须执行的过程sys = [];function sys=mdlOutputs(t,x,u)%该函数必须存在sys = [];function sys=mdlGetTimeOfNextVarHit(t,x,u)%计算下一个采样时间,仅在系统为变采样时间系统时调用sampleTime = 1;    % 设置下一个采样时间为1s以后sys = t + sampleTime;%function sys=mdlTerminate(t,x,u)%仿真结束时调用,在此完成仿真结束的收尾工作sys = [];

模块使用

  • S-function name:填写Edit中写的M文件中的S-function函数名称
  • S-function parameters:填写需要输入的外部参数,多个变量使用,隔开
  • S-function modules:使用MATLAB写的不需要此参数,其他语言需要

Edit进入编辑模式,以增益模块为例:

function [sys,x0,str,ts,simStateCompliance] = mySfunDemo1(t,x,u,flag,gain)
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,gain);case 4,sys=mdlGetTimeOfNextVarHit(t,x,u);case 9,sys=mdlTerminate(t,x,u);otherwiseDAStudio.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; 
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,gain)
sys =gain*u;
function sys=mdlGetTimeOfNextVarHit(t,x,u)
sampleTime = 1;   
sys = t + sampleTime;
function sys=mdlTerminate(t,x,u)
sys = [];

封装变量输入框到模块:


注意,封装后,双击模块无法再打开设定输入参数的界面,此时按如下操作:
快捷键:Ctrl+U

设置模块输入的变量:


效果:


参考《MATLAB Simulink系统仿真超级学习手册》

与本文相关的文章

发布评论

评论列表 (0)

  1. 暂无评论