《MATLAB的S-Function编写指导》.pdf
《《MATLAB的S-Function编写指导》.pdf》由会员分享,可在线阅读,更多相关《《MATLAB的S-Function编写指导》.pdf(100页珍藏版)》请在冰点文库上搜索。
Simulink基于模型与基于系统的设计?
建模?
仿真?
实现S-Function的编写Version5i目录S-FUNCTION概述.1什么是S-FUNCTION.2在模型中使用S-FUNCTION.3向S-Function传递参数.3何时使用S-Function.4S-FUNCTION的工作原理.5Simulink块的数学关系.5仿真过程.5S-Function回调程序.6S-FUNCTION的实现.8M-文件的S-Function.8MEX文件的S-function.8MEX文件与M-文件的S-function比较.9S-FUNCTION的概念.10直接馈通.10动态维矩阵.10设置采样时间和偏移量.11S-FUNCTION范例.14M文件S-function范例.15CS-Function范例.16FortranS-Function范例.18C+S-Function范例.18AdaS-Function范例.18编写MS-FUNCTION.19概述.20S-Function参数.20S-Function的输出.20定义S-FUNCTION块特性.22处理S-FUNCTION参数.22M文件的S-FUNCTION范例.23范例1简单的M文件S-Function.23范例2连续状态S-Function.25范例3离散状态S-Function.27范例4混合系统S-Function.28范例5变步长S-Function.31ii使用C语言编写S-FUNCTION.33概述.34创建CMEXS-Function.35自动生成S-FUNCTION.36配置生成的S-Function.37S-FunctionBuilder如何生成S-Function.37设置include路径.37S-FUNCTIONBUILDER的对话窗.39Initialization选卡.39DataProperties选卡.40Libraries选卡.42Outputs选卡.43ContinuousDerivatives选卡.45DiscreteUpdate选卡.46BuildInfo选卡.47一个基本的CMEXS-FUNCTION范例.48定义与包含.49回调函数的实现.50Simulink/Real-TimeWorkshop接口.51BuildingTimestwo范例.51CS-FUNCTION模板.52S-Function源文件必需的内容.52SimStruct.53编译CS-Function.53SIMULINK如何与CS-FUNCTION相互作用.54进程层面.54数据层面.56编写回调函数.59将LEVEL1CMEXS-FUNCTION转换到LEVEL2.60创建C+S-FUNCTION.63创建ADAS-FUNCTION.64创建FORTRANS-FUNCTION.65实现块特性.67对话框参数.68iii可调参数.68运行参数.70创建运行参数.70更新运行参数.71创建输入和输出端口.72创建输入端口.72创建输出端口.73输入的标量扩展.74掩码多端口S-Function.75自定义数据类型.76采样时间.77基于块的采样时间.77指定基于端口的采样时间.79基于块与基于端口的混合采样时间.81多速率S-Function块.82多速率S-Function块的同步.83工作向量.84工作向量与过零检测.85包括指针工作向量的范例.85内存分配.86FUNCTION-CALL子系统.87错误处理.89防超程代码.89SsSetErrorStatus的终止条件.90数组边界检查.90S-FUNCTION范例.91连续状态的S-Function范例.92离散状态的S-Function范例.93混合系统的S-Function范例.93变步长的S-Function范例.94过零检测的S-Function范例.94时变连续传递函数的S-Function范例.941第一章S-Function概述S-Function(系统函数)为扩展Simulink的性能提供了一个有力的工具。
以下下节阐述了什么是S-Function,为什么可以使用S-Function,以及怎样编写自己的S-Function。
SimulinkS-Function的编写2什么是S-FunctionS-Function可以使用MATLAB,C,C+,Ada,或Fortran语言来编写。
使用MEX实用工具,将C,C+,Ada,和Fortran语言的S-Function编译成MEX-文件,在需要的时候,它们可与其它的MEX-文件一起动态地连接到MATLAB中。
S-Function使用一种特殊的调用格式让你可以与Simulink方程求解器相互作用,这与发生在求解器和内置Simulink块之间的相互作用非常相似。
S-Function的形式是非常通用的,且适用于连续、离散和混合系统。
S-function为你提供了一种在Simulink模型中增加自制块的手段,你可以使用MATLAB,C,C+,Ada,或Fortran语言来创建自己的块。
按照下面一套简单的规则,你可以在S-function中实现自己的算法。
在你编写一个S-Functin函数,并将函数名放置在一个S-Functin块中(在用户定义的函数块库中有效)之后,通过使用masking定制用户界面。
你可以与Real-TimeWorkshop(RTW)一起使用S-function,也可通过编写目标语言编译器(TLC)文件来定制由RTW生成的代码。
参看第八章“对于Real-TimeWorkshop编写S-Function”和Real-TimeWorkshop文档资料以获取更多信息。
第一章S-Function概述3在模型中使用S-Function为了将一个S-function组合到一个Simulink模型中,首先从Simulink用户定义的函数块库中拖出一个S-Function块,然后在S-Function块对话框中的S-Functionname区域指定S-Function的名字。
如下图所示:
图1-1S-function块、对话框、及决定块功能的源文件之间的关系在本例中,模型包含了两个的S-function块,这两个块使用到同一个源文件(mysfun,可以是一个CMEX文件,或者是一个M文件)。
如果一个CMEX文件与一个M文件具有相同的名字,则CMEX文件被优先使用,即在S-function块中使用的是CMEX文件。
向S-Function传递参数在S-function块的S-functionparameters区域可以指定参数值,这些值将被传递到相应的S-function中。
要使用这个区域,必须了解S-function所需要的参数,及参数的顺序(如果不知道,应查询S-function的编制者、相关文件,或源代码)。
输入参数值时,参数之间应使用逗号分隔,并按照S-function要求的参数顺序进行输入。
参数值可以是常量、模型空做区间定义的变量名、或MATLAB表达式。
下面的图示使用S-functionparameters区域输入用户自定义参数的用法:
/*MYSFUN*/*Thefollo#defineS_FU.Functionsys%mysfunM-file%switch(flag).S-function源文件C-MEX文件M文件或SimulinkS-Function的编写4在本例中,模型使用的是由Simulink提供的S-function范例,limintm。
该S-function的源代码在目录toolbox/simulink/blocks下可以找到。
函数limintm接受了三个参数:
一个下边界,一个上边界,及一个初始条件。
该函数将输入信号对时间进行积分,如果积分值在上下边界之间则输出积分值;如果积分值小于下边界值,则输出先边界值;如果积分值大于上边界值,则输出上边界的值。
在本例的对话框中指定下边界值、上边界和初始条件分别为2,3,和2.5。
图中示波器显示的曲线是当输入振幅为1的正弦波时的输出结果。
你可以使用Simulink的masking工具来为自己的S-function块创建用户对话框和图标。
通过封装对话框可以使S-function附加参数的指定更清楚容易。
关于附加参数及封装,参考文档UsingSimulink。
何时使用S-FunctionS-function的应用在大多数情况下是创建自定义的Simulink块。
你可以使用S-function作为一些类型的应用,这些应用包括:
?
向Simulink增加一些新的通用块?
增加作为硬件设备驱动程序的块?
将已有的C代码组合到仿真中?
使用一组数学方程式来对系统进行描述?
使用可视化动作(参见倒立摆范例,penddemo)使用S-function的一个优点是你可以创建一个普通用途的块,在一个模型中多次使用,而且可单独改变模型中所使用的每个块的参数。
第一章S-Function概述5S-Function的工作原理要创建S-function,你必须了解S-function是如何工作的。
要了解S-function如何工作,则需要了解Simulink是如何进行模型仿真的,那么又需要了解块的数学公式。
因此,本节首先从一个块的输入、状态和输出之间的数学关系开始介绍。
Simulink块的数学关系Simulink块包含一组输入、一组状态和一组输出。
其中,输出是采样时间、输入和块状态的函数。
下面的方程式表述了输入、输出和状态之间的数学关系:
仿真过程Simulink模型的执行分几个阶段进行。
首先进行的是初始化阶段,在此阶段,Simulink将库块合并到模型中来,确定传送宽度、数据类型和采样时间,计算块参数,确定块的执行顺序,以及分配内存。
然后,Simulink进入到“仿真循环”,每次循环可认为是一个“仿真步”。
在每个仿真步期间,Simulink按照初始化阶段确定的块执行顺序依次执行模型中的每个块。
对于每个块而言,Simulink调用函数来计算块在当前采样时间下的状态,导数和输出。
如此反复,一直持续到仿真结束。
下图所示为一个仿真的步骤:
u(输入)x(状态)y(输出)y=f0(t,x,u)(输出)xc=fd(t,x,u)(求导)xdk+1=fu(t,x,u)(更新)其中,x=xc+xdSimulinkS-Function的编写6图1-2Simulink执行仿真的步骤S-Function回调程序一个S-function包含了一组S-function回调程序,用以执行在每个仿真阶段所必需的任务。
在模型仿真期间,Simulink对于模型中的每个S-function块调用适当的程序,通过S-function程序来执行的任务包括:
?
初始化在仿真循环之前,Simulink初始化S-function。
在该阶段期间,Simulink:
?
初始化SimStruct,这是一个仿真数据结构,包含了关于S-function的信息?
设置输入和输出端口的数量和宽度?
设置块的采样时间?
分配存贮区间和参数sizes的阵列?
计算下步采样点如果你创建了一个变步长块,那么在这里计算下一步的采样点,即计算下一个仿真步长。
?
计算主步长的输出在该调用完成后,所有块的输出端口对于当前仿真步长有效。
?
按主步长更新离散状态在这个调用中,所有的块应该执行“每步一次”的动作,如为下一个仿真循环更新离散状态,?
计算积分这适用于连续状态和/或非采样过零的状态。
如果S-function中具有连续状态,模型初始化计算下一步的采样步长(仅适用于变步长块)计算输出更新离散状态计算导数计算输出计算导数过零检测在最后一步时清除积分(积分微步)仿真循环第一章S-Function概述7Simulink在积分微步中调用S-function的输出和导数部分。
这是Simulink能够计算S-function状态的原因。
如果S-function(仅对于CMEX)具有非采样过零的状态,Simulink在积分微步中调用S-function的输出和过零部分,这样可以检测到过零点。
注意:
参考UsingSimulink文档的“Simulink如何工作”中关于主步长和微步的解释。
SimulinkS-Function的编写8S-Function的实现S-Function可以通过M-文件或者MEX文件来实现。
以下部分介绍了这些实现方法,并讨论各种实现方法各自的优缺点。
M-文件的S-Function一个M-文件的S-Function由以下形式的MATLAB函数构成:
sys,x0,str,ts=f(t,x,u,flag,p1,p2,.)其中,f是S-Function的函数名,t是当前时间,x是相应S-function块的状态向量,u是块的输入,flag指示了需被执行的任务,p1,p2,.是块参数。
在模型仿真过程中,Simulink反复调用f,对于特定的调用使用flag来指示需执行的任务。
S-function每次执行任务都返回一个结构,该结构的格式在语法范例中给出。
在目录matlabroot/toolbox/simulink/blocks中给出了M-文件S-function的模板,sfuntmpl.m。
该模板由一个主函数和一组骨架子函数组成,每个子函数对应于一个特定的flag值。
主函数通过flag的值分别调用不同的子函数。
在仿真期间,这些子函数被S-function以回调程序的方式调用,执行S-function所需的任务。
下表列出了按此标准格式编写的M-文件S-function的内容。
仿真阶段S-function程序flag初始化mdlInitializeSizesflag=0计算下一步的采样步长(仅用于变步长块)mdlGetTimeOfNextVarHitflag=4计算输出mdlOutputsflag=3更新离散状态mdlUpdateflag=2计算导数mdlDerivativesflag=1结束仿真时的任务mdlTerminateflag=9当创建M-文件的S-function时,推荐使用模板的结构和命名习惯。
这可方便其他人读懂和维护你所创建的M-文件的S-function。
MEX文件的S-function类似于M-文件的S-function,MEX文件的S-function也由一组回调程序组成,在仿真期间,Simulink调用这些回调程序来执行各种块相关任务。
然而,两者之间也存在很大的不同。
其一,MEX文件的S-function的实现使用了不同的编程语言:
C,C+,Ada,或Fortran;其二,Simulink直接调用MEX文件的S-function程序,而不象调用M-文件的S-function程序通过flag值来选择。
因为Simulink要直接调用这些函数,MEX文件的S-function函数必须按照Simulink指定的标准命名规定来定义函数名。
第一章S-Function概述9还存在着其它一些关键的不同点。
第一,MEX函数能实现的回调函数比M-文件能实现的回调函数要多得多;其次,MEX函数直接访问内部数据结构SimStruct,SimStruct是Simulink用来保存关于S-function信息的一个数据结构;另外,MEX函数也可使用MATLABMEX文件API直接来访问MATLAB的工作空间。
在目录matlabroot/simulink/src中有一个C语言的MEX文件S-function的模板,sfuntmpl_basic.c。
该模板包含了所有C语言的MEX文件S-function可执行的必需和可选的回调函数的基本结构。
该目录下的另一个模板程序sfuntmpl_doc.c具有更详细的注释。
MEX文件与M-文件的S-function比较MEX文件与M-文件的S-function都有各自的优点。
M-文件的S-function的优点是开发速度。
开发M-文件的S-function避免了开发编译语言的编译-连接-执行所需的时间开销。
M-文件的S-function还可以更容易地访问MATLAB和工具箱函数。
MEX文件的S-function的主要优点是多功能性。
更多数量的回调函数及对SimStruct的访问使MEX函数可实现M-文件的S-function所不能实现的许多功能。
这些功能包括,可处理除了double之外的数据类型、复数输入、矩阵输入等。
SimulinkS-Function的编写10S-Function的概念了解以下几个关键概念有助于正确编写S-function?
直接馈通?
动态宽度的输入?
设置采样时间和偏移量直接馈通直接馈通意味着输出(或者是对于变步长采样块的可变步长)直接受控于一个输入口的值。
有一条很好的经验方法来判断输入是否为直接馈通,如果:
?
输出函数(mdlOutputs或flag=3)是输入u的函数。
即,如果输入u在mdlOutputs中被访问,则存在直接馈通。
输出也可以包含图形输出,类似于一个XY绘图板。
?
对于一个变步长S-function的“下一步采样时间”函数(mdlGetTimeOfNextVarHit或flag=4)中可以访问输入u。
例如,一个需要其输入的系统(也就是具有直接馈通)是运算y=ku,其中,u是输入,k是增益,y是输出。
又如,一个不需要其输入的系统(也就是没有直接馈通)是一种简单的积分运算:
输出:
y=x导数:
x=u其中,x是状态,x是状态对时间的导数,u是输入,y是输出。
注意x是Simulink的积分变量。
正确设置直接馈通标志是十分重要的,因为它影响模型中块的执行顺序,并可用来检测代数环。
动态维矩阵S-function可编写成支持任意维的输入。
在这种情况下,当仿真开始时,根据驱动S-function的输入向量的维数动态确定实际输入的维数。
输入的维数也可用来确定连续状态的数量、离散状态的数量、以及输出的数量。
M-文件的S-function只可有一个输入端口,而且输入端口只能接受一维(向量)的信号输入。
但是,信号的宽度是可以变化的。
在一个M-文件的S-function内,如果要指示输入宽度是动态的,必须在数据结构sizes中相应的域值指定为-1,结构sizes是在调用mdlInitializeSizes时返回的一个结构。
当S-function通过使用length(u)来调用时,你可以确定实际输入的宽度。
如果指定为0宽度,那么S-function块中将不出现输入端口。
一个CS-function可以有多个I/O端口,而且每个端口可以具有不同的维数。
维数及每维的大小可以动态确定。
例如,下图所示为在一个模型中,将一个相同的S-function块进行了两次使用:
第一章S-Function概述11图中上面的S-function块由一个带三元素输出的块来作为输入;下面的S-function块由一个标量输出块来驱动。
通过指定该S-function块的输入端口具有动态宽度,那么同一个S-function可以适用于两种情况。
Simulink会自动地按照合适宽度的输入端口来调用该块。
同样地,如果块的其它特性,如输出数量、离散状态数量或连续状态数量,被指定为动态宽度,那么Simulink会将这些向量定义为与输入向量具有相同的长度。
CS-function在指定输入和输出宽度时提供了更多的灵活性。
具体介绍可参考第七章中的“创建输入和输出端口”一节的内容。
设置采样时间和偏移量M-文件与CMEX文件的S-function在指定S-function何时执行上都具有高度的灵活性。
Simulink对于采样时间提供了下列选项:
?
连续采样时间用于具有连续状态和/或非过零采样的S-function。
对于这种类型的S-function,其输出在每个微步上变化。
?
连续但微步长固定采样时间用于需要在每一个主仿真步上执行,但在微步长内值不发生变化的S-function。
?
离散采样时间如果S-function块的行为是离散时间间隔的函数,那么可以定义一个采样时间来控制Simulink何时调用该块。
你也可以定义一个偏移量来延迟每个采样时间点。
偏移量的值不可超过相应采样时间的值。
采样时间点发生的时间按照下面的公式来计算:
TimeHit=(n*period)+offset其中,n是整数,当前仿真步。
n的起始值总是为0。
如果定义了一个离散采样时间,Simulink在每个采样时间点时调用S-function的mdlOutput和mdlUpdate。
?
可变采样时间采样时间间隔变化的离散采样时间。
在每步仿真的开始,具有可变采样时间的S-function需要计算下一次采样点的时间。
?
继承采样时间有时,S-function块没有专门的采样时间特性(即,它既可以是连续的也可以是离散的,取决于系统中其它块的采样时间)。
你可以指定这种块的采样时间为inherited(继承)。
比如,一个增益块就是继承采样时间的例子,它从其输入块继承采样时间。
一个块可以从以下几种块中继承采样时间:
MuxsystemS-FunctionMuxsystemS-Function1ClockSimulinkS-Function的编写12?
输入块?
输出块?
系统中最快的采样时间要将一个块的采样时间设置为继承,那么在M-文件的S-function中使用-1作为采样时间,在CS-function中使用INHERITED_SAMPLE_TIME作为采样时间。
S-function可以是单速率的,也可以是多速率的,多速率系统有多个采样时间。
采样时间是按照固定格式成对指定的:
采样时间,偏移时间。
有效的采样时间对如下:
CONTINUOUS_SAMPLE_TIME,0.0CONTINUOUS_SAMPLE_TIME,FIXED_IN_MINOR_STEP_OFFSETdiscrete_sample_time_period,offsetVARIABLE_SAMPLE_TIME,0.0其中:
CONTINUOUS_SAMPLE_TIME=0.0FIXED_IN_MINOR_STEP_OFFSET=1.0VARIABLE_SAMPLE_TIME=-2.0斜体字是必须给定的实际值。
另外,还可指定采样时间为从驱动块继承而来。
在此情况下,S-function只能有一个采样时间对:
INHERITED_SAMPLE_TIME,0.0或者,INHERITED_SAMPLE_TIME,FIXED_IN_MINOR_ST