Simulink S-function 学习及使用实例_simulink sfunction-程序员宅基地

技术标签: matlab  simulink  其他  仿真器  

前言

本文介绍了s-function 的基本概念和使用案例。

1. 概述

函数是系统函数(System Function)的简称,在Simulink中用非图形化的方式来描述一个模块。一个完整的S-函数结构体系包含了描述一个动态系统所需要的全部能力。使用S-函数用户可以向Simulink模型中添加自己的模块,可以自由选择使用MATLAB、C、C++等语言来创建自己的模块。

1.1 基本概念

1. 直接馈通(direct feedthrough)
直接馈通表示系统的输出或可变采样时间是否受到输入的控制。

a. 输出函数(mdlOutputs或flag==3)是输入u的函数。即,如果输入u在mdlOutputs中被访问,则存在直接馈通。

b. 对于一个变步长S-Function的“下一个采样时间”函数(mdlGetTimeOfNextVarHit或flag==4)中可以访问输入u。

例如,一个需要其输入的系统(也就是具有直接馈通)是运算y=kXu,其中,u是输入,k是增益,y是输出。

又如,一个不需要其输入的系统(也就是没有直馈通)是一种简单的积分运算:

输出:y=x;

导数:dx/dt=u

其中,x是状态,dx/dt是状态对时间的导数,u是输入,y是输出。

正确设置直接馈通标志是十分重要的,因为它影响模型中块的执行顺序,并可用检测代数环。
**2. 动态维矩阵 **
只可以有一个输入端口 ,但宽度可变,即使用mux 将多路信号转换为一路信号
在这里插入图片描述
3. 采样时间和偏移量
4. 可变采样时间
5. 继承采样时间

1.2 s-functiong 模块

在这里插入图片描述
S-function name: 填入相应的.m文件,建立联系。
S-function parameters: 填入需要输入的外部参数名称,如a 、b、c
如下s-functino中a,b,c ,即为外部参数,需在此定义。

function [sys,x0,str,ts,simStateCompliance] = sfuntmpl(t,x,u,flag,a,b,c)

S-function modules: 使用C语言编写并用MEX工具编译的C MEX文件时,才需要填写该参数。

1.3 在模型中使用

1.在matlab安装目录中搜索到S-functionde模板文件sfuntmpl.m, 另存一份为test.m
2.找到函数mdlInitializeSizes,修改如下

sizes.NumOutputs     = 1;
sizes.NumInputs      = 1;

3.找到mdlOutputs(t,x,u)

sys = 2*u;

4.建立如下模型
在这里插入图片描述
5. 仿真结果如下
在这里插入图片描述

1.4 何时使用S-function

1.向SIMULINK增加一些新的通用模块;增加作为硬件设备驱动程序的模块;将已有的C代码组合到仿真中;
2.使用S-函数的一个优点是可以创建一个普通用途的模块,在一个模型中多次使用,而且可单独改变模型中所使用的每个模块的参数.
3.使用S-函数的一个优点是可以创建一个普通用途的模块,在一个模型中多次使用,而且可单独改变模型中所使用的每个模块的参数.

2. S-function 工作原理

2.1 Simulink模块的数学关系

Simulink模块包含一组输入、一组状态和一组输出。其中,输出是采样时间、输入和模块状态的函数,如图所示。
在这里插入图片描述
在这里插入图片描述

2.2 Simulink 与S-function 仿真流程

