matlab中S函数编辑流程

合集下载

matlab中s-function用法

matlab中s-function用法

matlab中s-function用法创建一个有1输入(2维),2输出(1维),3个参数,还有全局变量的s-function。

1.新建sfunction的C语言文件打开simulink,点击User-Defined Functions里面的S-Function Examples。

这个里面有多个语言版本的模板,有C,C++,Ada,Fortran和M语言的版本,其实都大同小异,只要了解几个函数就很容易使用了。

选择C语言的版本:从S-function模块中选择C-file S-functions里面的Basic C-MEX template。

打开后,另存为自己的模块名字,如test.c。

下面我们来分析代码:#define S_FUNCTION_NAME test//这里把文件名sfuntmpl_basic修改为test #define S_FUNCTION_LEVEL 2#include "simstruc.h"//程序里面要用到的头文件在这里引用,如“math.h”等。

float global_var; //定义全局变量static void mdlInitializeSizes(SimStruct *S){//这个函数用来设置输入、输出和参数的。

ssSetNumSFcnParams(S, 3); /*设置参数个数,这里为3 */if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {return;}; ssSetNumContStates(S, 0);//设置连续状态的个数,缺省为0ssSetNumDiscStates(S, 0);//设置离散状态的个数,缺省为0;if (!ssSetNumInputPorts(S, 1)) return;//设置输入变量的个数,这里为1 ssSetInputPortWidth(S, 0, 2); //设置输入变量0的维数为2ssSetInputPortRequiredContiguous(S, 0, true); //设置input0的访问方式,true就是临近访问,这样指针的增量后就可以直接访问下个input端口了。

MATLAB中S函数使用

MATLAB中S函数使用

最后一个,在 sfuntmpl 的 130 行
case 9,
sys=mdlTerminate(t,x,u);
flag=9 表示此时系统要结束,一般来说写上在 mdlTerminate 函数中写上 sys=[]就可,如果你 在结束时还要设置什么,就在此函数中写
关于 sfuntmpl 这个 s 函数的模板讲完了。
sizes.DirFeedthrough = 0; sizes.NumSampleTimes = 0; sys = simsizes(sizes); x0 = [0 6 1 0];%x(1)时间 0 开始;x(2)幅值;x(3)切换标志位;x(4)周期标志位; str = []; ts = []; function sys=mdlUpdate(t,x,u) T=0.000125;%周期设置 k=x(4); s=x(2); i=x(3); if mod(i,2)==1 p1=1.56*10^(-6); p2=-1.295*10^(-6); p3=-7.847*10^(-6);
sizes.NumContStates = 0;
sizes.NumDiscStates = 0;
sizes.NumOutputs = 1;
sizes.NumInputs = 1;
sizes.DirFeedthrough = 1;
sizes.NumSampleTimes = 1;
sys = simsizes(sizes);
在 matlab 的 workspace 里打 edit sfuntmpl(这是 matlab 自己提供的 s 函数模板),我们看它 来具体分析 s 函数的结构。 它的第一行是这样的:function [sys,x0,str,ts]=sfuntmpl(t,x,u,flag) . 先讲输入与输出变量的含义:t 是采样时间,x 是状态变量,u 是输入(是做成 simulink 模块的输 入),flag 是仿真过程中的状态标志(以它来判断当前是初始化还是运行等);sys 输出根据 flag 的 不同而不同 (下面将结合 flag 来讲 sys 的含义) , x0 是状态变量的初始值, str 是保留参数 (mathworks 公司还没想好该怎么用它,嘻嘻,一般在初始化中将它置空就可以了,str=[]),ts 是一个 1×2 的向 量,ts(1)是采样周期,ts(2)是偏移量。

matlab中S函数编写

matlab中S函数编写

matlab中S函数编写matlab中S函数编写S函数是system Function的简称,用它来写自己的simulink模块,可以用matlab、C、C++、Fortran、Ada等语言来写。

C或C++等语言写的s函数还可以实现对硬件端口的操作,还可以操作windows API等。

Simulink的仿真有两个阶段:一个为初始化,这个阶段主要是设置一些参数,像系统的输入输出个数、状态初值、采样时间等;第二个阶段就是运行阶段,这个阶段里要进行计算输出、更新离散状态、计算连续状态等等,这个阶段需要反复运行,直至结束。

在matlab的workspace里打edit sfuntmpl(这是matlab提供的s函数模板),具体分析S函数的结构。

它的第一行:function [sys,x0,str,ts,simStateCompliance]=sfuntmpl(t,x,u,flag) 输入与输出变量的含义:t是采样时间,x是状态变量,u是输入,flag是仿真过程中的状态标志(以它来判断当前是初始化还是运行等);sys输出根据flag的不同而不同,x0是状态变量的初始值,str是保留参数(一般在初始化中将它置空就可以了,str=[]),ts是一个1×2的向量,ts(1)是采样周期,ts(2)是偏移量。

下面结合sfuntmpl.m中的代码来讲具体的结构:switch flag, %判断flag,看当前处于哪个状态case 0,[sys,x0,str,ts]=mdlInitializeSizes;flag=0表示处于初始化状态,sys是一个结构体,用它来设置模块的一些参数,各个参数详细说明如下:size = simsizes; %用于设置模块参数的结构体用simsizes来生成sizes.NumContStates = 0; %模块连续状态变量的个数sizes.NumDiscStates = 0; %模块离散状态变量的个数sizes.NumOutputs = 0; %模块输出变量的个数sizes.NumInputs = 0; %模块输入变量的个数sizes.DirFeedthrough = 1; %模块是否存在直接贯通(输入能直接控制输出)sizes.NumSampleTimes = 1;%模块的采样时间个数,至少是一个sys = simsizes(sizes); %设置完后赋给sys输出举个例子,考虑如下模型:dx/dt=fc(t,x,u) 也可以用连续状态方程描述:dx/dt=A*x+B*u x(k+1)=fd(t,x,u) 也可以用离散状态方程描述:x(k+1)=H*x(k)+G*u(k)y=fo(t,x,u) 也可以用输出状态方程描述:y=C*x+D*u设上述模型连续状态变量、离散状态变量、输入变量、输出变量均为1个,我们就只需改上面那一段代码为:sizes.NumContStates=1;sizes.NumDiscStates=1;sizes.NumOutputs=1;sizes.NumInputs=1;其他的可以不变。

Matlab中基于C语言的S函数的编写与应用

