第2章MATLAB仿真

上传人:cl****1 文档编号:569914454 上传时间:2024-07-31 格式:PPT 页数:207 大小:7.01MB
返回 下载 相关 举报
第2章MATLAB仿真_第1页
第1页 / 共207页
第2章MATLAB仿真_第2页
第2页 / 共207页
第2章MATLAB仿真_第3页
第3页 / 共207页
第2章MATLAB仿真_第4页
第4页 / 共207页
第2章MATLAB仿真_第5页
第5页 / 共207页
点击查看更多>>
资源描述

《第2章MATLAB仿真》由会员分享,可在线阅读,更多相关《第2章MATLAB仿真(207页珍藏版)》请在金锄头文库上搜索。

1、第第2章章 MATLAB仿真仿真 第第2章章 MATLAB仿真仿真 2.1 MATLAB介绍介绍2.2 MATLAB编程仿真编程仿真2.3 Simulink仿真仿真 第第2章章 MATLAB仿真仿真 2.1 MATLAB介绍介绍2.1.1MATLAB的特点MATLAB是MathWorks公司开发的一种跨平台的,用于矩阵数值计算的简单高效的数学语言,与其它计算机高级语言如C,C+,Fortran,Basic,Pascal等相比,MATLAB语言编程要简洁得多,编程语句更加接近数学描述,可读性好,其强大的图形功能和可视化数据处理能力也是其它高级语言望尘莫及的。对于具有任何一门高级语言基础的读者来说

2、,学习MATLAB十分容易。第第2章章 MATLAB仿真仿真 但是,要用好MATLAB却不是在短时间就可以达到的。这并不是因为MATLAB语言复杂难懂,而是实际问题的求解往往更多的是需要使用者具备数学知识和专业知识。MATLAB使得人们摆脱了常规计算机编程的繁琐,让人们能够将大部分精力投入到研究问题的数学建模上。可以说,应用MATLAB这一数学计算和系统仿真的强大工具,可以使科学研究的效率得以成百倍的提高。目前,MATLAB已经广泛用于理工科大学从高等数学到几乎各门专业课程之中,成为这些课程进行虚拟实验的有效工具。在科研部门,MATLAB更是极为广泛地得到应用,成为全球科学家和工程师进行学术交

3、流首选的共同语言。在国内外许多著名学术期刊上登载的论文,大部分的数值结果和图形都是借助MATLAB来完成的。第第2章章 MATLAB仿真仿真 与其它高级语言相比较,MATLAB具有独特的优势:(1)MATLAB是一种跨平台的数学语言。采用MATLAB编写的程序可以在目前所有的操作系统上运行(只要这些系统上安装了MATLAB平台)。MATLAB程序不依赖于计算机类型和操作系统类型。(2)MATLAB是一种超高级语言。MATLAB平台本身是用C语言写成的,其中汇集了当前最新的数学算法库,是许多 专 业 数 学 家 和 工 程 学 者 多 年 的 劳 动 结 晶 。 使 用MATLAB意味着站在巨人

4、的肩膀上观察和处理问题,所以在编程效率,程序的可读性、可靠性和可移植性上远远超过了常规的高级语言。这使得MATLAB成为了进行科学研究和数值计算的首选语言。第第2章章 MATLAB仿真仿真 (3)MATLAB语法简单,编程风格接近数学语言描述,是数学算法开发和验证的最佳工具。MATLAB以复数矩阵运算为基础,其基本编程单位是矩阵,使得编程简单,而功能极为强大。对于常规语言中必须使用许多语句才能实现的功能,如矩阵分解、矩阵求逆、积分、快速傅立叶变换,甚至串口操作、声音的输入输出等,在MATLAB中均用一两句指令即可实现。而且,MATLAB中的数值算法是经过千锤百炼的,比用户自己编程实现的算法的可

5、信度和可靠性都大为提高。(4)MATLAB计算精度很高。MATLAB中数据是以双精度存储的,一个实数采用8字节存储,而一个复数则采用16字节存储。通常矩阵运算精度高达1015以上,完全能够满足一般工程和科学计算的需要。与其它语言相比,MATLAB对计算机内存、硬盘空间的要求也是比较高的。第第2章章 MATLAB仿真仿真 (5)MATLAB具有强大的绘图功能。利用MATLAB的绘图功能,可以轻易地获得高质量的(印刷级)曲线图。具有多种形式来表达二维、三维图形,并具有强大的动画功能,可以非常直观地表现抽象的数值结果。这也是MATLAB广为流行的重要原因之一。(6)MATLAB具有串口操作、声音输入

6、输出等硬件操控能力。随着版本的提高,这种能力还会不断加强,使得人们利用计算机和实际硬件相连接的半实物仿真的梦想得以轻易实现。(7)MATLAB程序可以直接映射为DSP芯片可接受的代码,大大提高了现代电子通信设备的研发效率。第第2章章 MATLAB仿真仿真 (8)MATLAB的 程 序 执 行 效 率 比 其 它 语 言 低 。MATLAB程序通常是解释执行的,在执行效率和速度上低于其它高级语言,当然如果对执行效率有特别要求,可以采用C语言编制算法,然后通过MATLAB接口在MATLAB中执行。事实上,MATLAB自带的许多内部 函 数 均 是 用 C语 言 编 写 并 编 译 的 , 因 此

7、利 用MATLAB内部函数的程序部分运行速度并不比其它语言中相应函数低。本 书 给 出 的 程 序 和 例 子 均 在MATLABReleaseR13(6.5.1)(完全安装)版本下验证通过。第第2章章 MATLAB仿真仿真 2.1.2MATLAB快速入门1.MATLAB的启动和退出本书以Windows2000下的MATLAB6.5.1为例,在其它Windows版 本 下 操 作 是 类 似 的 。 假 定 已 经 正 确 安 装 了MATLAB的Windows版本,从Windows的“开始|程序”菜单中找到MATLAB图标,单击该图标即可进入MATLAB环境。进入MATLAB后操作环境通常显

8、示的是MATLAB的命令窗口,在该窗口中可以输入各种MATLAB命令和语句,通过命令方式与MATLAB进行交互。虽然MATLAB也像通常的Windows程序一样提供了菜单和快捷工具栏,通过它们可以很方便地对MATLAB进行操作,但是建议读者尽可能使用命令方式去操作MATLAB,虽然刚开始可能觉得不太方便,但是与菜单和快捷工具方式相比,命令方式的功能最为强大,也最能体现MATLAB的精髓,而且命令方式本身也是跨平台的。第第2章章 MATLAB仿真仿真 MATLAB命令窗口中,输入命令的提示符为“”。在MATLAB命令窗口中,键入命令“quit”或“exit”并按回车键(回车),即可退出MATLA

9、B环境。2.在MATLAB中如何获取帮助MATLAB几乎涉及了所有工程领域的数学问题,没有一本书能够完全覆盖读者所需要解决的问题。因为MATLAB帮助文档是惟一完全覆盖MATLAB功能函数的权威技术文件,所以,善于利用MATLAB的帮助文档将是非常重要的。第第2章章 MATLAB仿真仿真 在MATLAB命令窗口中,使用命令“intro”可以进入MATLAB简介演示。而使用命令“demo”可以打开MATLAB的演示窗口,其中包含了大量MATLAB程序的演示实例,对于初学者具有很高的参考价值。如果读者需要打开MATLAB的帮助文档,使用命令“helpwin”即可。如果要用浏览器打开html形式的帮

10、助文档,可使用命令“doc”。若需要打开MATLAB某条命令或函数用法的html帮助文档,则只需输入命令doc命令或函数名回车即可。第第2章章 MATLAB仿真仿真 如果要在命令窗口中显示帮助信息,则只需输入命令“help”即可。若需要了解MATLAB某条命令或函数的用法,使用命令help命令或函数名回车即可。例如,要查询自然对数函数命令“log”的用法,应使用命令helplog回车另外,MATLAB帮助文档还以PDF电子文件格式提供,存放在MATLAB的安装目录中,读者可以用AcrobatReader等 软 件 阅 读 。 读 者 也 可 以 通 过 介 绍MATLAB的若干网站获取和交流应