在这里插入图片描述
在这里插入图片描述
S-function包括主函数和6个功能子函数,包括mdlInitializeSizes初始化、mdlDerivatives连续状态微分、mdlUpdate离散状态更新mdlOutputs模块输出mdlGetTimeOfNextVarHit计算下次采样时刻mdITerminate仿真结束
在S-function仿真过程中,利用switch-case语句,根据不同阶段对应的 flag值(仿真流程标志向量〉来调用S-function的不同子函数,以完成对S-function模块仿真流程的控制。
由流程图可知,S-function 的仿真流程图和Simulink的仿真流程图十分相似,都包含初始化、仿真结束、以及仿真循环部分。

2.4 S-function回调程序

一个S-function包含了一组S-function回调程序,用以执行在每个仿真阶段所必需的任务。在模型仿真期间,Simulink 对于模型中的每个S-function模块调用适当的程序,通过S-function程序来执行的任务。

3. M文件的S-function 模板

M文件的S-function结构明晰,易于理解,书写方便,且可以调用丰富的MATLAB函数,对于一般的应用,使用MATLAB语言编写S-function就足够了。

要了解S-function是如何工作的,最直接有效的方法就是学习S-function范例。下面先详细分析模板sfuntmpl.m中的代码内容,原代码中的注释已删除,为方便分析,现加入一些中文注释:

function [sys,x0,str,ts,simStateCompliance] = sfuntmpl(t,x,u,flag)
%主函数
%主函数包含四个输出:
%                 sys数组包含某个子函数返回的值,返回值取决于flag的值。例如flag=3,sys则包含了S-function的输出。
%                 x0为所有状态的初始化向量,除flag=0外,x0被忽略
%                 str是保留参数,总是一个空矩阵(M文件s-function 必须设置该元素为空矩阵)
%                 Ts返回系统采样时间(一个两列矩阵,包含块的采样时间和偏移量)
%函数的四个输入分别为采样时间t、状态x、输入u和仿真流程控制标志变量flag
%输入参数后面还可以接续一系列的附带参数simStateCompliance
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);
  case 4,
    sys=mdlGetTimeOfNextVarHit(t,x,u);
  case 9,
    sys=mdlTerminate(t,x,u);
  otherwise
    DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag));
 
end
%主函数结束
%下面是各个子函数,即各个回调过程

function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes
%初始化回调子函数
%提供状态、输入、输出、采样时间数目和初始状态的值
%初始化阶段,标志变量flag首先被置为0,S-function首次被调用时该子函数首先被调用,
%且为S-function模块提供下面信息
%该子函数必须存在
sizes = simsizes;
%生成sizes数据结构,信息被包含在其中
sizes.NumContStates  = 0;
%连续状态数,缺省为0
sizes.NumDiscStates  = 0;
%离散状态数,缺省为0
sizes.NumOutputs     = 0;
%输出个数,缺省为0
sizes.NumInputs      = 0;
%输入个数,缺省为0
sizes.DirFeedthrough = 1;
%是否存在直馈通道,1存在,0不存在
sizes.NumSampleTimes = 1;
%采样时间个数,至少是一个
sys = simsizes(sizes);
%返回size数据结构所包含的信息
x0  = [];
%设置初始状态
str = [];
%保留变量置空
ts  = [0 0];
%设置采样时间
simStateCompliance = 'UnknownSimState';


function sys=mdlDerivatives(t,x,u)
%计算导数回调子函数
%给定t,x,u计算连续状态的导数,可以在此给出系统的连续状态方程
%该子函数可以不存在
sys = [];
%sys表示状态导数,即dx


function sys=mdlUpdate(t,x,u)
%状态更新回调子函数
%给定t、x、u计算离散状态的更新
%每个仿真步内必然调用该子函数,不论是否有意义
%除了在此描述系统的离散状态方程外,还可以在此添加其他每个仿真步内都必须执行的代码
sys = [];
%sys表示下一个离散状态,即x(k+1)


function sys=mdlOutputs(t,x,u)
%计算输出回调函数
%给定t,x,u计算输出,可以在此描述系统的输出方程
%该子函数必须存在
sys = [];
%sys表示输出,即y

function sys=mdlGetTimeOfNextVarHit(t,x,u)
%计算下一个采样时间
%仅在系统是变采样时间系统时调用
sampleTime = 1; 
%设置下一次采样时间是在1s以后
sys = t + sampleTime;
%sys表示下一个采样时间点

function sys=mdlTerminate(t,x,u)
%仿真结束时要调用的回调函数
%在仿真结束时,可以在此完成仿真结束所需的必要工作
sys = [];

在这里插入图片描述

4. 使用实例

4.1 S-function实现离散系统

用S-function模板实现一个离散系统时,首先对mdInitializeSizes子函数进行修改,声明离散状态的个数,对状态进行初始化,确定采样时间等。然后再对mdlUpdate和 mdlOutputs子函数做适当修改,分别输入要表示的系统的离散状态方程和输出方程即可。
在这里插入图片描述
1)将模板文件另存为ep7_3.m,并修改主函数明为ep7_3
2) 修改mdlInitializeSizes子函数:

sizes.NumDiscStates  = 1;
%离散状态数,缺省为0
sizes.NumOutputs     = 1;
%输出个数,缺省为0
sizes.NumInputs      = 1;
%输入个数,缺省为0
x0  = 0;
ts  = [0.5 0];
%设置采样时间0.5s