Matlab中基于C语言的S函数的编写与应用
1
在正式对 S 函数进行介绍前,先看一个例子,这个例子是对网络的随机延时 环境进行算法模拟,能够对输入的正常的时钟信号产生 0.2s 到 0.7s 不等的随机 延时。本小节采用“从整体到局部,从结果到原因”的方式对此示例进行介绍。
用数字程序建立一个随机延时为 0.3s 到 0.6s 不等的网络随机延时环境,所涉 及的 Simulink 仿真程序结构如图 2-1 所示。
3.3 S 函数的编译
在编写好 S 函数的实现代码*.c 文件后,还需要在 Matlab 的命令输出窗口中 进行命令行输入,完成对源代码的编译,这样才能被 S 函数模块所调用。在命令 窗口中输入命令:
“mex -g RandomTimeDelay.c” M 文件 S-函数在 MATLAB 环境下可以通过解释器直接执行,而 C 文件或其 它语言编写的 C-函数,则需要先编译成可以在 MATLAB 内运行的二进制代码: 动态连接库或静态连接库,然后才可以使用,这些经过编译的二进制文件就称作
S-函数作为与其他语言相结合的接口,可以使用这个语言所提供的强大能力。 例如,Matlab 语言编写的 S-函数可以充分利用 MATLAB 所提供的丰富资源,方 便地调用各种工具箱函数和图形函数;使用 C 语言编写的 S-函数可以实现对操 作系统的访问,如实现与其他进程的通信和同步等。
Simulink 已经提供了大量的内置的系统模块,并且允许用户自定义模块,对 于大多数动态系统仿真分析语言,使用 Simulink 提供的模块即可实现,而无需 使用 S-函数。但是,当需要开发一个新的通用的模块作为一个独立的功能单元 时,使用 S-函数实现则是一种相当简便的方法。另外,由于 S-函数可以使用多 种语言编写,因此可以将已有的代码结合进来,而不需要在 Simulink 中重新实 现算法,从而在某种程度上实现了代码移植。此外,在 S-函数中使用文本方式 输入公式、方程,非常适合复杂动态系统的数学描述,并且在仿真过程中可以对 仿真进行更精确的控制。”

matlab中s函数模板 -回复

matlab中s函数模板 -回复

matlab中s函数模板-回复MATLAB中的s函数模板是一种用于编写自定义模块的工具,它允许用户以自己的方式定义系统的动态行为。

本文将详细介绍s函数模板的具体操作步骤和相关注意事项。

首先,为了能够使用s函数模板,我们需要在MATLAB工作区创建一个新的模型或打开一个已有的模型。

然后,我们可以按照以下步骤进行s函数模板的编写。

第一步,创建s函数模板文件。

在MATLAB的命令窗口中输入以下命令:sfunctionname这将会创建一个名为"sfunctionname.m"的文件,其中"sfunctionname"是我们给s函数模板命名的名称。

第二步,打开s函数模板文件,并编辑其内容。

在"function"关键字下方的行中,可以定义输入输出参数以及任何需要的局部变量。

例如,以下是一个基本的s函数模板:function [sys,x0,str,ts] = sfunctionname(t,x,u,flag)switch flagcase 0 初始化模型[sys,x0,str,ts] = mdlInitializeSizes; 调用模型初始化函数case 1 计算模型状态方程sys = mdlDerivatives(t,x,u);case 2 计算模型输出方程sys = mdlOutputs(t,x,u);case 3 处理模型状态信息sys = mdlUpdate(t,x,u);case 4 处理模型输出信息sys = mdlGetTimeOfNextVarHit(t,x,u);case 9 处理模型示意图sys = mdlTerminate(t,x,u);otherwiseerror(['Unhandled flag = ',num2str(flag)]);endend在上述代码中,我们定义了四个输入参数t、x、u和flag,以及四个输出参数sys、x0、str和ts。

(完整版)matlab中s函数编写心得(转)

(完整版)matlab中s函数编写心得(转)