11、用MATLAB的心得体会。第第2章章 MATLAB仿真仿真 3.在MATLAB命令窗口中计算数学表达式MATLAB语言是一种解释性语言,它提供了方便的演算纸式的数学计算方式。在MATLAB命令窗口中输入数学表达式,然后回车即可得出计算结果。MATLAB的数学表达式与数学公式表达极为相似,也非常类似于C语言的表达。例如,计算表达式2sin(0.3)/(1+KF(5KF)的值,在MATLAB命令窗口中输入以下语句并回车就能得到结果。2*sin(0.3*pi)/(1+sqrt(5)回车ans=0.5000第第2章章 MATLAB仿真仿真 以上语句中,“pi”是MATLAB已定义的常数,即圆周率;“a

12、ns”是表达式计算结果的默认存储变量。MATLAB定义的常数中,常用的有以下一些:ans最新表达式计算结果的默认存储变量inf表示正无穷大+NaN非数,例如0/0将得到非数i或j虚数单位,即eps从1.0到下一个最大浮点数的距离,常用来作为浮点计算相对误差使用第第2章章 MATLAB仿真仿真 pi圆周率realminMATLAB所能表示的最小正实数realmaxMATLAB所能表示的最大正实数MATLAB中常用的算术运算符有+、-、*、/、等,含义如下:+数量加法,矩阵加法-数量减法,矩阵减法*数量乘法,矩阵乘法.*数组乘法/数量除法,矩阵右除第第2章章 MATLAB仿真仿真 数量除法(左除)

13、,矩阵左除./数组除法矩阵乘方.数组乘方矩阵的共轭转置,对于一个复数而言将得到其共轭复数.矩阵转置(不共轭)关于这些算术运算符的详细用法以及示例,可以用docarithmeticoperators回车打开html格式的帮助文档查看。第第2章章 MATLAB仿真仿真 4.在MATLAB命令窗口中输入简单矩阵例如,输入矩阵时可以采用下面的方法:A=1,2,3;4,5,6;7,8,9回车A=123456789(2-1)第第2章章 MATLAB仿真仿真 MATLAB中可以采用逗号或空格来分隔矩阵中的列元素,而采用分号或回车符来分隔矩阵的行,整个矩阵包含在方括号“”内。采用命令“whos”可以查看用户在

14、MATLAB工作空间(内存)中所存储的变量情况。使用命令“workspace”就可以打开工作空间浏览器窗口,双击其中的变量可以对其值进行修改。命令“clear变量名”可以清除相应的变量,而命令“clear”则清除所有用户自定义的变量。系统的默认变量是不会被“clear”清除的。为了避免前面的程序对后续程序的影响,通常在程序的开始使用“clear”语句来复位MATLAB的内存空间。使用命令“clc”可以清除命令窗口中的显示字符。使用命令“home”可以使得命令窗口中提示符光标回到窗口的左上角。这两个命令仅仅影响屏幕的显示,不会清除内存中的变量。第第2章章 MATLAB仿真仿真 5.MATLAB的

15、语句和变量MATLAB语句可以有两种形式:(1)表达式;(2)变量名表达式。在第一种形式中,表达式计算的值将存放于默认变量“ans”中;而在第二种形式中,表达式的值将存放于变量名所指定的变量中。MATLAB中多条语句可以在一行内书写,以逗号“,”或分号“;”相互隔开。如果是以分号隔开的,则计算结果不显示在屏幕上,否 则 回 车 后 将 显 示 计 算 结 果 。 例 如 , 计 算1+2+3+100的值以及100的阶乘100!。第第2章章 MATLAB仿真仿真 s=1:100;sum(s),p=prod(s)回车ans=5050p=9.3326e+157MATLAB中的变量是区分大小写的,变量

16、、函数名必须以字母开头,其后最多可接19个字母、数字或下划线。例如:a和A是不同的变量,p121-6,yinyue3是合法的变量名,而3sd则是非法的变量。在变量或函数的命名时,应该养成良好的命名习惯,命名不要和MATLAB中的系统函数或变量相同。特别地,如果计算中存在复数运算,那么就应该避免采用“i”和“j”作为循环变量。第第2章章 MATLAB仿真仿真 MATLAB中可以方便地进行复数运算,例如计算,其中,a=15+j3,b=5ej2。可在命令窗口中输入:a=15+j*3,b=5*exp(j*2),(a.2+b).(1/5)回车6.绘制简单的函数曲线MATLAB提供了极为便利的数据可视化手

17、段,可以作出任意函数的图像。作为快速入门,在此以一个二维作图为例,作出函数y=e-x/10sinx在x-1,10范围的图像。第第2章章 MATLAB仿真仿真 x=-1:0.1:20;%定义x的范围和步进回车y=exp(-x./10).*sin(x);%计算函数值回车plot(x,y);grid;%作出函数图像,并在坐标上画出网格回车结果如图2-1所示。注意,在程序语句中,以百分号“%”开始的是注释部分。关于“plot”的详细用法和例子可以用“docplot”命令查看帮助文档。第第2章章 MATLAB仿真仿真 图2-1函数y=e-x/10sinx在x-1,10范围的图像第第2章章 MATLAB仿

18、真仿真 7.编写简单的MATLAB程序MATLAB是解释性语言,输入一行语句后回车,就会立即执行得出结果。如果要实现比较复杂的功能,单靠一条一条地在命令窗口中输入指令执行,效率是很低的。如何解决这个问题呢?为此MATLAB提供了扩展名为“.m”的文本文件,在文件中事先写入一行行的MATLAB命令,存盘后从MATLAB的命令窗口调入执行(类似于DOS下的批处理),这种文件称为底稿文件或MATLAB脚本文件。第第2章章 MATLAB仿真仿真 用前面作图的三条语句为例,在文本编辑器中输入这些语句,然后将文件存盘,例如命名文件名为“my1stprg.m”,保存于MATLAB的默认工作路径中。然后回到M

19、ATLAB命令窗口,在提示符“”下键入文件名(可以省略扩展名)后回车,即可运行程序得到结果,即my1stprg回车在任何一种纯文本编辑器中均可以书写MATLAB程序,只要以“.m”为扩展名保存,即可在MATLAB中调用运行。MATLAB命令窗口中,在提示符“”后输入的命令语句要回车才能执行,本书以后的例子中,将省略回车字样,在此提醒读者注意。第第2章章 MATLAB仿真仿真 2.1.3MATLAB程序设计1.M文件简介MATLAB除了如前所述的在命令窗口进行的直接交互的指令操作方式外,另外一种更为重要的工作方式就是M文件的编程工作方式。M文件有两种形式,一种是脚本文件,另一种是函数文件。M文件

20、的扩展名为“.m”。M文件可以通过任何纯文本编辑器进行编辑 , MATLAB中 也 有 自 带 的 文 本 编 辑 器 , 使 用“edit”命令即可开启。第第2章章 MATLAB仿真仿真 2.程序控制流语句任何计算机语言,只要利用顺序结构、循环结构以及分支结构,就可以完成任何程序功能。在MATLAB中也有这三种基本的程序结构。但值得注意的是,由于MATLAB语言矩阵计算功能十分强大,常常仅使用顺序结构借以矩阵的逻辑运算就可以完成计算任务。由于循环结构和分支结构在MATLAB语言中的运行速度相对较慢,因此在算法优化的编程中应当尽可能避免使用,而代之以矩阵运算,从而提高程序运行速度,简化程序代码

21、,并使得程序代码更加接近于数学表达。当然,采用矩阵编程的编程方法需要读者具有更多的关于线性代数和矩阵数学的知识和思维方式。第第2章章 MATLAB仿真仿真 顺序结构是MATLAB中最常用的程序结构,也是执行效率最高的程序结构。顺序结构的语句是按照书写的前后顺序来执行的。MATLAB用于循环结构的语句有两种:“forend”循环和“whileend”循环。1)forend语句利用“helpfor”或“docfor”可以获得关于该语句的使用手册。“forend”语句适用于循环次数确定的情况,将 循 环 变 量 的 初 值 、 判 别 和 变 化 放 在 循 环 开 头 。“forend”语句的调用

22、形式是:第第2章章 MATLAB仿真仿真 forv=表达式语句1;语句n;end例如,最简单的forend循环:fork=1:10x(k)=k.2;end第第2章章 MATLAB仿真仿真 事实上,采用矩阵思想也可以获得相同的结果,但编程更加简单明了:k=1:10;x=k.2x=149162536496481100绝大部分循环都可以遵从这样的方法变成向量化(矩阵化)的算法,避免采用循环语句,从而大大提高程序的执行效率。第第2章章 MATLAB仿真仿真 2)whileend语句对于循环次数不能预先确定,而是由某个逻辑条件 来 控 制 循 环 次 数 的 情 况 , MATLAB提 供 了“whil

23、eend”来实现。和“forend”语句类似,“whileend”语句也允许嵌套。“whileend”语句的一般形式是:whilev=表达式语句1;语句n;end第第2章章 MATLAB仿真仿真 例如,求当整数n的阶乘值是一个50位数的第一个数时,n为多少?(程序jiechen50.m)n=1;%n的初值whileprod(1:n)1e50,break;end%满足条件,则跳出循环endn%显示结果n=42第第2章章 MATLAB仿真仿真 “switch”语句来实现多重分支结构。其用法是:switch开关表达式case表达式1语句,语句case表达式1,表达式2,表达式3,语句,语句other

24、wise语句,语句end第第2章章 MATLAB仿真仿真 3.数据和文件的输入输出1)“input”指令“input”指令提示用户从键盘输入数据、字符串或表达式,并接受该输入。“input”指令的调用格式有两种:user-entry=input(prompt)%输入数据或表达式user-entry=input(prompt,s)%输入字符串例如:a=input(请输入矩阵或表达式,赋值到a:)DW%输入数据的例子请输入矩阵或表达式,赋值到a:12;34a=1234第第2章章 MATLAB仿真仿真 a=input(请输入矩阵或表达式,赋值到a:)DW%输入表达式的例子请输入矩阵或表达式,赋值到a

25、:sin(1)+8a=8.8415s=input(请输入一个字符串:,s)DW%输入字符串的例子请输入一个字符串:thisisastrings=thisisastring2)“pause”指令“pause”指令可以使程序暂停运行,等待用户按任意键继续。“pause”指令主要用于程序调试或显示中间结果。“pause(n)”指令使得程序暂停执行n秒。第第2章章 MATLAB仿真仿真 3)利用文件输入输出数据指令“save”和“load”用于MATLAB与磁盘的数据交换。“save”指令将MATLAB工作空间的数据存入磁盘;“load”指令则将数据从磁盘送入到MATLAB工作空间。举例说明如下:cl

26、ear;A=1,2;3,4;b=81;save(c:mymatlabdat.mat,A,b);%将变量A和b保存在文件C:mymatlabdat.m第第2章章 MATLAB仿真仿真 at中clear%清除内存变量whos%查看,应该无变量显示load(c:mymatlabdat.mat);%调入数据文件c:mymatlabdat.matwhos%显示调入的变量NameSizeBytesClassA2x232doublearrayb1x18doublearrayGrandtotalis5elementsusing40bytes第第2章章 MATLAB仿真仿真 4.MATLAB编程特点MATLAB

27、有两种工作方式:一种是在命令窗口进行的指令操作方式,前面我们所使用的大部分就是这种方式;另外一种是M文件编程方式,这种方式特别适合于复杂问题的求解,是MATLAB高级应用的一种常用方式。MATLAB编程中,要特别注意程序的书写风格,一个好的程序,必须思路清晰,注释详细,而且是运行速度较快的。M文件编程中开头的注释行将作为该程序的帮助信息,可以在命令窗口中用“help”命令显示出来。例如,编程计算函数f(x)=x3+x+lnxsinx+当x=1,3,5时的值。第第2章章 MATLAB仿真仿真 编写脚本文件calcfx.m如下:程序2-1%这是开头的注释行,可以用help命令显示%程序calcfx

28、.m的功能是计算表达式clear;%清除MATLAB内存空间,这一命令常用于脚本文件的首句%以避免前面命令在内存空间形成的变量的意外影响k=1;%数组下标变量,在MATLAB编程中,注释要尽可能详尽!Int-F=inline(t,t);%用inline函数建立积分的被积函数forx=1,3,5第第2章章 MATLAB仿真仿真 f-x(k)=x3+x+log(x)*sin(x)+quad8(Int-F,0,x);%计算表达式值k=k+1;%数组下标加1endf-x%显示计算结果文件编辑存盘后,在MATLAB命令窗口执行:helpcalcfx这是开头的注释行,可以用help命令显示程序calcfx

29、.m的功能是计算表达式calcfxf-x=2.500034.6550140.9567第第2章章 MATLAB仿真仿真 5.MATLAB函数编程如果M文件的第一行是以关键字“function”开头的,则就是函数文件。函数文件是MATLAB程序设计的主流,MATLAB自身所带的许多函数(指令)都是由相应的函数文件来定义的。函数文件好像一个黑箱,将数据送进去,经过函数处理,然后将结果数据输出。函数文件和脚本文件在内存使用上存在重要的区别,函数文件内部所定义的变量仅仅在该函数文件内部有效,函数返回后这些内部变量将自动被清除,也就是说,函数内部所定义的变量仅在函数内部起作用,是局部变量。第第2章章 MA

30、TLAB仿真仿真 而脚本文件中所定义的变量,在使用“clear”命令清除之前,始终存在于工作空间当中,是全局变量。另外,函数文件的文件名必须和函数名相同,而且注意切记不要和MATLAB已经定义的系统函数和其它自定义的函数同名。下面是函数编程的例子,函数的文件名与函数名相同,为stat.m。程序2-2functionmean,stdev=stat(x)n=length(x);%求输入向量x的长度mean=sum(x)/n;%求平均值stdev=sqrt(sum(x-mean).2/n);%求均方根值第第2章章 MATLAB仿真仿真 6.测定程序执行时间和时间分配利用“tic”和“toc”指令可以

