MATLAB第5章S函数

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

第5章S-函数•5.1S-函数概述•5.2S-函数的工作原理•5.3编写M文件S-函数5.1S-函数概述•5.1.1S-函数的基本概念•S-函数是系统函数(SystemFunction)的简称,是指采用非图形化的方式描述的一个功能块。用户可以采用MATLAB代码,C,C++等语言编写S-函数。S-函数由一种特定的语法构成,用来描述并实现连续系统、离散系统以及复合系统等动态系统。•简单来说,用户可以从如下的几个角度来理解S-函数:•(1)S-函数为Simulink的“系统”函数。•(2)能够响应Simulink求解器命令的函数。•(3)采用非图形化的方法实现一个动态系统。•(4)可以开发新的Simulink模块。•(5)可以与已有的代码相结合进行仿真。•(6)采用文本方式输入复杂的系统方程。•(7)扩展Simulink功能。M文件S-函数可以扩展图形能力,CMEXS-函数可以提供与操作系统的接口。•5.1.2如何使用S-函数•在动态系统设计、仿真与分析中,用户可以使用Functions&Tables模块库中的S-function模块来使用S-函数;S-function模块是一个单输入单输出的系统模块,如果有多个输入与多个输出信号,可以使用Mux模块与Demux模块对信号进行组合和分离操作。•一般而言,S-函数的使用步骤如下:•(1)创建S-函数源文件。创建S-函数源文件有多种方法,当然用户可以按照S-函数的语法格式自行书写每一行代码,但是这样做容易出错且麻烦。Simulink为我们提供了很多S-函数模板和例子,用户可以根据自己的需要修改相应的模板或例子即可。•(2)在动态系统的Simulink模型框图中添加S-function模块,并进行正确的设置。•(3)在Simulink模型框图中按照定义好的功能连接输入输出端口。/**my_sfunction**/#defineS_FUNCTION_NAMEmy_sfunction#defineS_FUNCTION_LEVEL2#includesimstruc.h/*====================**S-functionmethods**====================*//*Function:mdlInitializeSizes*/staticvoidmdlInitializeSizes(SimStruct*S){。。。S-函数对话框S-function块S-函数源文件图5.1S-函数块对话框图5.2一个用S-函数实现的简单系统•【例5.1】使用S-函数实现系统:y=2u。•解:(1)打开模板M文件S-函数模板文件sfuntmpl.m,在\MATLABroot\work目录下另存为doublesfunction.m。•(2)找到函数mdlInitializeSizes,修改以下代码:•sizes.NumOutputs=1;•sizes.NumInputs=1;•(3)找到函数mdlOutputs,加入以下代码:•sys=2*u;•(到现在为止我们的第一个S-函数写完了。下面演示一下它的作用。)•(4)在Simulink空白页中添加S-function块,打开S-function块对话框,参数S-functionname设置为doublesfunction。按照图5.2添加连接好其余的各个模块。•(5)开始仿真,在Scope中观察输出结果,可以看到输入正弦信号被放大为原来的2倍,如图5.2所示。5.2S-函数的工作原理•5.2.1状态方程•在对动态系统建模时,总是能够采用广义的状态空间形式对无论是线性系统还是非线性系统进行描述。这个描述包含以下两个方程:•状态方程:•输出方程:•其中A、B、C、D分别是状态矩阵、输入矩阵、输出矩阵、前馈矩阵。•Simulink框图的大部分模块都具有一个输入向量u、一个输出向量y和一个状态向量x,如图5.3所示。图5.3Simulink模块•S-函数同样是一个Simulink模块。它的以下几个例程函数清楚地体现了状态空间所描述的特性。•(1) S-函数中的连续状态方程描述。状态向量的一阶导数是状态x、输入u和时间t的函数。在S-函数中,状态的一阶导数是在mdlDerivatives例程中计算的,并将结果返回供求解器积分。•(2) S-函数中的离散状态方程描述。下一步状态的值依赖于当前的状态输入u和时间t。这是通过mdlUpdate例程完成的,并将结果返回供求解器在下一步时使用。•(3) S-函数中的输出方程描述。输出值是状态、输入和时间的函数。•5.2.2Simulink仿真的两个阶段•理解S-函数首先要很好地了解Simulink的仿真过程。仿真包含两个主要阶段,第一个阶段是初始化,这时块的所有参数都已确定下来。初始化阶段完成了以下工作:•(1)传递参数给MATLAB进行求值。•(2)得到的数值作为实际的参数使用。•(3)展开模型的层次,每个子系统被它们所包含的块替代。•(4)检查信号的宽度和连接。•(5)确定状态初值和采样时间。•仿真运行阶段的工作可以概括为:•(1)计算输出。•(2)更新离散状态。•(3)计算连续状态,连续状态的计算过程:•①每个块按照预先确定的顺序计算输出。•②每个块使用当前时间、块的输入和状态计算它的导数。•③导数返回给求解器,通过积分得到下一步状态的值。•(4)计算输出,过零可能被激活。•5.2.3S-函数仿真流程•S-函数是Simulink的重要组成部分,它的仿真过程包含在Simulink仿真过程之中,所以上一节所述同样适用于S-函数。S-函数的仿真流程也包括初始化阶段和运行阶段两个阶段。•(1)初始化:在仿真开始前,Simulink在这个阶段初始化S-函数。•①初始化结构体SimStruct,它包含了S-函数的所有信息。•②设置输入输出端口数。•③设置采样时间。•④分配存储空间。•(2)计算下一个采样时间点:只有在使用变步长求解器进行仿真时,才需要计算下一个采样时间点,即计算下一步的仿真步长。•(3)计算输出:计算所有输出端口的输出值。•(4)更新状态:此例程在每个步长处都要执行一次,可以在这个例程中添加每一个仿真步都需要更新的内容,例如离散状态的更新。•(5)数值积分:用于连续状态的求解和非采样过零点。如果S-函数存在连续状态,Simulink就在minorsteptime内调用mdlDdrivatives和mdlOutput两个S-函数例程。5.3编写M文件S-函数•5.3.1M文件S-函数的工作流程•M文件S-函数和上节所介绍的S-函数仿真流程是一致的。它调用例程函数的顺序是通过标志Flag来控制的。图5.6给出了各仿真阶段的标志值、变量值及其对应仿真例程。图5.6M文件S-函数流程设置初始条件计算下一个采样时间(仅适用于变采样时间)计算输出更新离散状态计算输出计算导数结束仿真时需要进行的工作Flag=0mdlInitializeConditionsmdlInitializeSizesmdlInitializeSampleTimesFlag=4mdlGetTimeNextVarHitFlag=3mdlOutputsFlag=2mdlUpdateFlag=3mdlOutputsFlag=1mdlDerivativesFlag=9mdlTerminate•5.3.2M文件S-函数模板•Simulink为我们编写S-函数提供了各种模板文件,其中定义了S-函数完整的框架结构,用户可以根据自己的需要加以剪裁。编写M文件S-函数时,推荐使用S-函数模板文件sfuntmpl.m。这个文件包含了一个完整的M文件S-函数,它包含1个主函数和6个子函数。在主函数内程序根据标志变量Flag,由一个开关转移结构(Switch-Case)根据标志将执行流程转移到相应的子函数,即例程函数。Flag标志量作为主函数的参数由系统(Simulink引擎)调用时给出。了解这个模板文件的最好方式莫过于直接打开看看其代码。•要打开模板文件,可在MATLAB命令行下输入:•editsfuntmpl•或者双击\S-functiondemos\M-fileS-functions\M-filetemplate块。•下面是删除了其原有注释的代码,结构反而更为清晰紧凑。•function[sys,x0,str,ts]=sfuntmpl(t,x,u,flag)%主函数•%主函数包含四个输出:sys数组包含某个子函数返回的值,它的含义随着调用子函数的不同而不同;x0为所有状态的初始化向量;str是保留参数,总是一个空矩阵;Ts返回系统采样时间。•%仿真流程位置如图5.6所示;此外输入参数后面还可以接续一系列的附带参数。另外别忘了编写自己的S-函数时,应该把函数名sfuntmpl改为S-function块中对应的函数名•function[sys,x0,str,ts]=sfuntmpl(t,x,u,flag)•switchflag•case0•[sys,x0,str,ts]=mdlInitializeSizes;•case1•sys=mdlDerivatives(t,x,u);•case2•sys=mdlUpdate(t,x,u);•case3•sys=mdlOutputs(t,x,u);•case4•sys=mdlGetTimeOfNextVarHit(t,x,u);•case5•sys=mdlTerminate(t,x,u);•otherwise•error(['Unhandledflag=',num2str(flag)]);•end•%主函数结束•%下面是各个子函数,即各个仿真例程•%1.初始化例程子函数:提供状态、输入、输出、采样时间数目和初始状态的值。必须有该子函数。•%初始化阶段,标志变量首先被置为0,S-函数被第一次调用时,mdlInitializeSizes子函数首先被调用。这个子函数应当为系统提供S-function块的下列信息:•sizes.NumContStates=0;%连续状态的个数•sizes.NumDiscStates=0;%离散状态的个数•sizes.NumOutputs=0;%输出的个数•sizes.NumInputs=0;%输入的个数•sizes.DirFeedthrough=1;%是否直接馈通:这是一个布尔量,当输出值直接依赖于同一时刻的输入值时为1;否则为0•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•sizes.NumInputs=0;%输入量个数,缺省为0•sizes.DirFeedthrough=1;%是否存在直接馈通。1:存在;0:不存在,缺省为1•sizes.NumSampleTimes=1;%采样时间个数,至少是一个•sys=simsizes(sizes);%返回sizes数据结构所包含的信息••x0=[ ];%设置初始状态•str=[ ];%保留变量置空•ts=[00];%采样时间:[采样周期偏移量],采样周期为0表示是连续系统•%2.计算导数例程子函数:给定t,x,u,计算连续状态的导数,用户应该在此给出系统的连续状态方程。该子函数可以不存在•functionsys=mdlDerivatives(t,x,u)•sys=[ ];%sys表

1 / 30
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功