matlab中s函数编写心得(转)Part I:所谓s函数是system Function的简称, 用它来写自己的simulink模块. s函数可以用matlab、C、C++、Fortran、Ada等语言来写,这儿我只介绍怎样用matlab语言来写吧(主要是它比较简单)< xmlnamespace prefix ="o" ns="urn:schemas-microsoft-com:office:office" />先讲讲为什么要用s函数,我觉得用s函数可以利用matlab的丰富资源,而不仅仅局限于simulink提供的模块,而用c或c++等语言写的s函数还可以实现对硬件端口的操作,还可以操作windows API等先介绍一下simulink的仿真过程(以便理解s函数),simulink的仿真有两个阶段:一个为初始化,这个阶段主要是设置一些参数,像系统的输入输出个数、状态初值、采样时间等;第二个阶段就是运行阶段,这个阶段里要进行计算输出、更新离散状态、计算连续状态等等,这个阶段需要反复运行,直至结束.在matlab的workspace里输入edit sfuntmpl(这是matlab自己提供的s函数模板),我们看它来具体分析s函数的结构.1. 函数的函数头函数的第一行:function [sys,x0,str,ts]=sfuntmpl(t,x,u,flag) , 先讲输入与输出变量的含义:t是采样时间, x是状态变量, u是输入(是做成simulink模块的输入), flag是仿真过程中的状态标志(以它来判断当前是初始化还是运行等) sys输出根据flag的不同而不同(下面将结合flag来讲sys的含义), x0是状态变量的初始值, str是保留参数(mathworks公司还没想好该怎么用它, 一般在初始化中将它置空就可以了, str=[]), ts是一个1×2的向量, ts(1)是采样周期, ts(2)是偏移量2. 函数分析下面结合sfuntmpl.m中的代码来讲具体的结构:switch flag, %判断flag,看当前处于哪个状态case 0,[sys,x0,str,ts]=mdlInitializeSizes;// 解释说明flag=0表示当前处于初始化状态,此时调用函数mdlInitializeSizes进行初始化,此函数在该文件的第149行定义. 其中的参数sys是一个结构体,它用来设置模块的一些参数,各个参数详细说明如下size = simsizes;%用于设置模块参数的结构体用simsizes来生成sizes.NumContStates = 0; %模块连续状态变量的个数sizes.NumDiscStates = 0; %模块离散状态变量的个数sizes.NumOutputs = 0; %模块输出变量的个数sizes.NumInputs = 0; %模块输入变量的个数sizes.DirFeedthrough = 1; %模块是否存在直接贯通sizes.NumSampleTimes = 1; %模块的采样时间个数, 至少是一个sys = simsizes(sizes); %设置完后赋给sys输出举个例子,考虑如下模型:dx/dt=fc(t,x,u) 也可以用连续状态方程描述:dx/dt=A*x+B*u x(k+1)=fd(t,x,u) 也可以用离散状态方程描述:x(k+1)=H*x(k)+G*u(k)y=fo(t,x,u) 也可以用输出状态方程描述:y=C*x+D*u设上述模型连续状态变量、离散状态变量、输入变量、输出变量均为1个,我们就只需改上面那一段代码为(一般连续状态与离散状态不会一块用, 我这儿是为了方便说明):sizes.NumContStates=1;sizes.NumDiscStates=1;sizes.Nu mOutputs=1;sizes.NumInputs=1;其他的可以不变, 继续在mdlInitializeSizes函数中往下看:x0 = []; %状态变量设置为空,表示没有状态变量,以我们上面的假设,可改为x0=[0,0](离散和连续的状态变量我们都设它初值为0)str = []; %保留参数, 置[]就可以了, 没什么用ts = [0 0]; %采样周期设为0表示是连续系统, 如果是离散系统在下面的mdlGetTimeOfNextVarHit函数中具体介绍case 1,sys=mdlDerivatives(t,x,u);//flag=1表示此时要计算连续状态的微分, 即上面提到的dx/dt=fc(t,x,u)中的dx/dt, 找到193行的函数mdlDerivatives, 如果设置连续状态变量个数为0, 此处只需sys=[]就可以了, 按我们上述讨论的那个模型, 此处改成sys=fc(t,x(1),u)或sys=A*x(1)+B*u, 我们这儿x(1)是连续状态变量, 而x(2)是离散的, 这儿只用到连续的, 此时的输出sys就是微分case 2,sys=mdlUpdate(t,x,u);//flag=2表示此时要计算下一个离散状态, 即上面提到的x(k+1)=fd(t,x,u), 找到mdlUpdate函数, 它这儿sys=[]表示没有离散状态, 我们这儿可以改成sys=fd(t,x(2),u)或sys=H*x(2)+G*u;%sys即为x(k+1)case 3,sys=mdlOutputs(t,x,u);//flag=3表示此时要计算输出, 即y=fo(t,x,u), 找到218行的mdlOutputs函数. 如果sys=[]表示没有输出, 我们改成sys=fo(t,x,u)或sys=C*x+D*u %sys此时为输出ycase 4,sys=mdlGetTimeOfNextVarHit(t,x,u);//flag=4表示此时要计算下一次采样的时间, 只在离散采样系统中有用(即上文的mdlInitializeSizes中提到的ts设置ts(1)不为0), 连续系统中只需在mdlGetTimeOfNextVarHit函数中写上sys=[]. 这个函数主要用于变步长的设置, 具体实现大家可以用edit vsfunc看vsfunc.m这个例子case 9,sys=mdlTerminate(t,x,u);//flag=9表示此时系统要结束,一般来说写上在mdlTerminate函数中写上sys=[]就可, 如果你在结束时还要设置什么,就在此函数中写完了.Part II此外, s函数还可以带用户参数, 下面给个例子, 它和simulink下的gain模块功能一样function [sys,x0,str,ts] = sfungain(t,x,u,flag,gain)switch flag,case 0,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];case 3,sys=gain*u;case {1,2,4,9},sys = [];end做好了s函数后, simulink --> user-defined function下拖一个S-Function到你的模型, 就可以用了. 在simulink -->user-defined function还有个s-Function Builder, 他可以生成用c 语言写的s函数. 或者在matlab的workspace下打sfundemos, 可以看到很多演示s函数的程序Part IIISIMULINK s-function的设计Simulink为用户提供了许多内置的基本库模块, 通过这些模块进行连接而构成系统的模型. 对于那些经常使用的模块进行组合并封装可以构建出重复使用的新模块, 但它依然是基于Simulink原来提供的内置模块.而Simulink s-function是一种强大的对模块库进行扩展的新工具.(一) s-function的概念s-function是一个动态系统的计算机语言描述, 在MATLAB里, 用户可以选择用m文件编写, 也可以用c或mex文件编写, 在这里只给大家介绍如何用m文件编写s-function.S-function提供了扩展Simulink模块库的有力工具, 它采用一种特定的调用语法, 使函数和Simulink解法器进行交互.S-function最广泛的用途是定制用户自己的Simulink模块. 它的形式十分通用, 能够支持连续系统、离散系统和混合系统.(二) 建立m文件s-function1. 使用模板文件:sfuntmp1.m, 其格式为[sys,x0]=function(t,x,u,flag). 该该模板文件位于MATLAB根目录下toolbox/simulink/blocks目录下模板文件里s-function的结构十分简单, 它只为不同的flag的值指定要相应调用的m文件子函数. 比如当flag=3时, 即模块处于计算输出这个仿真阶段时, 相应调用的子函数为sys=mdloutputs(t,x,u). 模板文件使用switch语句来完成这种指定, 当然这种结构并不唯一, 用户也可以使用if语句来完成同样的功能. 而且在实际运用时, 可以根据实际需要来去掉某些值, 因为并不是每个模块都需要经过所有的子函数调用.模板文件只是Simulink为方便用户而提供的一种参考格式, 并不是编写s-function的语法要求, 用户完全可以改变子函数的名称, 或者直接把代码写在主函数里, 但使用模板文件的好处是, 比较方便, 而且条理清晰.使用模板编写s-function, 用户只需把s-函数名换成期望的函数名称, 如果需要额外的输入参量, 还需在输入参数列表的后面增加这些参数, 因为前面的4个参数是simulink调用s-function时自动传入的.对于输出参数, 最好不做修改. 接下去的工作就是根据所编s-function要完成的任务, 用相应的代码去替代模板里各个子函数的代码即可.Simulink在每个仿真阶段都会对s-function进行调用. 在调用时, Simulink会根据所处的仿真阶段为flag传入不同的值, 而且还会为sys这个返回参数指定不同的角色. 也就是说尽管是相同的sys变量, 但在不同的仿真阶段其意义却不相同, 这种变化由simulink自动完成.m文件s-function可用的子函数说明如下:mdlInitializeSizes(flag=0) -- 定义s-function模块的基本特性, 包括采样时间、连续或者离散状态的初始条件和sizes数组mdlDerivatives(flag=1) -- 计算连续状态变量的微分方程mdlUpdate(flag=2) -- 更新离散状态、采样时间和主时间步的要求mdlOutputs(flag=3) -- 计算s-function的输出mdlGetTimeOfNextVarHit(flag=4) -- 计算下一个采样点的绝对时间, 这个方法仅仅是在用户在mdlInitializeSizes 里说明了一个可变的离散采样时间概括说来, 建立s-function可以分成两个分离的任务: 第一, 初始化模块特性包括输入输出信号的宽度, 离散连续状态的初始条件和采样时间. 第二, 将算法放到合适的s-function子函数中去。

matlab中s-function用法

matlab中s-function用法

ssSetOffsetTime(S, 0, 0.0); } #define MDL_INITIALIZE_CONDITIONS function */ #if defined(MDL_INITIALIZE_CONDITIONS)
/* Change to #undef to remove
static void mdlInitializeConditions(SimStruct *S)//暂时不管 { } #endif /* MDL_INITIALIZE_CONDITIONS */ #define MDL_START /* Change to #undef to remove function */ #if defined(MDL_START) static void mdlStart(SimStruct *S)//暂时不管 { } #endif /* MDL_START */ static v//这里填入相关的运算、算法等 { real_T *para1 = mxGetPr(ssGetSFcnParam(S,0)); real_T *para2 = mxGetPr(ssGetSFcnParam(S,1)); real_T *para3 = mxGetPr(ssGetSFcnParam(S,2)); const real_T *u = (const real_T*) ssGetInputPortSignal(S,0); real_T *y1 = ssGetOutputPortSignal(S,0); real_T *y2 = ssGetOutputPortSignal(S,1); y1[0]=u[0]*para1[0]+u[1]*para2[0]; y2[0]=u[1]*para3[0]+u[0]*para1[0]; } #define MDL_UPDATE /* Change to #undef to remove function */ #if defined(MDL_UPDATE) static void mdlUpdate(SimStruct *S, int_T tid) { } #endif /* MDL_UPDATE */ #define MDL_DERIVATIVES /* Change to #undef to remove function */ #if defined(MDL_DERIVATIVES) static void mdlDerivatives(SimStruct *S) { } #endif /* MDL_DERIVATIVES */ static void mdlTerminate(SimStruct *S)//这里需要把 global 变量全部初始化,否则 下次运行程序时,全局变量还是之前的值。 {

matlab中的S函数

matlab中的S函数

