Simulink系列 —— S-function的使用笔记(1)
文章目录
- 为什么使用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 |
---|---|---|
初始化 | mdlInitializeSizes | 0 |
计算下一步的采样步长(仅用于变步长模块) | mdlGetTimeOfNextVarHit | 4 |
计算输出 | mdlOutputs | 3 |
更新离散状态 | mdlUpdate | 2 |
计算导数 | mdlDerivatives | 1 |
结束仿真时的任务 | mdlTerminate | 9 |
S-function的输入参数
Simulink传递如下参数给S-function:
- t:当前时间
- x:状态向量
- u:输入向量
S-function的输出参数
- sys:通用的返回参数,返回值取决于flag
- x0:初始状态值,若没有则为空,只作用于初始化阶段,其余阶段被忽略
- str:MATLAB的S-function必须设置该元素为空矩阵
- ts:两列的矩阵,包含块的采样时间和偏移量
对于ts
:
- 设置S-function在每个时间步(连续采样时间)都运行,
ts=[0,0]
- 设置S-function按其所连接块的速率运行,
ts=[-1,0]
- 设置其在仿真开始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-function的使用笔记(1)相关推荐
- Zynq-7000系列之linux开发学习笔记:编译Linux内核和制作设备树(六)
开发板:Zynq7030数据采集板 PC平台:Ubuntu-18.04 + MobaXterm 开发环境:Xilinx Vivado + SDK -18.3 交叉编译工具:arm-linux-gnue ...
- 基于赛灵思7系列+vivado软件的入门笔记
基于赛灵思7系列+vivado软件的入门笔记 0. 基础准备 0.0. 参考资料 0.1. start up 写一个计数器,实现LED灯闪烁 0.2 常见语法相关的注意事项 0. 基础准备 0.0. ...
- MATLAB写UCB算法,科学网—【RL系列】Multi-Armed Bandit问题笔记——UCB策略实现 - 管金昱的博文...
本篇主要是为了记录UCB策略在解决Multi-Armed Bandit问题时的实现方法,涉及理论部分较少,所以请先阅读Reinforcement Learning: An Introduction ( ...
- 吴恩达老师DeepLearning系列课程最详细学习笔记之23—Jupyter Ipython笔记本的快速指南
教程是本人学习吴恩达老师DeepLearing系列课程中整理的最为详细的学习笔记.学习视频主要来自B站[双语字幕]吴恩达深度学习deeplearning.ai_哔哩哔哩_bilibili?,以及Dee ...
- 微信小程序应用开发赛全国三等奖总结,以及关键点汇总,开发基本功系列(含云开发笔记、wxcharts数据可视化)
在华南赛区近千支队伍里以第四名脱颖而出,成为唯一一支入围国赛的专科队伍. 当时是专科大二,省赛作品提交剩下两个月左右我们才报名,然后开始学小程序,边学边开发,没想到第一次参加比赛就拿到国奖,兴奋了好久 ...
- onenote快捷键_onenote链接系列:4种链接笔记的地址
前面已经讲过,链接笔记的内容来源窗口可以是以下四种:onenote.Word.PPT或者IE浏览器.不同软件下形成的链接笔记,具体的链接地址是不同的. 本文详细解析4种链接笔记的链接地址结构. 1 w ...
- (java)玩转算法系列-数据结构精讲[学习笔记](一)不要小瞧数组
前言: 课程:玩转算法系列–数据结构精讲 更适合0算法基础入门到进阶(java版) 此处是个人学习笔记,用作回顾用途 不要小瞧数组 1.使用java中的数组 Main.java: public cla ...
- 【RL系列】Multi-Armed Bandit问题笔记
原文地址:http://blog.sciencenet.cn/home.php?mod=space&uid=3189881&do=blog&id=1121466 这是我学习Re ...
- 详谈PCB电路板结构系列之PCB材料组成笔记
可能有一些硬件工程师会画PCB,但是对于PCB的构造,缺模模糊糊,对PCB的板层结构没有清晰地认知,我认为,会画PCB,不仅仅就局限于对简单的PCB的绘制,要在高层的PCB有所提升,但前提要了解PCB ...
最新文章
- 20135231 —— 第六周任务总结报告
- nginx 内置变量
- SparkStreaming -Kafka数据源
- 看看这帮猴子的伪原创工具
- Pytorch 一种调整学习率的思路
- 强悍的 ubuntu —— ubuntu 与 windows 双系统的交互
- Charles青花瓷安装使用及断点设置
- mybatis批量操作(批量查询,批量插入,批量更新)
- 简析平衡树(一)——替罪羊树 Scapegoat Tree
- excel f2键功能_您的功能键在Microsoft Excel中做什么
- 多个域名指向一个ip
- 专家议微软黑屏:目的正当 手段未必正当
- 抖音直播间弹幕rpc学习
- np.subtract.outer()
- 深入探索透视纹理映射(下)
- 骂人的到底是些什么人
- 使用Charles代理工具,导致浏览器无法打开网页
- 788错误。L2TP 连接尝试失败,因为安全层不能身份验证远程计算机。怎么解决?...
- Python实现树结构的两种方式
- 词向量:对word2vec的理解