(3) 对mdlUpdate和 mdlOutputs子函数做修改:

function sys=mdlUpdate(t,x,u)
sys = u;
%sys表示下一个离散状态,即x(k+1)
function sys=mdlOutputs(t,x,u)
sys = x;
%sys表示输出,即y

在这里插入图片描述

在这里插入图片描述
用S-function 实现下面离散系统
在这里插入图片描述
(1)在主函数主体中输入矩阵A、B、C和D的值:,将其当作外部函数输入。

function [sys,x0,str,ts,simStateCompliance] = ep7_4(t,x,u,flag,A,B,C,D)

(2)状态的更新和输出依赖于参数A、B、C和 D,因此需要对mdlUpdate和 mdlOutputs的调用做修改:

case 2,
    sys=mdlUpdate(t,x,u,A,B);
  case 3,
    sys=mdlOutputs(t,x,u,C,D);

(3)从A、B、C和D的维数中可以看出状态变量个数为2,输出变量个数位2,输入变量个数为1,修改mdlInitializeSizes初始化回调子函数:

sizes.NumDiscStates  = 2;
sizes.NumOutputs     = 2;
sizes.NumInputs      = 1;
x0  = [1,1];
ts  = [0.1 0];

(4)修改mdIlUpdate和 mdlOutputs子函数,以满足对离散状态方程的实现:

function sys=mdlUpdate(t,x,u,A,B)
sys = A*x+B*u;
function sys=mdlOutputs(t,x,u,C,D)
sys = C*x+D*u;

5)建立如下系统模型
在这里插入图片描述

6)对s-funciton进行封装,并将外部参数直观表达
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

疑问:

  1. Ts 与t分别在哪里设置,有什么区别?

总结

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_42722455/article/details/109823946

智能推荐

时间序列分析之误差修正模型(ECM)_ecm模型-程序员宅基地

文章浏览阅读3.8w次,点赞32次,收藏163次。误差修正模型(Error Correction Model, ECM)协整(cointegration)反映的是序列中变量之间的长期均衡关系,用网上的一个例子来描述协整就是一个醉汉牵着一只狗,他们之间的距离虽然会时远时近,但是由于绳子的存在,当达到绳子的长度时,他们的距离又会拉近,这样他们之间就存在着协整关系。通过协整建立的模型是静态模型,而误差修正模型的使用就是为了建立短期的动态模型来弥补长期..._ecm模型

C#版的MapReduce_c# mapreduce-程序员宅基地