S函数的简介及编写摘自恒润科技S-function的编写1. S函数模板编辑环境进入:在MATLAB主界面中直接输入:edit sfuntmpl即可弹出S函数模板编辑的M文件环境,修改即可。

在MATLAB主界面中直接输入:sfundemos,即可调出S 函数的许多编程例子。

2. S函数模板的相关基础:1)M文件S函数的引导语句为:xtflagfuFunction[psysxstrtsp,,12,...),,,0,],(,S函数默认的四个输入参数:t ,x ,u ,flagS函数默认的四个输出函数:sys ,x0 ,str ,ts各个参数的含义如下:T :代表当前的仿真时间,该输入决定了下一个采样时间;X :表示状态向量,行向量,引用格式:X(1),X(2)U :表示输入向量;Flag :控制在每一个仿真阶段调用哪一个子函数的参数,由SIMULINK在调用时自动取值;Sys :通用的返回变量,返回的数值决定Flag值,mdlUpdates里:列向量,引用格式:Sys(1,1),Sys(2,1);mdlOutputs里:行向量,引用格式:Sys =x、X0 :初始的状态值;列向量,引用格式:X0=[ 0;0;0 ]Str :空矩阵,无具体含义;Ts :包含模块采样时间与偏差的矩阵。

[period, offset]当Ts为-1时,表示与输入信号同采样周期。

2)S函数工作方式:Flag = 0时,调用mdlInitializeSizes函数,定义S函数的基本特性,包括采样时间,连续或者离散状态的初始条件与Sizes数组;Flag = 1时,调用mdlDerivatives函数,计算连续状态变量的微分方程;求所给表达式的等号左边状态变量的积分值的过程。

Flag = 2时,调用mdlUpdate函数,用于更新离散状态,采样时间与主时间步的要求;Flag = 3时,调用mdlOutputs函数,计算S函数的输出;Flag = 4时,调用mdlGetTimeOfNextVarHit函数,计算下一个采样点的绝对时间,这个方法仅仅就是使用户在mdlInitializeSize 里说明一个可变的离散采样时间;Flag = 9时,调用mdlTerminate函数,实现仿真任务的结束。

sfunction使用方法

sfunction使用方法

sfunction使用方法在matlab命令行中输入 edit sfuntmpl ,可以打开S-function的模板,里面对S-function的函数和变量作用均作了介绍。

S-function的基础是现代控制理论的状态定义,使用S-function需具备现代控制理论的基本知识为什么要有S-function•因为matlab中的模块太过标准化,无法满足多变的应用和调试需求,在以下情况下,S-function可以很方便的对系统进行建模。

•控制或受控系统具有复杂时变特性•控制系统在控制过程中自我迭代,存在需要保留和记录的变量•控制系统的输出较为复杂,难以用function和m-function表示•系统在生成、运行或结束时需要执行特殊操作S-function属性窗口介绍•S-function name :S-function的名字,随便写,自己认识即可•S-function parameters:S-function的模块参数,默认为空•S-function modules :S-function的模块,无需修改,采用系统默认模块即可也就是说,这三个参数,只需要修改第一个参数为模块命名即可•点击Edit,可以进入S-function的代码编辑界面S-function内部函数介绍•[sys,x0,str,ts] = functionName(t,x,u,flag) 这是函数的总入口,收到信号后,首先进入这个函数.这个函数包含一个switch语句,根据情况进入不同的子函数•[sys,x0,str,ts,simStateCompliance]=mdlInitializeS izes; S-function进行基本的设置,具体参数会在后面进行介绍。

相当于构造函数•sys=mdlDerivatives(t,x,u); 该函数仅在连续系统中被调用,用于产生控制系统状态的导数•sys=mdlUpdate(t,x,u); 该函数仅在离散系统中被调用,用于产生控制系统的下一个状态•sys=mdlOutputs(t,x,u); 产生(传递)系统输出•sys=mdlGetTimeOfNextVarHit(t,x,u) 获得下一次系统执行(next hit)的时间,该时间为绝对时间此函数仅在采样时间数组中指定变量离散时间采样时间[-2 0]时会被调用。

matlab的sfunction执行流程

matlab的sfunction执行流程

matlab的sfunction执行流程MATLAB的S-Function(System Function)是一种用于扩展Simulink模型功能的强大工具。

S-Function允许用户以C、C++或MATLAB语言编写自定义的动态系统。

以下是S-Function的基本执行流程:1.初始化(Initialization):•当Simulink模型开始仿真时,S-Function的初始化函数(如mdlInitializeSizes)首先被调用。

在这个阶段,S-Function定义了它的输入和输出数量、离散状态的数量、采样时间等。

•如果S-Function使用工作向量(work vector),它也会在这个阶段被分配。

2.计算采样时间(Compute Sample Times):•在初始化之后,Simulink会调用S-Function的mdlGetSampleTimes 函数来确定其采样时间。

这对于确定何时调用S-Function的其他函数至关重要。

3.开始仿真(Start of Simulation):•在仿真开始时,可以调用一个可选的S-Function函数(如mdlStart),用于执行任何需要在仿真开始时执行的初始化或预计算。

4.仿真循环(Simulation Loop):•在仿真的每个采样点,S-Function的主要功能函数(如mdlOutputs,mdlUpdate,mdlDerivatives)被调用。

▪mdlOutputs:计算S-Function的输出。

▪mdlUpdate:更新S-Function的离散状态。

▪mdlDerivatives:计算S-Function的连续状态导数(对于连续时间系统)。

•根据S-Function的类型(连续、离散或混合)和配置,这些函数可能会被以不同的方式调用。

5.结束仿真(End of Simulation):•在仿真结束时,可以调用一个可选的S-Function函数(如mdlTerminate),用于执行任何需要在仿真结束时执行的清理操作。

matlab s-function参数

matlab s-function参数

MATLAB S-Function是一种特殊的M文件函数,用于创建自定义的Simulink模块。

它允许用户编写自己的Simulink块,以扩展Simulink的功能和适应特定的应用需求。

在MATLAB中,S-Function通过定义M文件和一组参数来实现。

在使用MATLAB S-Function时,参数起着至关重要的作用。

参数用于在S-Function和Simulink模型之间进行数据传递和通信。

它们可以控制S-Function的行为,影响模型的仿真结果,以及改变模型的外部接口。

了解和熟练使用S-Function参数是使用MATLAB进行模型开发和仿真的重要技能。

接下来,我们将详细介绍MATLAB S-Function参数的使用方法和技巧,帮助用户更好地理解和应用S-Function。

一、S-Function参数的作用S-Function参数是S-Function的输入和输出。

它们可以用于以下几个方面:1. 控制S-Function的行为。

通过设置参数来开启或关闭某些功能,调整模型的参数等。

2. 设置S-Function的输入和输出端口。

参数可以指定输入和输出端口的数量、名称、类型等。

3. 传递数据到S-Function中。

参数可以作为S-Function的输入,传递数据到S-Function中,影响S-Function的行为和输出结果。

4. 从S-Function中获取数据。

参数可以作为S-Function的输出,将S-Function的计算结果返回给Simulink模型其他部分使用。

二、S-Function参数的定义和声明在编写S-Function时,首先需要定义和声明参数。

通常,参数的定义和声明是在S-Function的初始化函数中完成的。

