本文介绍了s-function 的基本概念和使用案例。
函数是系统函数(System Function)的简称,在Simulink中用非图形化的方式来描述一个模块。一个完整的S-函数结构体系包含了描述一个动态系统所需要的全部能力。使用S-函数用户可以向Simulink模型中添加自己的模块,可以自由选择使用MATLAB、C、C++等语言来创建自己的模块。
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. 继承采样时间
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.在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.向SIMULINK增加一些新的通用模块;增加作为硬件设备驱动程序的模块;将已有的C代码组合到仿真中;
2.使用S-函数的一个优点是可以创建一个普通用途的模块,在一个模型中多次使用,而且可单独改变模型中所使用的每个模块的参数.
3.使用S-函数的一个优点是可以创建一个普通用途的模块,在一个模型中多次使用,而且可单独改变模型中所使用的每个模块的参数.
Simulink模块包含一组输入、一组状态和一组输出。其中,输出是采样时间、输入和模块状态的函数,如图所示。
S-function包括主函数和6个功能子函数,包括mdlInitializeSizes初始化、mdlDerivatives连续状态微分、mdlUpdate离散状态更新、mdlOutputs模块输出、mdlGetTimeOfNextVarHit计算下次采样时刻和 mdITerminate仿真结束。
在S-function仿真过程中,利用switch-case语句,根据不同阶段对应的 flag值(仿真流程标志向量〉来调用S-function的不同子函数,以完成对S-function模块仿真流程的控制。
由流程图可知,S-function 的仿真流程图和Simulink的仿真流程图十分相似,都包含初始化、仿真结束、以及仿真循环部分。
一个S-function包含了一组S-function回调程序,用以执行在每个仿真阶段所必需的任务。在模型仿真期间,Simulink 对于模型中的每个S-function模块调用适当的程序,通过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 = [];
用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进行封装,并将外部参数直观表达
疑问:
文章浏览阅读318次。环境window10虚拟机、secureCRTIntellij IDEARPCRemote Procedure Call。远程过程调用:调用的程序或者函数,并不在本地,而是在远程计算机中。这个时候不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。要利用RabbitMQ来实现RPC功能是很简单的;客户端发送消息,服务端回复响应的消息。为了接收响应的消息,我们需要在请求中发送一个回调队列。可以使用默认的队列。String message = "rabbitmq rpc";// 匿名回_rabbitmq channelrpctimeout
文章浏览阅读3k次。答:浏览器输入网址之后,首先步骤1:需要查找域名的IP地址,DNS查找过程如下:(1)浏览器缓存 – 浏览器的缓存DNS记录一段时间。 有趣的是,操作系统没有告诉浏览器储存DNS记录的时间,这样不同浏览器会储存各自固定的一个时间(2分钟到30分钟不等)。(2)系统缓存 – 如果在浏览器缓存里没有找到需要的记录,浏览器会做一个系统调用(windows里是gethostbyname)。这样_用前面学习过的知识描述从用户在浏览器中输入一个网站的地址,并按下回车键进
文章浏览阅读364次。ParencodingsTime Limit: 1000MS Memory Limit: 10000KTotal Submissions: 30527 Accepted: 17996DescriptionLet S = s1 s2…s2n be a well-formed string of parentheses. S can be encoded in two different ways:By an integer sequence P = p1 p2…pn where pi is t
文章浏览阅读297次。Delphi的便于开发为程序员提供了很多便捷,但是有些效果可能也被忽略了,delphi自带的showmessge或者messagebox是我们一般使用的方法,但是有没有更好的提示信息呢,下面就介绍一种,气球式的方式,效果如下所示:但是效果不是很好,使用时当鼠标离开一定范围时提示信息会消失。 unit Unit1;interfaceuses Windows, M
文章浏览阅读9.8k次。最近由于公司的一个项目需要,需要使用Sql Server 2008数据库,开发语言使用Python,并基于windows平台上的Wing IDE4.0进行。 之前并未使用过Sql Server数据库,这次也当作一次练手,并把这次数据库前期开发过程中遇到的一些问题进行记录。 一、关于pyodbc库和pymssql库的选择 在使用python_import random sql2008能用吗
文章浏览阅读507次。使用代码:val file = spark.sparkContext.textFile("file:///home/iie4bu/data/hello.txt")val wordCounts = file.flatMap(line => line.split(",")).map((word => (word,1))).reduceByKey(_ + _)wordCounts.co...
文章浏览阅读3.6k次。写在前面最近公司搞自动化打包,从0开始折腾了几天终于完成了,准备整理一下,写成文档。 1、下载Jenkins并安装Jenkins下载地址:https://jenkins.io在主页面点击Download Jenkins选择Mac OS。安装没有什么好介绍的,双击安装包,按照提示进行就好了。2、下载Java SDKJenkins 需要运行 Java 5以及以上的版本。..._jenkins接入iam
文章浏览阅读1.8w次,点赞4次,收藏13次。单链表反转是面试时经常会遇到的问题,之前只是在数据结构里用伪代码实现过单链表反转。为落实亲手编写每一个程序的目标,在这里用java实现反转。方法有很多,这里只写最优的。时间复杂度O(n),空间复杂度O(1)。也就是说不新开辟空间,原地反转。这篇博客主要讲述如何采用头插和尾插两种方法建立单链表。反转链表见下一篇博客。_头插法和尾插法区别
文章浏览阅读1w次。链接:https://www.cnblogs.com/caidingyu/p/10679422.html# CentOS7.6 下载地址# CentOS-7-x86_64-DVD-1810.iso CentOS 7.6 DVD 版 4Ghttp://mirrors.163.com/centos/7.6.1810/isos/x86_64/C..._centos-7-x86_64-everything-1804.iso下载
文章浏览阅读2.8k次。Cryptosimple根据题目名称提示,本题为简单仿射密码,爆破得映射关系为:y = 8a + 22 (mod 26),密钥使用方法为:123456 % 26 = 8,321564 % 26 = 22与爆破结果相同。于是得到正向替换表a-w b-e c-m d-u e-c f-k,反向替换得到flag。RUA题目给出了三组n和c,且三个n之间两两互质,所以本题只可能是利用中国剩余定理求出me,然后爆破e求解m。解题代码如下:#!/usr/bin/env python# -*- coding: _网鼎杯 hafuhafu
文章浏览阅读5.4k次。原文:http://blog.appliedis.com/2012/10/29/wireless-distribution-of-enterprise-ios-apps/我在自己的mac上装了nginx,测试时总是无法弹出安装的alert,后来发现原来是文件的权限问题,权限修改后就可以了,大家一定要注意,下面是原文One of the tasks we are be_apple configurator 配置web clip安装ipa
文章浏览阅读438次。1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 933 Solved: 370[Submit][Status][Discuss]Description了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发