31、对程序段的执行时间进行测定,从而估计出程序执行效率,并找出改进程序、提高效率的方法。“tic”用于计时开始,而“toc”用于计时结束并显示计时结果。MATLAB还提供了对程序执行的耗时剖析功能“profile”指令。用户通过调用该功能函数,可以轻松地观察程序中各条语句的执行耗时情况,从而为提高程序运行效率的改进思路提供参考依据。(详细情况请参见在线帮助。)第第2章章 MATLAB仿真仿真 7.提高程序执行速度的原则MATLAB是一种解释性语言,它与C语言等编译性语言有着相当大的区别,如果按照C语言的思路去编写MATLAB程序,那么执行效率肯定不是很理想。要提高编程的执行效率,则一定要根据MAT

32、LAB的特点来编写程序,具体有以下原则:首先,在编程中要尽量避免采用循环语句。利用向量化语句来代替循环语句可以大大提高程序运行速度。如果不得不采用多重循环,那么内循环的次数应该尽可能多于外循环的次数。其次,在使用大型数组或矩阵之前对其进行初始化,即采用指令“zeros”或 “ones”对 矩 阵 定 维 , 这 样 可 以 减 少MATLAB在内存分配过程中的耗时,大大提高速度。第第2章章 MATLAB仿真仿真 第三,应该优先考虑使用MATLAB的内在函数。MATLAB的内在函数是采用C语言优化构造的,并固化在MATLAB的内核中,其运行速度可以和C语言的速度等价,而用户自行编制的M文件则是在

33、MATLAB中解释执行的。另外,采用更先进更有效的算法也可以提供计算效率。快速傅立叶变换就是一个典型的例子。第第2章章 MATLAB仿真仿真 2.2 MATLAB编程仿真编程仿真 2.2.1时间连续信号与系统的计算机仿真问题时间连续的确定信号在物理上是一个随时间变化的(电压或电流)波形,在数学上表示为一个时间连续的函数f(t)。时间连续信号也称为模拟信号。而时间离散的确定信号在数学上可以表示为一个确定的序列fn。如果以满足取样定理的取样速率对时间连续函数f(t)进行取样,就可以得到对应的时间离散序列fn,而将时间离散序列fn通过取样定理所规定的理想低通滤波器后,就能够恢复连续信号f(t)。第第

34、2章章 MATLAB仿真仿真 换句话说,在满足取样定理的前提下,f(t)与fn是一一对应的关系。对时间离散序列fn进行幅度值上的离散化(这个过程称为量化)就得到了数字信号。数字信号通常以二进制编码的形式存储在计算机中。因此,利用计算机所表达的时间连续信号f(t)实质上是其所对应的数字信号。本质上,计算机不能直接处理模拟信号,计算机中的信号处理均是对数字信号的处理。而由取样定理保证了它与模拟信号处理之间的一一对应关系。第第2章章 MATLAB仿真仿真 连续系统可以用微分方程来描述,离散系统可以用差分方程来描述。当系统为无记忆系统时,微分方程或差分方程退化为代数方程。因此,对系统进行仿真的过程就数

35、学意义而言,就是求解这些微分方程、差分方程或代数方程的过程。为了对连续系统进行仿真,首先需要建立其数学模型,然后利用计算机求解这些数学模型,从而得出数学模型的数值解。计算机对数学模型的求解过程就是对系统的仿真过程。由于连续系统是通过微分方程来建模的,因此对此的计算机仿真本质上就是微分方程的数值求解问题。通常,对连续系统进行计算机仿真的过程是:第第2章章 MATLAB仿真仿真 (1)建立数学模型:就是将物理模型转换为数学模型的过程。对于电子电路而言,就是利用电路的拓扑、元件的属性,列出网孔方程或节点方程,并简化为标准形式的计算机可求解的一阶微分方程组(即状态方程)的过程。对于线性时不变系统来说,

36、就是建立其传递函数模型,并简化为计算机易于求解的线性一阶微分方程组(即状态方程)的过程。而对于一般的系统,通常可建模为一组非线性的微分方程组。(2)选择适合的计算机求解方法求解仿真模型。不同的微分方程求解算法的精度和适用范围均有所不同。(3)编写MATLAB仿真程序或建立Simulink模块方框图,调试并运行程序。(4)得出数值解,即仿真结果,对仿真结果进行分析,以确定结果的可靠性和有效性。第第2章章 MATLAB仿真仿真 图2-2一个二阶电路系统第第2章章 MATLAB仿真仿真 下面我们举例说明。对于一个二阶系统,电路如图2-2所示,试利用MATLAB编程仿真求解:(1)零状态响应:系统在t

37、=-1秒时刻的初状态为零,输入信号为阶跃信号f(t)=u(t),输出为电容电压,试对时间t=-1,10秒的输出信号波形进行仿真求解。(2)零输入响应:系统在t=-1秒时刻电容电压为uC=1V,当t=-1秒时刻信号输入二端闭合,试对时间t=-1,10秒的输出信号波形进行仿真求解。(3)全响应:系统在t=-1秒时刻电容电压为uC=1V,输入信号为阶跃信号f(t)=u(t),试对时间t=-1,10秒的输出信号波形进行仿真求解。第第2章章 MATLAB仿真仿真 解(1)设电感电流为iL(t),电容电压为uC(t),根据电路,列出KVL方程:(2-2)改写为标准形式:第第2章章 MATLAB仿真仿真 令

38、电路的状态变量iL(t)=x1(t),uC(t)=x2(t),输入信号为f(t),则微分方程简写为写出该微分方程的MATLAB函数。注意,这一组微分方程组就是该二阶电路的状态方程,对于同一个物理系统,如果选取的状态变量不同,所得到的状态方程也就不同,但都表达了该物理系统的状态信息。(2-3)第第2章章 MATLAB仿真仿真 按照MATLAB的固定写法,编写出该微分方程组的MATLAB函数(函数文件名为funcforex123.m)如下:程序2-3functionxdot=funcforex123(t,x,flag,R,L,C)xdot=zeros(2,1);%矩阵初始化xdot(1)=-R/L

39、*x(1)-1/L*x(2)+1/L*f(t);%方程1xdot(2)=1/C*x(1);%方程2functionin=f(t)%输入信号in=(t0)*1;%阶跃信号第第2章章 MATLAB仿真仿真 然后,利用MATLAB提供的求解微分方程的指令对该微分方程组求解。MATLAB提供的求解微分方程的算法有多个,如“ode45”、“ode23”、“ode15s”等,不同的算法适用的场合稍有不同。例如,通过“ode45”函数求解,MATLAB程序(程序名为ex123.m)如下:程序2-4%filenameex123.mL=1;%电感值C=0.1;%电容值forR=1.535%仿真电阻值分别为1.5