以下是一个简单的示例:```matlabfunction [sys,x0,str] = sfun(t,x,u,flag,param1,param2,param3) switch flagcase 0 Initialization[sys,x0,str] = mdlInitializeSizes(param1,param2,param3);case 3 Outputssys = mdlOutputs(t,x,u,param1,param2,param3);case {1, 2, 4, 9} Unused flagssys = [];otherwiseerror(['Unhandled flag = ',num2str(flag)]); endendfunction [sys,x0,str,ts] = mdlInitializeSizes(param1,param2,param3) Initialize the state xx0 = 0;sys = 0;Return the details of the S-functionsizes = simsizes;sizes.NumContStates = 0;sizes.NumDiscStates = 1;sizes.NumOutputs = 1;sizes.NumInputs = 1;sizes.DirFeedthrough = 1;sizes.NumSampleTimes = 1;sys = simsizes(sizes);str = [];ts = [0 0];endfunction sys = mdlOutputs(t,x,u,param1,param2,param3)Compute the output of the S-functiony = u(1) + param1 * u(1) + param2 * u(1)^2 + param3 * u(1)^3; sys = y;end```在上面的例子中,我们定义了三个参数param1、param2和param3,并在初始化函数和输出函数中使用了这些参数。

29_Matlab中S-函数的编写

29_Matlab中S-函数的编写

Matlab中S-函数的编写S-函数使Simulink的功能大大扩充,除Mmatlab外,用户还可以用其他语言(C/C++/FORTRAN/Ada)编写实现算法,很强大的同时也对使用者提出了较高的要求。

下面是编写S-函数的整个流程:0 基础知识(1)Simulink仿真过程Simulnk仿真分为两步:初始化、仿真循环。

仿真是由求解器控制的,求解器主要作用是:计算模块输出、更新模块离散状态、计算连续状态。

求解器传递给系统的信息包括:时间、输入和当前状态。

系统的作用:计算模块的输出、更新状态、计算状态导数,然后将这些信息传递给求解器。

求解器和系统之间的信息传递是通过不同标志来控制的。

(2)S-函数控制流(3)S-函数的几个概念1)直接馈通在编写S-函数时,初始化函数中需要对sizes.DirFeedthrough 进行设置,如果输出函数mdlOutputs或者对于变采样时间的mdlGetTimeOf NextVarHit是输入u的函数,则模块具有直接馈通的特性sizes.DirFee dthrough=1;否则为0。

2)采样时间仿真步长就是整个模型的基础采样时间,各个子系统或模块的采样时间,必须以这个步长为整数倍。

连续信号和离散信号对计算机而言其实都是采样而来的,只是采样时间不同,连续信号采样时间可认为趋于0且基于微分方程,离散信号采样时间比较长基于差分方程。

离散信号当前状态由前一个时刻的状态决定,连续信号可以通过微分方程计算得到。

如果要将连续信号离散化还要考虑下信号能否恢复的问题,即香农定理。

采样时间点的确定:下一个采样时间=(n*采样间隔)+ 偏移量,n表示当前的仿真步,从0开始。

对于连续采样时间,ts可以设置为[0 0],其中偏移量为0;对于离散采样时间,ts假设为[0.25 0.1],表示在S-函数仿真开始后0. 1s开始每隔0.25s运行一次,当然每个采样时刻都会调用mdlOutPuts 和mdlUpdate函数;对于变采样时间,即离散采样时间的两次采样时间间隔是可变的,每次仿真步开始时都需要用mdlGetTimeNextVarHit计算下一个采样时间的时刻值。

MATLAB第5章S函数

MATLAB第5章S函数


• • •

(3) 找到函数mdlOutputs,加入以下代码: sys=2*u; (到现在为止我们的第一个S-函数写完了。下面演 示一下它的作用。) (4) 在Simulink空白页中添加S-function 块, 打开S-function 块对话框,参数S-function name 设置为doublesfunction 。按照图5.2添加连接好 其余的各个模块。 (5) 开始仿真,在Scope中观察输出结果,可 以看到输入正弦信号被放大为原来的2倍,如图 5.2所示。
• • • • •
• sizes.NumSampleTimes = 1; % 采样时间的个数:每个 系统至少有一个采样时间 • % 这些信息是通过一个数据结构sizes来表示的 • % 在该函数中用户还应该提供初始状态 x0,采样时间 ts。ts 是一个 m×2 的矩阵,其中第 k 行包含了对应与 第 k 个采样时间的采样周期值和偏移量。另外,在该子 函数中str 设置为空:[ ],str是保留变量,暂时没有任 何意义 • function [sys,x0,str,ts]=mdlInitializeSizes • sizes = simsizes; % 生成sizes数据结构 • sizes.NumContStates = 0; % 连续状态数,缺省为 0 • sizes.NumDiscStates = 0; % 离散状态数,缺省为 0 • sizes.NumOutputs = 0; % 输出量个数,缺省为 0
第5章
S-函 数
• 5.1 S-函数概述 • 5.2 S-函数的工作原理 • 5.3 编写M文件S-函数
5.1


S-函数概述
5.1.1 S-函数的基本概念

s函数编写

s函数编写

