总结matlab-s函数的用法.doc_第1页
总结matlab-s函数的用法.doc_第2页
总结matlab-s函数的用法.doc_第3页
总结matlab-s函数的用法.doc_第4页
总结matlab-s函数的用法.doc_第5页
免费预览已结束,剩余16页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

函数是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是一个12的向量,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;其他的可以不变。继续在mdlInitializeSizes函数中往下看:x0 = ; %状态变量设置为空,表示没有状态变量,以我们上面的假设,可改为x0=0,0(离散和连续的状态变量我们都设它初值为0)str = ; %这个就不用说了,保留参数嘛,置就可以了,反正没什么用,可能7.0会给它一些意义ts = 0 0; %采样周期设为0表示是连续系统,如果是离散系统在下面的mdlGet %TimeOfNextVarHit函数中具体介绍。嘻嘻,总算讲完了初始化,后面的应该快了在sfuntmpl的106行继续往下看:case 1,sys=mdlDerivatives(t,x,u);flag=1表示此时要计算连续状态的微分,即上面提到的dx/dt=fc(t,x,u)中的dx/dt,找到 mdlDerivatives函数(在193行)如果设置连续状态变量个数为0,此处只需sys=; 就可以了(如sfuntmpl中一样),按我们上述讨论的那个模型,此处改成 sys=fc(t,x(1),u)或sys=A*x(1)+B*u %我们这儿x(1)是连续状态变量,而x(2)是离散的,这儿只用到连续的,此时的输出sys就是微分继续,在sfuntmpl的112行:case 2,sys=mdlUpdate(t,x,u);flag=2表示此时要计算下一个离散状态,即上面提到的x(k+1)=fd(t,x,u),找到mdlUpd ate函数(在206行)它这儿sys=;表示没有离散状态,我们这而可以改成 sys=fd(t,x(2),u)或sys=H*x(2)+G*u;%sys即为x(k+1)看来后面几个一两句话就可了,呵呵,在sfuntmpl的118行case 3,sys=mdlOutputs(t,x,u);flag=3表示此时要计算输出,即y=fo(t,x,u),找到mdlOutputs函数(在218行),如上,如果sys=表示没有输出,我们改成sys=fo(t,x,u)或sys=C*x+D*u %sys此时为输出y好像快完了,嘻嘻,在sfuntmpl的124行case 4,sys=mdlGetTimeOfNextVarHit(t,x,u);flag=4表示此时要计算下一次采样的时间,只在离散采样系统中有用(即上文的mdlInit ializeSizes中提到的ts设置ts(1)不为0)连续系统中只需在mdlGetTimeOfNextVarHit函数中写上sys=;这个函数主要用于变步长的设置,具体实现大家可以用edit vsfunc看vsfunc.m这个例子最后一个,在sfuntmpl的130行case 9,sys=mdlTerminate(t,x,u);flag=9表示此时系统要结束,一般来说写上在mdlTerminate函数中写上sys=就可,如果你在结束时还要设置什么,就在此函数中写关于sfuntmpl这个s函数的模板讲完了。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函数的程序。matlab中S函数的编程问题程序如下:function sys=mdlOutputs(t,x,u,n) sys(1)=6;for m=1:100 n(m)=m*0.00001;end sys(1)=-6;想用for循环做一个延时,生成一个脉冲序列,高电平为6低电平为-6,可输出波形总是输出-6,没有变化。还有为什么两个全写成sys就提示前面的sys不被使用。请高手指教 问题补充:高手,我首先感谢你的热心帮忙!并已生成了幅值是6的脉冲序列!可是我还要再问你一个问题,以前没说清楚,这个脉冲是随时按照下面的式子改变占空比的。a=p1*311sin(100*pi*(k+1)+p2*u(k)+p3*i(k)+p4.得到的a是6保持的时间,p1=1.56*10(-6),p2=-1.295*10(-6),p3=-7.847*10(-6),p4=61.5*10(-6)都是常数,u(k),i(k)是S函数的两个输入,311sin(100*pi*(k+1)是下一采样时刻的正弦值。脉冲的周期是T=0.000125s.能不能再改改您的回答。谢谢了!我把剩余的分数28分全给你了。能再帮帮我吗,我是个新手,您估计也早看出了,matlab的基本东西都不会,可是这个任务真的太急了。谢谢谢谢了!提问者: ch_567 - 一级最佳答案function sys,x0,str,ts=mdlInitializeSizessizes = simsizes;sizes.NumContStates = 0;sizes.NumDiscStates = 4;sizes.NumOutputs = 1;sizes.NumInputs = 2;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); p4=61.5*10(-6); m=u(1); n=u(2); a=p1*311*sin(100*pi*(k+1)+p2*m+p3*n+p4; t3=T*k+a;endif mod(i,2)=0 t3=T*k;endt1=x(1);t2=t;if (t1t3)%寻找切换时间点 s=-s; i=i+1; if mod(i,2)=0 k=k+1; endendsys=t2 s i k;function sys=mdlOutputs(t,x,u)sys=x(2);因为时间关系,没有仔细斟酌,程序不是很简洁,但是可以用。matlab中s函数编写(转)2010-03-25 14:40 matlab中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是一个12的向量,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*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;其他的可以不变。继续在mdlInitializeSizes函数中往下看: x0 = ; %状态变量设置为空,表示没有状态变量,以我们上面的假设,可改 %为x0=0,0(离散和连续的状态变量我们都设它初值为0) str = ; %这个就不用说了,保留参数嘛,置就可以了,反正没什么用,可 %能7.0会给它一些意义 ts = 0 0; %采样周期设为0表示是连续系统,如果是离散系统在下面的mdlGet %TimeOfNextVarHit函数中具体介绍嘻嘻,总算讲完了初始化,后面的应该快了在sfuntmpl的106行继续往下看:case 1, sys=mdlDerivatives(t,x,u);flag=1表示此时要计算连续状态的微分,即上面提到的dx/dt=fc(t,x,u)中的dx/dt,找到 mdlDerivatives函数(在193行)如果设置连续状态变量个数为0,此处只需sys=; 就可以了(如sfuntmpl中一样),按我们上述讨论的那个模型,此处改成 sys=fc(t,x(1),u)或sys=A*x(1)+B*u %我们这儿x(1)是连续状态变量,而x(2)是离散的,这儿只用到连续的,此时的输出sys就是微分继续,在sfuntmpl的112行: case 2, sys=mdlUpdate(t,x,u);flag=2表示此时要计算下一个离散状态,即上面提到的x(k+1)=fd(t,x,u),找到mdlUpd ate函数(在206行)它这儿sys=;表示没有离散状态,我们这而可以改成 sys=fd(t,x(2),u)或sys=H*x(2)+G*u;%sys即为x(k+1) 看来后面几个一两句话就可了,呵呵,在sfuntmpl的118行case 3, sys=mdlOutputs(t,x,u);flag=3表示此时要计算输出,即y=fo(t,x,u),找到mdlOutputs函数(在218行),如上,如果sys=表示没有输出,我们改成sys=fo(t,x,u)或sys=C*x+D*u %sys此时为输出y好像快完了,嘻嘻,在sfuntmpl的124行case 4, sys=mdlGetTimeOfNextVarHit(t,x,u);flag=4表示此时要计算下一次采样的时间,只在离散采样系统中有用(即上文的mdlInit ializeSizes中提到的ts设置ts(1)不为0)连续系统中只需在mdlGetTimeOfNextVarHit函数中写上sys=;这个函数主要用于变步长的设置,具体实现大家可以用edit vsfunc看vsfunc.m这个例子最后一个,在sfuntmpl的130行case 9, sys=mdlTerminate(t,x,u);flag=9表示此时系统要结束,一般来说写上在mdlTerminate函数中写上sys=就可,如果你在结束时还要设置什么,就在此函数中写关于sfuntmpl这个s函数的模板讲完了。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函数的程序SIMULINK 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-function 1、使用模板文件: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子函数中去。 2 、定义s-function的初始信息为了让Simulink识别出一个m文件s-function,用户必须在s-函数里提供有关s-函数的说明信息,包括采样时间、连续或者离散状态个数等初始条件。这一部分主要是在mdlInitializeSizes子函数里完成。Sizes数组是s-function函数信息的载体,它内部的字段意义为:NumContStates(sys(1):连续状态的个数(状态向量连续部分的宽度)NumDiscStates(sys(2):离散状态的个数(状态向量离散部分的宽度)NumOutputs(sys(3): 输出变量的个数(输出向量的宽度)NumInputs(sys(4):输入变量的个数(输入向量的宽度)DirFeedthrough(sys(5):有不连续根的数量NumSampleTimes(sys(6):采样时间的个数,有无代数循环标志如果字段代表的向量宽度为动态可变,则可以将它们赋值为1。注意DirFeedthrough是一个布尔变量,它的取值只有0和1两种,0表示没有直接馈入,此时用户在编写mdlOutputs子函数时就要确保子函数的代码里不出现输入变量u;1表示有直接馈入。NumSampleTimes表示采样时间的个数,也就是ts变量的行数,与用户对ts的定义有关。需要指出的是,由于s-function会忽略端口,所以当有多个输入变量或多个输出变量时,必须用mux模块或demux模块将多个单一输入合成一个复合输入向量或将一个复合输出向量分解为多个单一输出。 3、输入和输出参量说明S-function默认的4个输入参数为t、x、u和flag,它们的次序不能变动,代表的意义分别为:t:代表当前的仿真时间,这个输入参数通常用于决定下一个采样时刻,或者在多采样速率系统中,用来区分不同的采样时刻点,并据此进行不同的处理。x:表示状态向量,这个参数是必须的,甚至在系统中不存在状态时也是如此。它具有很灵活的运用。u:表示输入向量。flag:是一个控制在每一个仿真阶段调用哪一个子函数的参数,由Simulink在调用时自动取值。S-function默认的4个返回参数为sys、x0、它们的次序不能变动,代表的意义分别为:sys:是一个通用的返回参数,它所返回值的意义取决于flag的值。x0:是初始的状态值(没有状态时是一个空矩阵),这个返回参数只在flag值为0时才有效,其他时候都会被忽略。一、有一系统如下:dx1=x2dx2=9.81*sin(x(1)-2*x(2)+u求出系统在单位阶跃输入下的x1的状态变化曲线,假设x1,x2初值为0。function sys,x0=dong(t,x,u,flag)if flag=0sys=2;0;2;1;0;0;x0=0;0;elseif flag=1sys=x(2);9.81*sin(x(1)-2*x(2)+u;elseif flag=3sys=x(1);x(2);elsesys=;endS函数 S函数是扩展Simulink功能的强有力工具,它使用户可以利用MATLAB、C语言、C+语言等程序创建自己定义的Simulink模块。例如,对一个工程的几个不同的控制系统进行设计,而此时已经用M文件建立了一个动态模型,在这种情况下,可以将模型加入到S函数中,然后使用独立的Simulink模型来模拟这些控制系统。S函数还可以改善仿真的效率,尤其是在带有代数环的模型中。S函数使用一种特殊的调用规则来使得用户可以与Simulink的内部解法器进行交互,这种交互通Simulink内部解法器与内置的模块之间的交互非常相似。而且可以适用于不同性质的系统,例如连续系统、离散系统以及混合系统。7.7.1 S函数模块 S函数模块在functions & Tables模块库中,用此模块可以创建包含S函数的Simulink模型。图7.7.1显示了一个含有S函数的简单模型。S函数模块的对话框如图7.7.2所示,它有两个区:S函数文件名区和S函数的参数区。S函数文件名区要填写S函数的文件名。S函数参数区要填写S函数所需要的参数。参数并列给出,各参数间以逗号分隔。如图7.7.2所示。表示了S函数的参数为:1.5,矩阵1 2;3 4和字符串miles。 图7.7.1 包含S函数的模型 图7.7.2 S函数模块的对话框7.7.2 S函数的工作原理 S函数具有一套不同的调用方法,可以在仿真的不同阶段完成不同的调用任务。在模型仿真的不同阶段,Simulink会对模型中S函数模块选择适当的方法来完成调用。S函数可以完成的任务大体分为以下几种。 (1) 初始化。在进入仿真循环之间,Simulink首先初始化S函数,主要完成任务: 初始化包含S函数信息的仿真结构SimStruct。 设置输入输出端口的数目和维数。 设置模块的采样时间。 分派内存区和sizes数组。 (2) 计算下一个采样点。若用户使用了可变采样时间的模块,在这一阶段需要计算下一个采样点时间,也就是说要计算下一个时间步长。 (3) 计算主时间步的输出量。此调用结束后,所有模块的输出端口对当前的时间步都是有效的。 (4) 更新主时间步的离散状态。 (5) 积分计算。这一步只有当模型带有连续状态或带有非采样过零点时才有效。若S函数带有连续状态,则Simulink以较小的时间步长来调用S函数的输出和微分方法;若S函数具有非采样过零点,Simulink将以较小的时间步来计算S函数的输出和过零点部分。7.7.3 S函数中的几个概念 S函数中有几个关键的概念需要详细解释,对这几个概念的深入理解对正确使用S函数是非常重要的。 (1) 直接馈入 所谓的直接馈入是指模块的输出或采样时间是由它的一个输入端口的值直接控制。判断S函数地输入端口是否有直接馈入的判据有: 输出函数(mdlOutpits或者flag=3)是一个参数包含u的函数。 若改S函数是一个可变采样时间的S函数,且下一个采样时间点的计算中要用到输入参数u时,也可以判断此S函数为直接馈入型。 (2) 动态尺寸的输入 S函数可以支持任意维的输入,此时,输入的维数是由输入变量的维数动态确定的。同时,输入变量的维数也决定了连续和离散状态量的个数以及输出变量的维数。 M文件S函数只能有一个输入端口,并且输入端口只能接收一维信号。然而,信号可以是变宽度的。在一个M文件S函数里,为了指定输入的宽度是动态的,可以指定sizes结构的适当区域的值为1。也可以在S函数调用的时候使用length(u)来确定实际输入的宽度。若指定宽度值为0,则输入端口会从S函数模块中去掉。 例如,图7.7.3所示表示了在同一个模型中使用同一个S函数模块的两种情况,前者的S函数模块是由一个三元素向量驱动,后者则是由一个标量输出模块信号驱动,为了表明S函数函数模块的输入是动态的,两个S函数模块是完全相同的Simulink自适应地使用合适的尺寸来调用函数。类似地,若其它模块属性如输出变量数和状态数也被指定为动态尺寸的,Simulink将会定义这些变量与输入变量同维。 图7.7.3 同一个模型中使用同一个S函数模块的两种情况 (3) 采样时间的设置与采样延迟 M文件S函数和C语言S函数都在指定S函数的运行时间上有高度的自适应度。Simulink为采样时间提供了下面的几种选着。 连续采样时间:适用于具有连续状态和非采样过零点的S函数。这种S函数的输出按最小时间步改变。 连续但固定最小步长的采样时间:适用于需要在每一个主仿真时间步执行,但在最小仿真步内值不改变的。 离散采样时间:若S函数得行为发生具有离散时间间隔的函数,用户可以定义一个采样时间来规定Simulink何时调用函数。而且用户还可以定义一个延迟时间offset来延迟采样点,但offset的值不能超过采样周期。 若用户定义了一个离散采样时间,则Simulink就会在所定义的每个采样点调用S函数的mdlOutpit和mdlUpdate方法。 可变采样时间:相邻采样点的时间间隔可变得离散采样时间。在这种采样时间的情况下,S函数要在每一步仿真的开始,计算下一个采样点的时刻。 继承采样时间:在有些情况下,S函数模块自身没有特定的采样时间,它本身的状态是连续的还是离散的完全取决于系统中的其它模块。此时,该S函数模块的采样时间属性可以设为继承。例如gain模块就是一个继承输入信号采样时间的例子。一般,一个模块可以从以下几个方式来继承采样时间: 继承驱动模块的采样时间; 继承目标模块的采样时间; 继承系统中最快的采样时间。7.7.4 S函数动画 基于S函数地动画就是一个由没有状态函数、没有输出变量的S函数生成的动画。因此它们只能作常规显示。这种S函数有两个主要部分:初始化部分和更新部分。 在初始化过程中要创建图形窗口及动画对象; 在更新过程中,动画对象的属性将作为S函数模块的输入函数,且它的变化导致动画对象的运动可能会以其它形式变化。 (1) 动画的初始化 S函数动画的初始化语句包括S函数的初始化和图形的初始化。采样时间应设置为较小的数值以便动画可以看起来更加连续。但同时也不能太小,因为那会使得仿真过程运行起来太慢。 首先需要检验与当前S函数模块相联系的动画图形是否已打开。这里使用的方法是将当前模块的路径保存到图形的UserData参数中。此时使用gcd函数是一种比较安全的方法,因为在S函数的执行过程中,gcd总会返回S函数模块的路径。完成此任务的MATLAB命令可为如下形式: if(findobj(UserData,gcb) % 若模型已经打开,则不作任何事 else % 初始化图形 end其中的初始化图形语句可由figure命令实现,例如 h_fig=figure(Position,x_pos,y_pos,width,height然后,将当前S函数模块的路径保存到图形UserData中,这样对图形的存在性检验才会正常工作。下面的语句可以用来设置UserData: set(h_fig,UserData,gcb);使用MATLAB绘图命令绘制动画图形。接着保存这些图形元素的句柄。例如,要绘制由向量x_array和y_array定义的曲线,使用下面的语句: hdl=plot(x_array,y_array);图形初始化的最后一步是保存这些仿真元素的句柄。这里使用的方法是将这些元素成组地保存到一个MATLAB变量中,并把此变量保存到S函数模块的UserData中。UserData中可以保存MATLAB的任何变量,包括单元数组合结构。假设要绘制两个图形元素的动画,而它们的句柄名分别为hd1和hd2,下面的语句会把它们保存到一个结构中。 t_data.hd1=hd1; t_data.hd2=hd2; set_param(gcd,UserData,t_data); (2) 动画的更新 由于设置采样时间为正数,所以动画S函数可以被看成是离散模块。Simulink将以flag=2在采样时间执行S函数。更新函数会从S函数模块UserData中读取即将改变得图形对象的句柄。例如,如果句柄以结构变量的形式储存,则它们可以写成如下形式。 T_data=get_param(gcd,UserData); hd1=t_data.hd1; hd2=t_data.hd2;然后计算改变得对象属性的新值,并使用set命令更新属性。 Set(handle,propertyName,propertyValue); 其中handle为对象的句柄,propertyName为有即将改变得对象属性的对象名构成的MATLAB字符串。propertyValue为新的属性值。 例7.7.1 在本例中,将创建一个在半球形槽内往复滚动的圆盘的动画。分析:假设圆盘在槽内做无滑动的滚动,则系统的运动方程为 其中:, g为重力加速度,的动力学关系为 图7.7.4为此系统运动方程的Simulink模型,它用一个动画S函数模块来显示圆盘运动。 图7.7.4 例7.7.1的Simulink模型 S函数为一个M文件,其程序代码如下,执行后的动画图形如图7.7.5所示。function sys,x0,str,ts = s_anm81s(t,x,u,flag)% S-file animation example 1% This example demonstrates buidling an animation % using a single S-file with no callbacks.% Based on sfuntmpl.m, supplied with SIMULINK% Copyright (c) 1990-96 by The MathWorks, Inc.%switch flag, case 0, % Initialization sys,x0,str,ts=mdlInitializeSizes; case 1, % Derivatives sys=mdlDerivatives(t,x,u); case 2, sys=mdlUpdate(t,x,u); case 3, sys=mdlOutputs(t,x,u); % Compute output vector case 4, % Compute time of next sample sys=mdlGetTimeOfNextVarHit(t,x,u); case 9, % Finished. Do any needed sys=mdlTerminate(t,x,u); otherwise % Invalid input error(Unhandled flag = ,num2str(flag);end%*%* mdlInitializeSizes *%*function sys,x0,str,ts=mdlInitializeSizes()% Return the sizes of the system vectors, initial % conditions, and the sample times and offets.sizes = simsizes; % Create the sizes structuresizes.NumContStates = 0;sizes.NumDiscStates = 0;sizes.NumOutputs = 0;sizes.NumInputs = 1;sizes.DirFeedthrough = 0;sizes.NumSampleTimes = 1;sys = simsizes(sizes); x0 = ; % There are no

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论