40、,3,5欧姆的情况t,x=ode45(funcforex123,-1,10,0;0,R,L,C);第第2章章 MATLAB仿真仿真 %也可采用ode23,ode15s等求解figure(1);plot(t,x(:,1);holdon;xlabel(timesec);text(0.9,0.17,leftarrowi-L(t);grid;figure(2);plot(t,x(:,2);holdon;xlabel(timesec);text(0.5,0.3,leftarrowu-C(t);grid;end运行程序后,得到的电感电流、电容电压波形仿真结果如图2-3(a)、(b)所示。第第2章章 MAT

41、LAB仿真仿真 图2-3电感电流、电容电压零状态响应波形仿真结果(a)电感电流单位阶跃响应(零状态响应)波形仿真结果;(b)电容电压单位阶跃响应(零状态响应)波形仿真结果第第2章章 MATLAB仿真仿真 (2)当t=-1秒时刻信号输入二端闭合,相当于输入信号为零,因此修改MATLAB函数funcforex123.m如下:程序2-5functionxdot=funcforex123(t,x,flag,R,L,C)xdot=zeros(2,1);%矩阵初始化xdot(1)=-R/L*x(1)-1/L*x(2)+1/L*f(t);%方程1xdot(2)=1/C*x(1);%方程2functionin

42、=f(t)%输入信号in=0;%信号始终为零第第2章章 MATLAB仿真仿真 并修改ex123.m的“ode45”语句,将系统状态改为0,1,程序如下:程序2-6%filenameex123.mL=1;%电感值C=0.1;%电容值forR=1.535%仿真电阻值分别为1.5,3,5欧姆的情况t,x=ode45(funcforex123,-1,10,0;1,R,L,C);%也可采用ode23,ode15s等求解figure(1);plot(t,x(:,1);holdon;xlabel(timesec);第第2章章 MATLAB仿真仿真 text(0.9,0.07,leftarrowi-L(t);

43、grid;figure(2);plot(t,x(:,2);holdon;xlabel(timesec);text(0.5,0.3,leftarrowu-C(t);grid;end然后运行,得到的波形仿真结果如图2-4所示。第第2章章 MATLAB仿真仿真 图2-4电感电流、电容电压零输入响应波形仿真结果(a)电感电流零输入响应波形仿真结果;(b)电容电压零输入响应波形仿真结果第第2章章 MATLAB仿真仿真 ( 3)对 于 全 响 应 情 况 , 可 相 应 修 改 MATLAB函 数funcforex123.m如下:程序2-7functionxdot=funcforex123(t,x,fla

44、g,R,L,C)xdot=zeros(2,1);%矩阵初始化xdot(1)=-R/L*x(1)-1/L*x(2)+1/L*f(t);%方程1xdot(2)=1/C*x(1);%方程2functionin=f(t)%输入信号in=(t0)*1;%信号阶跃而ex123.m的“ode45”语句中仍然将系统状态改为0,1。运行后得到的波形仿真结果如图2-5所示。第第2章章 MATLAB仿真仿真 图2-5电感电流、电容电压全响应波形仿真结果(a)电感电流全响应波形仿真结果;(b)电容电压全响应波形仿真结果第第2章章 MATLAB仿真仿真 由此可见,一旦从物理系统中建立了其数学模型,也即得出系统的微分方程

45、描述之后,给定其边界条件,就可得出其数值解,求解的过程就是仿真的过程。在MATLAB中,我们可以方便地修改微分方程函数以及求解指令的参数,从而得出系统的零输入响应、零状态响应以及全响应等各种状态下的输出信号。读者可以将这个例子中的输入信号修改为一个宽度为0.3s的矩形脉冲,然后观察其响应波形。(提示:只需修改funcforex123.m中语句“in=(t0)*1;”为“in=(t0)*1-(t0.3)*1;”即可。)本例演示了对于一个动态电路瞬态响应的仿真过程。仿真的关键在于建立正确的数学模型。第第2章章 MATLAB仿真仿真 对于任何电子电路,都可以根据电路理论的知识得出其数学模型,即一阶微

46、分方程组,也称为状态方程。接下来以MATLAB所规定的格式编写状态方程的描述函数,然后选择合适的求解方式求解,也就完成了对电路的仿真。最后,对所得出的仿真波形进行分析。需要强调的是,微分方程的MATLAB函数格式是固定的,必须按MATLAB所规定的格式来编写。本例中,需要将方程参数“R;L;C”传入。传入参数前的标志变量“flag”是必需的,以符合求解函数“ode45”的要求。微分方程的MATLAB函数引导语句的格式为functionxdot=方程函数名(t,x,flag,附加参数)第第2章章 MATLAB仿真仿真 其中,“t”为时间变量矩阵,“x”为方程的状态变量矩阵,“xdot”为状态变量

47、对时间的一阶导数矩阵。在MATLAB中,对微分方程的求解有多种算法可供利用。通常有“ode23”、“ode45”以及“ode15s”等等,这些函数的调用方式完全相同,但针对的方程类型有所不同。其中,“ode23”和“ode45”分别采用二阶三级RKF算法和四阶五级RKF算法,适用于一般微分方程的求解;“ode15s”则适用于刚性微分方程的求解。所谓刚性方程,指的是方程的某些解(这些解是时间“t”的函数)变化缓慢,而另外一些解变化快速,两者形成明显对比的这样一类方程。“ode15s”同时也适合于一般微分方程的求解。关于其它解法和使用方法详见MTALAB的在线手册。第第2章章 MATLAB仿真仿真

48、 以“ode45”为例,其用法是:t,x=ode45(方程函数名,仿真时间范围,状态变量初始值,算法选项,附加参数)例 如 , 以 默 认 算 法 选 项 计 算 微 分 方 程 组funcforex123.m,仿真时间从-1s到10s,状态变量初始值为:电感电流x1(0)=0A,电容电压x2(0)=1V,附加参数为R=1.5,L=1H,C=0.1F,则解法写为t,x=ode45(funcforex123,-1,10,0;1,1.5,1,0.1);第第2章章 MATLAB仿真仿真 另外需要注意的是,为了达到算法快速有效,MATLAB中的状态方程的求解函数是自适应步长的,即其数值结果中时间自变量

49、t的离散取值是非均匀的,在解变化剧烈的地方取值点密,而在解变化缓慢的曲线段相对取值会稀疏一些。在信号处理中,进一步对求解信号进行分析时,往往又需要在时间上均匀取样间隔点上的波形函数值。我们可以采用一维插值的办法来解决。读者可以阅读插值命令“interp1”的在线帮助进一步了解这方面的信息。下面介绍求解系统的冲激响应的方法。由于输入冲激信号是超越函数,不适于作数值计算,因此首先求系统的阶跃响应,然后对其进行微分得到冲激响应。为了应用差分函数“diff”进行近似微分,首先需要通过插值将被微分的数据在时间上均匀化,然后再利用差分函数“diff”进行近似微分,从而得出系统的冲激响应波形。第第2章章 M

50、ATLAB仿真仿真 例如,对于电路如图2-2所示的一个二阶系统,输出信号从电容电压取出。现在通过仿真计算求系统的冲激响应,并与理论值相对比,分析仿真结果的正确性和仿真精度。为了分析仿真结果的正确性和仿真精度,我们首先计算电路中电容电压的冲激响应的解析值。将状态方程写为二阶微分方程形式,有(2-4)第第2章章 MATLAB仿真仿真 进行拉氏变换,得出传递函数为将R=3,L=1H,C=0.1F代入,并将H(s)化简为利用拉氏变换对(2-5)(2-6)(2-7)第第2章章 MATLAB仿真仿真 得出冲激响应为(2-8)利用下面的程序求出上例电路中电容电压的均匀取样点的输出波形值(阶跃响应),然后对该

51、波形进行微分得出冲激响应,并与理论值进行比较。程序运行结果如图2-6所示。第第2章章 MATLAB仿真仿真 图2-6冲激响应的仿真结果与理论结果的比较第第2章章 MATLAB仿真仿真 (1)状态方程函数程序funcforex123.m如下:程序2-8functionxdot=funcforex123(t,x,flag,R,L,C)xdot=zeros(2,1);%矩阵初始化xdot(1)=-R/L*x(1)-1/L*x(2)+1/L*f(t);%方程1xdot(2)=1/C*x(1);%方程2functionin=f(t)%输入信号是in=(t0)*1;%阶跃信号第第2章章 MATLAB仿真仿

52、真 (2)主程序ex123b.m如下:程序2-9%filenameex123b.m t,x =ode45(funcforex123, -1,10,0;0,3,1,0.1);%求解上例电路的阶跃响应ts=0.001;t1=-1:ts:10;%均匀取样点间隔0.001sx1=interp1(t,x(:,2),t1,spline);%插值得出均匀时间样点的电容电压波形值;第第2章章 MATLAB仿真仿真 plot(t1,x1,k-.);%阶跃响应波形绘制holdon;x1dot=diff(x1)/ts,0;%近似微分得出冲激响应波形plot(t1,diff(x1)/ts,0,k);xlabel(ti

53、mesec);%冲激响应波形绘制ht=10/sqrt(7.75).*exp(-1.5*t1).*sin(sqrt(7.75)*t1).*(t10);%冲激响应的理论值plot(t1(1:50:length(t1),ht(1:50:length(t1),ko);legend(Stepresponse,Impluseresponse,Theoreticimpluseresponse);第第2章章 MATLAB仿真仿真 从图2-6中可以得出,在插值精度达到足够高的条件下,采用仿真数值计算方法所得出的系统冲激响应与采用理论解析公式计算的曲线是吻合的,这也从一个侧面说明了仿真数值计算的正确性。通过以上仿

54、真的实例,我们可总结出连续系统建模的一般规律。一般地,设线性时不变系统中有n个独立的储能元件(电容或电感),则系统中存在n个独立的状态,记为x1(t),x2(t),xn(t)(2-9)第第2章章 MATLAB仿真仿真 又设该系统有m个输入信号,记为f1(t),f2(t),fm(t)(2-10)系统有r个输出,记为y1(t),y2(t),yr(t)(2-11)由于所有输入输出信号、系统状态都是时间t的函数,简写时可以省略(t),于是状态方程和输出方程可表示为矩阵形式:(2-12)第第2章章 MATLAB仿真仿真 对于更一般的(非线性)时不变系统,状态方程和输出方程可表示为一般函数式:对于线性时不

55、变系统,状态方程为n元一阶线性微分方程组,输出方程是r元线性方程组,其中(2-13)(2-14)第第2章章 MATLAB仿真仿真 (2-15)(2-16)第第2章章 MATLAB仿真仿真 (2-17)(2-18)(2-19)第第2章章 MATLAB仿真仿真 对连续系统的计算机仿真,实质上就是利用求解常微分方程的数值算法求解的过程。那么,计算机是如何求解这样一个一阶常微分方程组的呢?不失一般性,设常微分方程组用矩阵形式表示为式中(2-20)(2-21)(2-22)(2-23)第第2章章 MATLAB仿真仿真 式,atb的解x是时间t的连续函数,数值解法就是求解x在若干离散时间点a=t0t10)*

56、1;%阶跃信号第第2章章 MATLAB仿真仿真 作为对比,调用“ode45”进行求解的状态方程的MATLAB函数mystateEQforODE45.m如下:(注意,仅在函数变量中加上了“flag”以适应“ode45”的调用规程序2-12functionxdot=mystateEQforODE45(t,x,flag,P)xdot=zeros(2,1);R=P(1);L=P(2);C=P(3);%RLC参数从P矩阵中读入xdot(1)=-R/L*x(1)-1/L*x(2)+1/L*f(t);xdot(2)=1/C*x(1);functionin=f(t)%输入信号是in=(t0)*1;%阶跃信号第

57、第2章章 MATLAB仿真仿真 对欧拉算法与“ode45”算法精度进行比较的主程序如下:(其中,欧拉算法采用步长分别为0.01,0.1,0.2。“ode45”算法以默认参数进行)程序2-13%filenamesybeulerTEST.mtic;%记时开始t,x=ode45(mystateEQforODE45,0,10,0;0,310.1);toc%记时结束,测定ode45计算耗时plot(t,x,k.);holdon;forh=0.2,0.1,0.01第第2章章 MATLAB仿真仿真 tic;t,x=sybeuler(mystateEQ,0,h,10,0;0,310.1);toc%记时结束,测

58、定sybeuler计算耗时plot(t,x,k);endlegend(u-C(t)ode45,i-L(t)ode45,sybeuler);程序运行结果如图2-7所示。第第2章章 MATLAB仿真仿真 图2-7欧拉算法与“ode45”算法的比较(欧拉算法精度随着计算步长减小而提高)第第2章章 MATLAB仿真仿真 计算耗时:“ode45”算法自适应步长0.1s欧拉算法步长0.2DW0.02s欧拉算法步长0.1DW0.04s欧拉算法步长0.01DW0.32s可见,欧拉算法的计算精度是比较低的,当欧拉算法步长达到0.01时,其计算曲线才基本与“ode45”算法的曲线吻合。同时我们也看到,数值求解算法

59、以及算法参数的选择在系统仿真中对仿真结果的影响是相当大的。第第2章章 MATLAB仿真仿真 MATLAB中的“ode45”算法是四阶龙格-库塔算法的改进算法,称为四阶五级的龙格-库塔算法。与传统的四阶龙格-库塔算法相比较,它具有更高的计算精度和稳定性。对于线性时不变连续时间系统,其数学模型为线性微分方程组(也即状态方程),这种方程组在数学上已经有了解析算法,可以得出解析解。然而,对于一般的连续时间信号与系统,其数学模型为一般微分方程组,通常可能是非线性的,对于非线性微分方程组的解析求解,目前数学上并无统一的方法,这时大量的要求求解非线性微分方程组的工程问题最为方便的办法就是数值求解了。可以说,

60、MATLAB仿真和数值计算扩展了传统线性系统的研究范围,为非线性系统的数值研究提供了一条捷径。第第2章章 MATLAB仿真仿真 总之,对连续时间信号与系统的计算机仿真问题就是建立连续系统的数学模型状态方程,然后利用适当的数值分析和求解算法计算其数值解的过程。类似地,对离散时间信号与系统的计算机仿真问题就是建立该离散时间系统的差分方程组(离散状态方程)并递推求解的过程。而对于混合系统的计算机仿真问题就成为了混合系统所对应的微分方程和差分方程联合方程组的求解问题。对于无记忆系统,以上系统的建模方程组退化为代数方程组,仿真的问题也就相应简化为对这些代数方程的数值计算问题。第第2章章 MATLAB仿真

61、仿真 2.2.2基于数据流的仿真方法MATLAB编程对数学方程的数值计算一般是基于数据流的,这称为基于数据流的仿真方法。所谓基于数据流的仿真,就是指在数值计算的一个阶段完成之后,所得出的数据才进入下一个阶段的数值计算中。例如,如果对由两个传递函数H1(s)和H2(s)级联的系统进行MATLAB编程仿真,第一步是求解在输入信号激励下H1(s)的输出波形数据,第二步,再利用这些得出的波形数据作为系统H2(s)的激励信号,去求解系统H2(s)的输出波形数据。可见,在求解的时间段上,我们无法“实时”地观察到系统各个输出点上的信号,只有当系统各个阶段均已经计算完毕之后,才能够观察到计算时间段上系统的状态

62、和各个输出点的变化情况。第第2章章 MATLAB仿真仿真 2.3 Simulink仿真仿真 2.3.1Simulink仿真入门1.Simulink的特点Simulink是MATLAB中的一个建立系统方框图和基于方框图级的系统仿真环境,是一个对动态系统进行建模、仿真并对仿真结果进行分析的软件包。使用Simulink可以更加方便地对系统进行可视化建模,并进行基于时间流的系统级仿真,使得仿真系统建模与工程中的方框图统一起来。并且仿真结果可以近乎“实时”地通过可视化模块,如示波器模块、频谱仪模块以及数据输入输出模块等显示出来,使得系统仿真工作大为方便。第第2章章 MATLAB仿真仿真 Simulink

63、使得用户可以用鼠标操作将一系列可视化模块连接起来,从而建立直观的功能上更为复杂的系统模型,避免了编写MATLAB仿真程序,简化了仿真建模过程,更加适用于大型系统的建模和仿真,如对IS-95CDMA通信系统全系统的建模仿真工作。通过上节的讨论我们知道,由于MATLAB具有微分方程的求解算法,利用MATLAB编程可以对微分方程进行求解,从而得到系统的仿真结果。然而,对于更为复杂的大系统,往往是一种连续、离散系统的混合,要通过编程语句的方式来建立整个系统的状态方程模型将是一件不容易的事情,况且这样的手工编程,直观性不好,对于复杂系统的建模编程来说往往错误难以避免,因此仿真结果的可信度也就成了问题,而

64、且手工编程的效率低下,出错(往往是算法上的错误)检查困难,编程程序的可重复利用程度不高。第第2章章 MATLAB仿真仿真 这些原因使得MATLAB向易用性和可视化方向努力,Simulink就是这种努力的结果。1990年,Simulink首次作为MATLAB的软件工具包出现,彻底改变了系统仿真界的软件工具和建模模式,很快成为了系统建模和仿真的主流软件工具,甚至将成为通用系统仿真的基准测试平台。Simulink仿真环境附带了许多专业仿真模块库,利用这些模块库可以快速建立该专业领域的系统模型并进行仿真,而不需要用户详细了解各个模块内部的实现细节,大大方便了复杂的大系统的建模,而且,由于Simulin

65、k提供的这些专业模块库均通过各专业权威专家的评测,可信度和稳定性都大为提高,从而也保证了系统建模整体的质量和仿真精度。在通信工程和电子工程领域,Simulink提供的常用专业模块库有:CDMA参考模块库、通信系统模块库、DSP(数字信号处理器)模块库等等。随着MATLAB版本升级,还将添加更多的专业模块库。第第2章章 MATLAB仿真仿真 Simulink全方位地支持动态系统的建模仿真,它支持连续系统、离散系统、连续离散混合系统、线性系统、非线性系统、时不变系统、时变系统的建模仿真,也支持具有多采样速率的多速率系统。可以说,在通用系统仿真领域,Simulink是无所不包的。结合MATLAB编程

66、和Simulink可视化建模仿真各自的特点,可以构建更为复杂的系统模型,并进行自动化程度更高的仿真和仿真结果的数据分析,这是MATLAB的高级应用方面。本书后面章节中的许多例子就是基于MATLAB编程和Simulink建模相融合的方式来构建的。第第2章章 MATLAB仿真仿真 2.使用Simulink建模和仿真的过程我们首先通过实例来简单介绍Simulink建模和仿真的全过程。启动MATLAB之后,在命令窗口中输入命令“simulink”或单击MATLAB工具栏上的Simulink图标,打开Simulink模块库窗口(使用命令“simulink3”可以打开老版本的Simulink模块库界面)。

67、在 Simulink模 块 库 窗 口 中 单 击 菜 单 项“File|New|Model”,就可以新建一个Simulink模型文件,如图2-8所示。第第2章章 MATLAB仿真仿真 图2-8Simulink模块库界面和新建模型文件窗口第第2章章 MATLAB仿真仿真 为了与MATLAB编程仿真进行对比,我们仍然以2.3.1小节描述的二阶系统为例。其输入输出的传递函数为(2-28)其中,R=3,L=1H,C=0.1F。H(s)简化为利用鼠标单击Simulink基础库中的Continuous子库,选取传递函数模块,将它拖动到新建模型窗口中的适当位置,如图2-9所示。(2-29)第第2章章 MA

68、TLAB仿真仿真 图图2-9 利用模块库建立仿真模型利用模块库建立仿真模型第第2章章 MATLAB仿真仿真 如果需要对模型模块进行参数设置和修改,只需选中模型文件中的相应模块,单击鼠标右键,弹出快捷菜单,从中选取相应参数进行修改,如图2-10所示。还可以在选中模块之后通过鼠标拖动修改模块的位置、大小和形状。单击模块下方的“TransferFun”可以对其进行编辑,例如修改为“传递函数”字样。从快捷菜单中选取“TransferFunparameters.”项修改传递函数参数,在弹出的对话框中的传递函数分子系数“Numerator:”栏填入10;在传递函数分母系数“Denominator”栏填入1

69、,3,10,其余参数使用默认值。如果需要进了解该模块的参数设置说明,可以单击该对话框下方的“Help”按钮,然后确认,就得到了所要进行仿真的传递函数。第第2章章 MATLAB仿真仿真 图2-10修改仿真模型的参数第第2章章 MATLAB仿真仿真 通过快捷菜单的其它选项还可以修改模型的颜色、旋转、字体、阴影等属性,也可对模型进行剪切、拷贝或删除。采用同样的方法,在Simulink基础库中的Sources子库中选取激励信号源,例如我们选取阶跃信号源,将之拖入建模窗口中。在Sinks子库中选取示波器作为系统输出波形显示。接下来利用鼠标将这三个模块连接起来。模块外部的大于符号“”分别表示信号的输入输出

70、节点,为了连接两个模块的输入输出,可以将鼠标置于节点处,这时鼠标显示为“十”字形状,拖动鼠标到另一个模块的端口,然后释放鼠标按钮,则形成了带箭头的连线,箭头方向表示信号的流向。完成后的建模系统可以通过“File”菜单存盘为模型文件,扩展名为“mdl”,如“lizi1.mdl”,如图2-11所示。第第2章章 MATLAB仿真仿真 图2-11完成的建模方框图第第2章章 MATLAB仿真仿真 接下来,需要对输入信号源(阶跃)的参数进行设置。将鼠标指向阶跃信号模块双击或通过快捷菜单打开属性设置对话框,设置阶跃信号的参数,如图2-12所示。图中右边的帮助窗口是通过单击参数设置对话框下方的“Help”按钮

71、显示的。通过阅读帮助文档可以了解参数的含义和设置情况。对于阶跃信号源来说,其参数含义、默认值以及我们根据仿真需要修改后的参数值如表2-1所示。第第2章章 MATLAB仿真仿真 表2-1阶跃信号源的参数含义、默认值及修改后的参数值第第2章章 MATLAB仿真仿真 图2-12阶跃信号源模块的参数设置对话框及其帮助文档第第2章章 MATLAB仿真仿真 根据仿真要求,我们将仿真-210s时间区间内的系统阶跃响应的输出波形,在时间为0s时的跃变。然后设置仿真参数,主要是仿真求解器的选择和仿真步长等参数的选取。通过前面的分析可知,动态系统仿真的本质就是求解其状态方程,而对状态方程的数值求解算法有多种,求解

72、算法的步长也可以不同。不同的算法适用的范围有所不同,而算法的步长也直接影响求解的精度。因此,对求解器的选择以及其仿真步长等参数的设定对系统仿真来说就成为相当重要的事情。从系统建模窗口的状态栏可以看到当前 使 用 的 求 解 器 , 如 图 2-11中 显 示 的 仿 真 求 解 器 是“ode45”算法。从建模窗口菜单项“Simulation|SimulationParameters.”打开仿真参数设置对话框(快捷键为Ctrl+E),我们现在设置求解器标签下的参数部分,如图2-13所示。第第2章章 MATLAB仿真仿真 设置仿真起始时间为-2秒,仿真结束时间为10秒,其余参数为默认值:求解器采

73、用“ode45”算法,步长设定为自适应变步长的,最大步长、最小步长以及初始步长均设为自动选取,相对求解精度为1e-3,绝对求解精度自动选取。第第2章章 MATLAB仿真仿真 图2-13仿真参数设置对话框第第2章章 MATLAB仿真仿真 最后,双击示波器模型图标,打开示波器显示窗口。在显示窗口中单击鼠标右键,通过快捷菜单设置显示坐标范围等属性,这里我们设置为自动刻度,如图2-14所示。第第2章章 MATLAB仿真仿真 图2-14示波器显示窗口以及参数设置第第2章章 MATLAB仿真仿真 所有这些工作完成之后,就可以进行仿真了。可通过建模窗口菜单项“Simulation|Start”启动仿真,也可

74、以单击工具栏上的小三角按钮或使用快捷键Ctrl+T启动仿真。仿真结果如图2-15所示。读者可以将结果与图2-3所示的结果进行比较。第第2章章 MATLAB仿真仿真 图2-15仿真结果第第2章章 MATLAB仿真仿真 更换信号源为Sources子模块库中的SignalGenerator,并设置信号源为0.2Hz的方波,幅度为1,如图2-16左边对话框所示。设置示波器显示窗口的属性(Parameters),使之成为双踪显示,然后将示波器第二输入节点与信号源输出相连,这样我们就可以同时观察系统的输入输出波形了。系统建模如图2-16中间窗口所示。将仿真时间设定为0秒到20秒,其余参数使用默认参数。运行

75、仿真后的结果如图2-16右边窗口显示。读者还可以进一步修改信号源参数,使用三角波、正弦波等作为激励信号,观察输出信号的情况。第第2章章 MATLAB仿真仿真 图图2-16 更换信号源并使用双踪示波器之后的仿真结果更换信号源并使用双踪示波器之后的仿真结果第第2章章 MATLAB仿真仿真 3.MATLAB命令窗口与Simulink之间的交互从以上仿真过程中我们可以感受到Simulink的方便和快捷。事实上,我们还可以通过MATLAB命令来打开Simulink模型并进行仿真。在MATLAB命令窗口中,使用“openlizi1.mdl”,然后使用“sim(lizi1.mdl)”就可以启动对模型lizi

76、1.mdl的仿真计算,从而实现Simulink仿真的自动化。而Simulink仿真的数据结果也可以送回MATLAB工作空间中作进一步数值分析。仍以上例加以说明。首先设置示波器,使得显示波形数据能够送回MATLAB工作空间。在示波器波形显示窗口单击“参数Parameters”工具图标,打开显示参数设置对话框。选中Datahistory标签下的Savedatatoworkspace,并设传递变量名称,例如设为ScopeData,格式选择为Structurewithtime(带时间的结构型变量)。参数设置的情况如图2-17所示。第第2章章 MATLAB仿真仿真 图2-17示波器显示窗口的参数设置第第

77、2章章 MATLAB仿真仿真 将建模存盘为lizi1.mdl,然后在MATLAB下运行如下命令(参见图2-18):clear;%工作空间初始化openlizi1.mdl;%这时将看到建模模型文件被打开sim(lizi1.mdl);%启动模型仿真,显示出仿真波形whosNameSizeBytesClassScopeData1x13578structarrayGrandtotalis307elementsusing3578bytes第第2章章 MATLAB仿真仿真 图2-18通过命令启动Simulink仿真第第2章章 MATLAB仿真仿真 可 见 , 仿 真 完 成 之 后 , 工 作 空 间 中

78、 出 现 了“ScopeData”结构变量,其中包含了示波器显示的全部波形数据。通过“plot”命令可以作出这些数据对应的波形,即t=ScopeData.time;%仿真的时间变量 signal=ScopeData.signals;wave1=signal(1,1).values;wave2=signal(1,2).values;subplot(2,1,1);plot(t,wave1);subplot(2,1,2);plot(t,wave2);axis(0,20,-2,2);作出的波形如图2-19所示。读者可以对比示波器上得到的波形(参见图2-18)。我们在此说明了Simulink与MATLA

79、B工作空间进行数据交换的一种方法。第第2章章 MATLAB仿真仿真 图2-19示波器数据传入工作空间后进行波形作图显示第第2章章 MATLAB仿真仿真 事实上,MATLAB提供了许多途径用于与Simulink的数据交互。通过Sources子模型库中的FromWorkspace模块可以从工作空间中读入仿真所需要的输入数据,而通过Sinks子模型库中的ToWorkspace模块可以将Simulink中产生的数据回送到工作空间,从而可以实现MATLAB编程与Simulink模型相结合的混合仿真,这样就大大加强了仿真的功能。下面的例子中,我们将从工作空间中读入输入波形数据,通过Simulink建模仿真

80、之后,将仿真结果再送回工作空间中进行处理。通过这种方式,我们可以通过MATLAB程序产生任意的数据送入Simulink中加以处理,然后再利用MATLAB强大的统计分析功能来处理数据。第第2章章 MATLAB仿真仿真 首先建立Simulink模型,如图2-20所示。图中使用了Sources子模型库中的FromWorkspace模块,以便从工作 空 间 中 读 入 数 据 。 使 用 Sinks子 模 型 库 中 的ToWorkspace模块,将输出数据回送到工作空间。设计输入为阶跃信号,仿真建模中使用Continuous子库中的微分器来获得系统的阶跃响应的微分冲激响应。第第2章章 MATLAB仿

81、真仿真 图2-20用于测试与MATLAB工作空间进行数据交互的Simulink模型第第2章章 MATLAB仿真仿真 图2-20中,FromWorkspace模块的参数设置如图2-21所示。其中,Data项使用了两个矢量T,U参数组合。T表示离散时间序列,U表示对应于离散时间序列T的波形取值。Sampletime项设置为0,表示采用仿真求解器的默认采样时间间隔。Interpolatedata选中表示允许数据插值,并且通过数据外插(Extrapolation)方式在最终数值后形成输出。第第2章章 MATLAB仿真仿真 图2-21FromWorkspace模块的参数设置第第2章章 MATLAB仿真仿

82、真 模型中我们使用了两个ToWorkspace模块,分别接不同的输出信号,这两个ToWorkspace模块的输出变量分别为simout1和simout2。数据格式可设置为带时间的结构变量,如图2-22所示。仿真求解器采用ode45算法。但是为了获得更为精细的波形,可以设定求解的初始步长和最大步长为0.01,最小步长为auto,仿真时间段为020s。其余参数采用默认值。建模完成之后,将模型文件存盘为lizi2.mdl文 件 。 然 后 编 写 如 下 的 MATLAB仿 真 程 序pro4lizi2.m,对模型进行仿真和分析。第第2章章 MATLAB仿真仿真 图2-22ToWorkspace模块

83、的参数设置第第2章章 MATLAB仿真仿真 程序2-14%pro4lizi2.mclear;T=(0:0.1:20);%仿真时间段和步进,为列向量U=(T5);%在时间为5秒跃变的阶跃信号sim(lizi2.mdl);%运行仿真lizi2.mdlfigure(1);plot(simout1.time,simout1.signals.values);xlabel(timesec)%阶跃响应figure(2);plot(simout2.time,simout2.signals.values);xlabel(timesec)%冲激响应程序运行结果如图2-23所示。第第2章章 MATLAB仿真仿真 图

84、2-23MATLAB编程调用Simulink模型的仿真结果(阶跃响应和冲激响应)第第2章章 MATLAB仿真仿真 4.Simulink子系统的构造实际建模过程中,常常会遇到一些较为复杂的系统,难以在一张模型方框图中画出来。这时候,就需要以层次结构来绘制框图。也就是首先将大系统中的一些具有独立功能的部分封装起来,形成一些子系统,然后再利用这些子系统来构成整个系统。Simulink允许构造多层子系统,即在子系统中仍然允许包含若干下层子系统。这里我们简单介绍Simulink中子系统的构造方法。举例说明如下:首先将Simulink模块库中Ports&Subsystems子模块库中的Subsystem模

85、块拖动到新建的模型文件窗口中,双击该Subsystem模块,就会打开该子系统,其输入用In模块表示,输出用Out模块表示,一个子系统可以有多个输入、输出。第第2章章 MATLAB仿真仿真 然后利用Simulink模型库中的连续时间Continuous子库 中 的 传 递 函 数 TransferFcn模 块 , 数 学 操 作MathOperations子库中的增益Gain模块、求和Sum模块以及乘法模块Product构成子系统。该子系统有两个输入端口,一个输出端口。在子系统外部输入端口加入两个信号源,在其输出端口接上示波器,如图2-24所示。第第2章章 MATLAB仿真仿真 图2-24子系统

86、的构建和仿真第第2章章 MATLAB仿真仿真 系统参数的设置如表2-2所示。第第2章章 MATLAB仿真仿真 表2-2lizi3.mdl模型的参数设置第第2章章 MATLAB仿真仿真 注意,在仿真运行之前,必须将子系统中的以变量表达的参数值确定下来。这些参数值只需在MATLAB命令窗口中输入即可。例如,在命令窗口中输入参数值后运行仿真:G=1;A=1;B=0.001;C=1;sim(lizi3.mdl);显然,利用命令语句可以方便地对模型参数进行修改,从而得出不同系统参数下的仿真结果。仿真运行结果如图2-25所示。如果结合循环语句来自动修改参数,并将仿真结果送回MATLAB工作空间,则我们可以

87、让计算机在不同系统参数条件下自动仿真若干次,得出响应的结果。如果不使用命令“sim”来进行仿真,那么我们只好通过Simulink可视化界面来修改系统参数,并通过使用鼠标点击仿真运行工具来启动仿真,这样效率将是十分低下的。由此可见MATLAB编程与Simulink结合进行仿真的优势。第第2章章 MATLAB仿真仿真 图2-25lizi3.mdl的仿真结果第第2章章 MATLAB仿真仿真 5.封装子系统通过上面的例子可以看到,通过系统分层和建立子系统的思想可以相当方便地构建大型的复杂系统,而且这些子系统还是可以重用的。然而,上例中子系统模型还存在一些缺点:子系统中的参数(如增益G),传递函数系数等

88、等,是通过MATLAB工作空间传入的,这就破坏了子系统内部的隐藏性质。为此,Simulink中给出了一种解决办法,也就是所谓的模块封装技术。对子系统封装以后,它就可以像Simulink模块库所提供的模块一样来使用,子系统模块内部的参数可以通过一个设计的对话框来输入。第第2章章 MATLAB仿真仿真 对一个用户自己建立的系统模型进行封装,首先要通过上面所讲的方法将系统模型转化为子系统,然后选中该子系统图标,选择“Edit|MaskSubsystem”菜单项(快捷键为Ctrl+M),然后设置所弹出的对话框内容。下面我们对lizi3.mdl中建立的子系统进行封装。打开lizi3.mdl,另存为liz

89、i4.mdl,然后选中子系统模 块 , 将 其 改 名 为 Mysubsystem, 选 择“Edit|MaskSubsystem”菜单项,弹出Maskeditor对话框,如图2-26所示。第第2章章 MATLAB仿真仿真 图2-26封装编辑器对话框(Icon标签和Parameters标签)第第2章章 MATLAB仿真仿真 在Icon标签下主要是对封装模块的图标进行设置,可以设置图标的边框是否可见,图标是否透明,是否旋转,以及绘图单位等,还可使用命令来绘制图标,该标签下部给出了绘制图标的语法举例。在Parameters标签下可以设置子系统的参数,本例中需要设置的参数就是G,A,B,C四个。参数

90、设置可以采用编辑框(Edit)、弹出列表(Popup)或复选框(Checkbox)形式,读者可参考在线帮助。我们这里只使用编辑框。设置参数如图2-26右面对话框所示。第第2章章 MATLAB仿真仿真 图 2-27所 示 是 设 置 封 装 编 辑 器 对 话 框 中 的“Initialization(初始化)”标签和“Documentation(文档)”标签的情况。一般情况下,初始化标签可使用默认值;文档标签的三部分将分别显示在封装模块的参数设置对话框和帮助文档中,如图2-28所示。第第2章章 MATLAB仿真仿真 图2-27封装编辑器对话框(Initialization标签和Document

91、ation标签)第第2章章 MATLAB仿真仿真 图2-28封装模块的参数设置对话框以及帮助文档第第2章章 MATLAB仿真仿真 对于已经封装的模块,采用“Edit|EditMask”(快捷键为Ctrl+M)菜单项就可以重新编辑封装对话框。在编辑封装对话框的下部有一个Unmask按钮(参见图2-26),单击该按钮可以去除封装。若需要修改子系统的内部结构,可以使用菜单项“Edit|Lookundermask”(快捷键为Ctrl+U)来打开子系统结构,从而对子系统方框图进行修改。第第2章章 MATLAB仿真仿真 6.组建用户自定义模块库如果建立了许多自定义的子系统,并且已经封装好了,而这些已经封装

92、的自定义模块又是会反复使用的,就像Simulink提供的模块库中那些模块一样,在这种情况下,就有必要对这些自定义的重用性较好的模块进行建库,以方便管理和反复使用,同时也可以作为新的专业库提供给其他用户使用。Simulink提 供 了 建 库 手 段 , 具 体 方 法 是 : 用“simulink”命令打开Simulink库浏览器,从其菜单中选择“New|Library”,新建一个空白的模块库窗口,然后将欲建库的模块用鼠标拖入该库文件窗口中即可。第第2章章 MATLAB仿真仿真 可用“File|Modelproperties”菜单项来修改自建库的属性,最后存盘,例如存为myku.mdl文件。以

93、后 需 要 使 用 时 , 在 MATLAB命 令 窗 口 中 键 入“myku.mdl”即可开启该模型库窗口,其中的自定义模块与Simulink提供的标准库中的模块的使用方法完全相同。自定义模块库存盘之后将处于锁定状态,如果要对库中的模块进行修改,可以再次打开该模块库,然后用“Edit|Unlocklibrary”解锁,修改并存盘之后,库自动恢复为锁定状态。图2-29给出了一个用户自定义模块库的例子。第第2章章 MATLAB仿真仿真 图2-29一个用户自定义模块库的例子第第2章章 MATLAB仿真仿真 2.3.2Simulink仿真原理上一小节我们讨论了Simulink建模的基本方法,Sim

94、ulink仿真与MATLAB编程的数据交互以及Simulink子系统建模和建库的方法。通过Simulink提供的这些功能,利用Simulink基本库,我们就可以构建自己的仿真模型、自己的专业模型库,并进行仿真和数值结果分析。本小节将进一步讨论Simulink是如何工作的。我们已经知道,Simulink进行仿真本质上就是利用某种求解算法对系统状态方程进行求解的过程。那么,Simulink是如何将系统的状态方程与系统方框图模型联系起来的呢?事实上,Simulink设计了固定格式的S函数接口,通过S函数可将系统的数学方程表达形式与方框图表达形式联系起来。第第2章章 MATLAB仿真仿真 通过编写和使

95、用S函数,用户也可以构建出采用Simulink普通模块难以搭建出来的系统模型,大大增强了Simulink的灵活性。S函数可以用MATLAB语言书写,也可以采用C、C+、Fortran等语言编写。S函数还可以进行编译,以提高执行速度。Simulink内建的标准模块库就是用S函数编写并进行编译后形成的。1.系统的状态方程描述对于连续系统,其状态方程为x=f(t,x,u)(2-30)第第2章章 MATLAB仿真仿真 若系统是线性时不变系统,则状态方程可简化为x=f(t,x,u)=Ax(t)+Bu(t)(2-31)系统的输出方程为 y=f0(t,x,u)(2-32)若为线性时不变系统,则输出方程可简化

96、为y=f0(t,x,u)=Cx(t)+Du(t)(2-33)m个输入的情况:u(t)=u1(t),u2(t),um(t)T(2-34)k个输出的情况:y(t)=y1(t),y2(t),yk(t)T(2-35)第第2章章 MATLAB仿真仿真 n个状态数的情况:x(t)=x1(t),x2(t),xn(t)T(2-36)最为简单的是单输入单输出系统,设其状态数为n,则状态方程为x=f(t,x,u)=Ax(t)+Bu(t)(2-37)输出方程为y=f0(t,x,u)=Cx(t)+Du(t)(2-38)第第2章章 MATLAB仿真仿真 无记忆系统是一般系统的特例,其状态数为0。例如:设计一个放大器系统

97、,将信号放大2.7倍,则该系统是无记忆的,故状态数为0,状态矩阵x=是空矩阵,而输出方程为y=f0(t,x,u)=Du(t)=2.7u(t)(2-39)对于离散时间系统,其状态方程表现为差分方程组的形式。对于更一般的系统,都有以下共同特征:一个输入向量u,一个输出向量y,一个状态向量x,这些向量可以是连续的,也可以是离散的,还可以是连续、离散混合的,如图2-30所示。第第2章章 MATLAB仿真仿真 图2-30一般系统的抽象数学模型第第2章章 MATLAB仿真仿真 输入向量、输出向量和状态向量之间的数学关系可以通过如下方程来表达:y=f0(t,x,u)(输出方程)(2-40)xc=fd(t,x

98、,u)(连续时间系统状态方程微分方程) (2-41)xdk+1=fu(t,x,u)(离散时间系统状态方程差分方程)(2-42)其中,x=xc+xd,xc是连续状态部分,xd是离散状态部分。第第2章章 MATLAB仿真仿真 在Simulink的S函数中,相应地将状态向量分为连续状态部分和离散状态部分,对于没有状态的模块(即无记忆系统),状态向量x为空矩阵。2.MATLAB语言的S函数模板MATLAB语言的S函数编写方法是固定的,MATLAB提供了标准S函数的模板sfuntmpl.m,文件在Toolboxsimulinkblocks目录下。其代码如下(为了节省篇幅,注释部分有所删节,并修改为中文)

99、:程序2-15functionsys,x0,str,ts=sfuntmpl(t,x,u,flag)switchflag,case0,%初始化部分第第2章章 MATLAB仿真仿真 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);第第2章章 MATLAB仿真仿真 case

100、9,%终止sys=mdlTerminate(t,x,u);otherwise%Unexpectedflags出错处理error( Unhandledflag=,num2str(flag) );end%sfuntmpl函数结束%=%mdlInitializeSizes模型初始化函数,返回:%sys是系统参数第第2章章 MATLAB仿真仿真 %x0是系统初始状态,若没有状态,取%str是系统阶字串,通常设为%ts是取样时间矩阵,对连续取样时间,ts取00%若使用内部取样时间,ts取-10,-1表示继承输入信号的采样周期%=functionsys,x0,str,ts=mdlInitializeSiz

101、es%模型初始化函数sizes=simsizes;%取系统默认设置sizes.NumContStates=0;%设置连续状态变量的个数sizes.NumDiscStates=0;%设置离散状态变量的个数第第2章章 MATLAB仿真仿真 sizes.NumOutputs=0;%设置系统输出变量的个数sizes.NumInputs=0;%设置系统输入变量的个数sizes.DirFeedthrough=1;%设置系统是否直通sizes.NumSampleTimes=1;%采样周期的个数,必须大于等于1sys=simsizes(sizes);%设置系统参数x0=;%系统状态初始化str=;%系统阶字串

102、总为空矩阵ts=00;%初始化采样时间矩阵第第2章章 MATLAB仿真仿真 %=%mdlDerivatives模型计算导数连续状态部分的计算,返回连续状态的导数%=functionsys=mdlDerivatives(t,x,u)sys=;%根据状态方程(微分方程部分)修改此处%=%mdlUpdate状态更新计算离散状态部分%=functionsys=mdlUpdate(t,x,u)第第2章章 MATLAB仿真仿真 sys=;%根据状态方程(差分方程部分)修改此处%=%mdlOutputs计算输出信号,返回模块的输出%=functionsys=mdlOutputs(t,x,u)sys=;%根据

103、输出方程修改此处%=%mdlGetTimeOfNextVarHit计算下一步的仿真时刻,该函数仅当在mdlInitializeSizes%函数中的采样时间向量定义了一个可变离散采样时间ts为-20时才被使用第第2章章 MATLAB仿真仿真 %=functionsys=mdlGetTimeOfNextVarHit(t,x,u)sampleTime=1;%例如,下一步仿真时间是1s之后sys=t+sampleTime;%=%mdlTerminate终止仿真设定,完成仿真终止时的任务%=functionsys=mdlTerminate(t,x,u)sys=;%程序结束第第2章章 MATLAB仿真仿真

104、 Simulink进行仿真的过程是:仿真开始时,调用各个模块的初始化函数进行系统初始化,接着进入仿真阶段,反复调用模型中的每一个模块,即调用这些模块对应的S函数,对每个模块执行诸如计算输出、计算连续函数导数以及计算离散函数的更新值等任务。在仿真结束时,调用终止仿真函数以结束仿真任务。具体某时刻Simulink执行什么任务,取决于当时调用S函数时传入的标志flag的值。第第2章章 MATLAB仿真仿真 进入第一次仿真循环之前为仿真初始化阶段,Simulink调用S函数的初始化功能mdlInitializeSizes完成初始化任务:首先初始化一个包含S函数信息的Simulink结构(sys),然后

105、设置输入和输出端口的数量和大小,并设置模块的采样时间、分配存储空间以及估计数组大小等等。进 入 仿 真 循 环 后 , Simulink首 先 调 用mdlGetTimeOfNextVarHit计算下一采样点时间(仅仅对于可变离散采样时间的模块),然后计算主要时间同步输出,得出当前时间步的模块的输入输出端口和状态取值。接着更新主要时间步的离散状态,最后进行辅助时间步的积分过程。在辅助时间步调用S函数的输出和导数计算,并定位过零区间,于是完成一次仿真循环。第第2章章 MATLAB仿真仿真 当Simulink跳出仿真循环后,就进入了仿真的最后阶段。这一阶段通过调用S函数中的mdlTerminate

106、来执行一些必要的任务,最后结束仿真。3.利用S函数建模和仿真的过程在Simulink模块浏览器中可以打开S函数的编程例子加以学习,如图2-31所示。这里我们通过几个S函数的建模实例来说明S函数建模和仿真的过程。第第2章章 MATLAB仿真仿真 图2-31在Simulink模块浏览器中打开S函数的编程例子第第2章章 MATLAB仿真仿真 下面以一个采用S函数来实现连续滤波器的例子来说明。要仿真的滤波器的传递函数为(2-43)(2-44)第第2章章 MATLAB仿真仿真 由此可得出系统信号流图,然后写出状态方程(当然可有若干形式,而不同形式就对应不同的状态变量选择,也就形成不同形式的状态方程和输出

107、方程。另外,MATLAB的控制系统工具箱提供了传递函数与状态方程之间的转换函数“tf2ss”和“ss2tf”,这里为了说明原理,采用了手工转换)。这是一个单输入、单输出的三阶线性时不变系统,可将其状态变量设为x1,x2,x3,输入为u(t),输出为y(t),则根据系统信号流图有状态空间方程:第第2章章 MATLAB仿真仿真 (2-45)以及输出方程:y=4x2(2-46)以矩阵表示为(2-47)第第2章章 MATLAB仿真仿真 或简写为通式:其中:(2-49)(2-48)(2-50)第第2章章 MATLAB仿真仿真 据此可以编写S函数myHsapp.m如下:程序2-16functionsys,

108、x0,str,ts=myHsapp(t,x,u,flag)%连续系统状态方程%x=Ax+Bu%y=Cx+Du%定义A,B,C,D矩阵第第2章章 MATLAB仿真仿真 A=010;001;-4-6-3;B=0;0;1;C=040;D=0;switchflag,case0%flag=0初始化sys,x0,str,ts=mdlInitializeSizes(A,B,C,D);%注意要将ABCD送入初始化case1%flag=1计算连续系统状态方程(导数)sys=mdlDerivatives(t,x,u,A,B,C,D);第第2章章 MATLAB仿真仿真 case3%flag=3计算输出sys=mdl

109、Outputs(t,x,u,A,B,C,D);case2,4,9%其它作不处理的flagsys=;otherwise%异常处理error( Unhandledflag=,num2str(flag) );end%主函数结束第第2章章 MATLAB仿真仿真 %-functionsys,x0,str,ts=mdlInitializeSizes(A,B,C,D)%初始化函数sizes=simsizes;sizes.NumContStates=3;%连续系统的状态数为3sizes.NumDiscStates=0;%离散系统的状态数,对于本系统此句可不用sizes.NumOutputs=1;%输入信号数目

110、是1sizes.NumInputs=1;%输出信号数目是1sizes.DirFeedthrough=0;%该系统不是直通的sizes.NumSampleTimes=1;%这里必须为1sys=simsizes(sizes);第第2章章 MATLAB仿真仿真 str=;%通常为空矩阵x0=0;0;0;%初始状态矩阵x(零状态情况)ts=00;%连续取样时间%初始化函数结束%-functionsys=mdlDerivatives(t,x,u,A,B,C,D)%系 统 状态方程函数sys=A*x+B*u;%系统状态函数结束%-%系统输出函数functionsys=mdlOutputs(t,x,u,A,

111、B,C,D)第第2章章 MATLAB仿真仿真 sys=C*x;%注意,如果使用语句sys=C*x+D*u;代替上句,即使D=0,也要将%sizes.DirFeedthrough设为1,即系统存在输入输出之间的直通项%系统输出函数结束接下来,将该S函数与系统方框图联系起来。打开一个新建建模文件窗口,利用Simulink基本模块库中的UserdefinedFunctions子库中的SFunction模块建立S函数模块方框图。第第2章章 MATLAB仿真仿真 打开其参数设置对话框,在其Sfunctionname栏填入S函数的名称myHsapp。为例验证自编的S函数的正确性,同时采用Simulink的

112、Continuous库中的TansferFunction模块构建与S函数功能相同的系统,然后同时测试波形。建立Simulink仿真系统模型文件为lizi5.mdl,其系统结构和参数设置如图2-32所示。第第2章章 MATLAB仿真仿真 图图2-32 利用利用S函数建模与测试系统仿真参数函数建模与测试系统仿真参数第第2章章 MATLAB仿真仿真 设置仿真求解器为ode45,仿真时间为040s。其余参数为默认值,得到的仿真结果如图2-33所示。可见,S函数模块和传递函数模块得出了相同的结果,这也就验证了S函数编写的正确性。第第2章章 MATLAB仿真仿真 图2-33利用S函数建模与测试系统仿真参数

113、第第2章章 MATLAB仿真仿真 为了看清楚Simulink调用S函数的内部过程,可以修改以上S函数,使得当S函数被调用的时候能够显示出调用时刻的函数变量值的情况。将S函数文件myHsapp.m修改并另存为myHsapp1.m,即:程序2-17functionsys,x0,str,ts=myHsapp1(t,x,u,flag)%文件名myHsapp1.m%连续系统状态方程%x=Ax+Bu%y=Cx+Du%定义A,B,C,D矩阵第第2章章 MATLAB仿真仿真 A=010;001;-4-6-3;B=0;0;1;C=040;D=0;%显示调用该S函数时,调用标志,仿真时间,系统状态,输入信号fla

114、gtxu%以下程序代码和myHsapp.m中的对应部分相同(略)第第2章章 MATLAB仿真仿真 将lizi5.mdl中S函数模块参数中的关联S函数文件名相应修改为myHsapp1,仿真时间段设定为01s,为了显示调用清楚,可选择仿真算法为固定步长的,步长为0.1s,然后运行。在命令窗口中将得到每次调用S函数myHsapp1的调用标志、仿真时间、系统状态、输入信号的当前值,即(为了节省篇幅,做了编辑和注释)(1)仿真开始时刻初始化flag=0调用初始化部分t=x=u=第第2章章 MATLAB仿真仿真 (2)进入仿真循环,计算0时刻输出flag=3调用输出方程的计算t=0(3)更新0时刻状态(离

115、散)flag=2调用计算离散状态更新部分,这一步在本S函数中不起作用t=0(4)更新0时刻状态(连续)flag=1调用计算连续状态部分t=0(5)第二次仿真循环,计算0.1时刻输出第第2章章 MATLAB仿真仿真 flag=3调用输出方程的计算t=0.1000(6)更新0.1时刻状态(离散)flag=2调用离散状态计算t=0.1000(7)更新0.1时刻状态(连续)flag=1调用连续状态计算t=0.1000(8)下一时刻t=0.2000(略)t=0.9000(略)第第2章章 MATLAB仿真仿真 (9)最后时刻输出计算flag=3t=1更新最后时刻状态(离散)flag=2t=1结束flag=

116、9调用终止仿真功能t=1第第2章章 MATLAB仿真仿真 4.S函数的编译为了使仿真运行速度更快,可以对编制调试好的S函数进行编译,形成动态链接库形式供Simulink调用。编译方法是,在MATLAB命令窗口使用“mcc”命令,即mcc-x函数文件名例如,对S函数myHsapp.m进行编译,应输入命令mcc-xSmyHsapp.m将在myHsapp.m所在目录下输出C语言代码文件,头文件以及可执行的动态链接库文件,即myHsapp.c,myHsapp.h,myHsapp-mex.c,simsizes.h,myHsapp.dll这五个文件。第第2章章 MATLAB仿真仿真 其中C源代码可以删除,

117、不影响执行。注意,如果M文件的S函数已经调试通过,而采用mcc编译出错的话,往往是编译器对中文注释支持不好造成的,笔者使用MATLAB的lcc编译器对myHsapp.m编译就会出现错误,检查发现将该文件中汉字注释中的汉字“数”造成的,将汉字“数”删除即可编译成功。最保险的方法是编译之前将全部汉语注释去除,或采用其它编译器,例如安装MicrosoftVC+6.0编译器后,可以使用MATLAB命令“mexsetup”来选择编译器,VC+6.0的编译器对中文支持较好。第第2章章 MATLAB仿真仿真 对编译后的S函数的仿真速度可以做如下测试(测试文件均在MATLAB默认工作路径work下),语句中调

118、用了Windows2000的控制台指令,即DOS指令,来检测dll文件是否存在,以及删除操作等等。程序2-18%testspeed4Sfun.mmcc-xmyHsapp.m%预先编译,以免前面仿真执行后再删除myHsapp.dll时拒绝访问a,w=system(dirmyHsapp.dll);%是否存在mcc编译输出的myHsapp.dll文件ifa=0%如果当前工作路径存在mcc编译输出的dll文件第第2章章 MATLAB仿真仿真 system(delmyHsapp.dll);%那么将该文件删除endopenlizi5.mdl;%打开模型后手工修改仿真时间为040秒,固定步长为0.01tic

119、%启动计时器sim(lizi5.mdl);toc%未编译的S函数的仿真执行时间mcc-xmyHsapp.m%编译myHsapp.m生成myHsapp.dlltic%启动计时器第第2章章 MATLAB仿真仿真 %system(dirmyHsapp.dll);%使用此句可以显示是否 编 译 产 生 了 myHsapp.dllsim(lizi5.mdl);%当myHsapp.m和myHsapp.dll同时存在时,将会优先调用myHsapp.dlltoc%编译后S函数的仿真执行时间执行脚本程序testspeed4Sfun.m后,结果如图2-34所示。可见,在该模型和算法的仿真中,编译后的执行速度提高了

120、大致1倍左右。第第2章章 MATLAB仿真仿真 图2-34编译S函数的仿真速度测试模型和求解器参数设置情况第第2章章 MATLAB仿真仿真 5.S函数建模的其它例子下面再举一些S函数建模的例子。第一个例子是可设定增益的理想放大器,通过这个例子我们将讨论使用带辅助参数的S函数的编程方法,以及对S函数模块的封装技术。现在要求设计一个理想放大器,其增益可以由用户设定,并将设计好的S函数模块封装起来。对于一个理想放大器,其输入输出是直通的,而且是一个无记忆系统,因此状态数为0,状态矩阵x=是空矩阵,而输出方程为:y(t)=Gu(t),其中G为增益参数。据此编写S函数如下:第第2章章 MATLAB仿真仿

121、真 程序2-19functionsys,x0,str,ts=Ampvar(t,x,u,flag,G)%G是辅助参数,增益%实现输入输出关系:y=G*u;switchflag,case0%flag=0初始化sys,x0,str,ts=mdlInitializeSizes(G);%注意这里带了参数Gcase3%flag=3输出方程求解sys=mdlOutputs(t,x,u,G);%注意这里带了参数Gcase1,2,4,9%其它作不处理的flag第第2章章 MATLAB仿真仿真 sys=;otherwise%异常处理error( Unhandledflag=,num2str(flag) );end

122、%主函数结束function sys,x0,str,ts =mdlInitializeSizes(G)%初始化函数,注意这里带了参数Gsizes=simsizes;sizes.NumContStates=0;%连续系统的状态数sizes.NumDiscStates=0;%离散系统的状态数,对于本系统此句可不用sizes.NumOutputs=-1;%输入信号数目是动态的第第2章章 MATLAB仿真仿真 sizes.NumInputs=-1;%输出信号数目是动态的sizes.DirFeedthrough=1;%该系统是直通的sizes.NumSampleTimes=1;%这里必须为1sys=si

123、msizes(sizes);str=;%通常为空矩阵x0=;%初始状态矩阵ts=00;%连续取样时间%初始化函数结束第第2章章 MATLAB仿真仿真 functionsys=mdlOutputs(t,x,u,G)%系统输出函数,注意这里带了参数Gsys=u*G;%系统输出函数结束建立测试系统,设置该放大器增益为3,信号源设置为锯齿波,频率为1Hz,幅度为1。仿真系统设置和仿真结果如图2-35所示。求解器ode45的最大步长设定为0.01s。Simulink工具箱中带有许多S函数编程的例子,其M文件的S函数实例文件在SimulinkBlocks子目录下,文件名和实现的功能参见表2-3,读者可详加

124、研究。第第2章章 MATLAB仿真仿真 图2-35S函数编写的放大器、测试系统参数设置、仿真结果第第2章章 MATLAB仿真仿真 表2-3SimulinkBlocks子目录下的一些S函数的例子第第2章章 MATLAB仿真仿真 2.3.3基于时间流的仿真方法使用Simulink建模仿真时,每进行一次仿真循环,Simulink将对模型中每一个模块调用底层S函数,从而获得各个模块在当前仿真时刻的输出值和状态值,也就是说,仿真时间每前进一步,各个模块的状态也都前进一步,所有模块在该时间步上同时完成了计算。这就称为基于时间流的仿真。在基于时间流的仿真中,随着仿真时间步的前进,建模系统中的各个模块的输入输出以及状态数据是“实时”获得的。而对于前面讨论过的MATLAB编程仿真来说,只有当处于信号流上游的部分数据仿真得出以后,才能将数据送入其后的部分,这是一种基于数据流的仿真方法。第第2章章 MATLAB仿真仿真 基于时间流的Simulink框图仿真和基于数据流的MATLAB编程仿真各有所长,总的说来,基于时间流的仿真“实时”性较好,也比较直观;而基于数据流的仿真则需要编写代码,但可以比较灵活地控制仿真过程。Simulink框图和MATLAB编程仿真结合的混合模式常常可以更加灵活地对大型系统进行建模、自动仿真和结果数据处理。本书中许多例子是利用Simulink和MATLAB编程混合方式实现的。

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号