1. 函数的函数头函数的第一行:function [sys,x0,str,ts]=sfuntmpl(t,x,u,flag) , 先讲输入与输出变量的含义: t是采样时间, x是状态变量, u是输入(是做成simulink模块的输入), flag是仿真过程中的状态标志(以它来判断当前是初始化还是运行等)sys输出根据flag的不同而不同(下面将结合flag来讲sys的含义), x0是状态变量的初始值, str是保留参数(mathworks公司还没想好该怎么用它, 一般在初始化中将它置空就可以了, str=[]), ts是一个1×2的向量, ts(1)是采样周期, ts(2)是偏移量2. 函数分析下面结合sfuntmpl.m中的代码来讲具体的结构:switch flag, %判断flag,看当前处于哪个状态case 0,[sys,x0,str,ts]=mdlInitializeSizes;// 解释说明flag=0表示当前处于初始化状态,此时调用函数mdlInitializeSizes进行初始化,此函数在该文件的第149行定义. 其中的参数sys是一个结构体,它用来设置模块的一些参数,各个参数详细说明如下size = simsizes;%用于设置模块参数的结构体用simsizes来生成sizes.NumContStates = 0; %模块连续状态变量的个数sizes.NumDiscStates = 0; %模块离散状态变量的个数sizes.NumOutputs = 0; %模块输出变量的个数sizes.NumInputs = 0; %模块输入变量的个数sizes.DirFeedthrough = 1; %模块是否存在直接贯通sizes.NumSampleTimes = 1; %模块的采样时间个数, 至少是一个sys = simsizes(sizes); %设置完后赋给sys输出举个例子,考虑如下模型:dx/dt=fc(t,x,u) 也可以用连续状态方程描述:dx/dt=A*x+B*ux(k+1)=fd(t,x,u) 也可以用离散状态方程描述:x(k+1)=H*x(k)+G*u(k)y=fo(t,x,u) 也可以用输出状态方程描述:y=C*x+D*u设上述模型连续状态变量、离散状态变量、输入变量、输出变量均为1个,我们就只需改上面那一段代码为(一般连续状态与离散状态不会一块用, 我这儿是为了方便说明):sizes.NumContStates=1;sizes.NumDiscStates=1;sizes.NumOutputs=1;sizes.NumInputs=1;其他的可以不变, 继续在mdlInitializeSizes函数中往下看:x0 = []; %状态变量设置为空,表示没有状态变量,以我们上面的假设,可改为x0=[0,0](离散和连续的状态变量我们都设它初值为0)str = []; %保留参数, 置[]就可以了, 没什么用ts = [0 0]; %采样周期设为0表示是连续系统, 如果是离散系统在下面的mdlGetTimeOfNextVarHit函数中具体介绍case 1,sys=mdlDerivatives(t,x,u);//flag=1表示此时要计算连续状态的微分, 即上面提到的dx/dt=fc(t,x,u)中的dx/dt, 找到193行的函数mdlDerivatives, 如果设置连续状态变量个数为0, 此处只需sys=[]就可以了, 按我们上述讨论的那个模型, 此处改成 sys=fc(t,x(1),u)或sys=A*x(1)+B*u,我们这儿x(1)是连续状态变量, 而x(2)是离散的, 这儿只用到连续的, 此时的输出sys就是微分case 2,sys=mdlUpdate(t,x,u);//flag=2表示此时要计算下一个离散状态, 即上面提到的x(k+1)=fd(t,x,u), 找到mdlUpdate函数, 它这儿sys=[]表示没有离散状态, 我们这儿可以改成sys=fd(t,x(2),u)或sys=H*x(2)+G*u;%sys即为x(k+1)case 3,sys=mdlOutputs(t,x,u);//flag=3表示此时要计算输出, 即y=fo(t,x,u), 找到218行的mdlOutputs函数. 如果sys=[]表示没有输出, 我们改成sys=fo(t,x,u)或sys=C*x+D*u %sys此时为输出ycase 4,sys=mdlGetTimeOfNextVarHit(t,x,u);//flag=4表示此时要计算下一次采样的时间, 只在离散采样系统中有用(即上文的mdlInitializeSizes中提到的ts设置ts(1)不为0), 连续系统中只需在mdlGetTimeOfNextVarHit 函数中写上sys=[]. 这个函数主要用于变步长的设置, 具体实现大家可以用edit vsfunc看vsfunc.m这个例子case 9,sys=mdlTerminate(t,x,u);//flag=9表示此时系统要结束,一般来说写上在mdlTerminate函数中写上sys=[]就可, 如果你在结束时还要设置什么,就在此函数中写完了.Part II此外, s函数还可以带用户参数, 下面给个例子, 它和simulink下的gain模块功能一样function [sys,x0,str,ts] = sfungain(t,x,u,flag,gain)switch flag,case 0,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];case 3,sys=gain*u;case {1,2,4,9},sys = [];end做好了s函数后, simulink --> user-defined function下拖一个S-Function到你的模型, 就可以用了. 在simulink --> user-defined function还有个s-Function Builder, 他可以生成用c语言写的s函数. 或者在matlab的workspace下打sfundemos, 可以看到很多演示s函数的程序Part IIISIMULINK s-function的设计Simulink为用户提供了许多内置的基本库模块, 通过这些模块进行连接而构成系统的模型. 对于那些经常使用的模块进行组合并封装可以构建出重复使用的新模块, 但它依然是基于Simulink原来提供的内置模块.而Simulink s-function是一种强大的对模块库进行扩展的新工具.(一) s-function的概念s-function是一个动态系统的计算机语言描述, 在MATLAB里, 用户可以选择用m文件编写, 也可以用c或mex文件编写, 在这里只给大家介绍如何用m文件编写s-function.S-function提供了扩展Simulink模块库的有力工具, 它采用一种特定的调用语法, 使函数和Simulink解法器进行交互.S-function最广泛的用途是定制用户自己的Simulink模块. 它的形式十分通用, 能够支持连续系统、离散系统和混合系统.(二) 建立m文件s-function1. 使用模板文件:sfuntmp1.m, 其格式为[sys,x0]=function(t,x,u,flag). 该该模板文件位于MATLAB根目录下toolbox/simulink/blocks目录下模板文件里s-function的结构十分简单, 它只为不同的flag的值指定要相应调用的m文件子函数. 比如当flag=3时, 即模块处于计算输出这个仿真阶段时, 相应调用的子函数为sys=mdloutputs(t,x,u). 模板文件使用switch语句来完成这种指定, 当然这种结构并不唯一, 用户也可以使用if语句来完成同样的功能. 而且在实际运用时, 可以根据实际需要来去掉某些值, 因为并不是每个模块都需要经过所有的子函数调用.模板文件只是Simulink为方便用户而提供的一种参考格式, 并不是编写s-function的语法要求, 用户完全可以改变子函数的名称, 或者直接把代码写在主函数里, 但使用模板文件的好处是, 比较方便, 而且条理清晰.使用模板编写s-function, 用户只需把s-函数名换成期望的函数名称, 如果需要额外的输入参量, 还需在输入参数列表的后面增加这些参数, 因为前面的4个参数是simulink调用s-function时自动传入的. 对于输出参数, 最好不做修改. 接下去的工作就是根据所编s-function要完成的任务, 用相应的代码去替代模板里各个子函数的代码即可.Simulink在每个仿真阶段都会对s-function进行调用. 在调用时, Simulink会根据所处的仿真阶段为flag传入不同的值, 而且还会为sys这个返回参数指定不同的角色. 也就是说尽管是相同的sys变量, 但在不同的仿真阶段其意义却不相同, 这种变化由simulink自动完成.m文件s-function可用的子函数说明如下:mdlInitializeSizes(flag=0) -- 定义s-function模块的基本特性, 包括采样时间、连续或者离散状态的初始条件和sizes数组mdlDerivatives(flag=1) -- 计算连续状态变量的微分方程mdlUpdate(flag=2) -- 更新离散状态、采样时间和主时间步的要求mdlOutputs(flag=3) -- 计算s-function的输出mdlGetTimeOfNextVarHit(flag=4) -- 计算下一个采样点的绝对时间, 这个方法仅仅是在用户在mdlInitializeSizes 里说明了一个可变的离散采样时间概括说来, 建立s-function可以分成两个分离的任务: 第一, 初始化模块特性包括输入输出信号的宽度, 离散连续状态的初始条件和采样时间. 第二, 将算法放到合适的s-function子函数中去。

MATLAB的S函数

MATLAB的S函数

s函数s函数是system Function的简称,用它来写自己的simulink模块。

可以用matlab、C、C++、Fortran、Ada等语言来写,这儿只介绍怎样用matlab语言来写吧(主要是它比较简单)先讲讲为什么要用s函数,用s函数可以利用matlab的丰富资源,而不仅仅局限于simulink提供的模块,而用c或c++等语言写的s函数还可以实现对硬件端口的操作,还可以操作windows API等的先介绍一下simulink的仿真过程(以便理解s函数),simulink的仿真有两个阶段:第一个为初始化,这个阶段主要是设置一些参数,像系统的输入输出个数、状态初值、采样时间等;第二个阶段就是运行阶段,这个阶段里要进行计算输出、更新离散状态、计算连续状态等等,这个阶段需要反复运行,直至结束。

