Simulink中的自定义模块_第1页
Simulink中的自定义模块_第2页
Simulink中的自定义模块_第3页
Simulink中的自定义模块_第4页
Simulink中的自定义模块_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

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

文档简介

1、目录Fcn 模块MATLAB Fcn 模块S Function (System Function)1. 函数的函数头 2. 函数分析3.带参数的S函数 4.S函数格式及说明11simulink 中子模块的封装Fcn 模块Fen模块对它的输入进行指定的表达式运算。使用的表达式可由下面的一个或多个部分组成。u -模块的输入。 如果u是一个向量,u(i)表示此向量的第i个元素;u(1) 或者 u 表示第一个元素数值常数 (例如表达式 5.2*u)算术运算符(+ - * / A例如表达式 "2+5.2)关系运算符(= != > < >= <=)-表达式返回 1,如果关

2、系为真; 否则返回 0逻辑运算符(&&| !) 表达式返回 1,如果关系为真; 否则返回 0括号数学函数 (abs, acos, asin, atan, atan2, ceil, cos, cosh, exp, fabs, floor, hypot, ln, log, log10, pow, power, rem, sgn, sin, sinh, sqrt, tan, tanh.)Works pace中定义的变量-如果变量名字不是 Matlab保留字符(比如 sin),变量名字会被传递给 Matab,从而在 Maltab Works pace中获取相应给定的 值。矩阵或者向量必

3、须具体到其对应的元素。 (比如 A(1,1)注意:Fen模块中使用的表达式不支持矩阵运算,同样不支持(:)符。模块输入可以是标量或者向量,但输出总是标量数值。MATLAB Fcn 模块MATLAB Fen模块对它的输入进行指定的 Matlab函数或者表达式运算。输 出尺寸必须和模块中定义的尺寸相符,否则报错。下面是 MATLAB Fen 模块中可以使用的有效表达式u(1)Au(2)atan2(u(1),u(2)sin注意:同 Fcn 模块相比,在仿真中 MATLAB Fcn 模块速度要慢,因为它需要在每 个积分步骤中调用 Maltab 编译器。因此建议使用 Fcn 模块或者 Math Func

4、tion 模块代替 MATLAB Fcn 模块,或者编写 M 文件或者 MEX 文件 S 函数代替它。S Function (System Function)S函数,即系统函数,用来扩展Simulink模块库。一个S函数,相当于一个 Simulink 模块,只不过这个模块不是在 Simulink Library 中已经存在的,用户需 要根据自己对 Simulink 的功能需求,使用指定的编程语言来定制自己的 Simulink 模块。S函数 支持Matlab, C, C+, Ada, or Fortran等语言,编写S函数需要按照一 定的格式,具体如何编写S函数,参考Matlab自带文档。如果能

5、用现有的Simulink模块库中的模块满足需求,不建议使用S函数编写。所谓s函数是system Function的简称,用它来写自己的simulink模块.s函数 可以用 matlab、C、C+、Fortran、Ada 等语言来写, 这儿只介绍怎样用 matlab 语言来写吧(主要是它比较简单)先讲讲为什么要用s函数,我觉得用s函数可以利用matlab的丰富资源,而 不仅仅局限于simulink提供的模块,而用c或C+等语言写的s函数还可以实现 对硬件端口的操作, 还可以操作 windows API 等先介绍一下simulink的仿真过程(以便理解s函数),simulink的仿真有两 个阶段:

6、 一个为初始化,这个阶段主要是设置一些参数,像系统的输入输出个 数、状态初值、 采样时间等;第二个阶段就是运行阶段,这个阶段里要进行计 算输出、更新离散状态、 计算连续状态等等,这个阶段需要反复运行,直至结 束.在matlab的works pace里输入edit sfuntmpi(这是matlab自己提供的s函数模 板),我们看它来具体分析 s 函数的结构 .1. 函数的函数头函数的第一行: function sys,x0,str,ts=sfuntmpl(t,x,u,flag) , 先讲输入与输出 变量的含义:t 是采样时间 ;x 是状态变量 ;u 是输入 (是做成 simulink 模块的输

7、入 );flag 是仿真过程中的状态标志 (以它来判断当前是初始化还是运行等 ) sys输出根据flag的不同而不同(下面将结合flag来讲sys的含义);x0 是状态变量的初始值 ;str 是保留参数 (mathworks 公司还没想好该怎么用它 , 一般在初始化中将它 置空就可以了 , str=);ts是一个1 X 2的向量,ts(1)是采样周期,ts(2)是偏移量2. 函数分析下面结合 sfuntmpl.m 中的代码来讲具体的结构:switch flag, %判断flag,看当前处于哪个状态 case 0,sys,x0,str,ts=mdlInitializeSizes;/ 解释说明fl

8、ag=0 表示当前处于初始化状态,此时调用函数 mdlInitializeSizes 进行 初始化,此函数在该文件的第149行定义.其中的参数sys是一个结构体,它用 来设置模块的一些参数,各个参数详细说明如下size = simsizes;%用于设置模块参数的结构体用 simsizes来生成sizes.NumContStates = 0; %模块连续状 态变量的个数 sizes.NumDiscStates = 0; %模块离散状态变量的个数 sizes.NumOutputs = 0;%模块输出变量的个数sizes.NumInputs = 0;%模块输入变量的个数sizes.DirFeedth

9、rough = 1; %模块是否存在直接贯通sizes.NumSampleTimes = 1; %模块的采样时间个数 , 至少是一个 sys = simsizes(sizes);%设置完后赋给举个例子,考虑如下模型 :dx/dt=fc(t,x,u) 也可以用连续状态方程描述: x(k+1)=fd(t,x,u) 也可以用离散状态方程描述:sys 输出dx/dt=A*x+B*ux(k+1)=H*x(k)+G*u(k)y=fo(t,x,u) 也可以用输出状态方程描述: y=C*x+D*u 设上述模型连续状态变量、离散状态变量、输入变量、输出变量均为 1 个, 我们就只需改上面那一段代码为(一般连续状

10、态与离散状态不会一块用, 我这儿是为了方便说明 ):sizes.NumContStates=1;sizes.NumDiscStates=1;sizes.NumOutputs=1;sizes.NumInputs=1;其他的可以不变 , 继续在 mdlInitializeSizes 函数中往下看:x0 = ;%状态变量设置为空,表示没有状态变量,以我们上面的假设,可改为xO=O,O(离散和连续的状态变量我们都设它初值为0)str = ;%保留参数, 置就可以了 , 没什么用ts = O O; %采样周期设为 O 表示是连续系统 , 如果是离散系统在下面的 mdlGetTimeOfNextVarHi

11、t 函数中具体介绍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 表示此时要

12、计算下一个离散状态 , 即上面提到的 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=mdlGetTimeOfNex

13、tVarHit(t,x,u);/flag=4 表示此时要计算下一次采样的时间 , 只在离散采样系统中有用 (即上 文的mdllnitializeSizes中提到的ts设置ts(1)不为0),连续系统中只需在 mdlGetTimeOfNextVarHit 函数中写上 sys=. 这个函数主要用于变步长的设置 , 具体实现大家可以用 edit vsfunc 看 vsfunc.m 这个例子case 9, sys=mdlTerminate(t,x,u);/flag=9表示此时系统要结束,一般来说写上在mdITerminate函数中写上sys= 就可, 如果你在结束时还要设置什么,就在此函数中写完了 .

14、3.带参数的 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(s

15、izes);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函数的程序4.S函数格式及说明function sys,x

16、0,str,ts = sfuntmpl(t,x,u,flag)% SFUNTMPL是M-文件S函数模板 通过剪裁,用户可以生成自己的 S 函数,不过一定要重新命名 利用 S 函数可以生成连续、离散混合系统等,实现任何模块的功能M-文件S函数的语法为:SYS,X0,STR,TS = SFUNC(T,X,U,FLAG ,P1,.,Pn)参数含义:t 是当前时间x 是 S 函数相应的状态向量u 是模块的输入 flag 是所要执行的任务功能FLAG 结果SIZES,X0,STR,TS 模块初始化DXDSTNEXT计算模块导数更新模块离散状态 计算模块输出计算下一个采样时间点结束仿真用户切勿改动输出参数

17、的顺序、名称和数目输入参数的数目不能小于 1,这四个参数的名称和排列顺序不能改动%9 等。%用户可以根据自己的要求添加额外的参数,位置依次为第5,6,7,8,S 函数的 flag 参数是一个标记变量,具有 6 个不同值,分别为 0,1 , 2 , 3,4,9% flag 的 6 个值分别指向 6 个不同的子函数% flag 所指向的子函数也成为回调方法 (Callback Methods) switch flag,%初始化,调用“模块初始化”子程序 %case 0,sys,x0,str,ts=mdlInitializeSizes;%连续状态变量计算,调用“计算模块导数”子函数 % case 1

18、,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);%其他的 flag%otherwiseDAStudio.error('Simulink:bloc

19、ks:unhandledFlag', num2str(flag); end% end sfuntmpl% “模块初始化”子函数% 返回大小、初始条件和样本function sys,x0,str,ts=mdlInitializeSizes% 调用 simsizes 函数,返回规范格式的 sizes 构架% 这条指令不要修改sizes = simsizes;% 模块的连续状态个数, 0 是默认值% 用户可以根据自己的要求进行修改sizes.NumContStates = 0;% 模块的离散状态个数, 0 是默认值 % 用户可以根据自己的要求进行修改sizes.NumDiscStates =

20、 0;% 模块的输出个数, 0 是默认值% 用户可以根据自己的要求进行修改sizes.NumOutputs = 0;% 模块的输入个数, 0 是默认值% 用户可以根据自己的要求进行修改sizes.NumInputs= 0;% 模块中包含的直通前向馈路个数, 1 是默认值 % 用户可以根据自己的要求进行修改sizes.DirFeedthrough = 1;% 模块中采样时间的个数, 1 是默认值,至少需要一个样本时间% 用户可以根据自己的要求进行修改sizes.NumSampleTimes = 1;% 初始化后的构架sizes经simsizes函数处理后向sys赋值sys = simsizes(

21、sizes); % 这条指令不要修改给模块初始值变量赋值, 是默认值 用户可以根据自己的要求进行修改= ;系统保留变量 切勿改动,保持为空 str = ;%x0ts“二元对”描述采样时间及偏移量。 0 0是默认值0 0适用于连续系统-1 0则表示该模块采样时间继承其前的模块采样时间设置 = 0 0;% end mdlInitializeSizesfunction sys=mdlDerivatives(t,x,u)% 计算导数向量此处填写计算导数向量的指令 是模块的默认值用户必须把算得的离散状态的导数向量赋给 sys sys = ;% end mdlDerivatives% 计算离散状态向量fu

22、nction sys=mdlUpdate(t,x,u)% 此处填写计算离散状态向量的指令% 是模块的默认值% 用户必须把算得的离散状态向量赋给 sys sys = ;% end mdlUpdatefunction sys=mdlOutputs(t,x,u)% 计算模块输出向量 此处填写计算模块输出向量的指令 是模块的默认值用户必须把算得的模块输出向量赋给 sys sys = ;% end mdlOutputsfunction sys=mdlGetTimeOfNextVarHit(t,x,u) % 计算下一采样时刻该子函数仅在“采样时间”情况下使用sampleTime = 1 是模块默认设置,

23、表示在当前时间 1 秒后再调用本模块 用户可以根据自己的要求修改sampleTime = 1;% 将计算得到的下一采样时刻赋给 sys% 切勿改动sys = t + sampleTime;% end mdlGetTimeOfNextVarHit function sys=mdlTerminate(t,x,u)% 模板默认设置,一般情况不要改动 sys = ;% end mdlTerminatesimulink中子模块的封装对于比较复杂的系统, 模块化思想是很有必要的, 使得思路较为清晰、 错误 容易排查。 对复杂的系统进行仿真, 如果将其中独立的功能进行封装, 会显得特 别清爽。这学期做了电机仿真和伺服系统仿真, 特别感觉到子模块封装的必要性, 有效的提高了系统的可读和可维护性。在 simulink 中建立子模块的步骤如下:1、 建立系统框图。这步需要确定输入输出的个数,输入端为sources 中的in,输出端为sinks中的out。将Simulink库下的Ports&Subsystems中的 Subsystem拉至 simulink 框图中。2、功能的搭建。点击建好的子模块,在其中进行功能模块的搭建。3、子模块的封装。所谓封装(masking),即将其对应的子系统内部结 构隐含以来, 访问该模块的时

温馨提示

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

评论

0/150

提交评论