文章浏览阅读1.7k次。using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace mapReduce{ public static class helper { public static Dictionary MapReduce( _c# mapreduce

DataGuard主备库上修改redo大小_dataguard 调整redo日志大小-程序员宅基地

文章浏览阅读419次。测试环境:RDBMS 11.2.0.4步骤:1 停掉备库的MRP2 在备库上添加standby logfile,大小100M (standby_file_management='manual';注意下这个参数)3 在备库上删除standby logfile,删除掉50M的4 在主库添加redo,大小为100M5 在主库删除redo ,大小为50M6 备库添加redo,大小为100M7 备库删除redo ,大小为50M8 主库添加standby ,大小为100M9 主库删除stand._dataguard 调整redo日志大小

利用matlab从TXT中读数据1_matlab读取txt中的科学计数-程序员宅基地

文章浏览阅读4.5w次,点赞12次,收藏48次。TXT是纯文本文件,常用的几种函数有load函数,importdata函数,dlmread函数,textread函数。科学计数法如1.03乘10的8次方,可简写为“1.03e+08”的形式1:examp0204.txt中只包含没有文字说明,且每行数据个数相同,只是有多种数据分隔符,此数据同样可以使用数据导入向导。9.5550 2.7027, 8.6014; 5.615..._matlab读取txt中的科学计数

洛谷P1996 约瑟夫问题【队列】_8个人站成一圈,从第1个人开始报数,报到5的人出圈,第6个人再从1开始报。依次类-程序员宅基地

文章浏览阅读340次。题目背景约瑟夫是一个无聊的人!!!题目描述n个人(n<=100)围成一圈,从第一个人开始报数,数到m的人出列,再由下一个人重新从1开始报数,数到m的人再出圈,……依次类推,直到所有的人都出圈,请输出依次出圈人的编号.输入输出格式输入格式: n m 输出格式: 出圈的编号 输入输出样例输入样例#1: 复制10 3输出样例#1: ..._8个人站成一圈,从第1个人开始报数,报到5的人出圈,第6个人再从1开始报。依次类

使用JavaScript代码制作网页年历_javascript年历-程序员宅基地

文章浏览阅读5.6k次,点赞5次,收藏43次。年历使用js代码制作网页年历生成<!doctype html><html> <head> <meta charset="utf-8"> <title>年历</title> <script> var year = parseInt(prompt('输入年份:','2019')); document.write(calendar(year)); _javascript年历

随便推点

jetson nano在archiconda环境里编译安装opencv(为了CUDA加速)_opencv cuda jetdon nano-程序员宅基地

文章浏览阅读2k次,点赞2次,收藏18次。DPYTHON_DEFAULT_EXECUTABLE=/home/tai/archiconda3/envs/yolo5/bin/python3.6m #这个决定安装在哪个python上。OPENCV_EXTRA_MODULES_PATH=/home/tai/open/opencv_contrib-4.5.3/modules #这个是opencv_contrib文件。记得搜索自己cv2.cpython-36m-aarch64-linux-gnu.so to cv2.so文件。..._opencv cuda jetdon nano

使用Spring Session集成redis实现Session共享_spring4集成redissession了吗-程序员宅基地

文章浏览阅读564次。在分布式系统中,session共享有很多解决方案,其中使用redis缓存是最常用的方案之一1.想要在springboot用到spring session共享功能,首先需要在springboot项目中添加相关依赖2.在application.yml添加配置属性这里为了方便,用同一个项目不同代码编译两次,代码如下@RestControllerpublic class Tes..._spring4集成redissession了吗

JavaMail API详解_有关javamail api的描述以下( )正确-程序员宅基地

文章浏览阅读5.4k次,点赞3次,收藏13次。JavaMail API详解cleverpig 发表于 2006-01-01 14:34:28作者:cleverpig&nbsp;&nbsp;&nbsp;&nbsp; 来源:Matrix摘要:JavaMail API是读取、撰写、发送电子信息的可选包。我们可用它来建立如Eudora、Foxmail、MS Outlook Express一般的邮件用户代理程序(Mail User Age..._有关javamail api的描述以下( )正确

百度天工笔记_端口1884是什么服务-程序员宅基地

文章浏览阅读883次。百度天工笔记参考资料:初识百度天工百度产品文档简介百度天工是融合了百度ABC(AI、Big Data、Cloud)的“一站式、全托管”智能物联网平台。 从端到云,从数据采集、传输、计算、存储、展现到分析,天工提供了全面的基础产品和服务。赋能物联网应用开发商和生态合作伙伴从”连接”、”理解”到”唤醒“的各项关键能力,从而轻松构建各类智能物联网应用,促进行业变革。连接:互联互通,让..._端口1884是什么服务

The 2021 ICPC Asia Jinan Regional Contest - C Optimal Strategy - 2021ICPC济南站C题 组合数学_2021 济南站icpc optimal strategy-程序员宅基地

文章浏览阅读3k次。题目大意Ena和Mizuki正在玩一个游戏。他们面前有n个项目,编号从1到n。第i个项目的价值是.Ena和Mizuki轮流操作,而Ena先操作。在一次移动中,玩家选择一个尚未被拿走的物品并将其带走。当所有物品都被拿走时,游戏结束。任何一方的目标都是使他们拿走的物品的价值之和最大。鉴于双方都以最佳方式行动,有多少个可能的游戏过程?由于这个数字可能太大,你应该输出998244353的模数。如果存在某个整数i(1≤i≤n),使第i次移动中拿走的物品的指数不同,则认为两个过程不同。输入描述._2021 济南站icpc optimal strategy

数据分析学习路线图_技术路线图颜色-程序员宅基地

文章浏览阅读1.8k次,点赞4次,收藏24次。个人欠缺1-数据库类必修:NoSQL(MangoDB, Redis)选修:了解各类NoSQL,基于图的数据库Neo4j,基于Column的数据库BigTable,基于key-value的数据库redis/cassendra2-大数据开发hadoop基础,包括hdfs、map-reduce、hive之类;后面接触spark和storm再说3-工具类可视化:http://plot.ly、d3.js、echarts.jsPython:seaborn, boken其他:爬虫(req_技术路线图颜色

推荐文章

热门文章

相关标签