在matlab的workspace里打edit sfuntmpl(这是matlab自己提供的s函数模板),我们看它来具体分析s函数的结构。

它的第一行是这样的:function [sys,x0,str,ts]=sfuntmpl(t,x,u,flag)先讲输入与输出变量的含义:t是采样时间,x是状态变量,u是输入(是做成simulink模块的输入),flag是仿真过程中的状态标志(以它来判断当前是初始化还是运行等);sys输出根据flag的不同而不同(下面将结合flag来讲sys 的含义),x0是状态变量的初始值,str是保留参数(mathworks公司还没想好该怎么用它,嘻嘻,一般在初始化中将它置空就可以了,str=[]),ts是一个1×2的向量,ts(1)是采样周期,ts(2)是偏移量。

下面结合sfuntmpl.m中的代码来讲具体的结构:switch flag, %判断flag,看当前处于哪个状态case 0,[sys,x0,str,ts]=mdlInitializeSizes;flag=0表示处于初始化状态,此时用函数mdlInitializeSizes进行初始化,此函数在sfuntmpl.m的149行我们找到他,在初始化状态下,sys是一个结构体,用它来设置模块的一些参数,各个参数详细说明如下size = simsizes;%用于设置模块参数的结构体用simsizes来生成sizes.NumContStates = 0;%模块连续状态变量的个数sizes.NumDiscStates = 0;%模块离散状态变量的个数sizes.NumOutputs = 0;%模块输出变量的个数sizes.NumInputs = 0;%模块输入变量的个数sizes.DirFeedthrough = 1;%模块是否存在直接贯通(直接贯通我的理解是输入能直接控制输出)sizes.NumSampleTimes = 1;%模块的采样时间个数,至少是一个sys = simsizes(sizes); %设置完后赋给sys输出举个例子,考虑如下模型:dx/dt=fc(t,x,u) 也可以用连续状态方程描述:dx/dt=A*x+B*ux(k+1)=fd(t,x,u) 也可以用离散状态方程描述:x(k+1)=H*x(k)+G*u(k) y=fo(t,x,u) 也可以用输出状态方程描述:y=C*x+D*u设上述模型连续状态变量、离散状态变量、输入变量、输出变量均为1个,我们就只需改上面那一段代码为:(一般连续状态与离散状态不会一块用,这儿是为了方便说明)sizes.NumContStates=1;sizes.NumDiscStates=1;sizes.NumOutputs=1;sizes. NumInputs=1;其他的可以不变。

MATLAB S函数编写示范

MATLAB S函数编写示范

otherwiseDAStudio.error('Simulink:blocks:unhandledFlag',num2str(flag));endfunction[sys,x0,str,ts,simStateCompliance]=mdlInitializeSizessizes=simsizes;sizes.NumContStates=2;sizes.NumDiscStates=0;sizes.NumOutputs=1;sizes.NumInputs=1;sizes.DirFeedthrough=1;sizes.NumSampleTimes=1;%at least one sample time is neededsys=simsizes(sizes);x0=[00];str=[];ts=[00];simStateCompliance='UnknownSimState';function sys=mdlDerivatives(t,x,u)sys=[-3*x(1)-x(2)+u;2*x(1)];//注意此处传递的是x向量,包含了x1和x2,引用时使用x(1),x(2),下标从1开始function sys=mdlUpdate(t,x,u)sys=[];function sys=mdlOutputs(t,x,u)sys=[x(2)];//x向量function sys=mdlGetTimeOfNextVarHit(t,x,u)sampleTime=1;%Example,set the next hit to be one second later.sys=t+sampleTime;function sys=mdlTerminate(t,x,u)sys=[];2.C语言S函数让我们做一个两个输入,两个输出,两个参数的例子。

在MATLAB命令行输入edit sfuntmpl_basic.c即可打开C语言S函数模板。

S函数M文件matlab示范详解教程

S函数M文件matlab示范详解教程
27学习资料函数年月日functionsysx0strtssimstatecompliancesfuntmpltxuflagt表示当前时间x表示状态变量u表示输入变量flag表示s函数现在应该运行哪个任比如flag0就运行初始化函数sys是一个通用的返回值在每一个子函数中都可以用它返回数值x0表示初始状态的值除了flag0以外x0均被忽略str是保留变量等mathwork公司想清楚了再说ts的设置例如如果你希望你的sfunction在每个时间步连续采样时间都运行则应设置为00
%============================================================================= % mdlUpdate % 更新离散状态,采样时间和主步长 %=============================================================================
F:\学习资料\Matlab S函数\sfuntmpl.m
2014年9月3日 16:27
function [sys,x0,str,ts,simStateCompliance] = sfuntmpl(t,x,u,flag) % t表示当前时间,X表示状态变量,u表示输入变量,flag表示S函数现在应该运行哪个任务,比如flag=0,就 运行初始化函数 % sys是一个通用的返回值,在每一个子函数中都可以用它返回数值 % x0表示初始状态的值,除了flag=0以外,x0均被忽略 % str是保留变量,等mathwork公司想清楚了再说 % ts的设置,例如,如果你希望你的 S-function 在每个时间步(连续采样时间)都运行,则应设置为 % [0,0];如果你希望你的 S-function 按照其所连接块的速率来运行,则应设置为[-1,0]; % 如果你希望它在仿真开始的 0.1 秒后每 0.25 秒(离散采样时间)运行一次,则应设置为[0.25,0.1]。 % 你可以创建一个 S-function 按照不同的速率来执行不同的任务(如:一个多速率 S-function) 。在 % 这种情况下,ts 应该按照采样时间升序排列来指定 S-function 所需使用的全部采样速率。例如,假设 % 你的 S-function 每 0.25 秒执行一个任务,同时在仿真开始的 0.1 秒后每 1 秒执行另一个任务,那么你 % 的 S-function 应设置 ts 为[0.25,0;1.0,0.1]。 %主函数 switch flag, case 0, [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes; %定义S函数的基本特性,并传送给simulink 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); %一般为[],simulink仿真结束时,如果有需要设置什么,就在这里面写。 otherwise DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag)); %flag不是0,1,2,3,4,9的话,未知的flag值 end %主函数结束
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

S函数编辑流程及相关1. S函数模板编辑环境进入:在MATLAB主界面中直接输入:edit sfuntmpl即可弹出S函数模板编辑的M文件环境,修改即可。

在MATLAB主界面中直接输入:sfundemos,即可调出S函数的许多编程例子。

2. S函数模板的相关基础:1)M文件S函数的引导语句为:txfpusysFunction[pxstrtsflag,,12,...),,,0,],(,S函数默认的四个输入参数:t ,x ,u ,flagS函数默认的四个输出函数:sys ,x0 ,str ,ts各个参数的含义如下:T :代表当前的仿真时间,该输入决定了下一个采样时间;X :表示状态向量,行向量,引用格式:X(1),X(2)U :表示输入向量;Flag :控制在每一个仿真阶段调用哪一个子函数的参数,由SIMULINK在调用时自动取值;Sys :通用的返回变量,返回的数值决定Flag值,mdlUpdates 里:列向量,引用格式:Sys(1,1),Sys(2,1);mdlOutputs里:行向量,引用格式:Sys =x.X0 :初始的状态值;列向量,引用格式:X0=[ 0;0;0 ]Str :空矩阵,无具体含义;Ts :包含模块采样时间和偏差的矩阵。

[period, offset]当Ts为-1时,表示与输入信号同采样周期。

2)S函数工作方式:Flag = 0时,调用mdlInitializeSizes函数,定义S函数的基本特性,包括采样时间,连续或者离散状态的初始条件和Sizes 数组;Flag = 1时,调用mdlDerivatives函数,计算连续状态变量的微分方程;求所给表达式的等号左边状态变量的积分值的过程。

Flag = 2时,调用mdlUpdate函数,用于更新离散状态,采样时间和主时间步的要求;Flag = 3时,调用mdlOutputs函数,计算S函数的输出;Flag = 4时,调用mdlGetTimeOfNextVarHit函数,计算下一个采样点的绝对时间,这个方法仅仅是使用户在mdlInitializeSize 里说明一个可变的离散采样时间;Flag = 9时,调用mdlTerminate函数,实现仿真任务的结束。

3)S函数仿真过程:①初始化:mdlInitializeSizes,初始化S函数●初始化SimStruct,包含了S函数的所有信息;●设置输入、输出端口数;●设置采样时间;●分配存储空间。

②数值积分:mdlDerivatives●用于连续状态的求解和非采样过零点;●如果存在连续状态,调用mdlDerivatives和mdlOutput两个子函数;●如果存在非采样过零点,调用mdlOutput和mdlZeroCrossings子函数,以定位过零点。

③更新离散状态:mdlUpdate④计算输出:mdlOutputs,计算所有输出端口的输出值。

⑤计算下一个采样时间点:mdlGetTimeOfNextVarHit⑥仿真结束:mdlTerminate,在仿真结束时调用。

3. S函数的编写:1)参数初始设定:初始化sizes结构,再调用simsizes函数;Sizes结构体:NumContStates:连续状态的个数NumDiscStates:离散状态的个数NumOutputs:输出变量的个数NumInputs:输入变量的个数DirFeedthrough:有无直接馈入,值为1时表示输入直接传到输出口NumSampleTimes:采样时间的个数,值为1时表示只有一个采样周期Simsizes函数的调用:sys = simsizes (sizes) ,即将sizes结构体中的信息传递给sys。

2)状态的动态更新:连续模块的状态更新由mdlDerivatives函数来进行;离散模块的状态更新由mdlUpdate函数来进行;3)输出信号的计算:计算出模块的输出信号,系统的输出仍然由sys变量返回。

4. M文件S函数的模块化:在动态系统仿真设计,分析中,用户可以使用S-Function 模块来调用S-函数。

1)S-Function模块是一个单输入单输出的模块,如果有多个输入与输出信号,可以使用Mux模块与Demux模块对信号进行组合和分离操作;2)在S-Function模块的参数设置对话框中,包含了调用的S函数名和用户输入的参数列表,如下图所示:3)S-Function模块是以图形的方式提供给用户一个调用S函数的接口,S函数中的源文件必须由用户自行编写;4)S-Function模块中的S-函数名和参数值列表必须与用户填写的S函数源文件的名称和参数列表完全一致,包括参数的顺序。

5. S-Function模块建立流程:创建一个有1输入(2维),2输出(1维),3个参数,还有全局变量的s-function。

1.新建sfunction的C语言文件打开simulink,点击User-Defined Functions里面的S-Function Examples。

这个里面有多个语言版本的模板,有C,C++,Ada,Fortran和M语言的版本,其实都大同小异,只要了解几个函数就很容易使用了。

选择C语言的版本:从S-function模块中选择C-file S-functions里面的Basic C-MEX template。

打开后,另存为自己的模块名字,如test.c。

下面我们来分析代码:#define S_FUNCTION_NAME test//这里把文件名sfuntmpl_basic修改为test#define S_FUNCTION_LEVEL 2#include "simstruc.h"//程序里面要用到的头文件在这里引用,如“math.h”等。

float global_var; //定义全局变量static void mdlInitializeSizes(SimStruct *S){//这个函数用来设置输入、输出和参数的。

ssSetNumSFcnParams(S, 3); /*设置参数个数,这里为3 */if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {return;}ssSetNumContStates(S, 0);//设置连续状态的个数,缺省为0;ssSetNumDiscStates(S, 0);//设置离散状态的个数,缺省为0;if (!ssSetNumInputPorts(S, 1)) return;//设置输入变量的个数,这里为1ssSetInputPortWidth(S, 0, 2); //设置输入变量0的维数为2 ssSetInputPortRequiredContiguous(S, 0, true); //设置input0的访问方式,true就是临近访问,这样指针的增量后就可以直接访问下个input端口了。

ssSetInputPortDirectFeedThrough(S, 0, 1);// 设置输入端口的信号是否mdlOutputs 函数中使用,这儿设置为true。

if (!ssSetNumOutputPorts(S, 2)) return;//设置输出变量的个数ssSetOutputPortWidth(S, 0, 1);//设置输出变量0的维数为1维ssSetOutputPortWidth(S, 1, 1);//设置输出变量1的维数为1维ssSetNumSampleTimes(S, 1); //设置采样时间,此处为1s。

ssSetNumRWork(S, 0);//不管ssSetNumIWork(S, 0);ssSetNumPWork(S, 0);ssSetNumModes(S, 0);ssSetNumNonsampledZCs(S, 0);ssSetOptions(S, 0);//下面可以写全局变量的初始化程序global_var=1;}static void mdlInitializeSampleTimes(SimStruct *S)//暂时不管{ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME);ssSetOffsetTime(S, 0, 0.0);}#define MDL_INITIALIZE_CONDITIONS /* Change to #undef to remove function */#if defined(MDL_INITIALIZE_CONDITIONS)static void mdlInitializeConditions(SimStruct *S)//暂时不管{}#endif /* MDL_INITIALIZE_CONDITIONS */#define MDL_START /* Change to #undef to remove function */#if defined(MDL_START)static void mdlStart(SimStruct *S)//暂时不管{}#endif /* MDL_START */static void mdlOutputs(SimStruct *S, int_T tid)//这里填入相关的运算、算法等{real_T *para1 = mxGetPr(ssGetSFcnParam(S,0));real_T *para2 = mxGetPr(ssGetSFcnParam(S,1));real_T *para3 = mxGetPr(ssGetSFcnParam(S,2));const real_T *u = (const real_T*) ssGetInputPortSignal(S,0);real_T *y1 = ssGetOutputPortSignal(S,0);real_T *y2 = ssGetOutputPortSignal(S,1);y1[0]=u[0]*para1[0]+u[1]*para2[0];y2[0]=u[1]*para3[0]+u[0]*para1[0];}#define MDL_UPDATE /* Change to #undef to remove function */#if defined(MDL_UPDATE)static void mdlUpdate(SimStruct *S, int_T tid){}#endif /* MDL_UPDATE */#define MDL_DERIV ATIVES /* Change to #undef to remove function */#if defined(MDL_DERIV ATIVES)static void mdlDerivatives(SimStruct *S){}#endif /* MDL_DERIV ATIVES */static void mdlTerminate(SimStruct *S)//这里需要把global变量全部初始化,否则下次运行程序时,全局变量还是之前的值。

相关文档
最新文档