本章讨论如何在Simulink中仿真动态系统,包括连续系统、离散系统和混合系统,本章的主要内容包括:
Simulink动态系统仿真过程介绍Simulink仿真动态系统的工作流程
离散系统仿真介绍如何在Simulink中设置离散系统的仿真步
长、仿真算法和其它仿真参数
多速率系统仿真多速率系统是包含多个采样时间的离散系统,介
绍如何选择多速率系统的采样步长 连续系统仿真介绍如何在Simulink中建立不同形式的连续系统
模型,如何仿真连续系统
混合系统仿真如何仿真由连续模块和离散模块组成的混合系统 模型离散化如何对模型进行离散化,也就是将模型中的连续
模块用等效的离散模块代替
诊断仿真错误若在仿真过程中出现错误,Simulink会中断仿真。
介绍如何利用Simulink的仿真诊断查看器查看错
误来源
改善仿真性能和精度介绍在Simulink中提高仿真速度和改善仿真性能
的几种可行方法106 第6章 Simulink动态系统仿真
6.1 Simulink动态系统仿真过程
仿真一个动态系统是指利用模型提供的信息计算一段时间内系统状态和输出的过程,当在模型编辑器的Simulation菜单上选择Start命令时,Simulink开始执行系统仿真。Simulink模型的仿真过程包括模型编译阶段和模型链接阶段。
6.1.1 模型编译阶段
首先,Simulink调用模型编译器,模型编译器把模型转换为可执行形式,这个转换过程称为编译。在这个阶段,Simulink编译器执行下列工作:
1.求取模型中模块的参数表达式用以确定表达式的值;
2.确定模型中未明确指定的信号属性,如信号名称、数据类型、数值类型和信号维数,并检查每个模块输入端可允许的输入信号。Simulink利用属性传递过程确定用户未明确指定的属性,这个过程继承模块源信号的属性,并将这个属性传递到信号所驱动模块的输入端;
3.执行模块优化;
4.用原子子系统所包含的模块替代原子子系统,并平铺模型层次;
5.将模块进行排序,并排列仿真过程中模块的执行顺序,当模型进入仿真执行阶段时将按照此时的排列顺序执行模块;
6.对于用户未明确指定采样时间的模块,确定所有这些模块的采样时间;
在仿真过程中,Simulink会在每个时间步内更新一次模型中模块的状态和输出,模块的更新顺序是根据模块类型决定的,Simulink按照一定的方式对模块进行排序。
1.直接馈通端口
为了创建Simulink模型仿真过程中有效的模块更新顺序,Simulink依据模块的输出与输入的关系将模块的输入端口进行排序,对于那些输入的当前值直接确定了模块某一输出端口当前值的输入端口,我们称其为直接馈通端口。换言之,也就是模块的输出方程中包含输入,它的输出直接依赖于输入。例如,Gain模块、Product模块和Sum模块就是具有直接馈通端口的模块。具有非直接馈通输入的模块包括Integrator模块(它的输出完全是其状态的函数)、Constant模块(没有输入)以及Memory模块(它的输出与前一时刻的输入有关)。
2.模块排序准则
Simulink利用下面的基本更新规则对模块进行排序:
在驱动任一模块的直接馈通端口之前必须对每个模块进行更新;
这个规则可以确保更新模块时连接到模块直接馈通端口的输入是有效的。
不带有直接馈通输入的模块可以以任意的顺序进行更新,但必须是在它们驱动任一带有直接馈通输入的模块之前进行更新;第6章 Simulink动态系统仿真 107
按照这个规则,把所有不带有直接馈通端口的模块以任意顺序放在更新列表的前
端,这样Simulink在排序过程中就可以忽略这些模块。
按照上述规则排列的更新列表中,不带有直接馈通端口的模块以任意顺序排列在列表
的最前面,接下来是带有直接馈通端口的模块,这些模块按照它们为所驱动模块提供有效
输入的顺序排列。
在Simulink的模块排序过程中,Simulink会检查并标记代数循环事件,也就是,一个
模块的直接馈通输出直接或间接地连接到该模块所对应的直接馈通输入的信号循环。这样
的循环表面上看是个死循环,因为Simulink需要用直接馈通的输入值计算其输出值,但是,
我们都知道,代数循环可以表示一组输入和输出均未知的联立代数方程,而且,这些方程
在每个时间步上都存在有效解,因此,Simulink假设这些包含直接馈通端口的代数循环表
示了一组可求解的代数方程,并在仿真过程中每次更新模块时解算这些方程。关于代数循
环的详细内容,读者可以参看第七章“高级仿真概念”。
6.1.2 模型链接阶段
在这个阶段,Simulink会为方块图执行过程中的信号、状态和运行时间参数等分配内
存,它也会为每个模块中存储运行信息的数据结构分配并初始化内存。对于内嵌模块,模
块中主要的运行时间数据结构称为SimBlock,它存储指向模块输入和输出缓存、状态、工
作向量的指针。
在这个阶段,Simulink也会创建方法执行列表,这个列表列出了执行模型中模块方法
计算模块输出的最有效顺序,Simulink使用在模型编译阶段生成的排序列表来构造方法执
行列表。用户也可以指定模块的更新优先权,Simulink会在低优先权模块之前执行高优先
权模块的输出方法。
6.1.3 仿真循环阶段
仿真现在进入执行阶段。在这个过程中,Simulink利用模型提供的信息,每隔一段时
间计算由仿真起始时间到终止时间之间的系统状态和输出,计算状态和输出的这些连续的
时间点被称为时间步(time steps),两个时间步之间的长度称为步长(step size),步长的大小
取决于用来计算系统连续状态的算法、系统的基本采样时间以及系统的连续状态中是否有
不连续因素。
仿真循环阶段包括两个子阶段:循环初始化阶段和循环迭代阶段。初始化阶段在循环
过程中只执行一次;迭代阶段在整个仿真过程中在每个时间步内都要重复一次。
在仿真开始时,Simulink确定被仿真系统的初始状态和输出。在每一步仿真中,Simulink
重新计算系统新的输入值、状态值和输出值,并更新模型以反映所计算的值。当仿真结束
时,模型反映的是系统输入、状态和输出的最终值,而且,Simulink还提供了数据显示和
记录模块,用户可以在模型中添加这些模块以显示和(或)记录中间的结果数据。
Simulink在每个仿真时间步中都执行如下操作:
1.按照模块的排列顺序,更新模型中所有模块的输出;108 第6章 Simulink动态系统仿真
Simulink通过调用模型的Outputs方法初始化这个阶段,模型的Outputs方法依次调用模型系统中模块的Outputs方法,它依照仿真链接阶段生成的Outputs方法列表中的顺序调用模型中每个模块的Outputs方法。
系统的Outputs方法向每个模块的Outputs方法传递下列变量:指向模块数据结构和模块SimBlock结构的指针。SimBlock数据结构指向Outputs方法用来计算模块输出的信息,包括模块输入缓存和输出缓存的位置。
2.按照模块的排列顺序,更新模型中所有模块的状态;
Simulink调用求解器来计算模型的状态,模型中使用的求解器类型取决于模型类型,即模型中是否含有状态、模型中只含有离散状态、模型中只含有连续状态,或者模型中包含有连续状态和离散状态。
如果模型中只包含离散状态,那么Simulink会调用用户选择的离散求解器,求解器计算满足模型采样时间的离散步长,然后调用模型的Update方法,模型的Update 方法再调用模型系统的Update方法,也就是按照链接阶段生成的Update方法列表顺序调用系统中每个模块的Update方法。
如果模型中只包含连续状态,那么Simulink会调用模型指定的连续求解器。根据求解器的不同,求解器或者依次调用模型的Derivatives方法,或者进入以最小时间步采样的子循环,在这个子循环中,求解器在较大时间步内以最小步长为采样间隔反复调用模型的Outputs方法和Derivatives方法计算模型的输出和微分值。模型的Outputs方法和Derivatives方法会依次调用相应的系统方法,调用的顺序按照链接阶段生成的Outputs和Derivatives方法执行列表中指定的顺序。
3.检测模块连续状态中的不连续性;
是否执行这步操作是根据用户的设置来决定的,如果用户在模型中选择了执行过零检测,那么Simulink会利用过零检测来检测模块连续状态中的不连续性。
4.计算下一个时间步的时间;
Simulink在整个仿真过程中的每个时间步内均执行1~ 4步操作,这个过程会一直进行下去,直至仿真结束。
注意:在仿真过程中,Simulink在每个时间步内更新一次模型中各个模块的状态和输出,因此,模型中模块的更新顺序对于仿真结果的有效性是非常重要
的。而且,如果在当前时间步,模块的输出是其输入的函数,那么这个模
块必须在驱动其输入的模块之后进行更新,否则的话,模块的输出就是无
效的。模块存储在模型文件中的顺序并不一定就是仿真过程中模块的更新
顺序,因此,Simulink在模型初始化阶段就将所有的模块按照正确的顺序
进行了排列。
Simulink仿真循环过程如图6-1所示。
第6章 Simulink动态系统仿真 109
仿
真
循
环
单任务(包括变步长)仿真循环
图6-1
6.1.4 求解器的分类
Simulink利用模型提供的信息和求解器在指定的时间段内连续计算动态系统的状态来
仿真动态系统,这个仿真计算系统模型状态的过程就是模型解算的过程。Simulink通常利
用求解器来求解,求解器的主要功能是计算模块的输出,Simulink通过在系统和求解器之
间建立对话的方式对系统进行求解,如图6-2所示,这里,求解器计算模块的输出以更新110 第6章 Simulink动态系统仿真
模块的状态并确定下一个时间步,而系统则把参数、模型方程等信息传递给求解器。
图6-2
1.定步长求解器和变步长求解器
Simulink算法分为定步长算法和变步长算法两类。
定步长求解器:顾名思义,仿真步长是固定不变的,这些算法依据相等的时间间隔来解算模型,时间间隔称为步长。用户可以指定步长的大小,或者由算法自己
选择步长。通常,减小步长可以提高仿真结果的精度,但同时也增加了系统仿真
所需要的时间。
变步长求解器:在仿真过程中,步长是变化的。当模型的状态变化很快时,步长减小以提高精度,而当模型的状态变化很慢时,步长增加以避免不必要的计算步
数。当然,在每一步中计算步长势必增加了计算负荷,但却减少了仿真的总步数,而且对于快速变化的模型或具有分段连续状态的模型,在保证其所要求精度的前
提下缩短了仿真时间。
2.连续求解器和离散求解器
Simulink提供了连续求解器和离散求解器。
连续求解器:利用数值积分计算当前时间步上模型的连续状态,当前时刻的状态是由在此时刻之前的所有状态和这些状态的微分来决定的。对于离散状态,连续
算法依赖模型中的模块来计算每个时间步上模型的离散状态值。
目前,有很多种数值积分算法可以求取动态系统连续状态的常微分方程(ODE),
Simulink提供了多种定步长和变步长的连续算法,用户可以根据自己的实际模型
来选择这些算法。
离散求解器:主要用来求解纯离散模型。这些算法只是计算下一步的仿真时刻,而不进行其它的运算。它们并不求解连续状态值,而且这些算法依赖模型中的模
块来更新模型的离散状态。
Simulink有两种离散求解器:定步长离散求解器和变步长离散求解器。缺省时,
定步长算法选择一个步长,选择的步长使仿真速度足以跟踪模型中最快速变化的
模块;变步长算法调整仿真步长,以便与模型中离散状态的实际变化率相一致,
这对于多速率模型来说可以避免不必要的仿真步数,并因此缩短仿真时间。
关于如何根据模型类型选择不同的求解器,读者可以参看第5章中的5.2节,这一部分对求解器的适用范围进行了详细的介绍。
注意:用户可以选择连续求解器,而不是离散求解器来求取既包含连续状态,也包含离散状态的模型,这是因为离散求解器无法处理连续状态。如果用户
为连续模型选择了离散求解器,那么Simulink会忽略用户的选择,而使用
连续求解器求解模型。
6.2 离散系统仿真
作为一般系统的定义,系统应该是由一组物理元素构成,能够接收一组输入,产生相对应的一组输出。对于不含有状态的系统,即在某一时刻的输出只依赖于该时刻的输入,而不依赖先前的输入值,而且系统对同一种输入信号的响应不会因时间的变化而变化,这样的系统通常称为简单系统,这种不含状态的简单系统采用代数方程,逻辑结构,或者二者结合的方式来表示,如例4-1、例4-2、例4-3中的模型。本节讨论如何在Simulink中仿真离散系统,包括纯离散系统、线性离散系统和多速率系统,以及如何在Simulink中实现离散差分方程,如何选择离散系统的仿真步长、仿真算法等。
6.2.1 差分方程的实现
离散系统是包含有离散状态的系统。Simulink可以仿真离散系统,包括组件以不同速率工作的系统(即多速率系统)和由离散组件和连续组件混合组成的系统(即混合系统)。
在离散系统中,一个状态实际上是一个存储元素,它在一定的周期内保存输入或输出值,这个周期称为这个系统的采样时间,采样时间是离散系统的一个最重要特性,在Simulink中的所有离散模块中都要给出采样时间,一个离散状态实际上储存的就是上一个采样时刻的信号值。
离散系统通常用差分方程描述,因为系统当前时刻的输出通常依赖于当前时刻的输入和过去时刻的输入和输出量,例如:
n
y
=n
u
+
n
y
−
u
n
3
)1
(
+
(
)1
(−
)
)
(
在Simulink中,为了实现差分方程需要一个能够在时间步上提供y(n-1)和u(n-1)的模块,Simulink提供了一个Discrete离散模块库,如图6-3所示。用户可以利用离散模块库中的Unit Delay (单位延迟)模块可以实现上述功能,Unit Delay模块是建立离散系统的基础,因为它给出了状态用来计算系统的输出。
要实现上面的差分方程,第一步就是确定方程中所需要的Unit Delay模块的数目,这里有两点是必须的:一是y(n-1)来自于y(n);二是u(n-1)来自于u(n)。如果方程中还包含y(n-2),那么这个值应当通过y(n-1)经由另外一个Unit Delay模块传递,然后,以单位延迟模块开头,把它的输入输出分别标志为(y(n),y(n-1),u(n),u(n-1)),并建立代数关系。
图6-3
接下来需要设置初始状态和采样时间,Discrete模块库中的所有模块在使用时都应该指定采样时间,这可以通过模块对话框中的Sample time参数设置,也可以通过前级提供输入的模块明确采样时间,也就是继承前级模块的采样时间,这种情况下采样时间应设置为-1。大多数标准的Simulink模块都可以继承与模块输入相连接模块的采样时间,但Continous库中的模块和没有输入的模块(如Sources库中的模块)是个例外。另外一个有关的参数就是模块输出的初始值。
注意:Unit Delay模块将输入信号延迟一个采样时间,如果模型中包含多速率转换,那么在由慢-快转换之间必须添加Unit Delay模块,Unit Delay模块的
采样速率必须设置为较慢模块的采样速率。对于由快-慢的转换,应使用
Zero-Order Hold模块。Unit Delay模块可以接受连续信号,当模块使用连
续采样时间时,它等同于Simulink中的Memory模块。
6.2.2 指定采样时间
Simulink允许用户指定任何包含Sample time参数的模块的采样时间,用户可以在模块参数对话框中的Sample time文本框内设置采样时间。可以将采样时间指定为常数,也可以用向量的方式[T s,T o]表示采样时间,其中第一个元素表示采样时间,第二个元素表示偏差值,不同的采样时间和偏差值都有特定的含意。
表6-1概括说明了参数设置的有效值,并说明了Simulink如何对这些参数进行插值以确定模块的采样时间。
表6-1 指定采样时间
采样时间用法
[T s,T o] 0>T s [0,0],0 指定模块在每个主时间步和最小时间步进行更新,具有0采样时间的模块可以认为是具有连续采样时间的模块。 [0,1] 指定模块跳过最小时间步,只在主时间步进行更新。这样的设置对于那些在主时间步之间无法改变采样时间的模块来说,可以避免不必要的计算。只在主时间步执行的模块的采样时间称为固定的最小时间步。 [-1,0],-1 如果模块不在触发子系统内,这种设置表明模块继承了与其输入相连模块的采样时间(继承性),或者说,在某些情况下,模块继承了与其输出相连模块的采样时间(向后继承性);如果模块在触发子系统内,对于这种设置,用户还必须设置Sample time参数。 需要说明的是,如果Sources模块驱动一个以上的模块,为Sources模块指定采样时间的继承性可能使Simulink为该模块指定一个不适当的采样时间,正因为如此,用户应该避免为Sources模块指定采样时间的继承性,如果这样做了,当更新或仿真模型时,Simulink会显示一个错误消息。 注意:用户不能在仿真运行期间改变模块的Sample time参数,如果想改变模块的采样时间,必须停止仿真,并重新设置采样时间后再运行仿真,以使新 的采样时间生效。 在仿真编译阶段,Simulink依据模块的Sample time参数(如果模块有该参数)、采样时间的继承性或模块类型(Continuous模块总是具有连续采样时间)来确定模块的采样时间,这就是被编译的采样时间,它确定了仿真过程中模块的采样频率。用户可以通过先更新模型,然后用get-param命令获得模块Compiled Sample Time参数的方法来确定模型中任意模块的被编译采样时间。 Simulink根据下面的原则设置不同模块的采样时间。 Continuous模块(也就是,Integrator,Derivative,Transfer Fcn等模块)根据定义,采样时间是连续的; Constant模块根据定义,是常值; Discrete模块(也就是,Zero-Order Hold,Unit Delay,Discrete Transfer Fcn等模块)的采样时间由用户在模块对话框内指定; 所有其它模块的采样时间依其输入的采样时间来定义。例如,在Integrator模块后的Gain模块也被作为连续模块,而在Zero-Order Hold模块后的Gain模块则被作 为离散模块处理,并与Zero-Order Hold模块有相同的采样时间。 对于那些输入有不同采样时间的模块,如果所有的采样时间是最小采样时间的整数倍,那么模块的采样时间也是最小采样时间。若使用变步长算法,则模块被指定为连续采样时间;若使用定步长算法,而且可以计算出采样时间的最大公约数(即基本采样时间),则模块使用该采样时间,否则使用连续采样时间。 6.2.3 采样时间的传递Simulink中模块的采样时间可以传递给下一个模块,以图6-4中的模型为例,模型中Discrete Filter(离散滤波器)模块的采样时间为T s,它驱动Gain模块。 图6-4 由于Gain模块的输出等于输入乘以常数,因此它的输出与滤波器的输出以相同的速率改变,换言之,Gain模块的采样速率与滤波器的采样速率相等,这是Simulink中采样时间传递的基本机制。 在有些情况下,Simulink也把采样时间向后传递给源模块,但这必须在不影响仿真输出的情况下才可以。例如,在图6-5所示的模型中,Simulink认为Signal Generator模块驱动Discrete-Time Integrator模块,因此,它指定Signal Generator模块和Gain模块与Discrete-Time Integrator模块具有相同的采样时间。 图6-5 用户可以选择Simulink模型窗口中Format菜单下的Sample Time Colors命令来证明这一点,此时所有的模块均被标记为红色,由于Discrete-Time Integrator模块只在采样时刻才有输入,因此这种变化不会影响仿真结果,但的确会改善仿真性能。 现在用连续积分模块Integrator代替Discrete-Time Integrator模块,并选择模型窗口中Edit菜单下的Update diagram命令为模型重新绘色,这会使Signal Generator模块和Gain 模块变成连续模块,并重新标记为黑色,如图6-6所示。 图6-6 Simulink中的模块或者有用户明确定义的采样时间,或者继承其它模块的采样时间。例如,Simulink指定Constant模块的采样时间为无穷大(inf),也就是该模块具有常值采样时间(constant sample time),如果某些模块从Constant模块获得输入,并且不继承其它模块的采样时间,那么这些模块也具有常值采样时间,这就意味着这些模块的输出在整个仿真期间都不会改变,除非用户更改模型参数。 例如,在图6-7所示的模型中,Constant模块和Gain模块都有常值采样时间。 图6-7由于Simulink可以在仿真过程中更改模块参数,因此,所有的模块,甚至具有常值采样时间的模块都必须在模型有效的采样时刻生成输出,正因为Simulink具有这样的特性,因此,所有的模块均在每个采样时刻计算模块输出,至于纯连续系统,则是在每个仿真步上产生输出。对于那些具有常值采样时间,而且在仿真过程中不改变参数的模块,在仿真过程中求取这些模块的值是无效的,而且还会降低仿真速度。 用户可以在仿真参数对话框中的Advanced选项页内设置在线参数(inline parameters,读者可以参看第七章中7.4.2“仿真性能优化设置”中的内容)选项来删除仿真循环中所有具有常值采样时间的模块,这样做的效果是双重的。首先,在仿真过程中参数不能改变;其次,仿真速度提高了,仿真速度提高的程度取决于模型的复杂度、具有常值采样时间的模块数目,以及仿真的有效采样率。 6.2.4 确定离散系统的步长 对离散系统进行仿真时要求仿真器在每个采样时刻都增加一个仿真步,这个采样时刻就是系统最小采样时间的整数倍,否则,仿真器可能会错过系统状态的关键转换。为了避免这种错误,Simulink通过选择仿真步长来保证仿真步与采样时刻的一致性。Simulink选择的步长取决于系统的基本采样时间和仿真系统时所使用的算法类型。 离散系统的基本采样时间(fundamental sample time)是系统实际采样时间的最大整数公约数,例如,假设系统的采样时间为0.25秒和0.5秒,此时的基本采样时间为0.25秒;若采样时间为0.5秒和0.75秒,这时的基本采样时间仍为0.25秒。 用户可以让Simulink使用定步长或变步长离散求解器求解离散系统。定步长求解器设置仿真步长等于离散系统的基本采样时间;变步长求解器改变步长,以使步长大小等于实际采样时刻之间的差值。 以图6-8所示的离散系统模型为例,模型中的Sine Wave模块设置的采样时间为0.25秒。 图6-8 图6-9说明了该模型使用定步长求解器和变步长求解器时在仿真时间上的不同,图中的箭头表示各仿真步,圆圈表示各采样时刻。定步长求解器以0.25秒作为模型的时间步采样一次,这也是模型的基本采样时间,即采样的时间步为:[0.00 0.25 0.50 0.75 1.00 1.25 …];与此不同,变步长求解器只有在模型真正产生输出时才花费一个时间步的时间,即:[0.00 0.50 0.75 1.00 1.50 2.00 2.25 …],这就大大减少了仿真模型时所需要的步数,因此也就缩短了仿真时间。 变步长求解器定步长求解器 图6-9 从图6-9可以看到,如果基本采样时间小于实际被仿真系统的任何一个采样时间,变步长求解器会用较少的仿真步数仿真系统;另一方面,对于定步长求解器,如果系统的任一采样时间是基本采样时间,那么它会利用较少的内存来实现仿真,这对于需要用Simulink 模型转换为快速仿真代码的应用程序来说,可以节省大量的时间(如使用Real-Time Workshop 工具)。 例6-1 人口的动态变化 要求:这个例子通过一个非线性离散模型描述人口的动态变化。一年的人口依赖于: 前一年的人口; 人口的繁殖速率r ,这里假设r = 1.05; 资源K ,这里K = 1e6; 人口的初始值是必不可少的,假设初始值为100000; 在模型中,某一年的人口数p (n )与上一年的人口数p (n -1)成比例,因此乘上一个繁殖速率r ,但是,资源只能够满足K 个个体的需求。整个系统的动力学模型由下面的差分方程给出: )/)1(1(*)1(*)(K n p n p r n p −−−= 解答: 在建立差分方程的Simulink 模型时,可以看到,当年的人口数由上一年的人口数推导得出,因此利用一个延迟模块Unit Delay ,将p (n )输入给延迟模块,得到输出p (n -1), p (n ) 表达式包含p (n -1)项和常数项,这个系统没有输入,只需给出人口的初始值便可,这里给定初始值p (0)为100000,建立的系统模型如图6-10所示,仿真这个系统100个时间单位,在示波器内观察仿真结果,如图6-10所示。 图6-10 6.2.5 多速率系统 纯离散系统可以用任何一种求解器进行仿真,这在结果上不会有什么不同,若要只是 在采样时刻生成输出点,可以选择任何一种离散求解器。离散求解器可以是定步长和变步 长的,定步长求解器对于一个单速率系统来说是足够了,但采用变步长求解器求解多速率 系统则更有优势。 多速率系统包含以不同速率进行采样的模块,这些系统可以用离散模块建模,或者用 离散模块和连续模块建模。图6-11说明了对多速率系统使用定步长求解器和变步长求解器 在仿真时刻的不同。 在图6-11中,模块1和模块2以不同的速率进行采样,这样模型中就包含了以不同速 率采样的模块,每个实线代表一次模块更新,也就是求解器在此时刻求解一次模型状态, 并更新模型以反映模型的变化。 定步长求解器 (T s = 0.2) 变步长求解器 模块2 (T s = 0.6) 模块1 (T s = 0.4) 时间 t 图6-11 如果在仿真参数对话框内设置最大步长和最小步长为auto ,那么Simulink 会自动确定 最大步长和最小步长,如果使用定步长求解器,Simulink 选择的步长要足够小才能适应所 有的更新时刻,导致了在某些仿真步进行了不必要的计算;但是在选择变步长求解器时, Simulink 考虑到这个因素,步长调整得恰好适应两个模块的更新。如果用户不想由Simulink 自动确定仿真步长,也可以手动设置步长大小。 例如,图6-12是一个简单的多速率离散系统模型。在这个模型中,Discrete Transfer Fcn (离散传递函数)模块的Sample time 设置为[1 0.1],给定的偏差值为0.1,Discrete Transfer Fcn1模块的Sample time 设置为0.7, 没有偏差。如果用Format 菜单下的Sample time colors 命令标记采样时间,则会发现Discrete Transfer Fcn 模块被标记为绿色,Discrete Transfer Fcn1模块被标记为红色,表示这两个模块使用不同的采样时间。 图6-12 将模型保存为multirate ,现在开始仿真模型,并使用stairs 函数绘制输出曲线。 >> [t ,x ,y] = sim(‘multirate’,3); >> stairs(t ,y) 生成的结果曲线如图6-13所示。 6-13 对于Discrete Transfer Fcn 模块,该模块有0.1的偏差,因此直到t=0.1时刻模块才有 输出,由于该模块传递函数的初始条件为0,Discrete Transfer Fcn 模块的输出y(1)在t=0.1 时刻之前一直为0。 6.2.6 线性离散系统 尽管这里提出的方法可以适用于所有的离散系统,但对于一个线性时不变系统,可以 大大简化,利用Z 变换建立传递函数,Z 变换可以保持系统的线性特性。Discrete 模块库 中提供了建立线性离散系统模型时使用的Discrete Transfer Fcn 模块、 Discrete Filter 模块和Discrete Zero-Pole 模块。 1.离散传递函数 Discrete Transfer Fcn 模块主要是控制工程人员以z 多项式形式描述离散系统。 Discrete Transfer Fcn 模块实现如下标准形式的传递函数。 n n n m n m n n den z den z den z num z num z num z den z num z H ++++++==−−−L L 110110)()()( y y 这里,m +1和n +1分别是分子和分母系数的总和,num 和den 包含z 按降幂排列的分 子和分母系数,分子的阶次必须大于或等于分母的阶次。num 可以是一个向量或矩阵,但 den 必须是一个向量,两者均为模块对话框中的参数, 2.离散滤波器 Discrete Filter 模块实现IIR 和FIR 滤波器, 用户必须以z -1的降幂排列指定分子和分母系数。Discrete Filter 模块通常是信号处理人员以z -1多项式形式描述数字滤波器,当分子 系数向量与分母系数向量等长度时,离散传递函数和离散滤波器这两种方法是完全相同的。 n n m m z den z den den z num z num num z den z num z H −−−−−−−++++++==L L 110110111 )()()( 这里,m+1和n+1分别是分子和分母系数的总和,num 和den 包含z -1按升幂排列的 分子和分母系数,分子的阶次必须大于或等于分母的阶次。 3.零极点传递函数 Discrete Zero-Pole 模块实现零极点形式的离散系统,对于单输入单输出的系统,传递 函数的形式如下: ) ())(()())(()()()(2121n m P z P z P z Z z Z z Z z K z P z Z K z H −−−−−−==L L 这里,Z 是零点向量,P 是极点向量,K 是零极点增益,极点的数目必须大于等于零 点数目,即m n ≥,零点和极点可以为复数。 例6-2 离散解调器 要求:离散滤波器的差分方程如下: )2(04.0)1(08.0)(04.0)2(7.0)1(6.1)(−+−+=−+−−n u n u n u n y n y n y 利用例4-4中的AM 调幅信号作为源信号,将发射信号与离散载波信号相乘(频率 =100Hz ,采样时间=5ms),将产生的信号通过离散滤波器,在示波器上显示发射信 号和输出信号。 解答: 将离散滤波器的差分方程转换为以z -1形式表示的离散滤波器方程,如下: 212 1111 7.06.110.008.004.0)()()(−−−−−−−+−++==z z z z z den z num z H 根据系统要求,选择的Simulink 模型组件如下: -- 例4-4中的AM 调制信号 -- Sources 库中的Sine Wave 模块 -- Math Operations 库中的Product 模块 -- Discrete 库中的Discrete Filter 模块 -- Sinks 库中的Scope 模块 设置Discrete Filter 和Sine Wave 模块中的采样时间为0.005s ,也可以用Discrete Transfer Function 模块代替Discrete Filter 模块,此时离散滤波器的差分方程可以转换为z 形式的标 准离散传递函数,最后的系统模型图如图6-14所示。选择变步长ode45算法,仿真时间为 10个单位,仿真后的输出信号波形如图6-14中的示波器所示。 图6-14 6.3 连续系统仿真 连续系统的输出是连续变化的,换句话说,连续系统以无穷小的时间间隔进行更新, 绝大多数的自然过程都属于连续系统。 在连续的动态系统中,系统的数学模型表达式中都包含输入和/或输出的连续导数。 Simulink 中的积分器就是一个很好的例子,输出的导数等于输入,即u y =&,连续系统包含连续状态,在某种意义上说,连续状态是记忆元素,它们保存系统的信息,系统输出可 以直接通过它们计算,而不涉及状态导数。 6.3.1 微分方程的实现 对于大多数的连续系统,其系统方程多是由各阶导数组成的微分方程,求解微分方程 可以使用不同的积分算法。Simulink 把动态系统模型转变为“状态空间”表达式的形式供 求解器使用,而求解器则使用一种非常具体的系统表达式求解系统,这个表达式为: 离散系统 )),(),(()1(n n u n x f n x d =+→更新方程 )),(),(()(n n u n x g n y = →输出方程 更新方程利用状态前一时刻的值计算当前值,输出方程使用当前的状态值计算当前的 输出值,与先前的状态值没有关系。 连续系统 )),(),(()(t t u t x f t x c =& →导数方程 )),(),(()(t t u t x g t y = →输出方程 在连续系统中,状态的表达式包含状态的一阶导数,在大多数情况下,x 是一个向量, 它包含若干个状态。 在Simulink 中,实现微分方程的第一步是确定模型中所需要的Integrator 模块的数目, 这一点非常重要,因为积分器模块是建立微分方程的基础,一个积分器就表示一阶微分。 例如,如果方程中包含y 的二阶导数,就需要两个积分器,一个输入22/dt y d ,并且输出 dy /dt ;第二个输入dy /dt ,并且输出y 。图6-15表示的是用Simulink 中积分器模块搭建的 二阶微分,它说明了变量、变量一阶导数、变量二阶导数之间的关系。 图6-15 注意:在每个积分器模块中,应当给出状态的初始条件,由于求解器处理连续状 态的方式所决定的,不提倡使用导数模块以相反的方式建立模型方程,即 Continuous 模块库中的Derivative 模块,只有当微分方程中包含输入的导 数时才可使用导数模块,因为这时的输入是已知的。 Simulink 模型指定了模型连续状态的时间导数,但并没有给出状态自身的值,这样, 当仿真一个系统时, Simulink 求解器必须对状态的微分值进行多次积分以计算连续状态值,仿真过程中的积分是近似的,不同的连续求解器使用不同的方法近似积分。当然,目前有 各种各样的通用数值积分算法,每种算法对特定的应用也都各有优势。Simulink 使用的是 数值积分算法中最稳定、最高效,而且精度最好的ODE(常微分方程,ordinary differential equation)算法,用户可以在模型中直接指定这些算法求解器,也可以在运行仿真时指定求 解器。 有些Simulink 中的连续求解器将仿真时间区域细分为主时间步和最小时间步,最小时 间步是由主时间步再细分而成。仿真算法在每个主时间步上生成结果,并在最小时间步上 应用这些结果以改善主时间步的结果精度。 6.3.2 线性连续系统 严格说来,一个具体的物理系统通常都是非线性系统,而且是以分布参数的形式存在 的,但这样的非线性系统建立的数学模型,需要求解非线性方程和偏微分方程,这是非常 困难的,因此,如果在误差允许的范围内,可以将非线性模型线性化,或者直接用线性集 总参数模型描述物理系统。 Simulink 中的Continuous 模块库提供了适用于建立线 性连续系统的模块,包括积分器模块、传递函数模块、状 态空间模块和零-极点模块等, 这些模块为用户以不同形式建立线性连续系统模型提供了方便,如图6-16所示。 利用积分器模块用户可以建立微分方程模型,这是非 常一般的方法,也可以用来建立非线性系统模型,而且允 许指定非零值的初始条件。下面介绍线性连续系统的其它 模型方程形式。 1.传递函数表达式 传递函数仅适用于单输入-单输出的线性定常系统,是 线性系统的时域表达式,初始条件为零。 如果连续系统是线性时不变系统,可以考虑将表达式 进一步简化。对微分方程(假定初始状态为0)使用拉普拉斯变换推导出输入/输出关系,从而得出系统的传递函数表达式,拉普拉斯变换保持了模型的线性关系。 以图6-17中的弹簧-质量-阻尼器系统为例,设k 为弹簧的弹性系数,f 为阻尼系数,试建立输入为外力u (t ),输出为位移y (t )的系统方程。 图6-17 根据牛顿定律可写出系统的动态方程如下: ky dt dy f u dt y d m −−=22 利用拉普拉斯变换,弹簧-质量-阻尼器微分方程可以转化为传递函数形式: k fs ms s Y s U ++=21)()( 用户可以利用Continuous 模块库中的Transfer Fcn 模块表示传递函数,Transfer Fcn 模块实现的是如下形式的传递函数: ) ()2()1()()2()1()()()(2121m den s den s den n num s num s num s u s y s H m m n n ++++++==−−−−L L 这里,n 和m 分别是分子和分母的系数数目,num 和den 参数包含着s 按降幂排列的分子和分母系数,num 可以是向量或矩阵,den 则必须是向量,这两个参数的数值均在Transfer Fcn 模块对话框内指定,分母的阶数必须大于或等于分子的阶数,即n m ≥。 图6-16 Transfer Fcn 模块的初始条件被重置为0,如果需要指定初始条件,可以用tf2ss 命令 将模型传递函数转换为状态空间形式,然后使用State-Space 模块,tf2ss 命令为系统提供了 状态空间表达式中的A 、B 、C 和D 矩阵。 2.状态空间表达式 状态空间表达式不仅适用于单输入-单输出系统,也适用于多输入-多输出系统,这些 系统可以是线性的或非线性的,也可以是定常的或时变的,它是系统的时域表示,它允许 非零值的初始条件。 状态空间表达式由状态方程和输出方程组成。状态方程是一个一阶微分方程组,它描 述系统输入与系统内部状态变化之间的关系,即描述系统的内部行为;输出方程是一个代 数方程,它描述系统状态和输出的关系,即系统的外部行为。Continuous 模块库中的 State-Space 模块实现的是如下形式的状态空间方程: Du Cx y Bu Ax x +=+=& 这里,x 是状态向量,u 是输入向量,y 是输出向量,方程中的矩阵系数必须满足如下 条件: A 必须是n ×n 矩阵,n 是状态个数; B 必须是n ×m 矩阵,m 是输入个数; C 必须是r ×n 矩阵,r 是输出个数; D 必须是r ×m 矩阵; State-Space 模块接受一个输入,产生一个输出,输入向量的宽度由B 矩阵和D 矩阵的 列数决定,输出向量的宽度由C 矩阵和D 矩阵的行数决定。需要注意的是,这样的表达式 并不是唯一的,但总是可能的,这是表达线性系统时最常用的方法,因为它能够在得到输 入和输出的同时得到状态。在推导出的弹簧-质点-阻尼系统的表达式中,位置和速度为系 统状态,加速度不是状态,因为它的导数没有包含在表达式中。一般地,每个表达式中的 状态数量是相同的,但是每个状态不一定与一个物理量相对应。弹簧-质点-阻尼系统的状 态空间表达式为: 1222121x m k x m f m u x x x x x x x −−====&&& []u x x y u m x x m f m k x x 0011010212121+⎥⎦⎤⎢⎣⎡=⎥⎥⎦⎤⎢⎢⎣⎡+⎥⎦⎤⎢⎣⎡⎥⎥⎦⎤⎢⎢⎣⎡−−=⎥⎦⎤⎢⎣⎡&& 3.零-极点表达式 零-极点表达式与传递函数相同,Continuous 模块库中的Zero-Pole 模块实现零-极点形 式的表达式,对于MATLAB 中的单输入单输出系统,表达式形式为: ))(())2(())1(())(())2(())1(() ()()(n P s P s P s m Z s Z s Z s K s P s Z K s H −−−−−−==L L 这里,Z 表示零点向量,P 是极点向量,K 是增益,Z 可以是向量或矩阵,P 则必须是 向量,增益K 是标量或向量,它的长度等于向量Z 的行数,模型方程中的极点数目必须大 于或等于零点数目。Zero-Pole 模块的输入和输出宽度等于零点矩阵的行数。 对于一个特定的动态系统,无论是使用积分器模块、传递函数、状态空间或零-极点表 达式,在给定相同输入和相同初始条件下,系统的输出响应应该是一致的。以下面的微分 方程为例: u y dt dy dt y d =++3422 系统的传递函数形式为:341)(2++= s s s H 系统的零-极点表达式为:) 1)(3(1)(++=s s s H 系统的状态空间表达式为:[]u x x y u x x x ×+⎥⎦ ⎤⎢⎣⎡=⎥⎦⎤⎢⎣⎡+⎥⎦⎤⎢⎣⎡⎥⎦⎤⎢⎣⎡−−=0100101342121& 依据上述表达式建立的系统模型如图6-18所示,模型中还使用了控制系统工具箱中的 LTI System 模块,该模块可以用来描述连续和离散LTI 系统,可以在LTI system variable 文本框内输入传递函数、状态空间和零-极点-增益形式的系统表达式。这里给出的是系统 传递函数表达式tf (1,[1 4 3])。 运行仿真,在示波器内观察输出波形,可以看到,在初始条件为零的情况下,系统的 输出响应曲线是一致的。 非线性时域线性时域 线性频域 图6-18 例6-3 蹦极跳系统 想象一下,当你系着弹力绳从桥上跳下来时,会发生什么?这里,我们以蹦极跳作为 一个连续系统的例子。按照物理规律,自由下落的物体满足牛顿运动定律:F = ma 。在这 个系统中,假设绳子的弹性系数为k ,它的拉伸影响系统的动力响应,如果定义人站在桥 上时绳索下端的初始位置为0位置,x 为拉伸位置,那么用b (x )表示绳子的张力,这个影 响可以表示为: ⎩ ⎨⎧≤>−=000x if x if kx x b )( 设m 为物体的质量,g 是重力加速度,a 1,a 2是空气阻尼系数,则系统方程可以表示 为: x |x |a x a )x (b mg x m &&&&&21−−+= 在MATLAB 中建立这个方程的Simulink 模型,这里需要使用两个积分器,因为方程 中包含的导数的最高阶数为2,一旦x 和它的导数已经搭好,可以使用一个增益模块(Gain 模块)表示空气阻力比例系数,使用Function 模块表示空气阻力中的非线性部分。因为b (x ) 是通过门槛为0的x 条件式确定的,这里使用一个Switch 模块实现判断条件。最终的系统 Simulink 模型方块图如图6-19所示。 设起始位置为绳索的长度-30米,起始速度为0,这两个初始值在仿真参数对话框的 Workspace I/O 页内设置。未伸长时绳索的端部距地面为50米,因此,为了得到更真实的 曲线,将输出位置减去50。物体的质量为90kg ,g 为9.8m/s 2,弹性系数k 为20,a 1和a 2 均为1。 图6-19 运行这个系统,利用示波器查看输出轨迹,如图6-16所示,可以看到,跳跃者已经撞 到了地上! 例6-4 汽车动力学系统 要求:建立一个行驶控制系统,实现简单的汽车动力学系统。使用一个幅值为500、频率 为0.002Herz 的方波作为输入信号,汽车的质量为m = 1000,阻尼因子b = 20。 解答:速度动力学方程为 bv v m F +=& -- Sources库中的Signal Generator模块,设置Wave form参数为square,amplitude 参数为500,frequency参数为0.002,units设置为Herz; -- Maths Operations库中的Gain模块和Sum模块; -- Continuous库中的Integrator模块; -- Sinks库中的Scope模块; 建立的系统模型如图6-20所示,为了观察系统的动态行为,将信号发生器的周期设的足够长,这里设置仿真时间为1000个时间单位,初始条件为零,运行仿真,得到的输出速度曲线如图6-20所示。 图6-20 例6-5 通信信道 要求:实现一个信道的动态模型,输入为例4-4中的AM调制信号,在模型中加性噪声干扰,噪声方差为0.01,信号经过大小为1024的缓冲区延迟,信道的动态方程为: u y y y= + +− −& &&3 910 10 在求波器中观察输出波形,并尝试使用不同的求解器。 解答: 通信信道的动态方程转换为传递函数形式如下: 1 10 10 1 ) ( ) ( ) ( 3 2 9+ + = = − −s s s u s y s H 根据系统要求,选择的Simulink模块组件如下: -- 例4-4中的AM调制信号; -- Sources模块库中的Random Number模块,将模块对话框中的Variance方差设为 0.01,Sample time设为0.001; -- Continuous模块库中的Transport Delay模块,设置对话框中Time delay为1,Initial buffer size为1024; -- Continuous模块库中的Transfer Fcn模块; -- Sinks模块库中的Scope模块; 最后建立的系统模型如图6-21所示。在仿真参数对话内选择一种钢体求解器,这里选择变步长ode23s求解器,仿真时间为10个时间单位,得到的输出波形如图6-18所示。 图6-21 模型中使用了一个Transport Delay模块,Transport Delay模块将输入信号延迟给定的时间量值,因此可以有它来仿真时间延迟。在仿真开始时,模块输出的是初始输入(Initial input)参数值,直至仿真时间超过时间延迟(Time delay)参数值,然后在此时刻之后模块开始生成被延迟的输入。Time delay必须是非负值。 Transport Delay模块在缓存中存储输入点和仿真时间,缓存的初始大小由Initial buffer size参数指定,如果存储的点数超过了缓存的大小,Transport Delay模块会分配附加内存,Simulink会在仿真结束后显示一个消息,以标识所需要的整个缓存数目。由于分配内存会降低仿真速度,因此如果仿真速度很慢,应该重新定义这个参数值。对于较长的时间延迟,和较大的输入维数,Transport Delay模块可能会使用相当大的内存。 Transport Delay模块不能够插值离散信号,但是它在Time delay时刻返回离散值,这个模块与Discrete模块库中的Unit Delay模块不同,Unit Delay模块只在采样点延迟并保持输出值, 6.4 混合系统仿真 混合的连续离散系统由离散模块和连续模块组成,这样的系统可以使用任何一种求解器进行仿真,尽管某些求解器可能比另一些求解器更高效和精确。变步长求解器充分考虑了仿真步长与离散采样时间相匹配的问题,所以对于一个混合系统应该选择一个变步长求解器。对于大多数混合的连续离散系统,Runge-Kutta(龙格-库塔)变步长求解器ode45和ode23比其它求解器在效率和精确度上都有优越性。由于离散模块中的不连续性与采样保持相关联,因此对于混合的连续离散系统不推荐使用ode15s和ode113算法。 注意:模型窗口中Format菜单下的Sample time colors命令可以标识模型中是否存在不同的采样时间,模型中的模块和线会根据不同的采样时间标记为不 同的颜色。黑色表示连续信号,红色表示模型中最快速的采样时间,绿色 表示模型中第二快的采样时间,黄色模块表示包含有不同采样时间的信 号,如果模型中所有的采样时间都是相同的,那么所有的模块和线都会标 记为红色。信号源则用灰色显示。 混合系统在使用变步长求解器进行仿真时,步长应调整在误差容限以内,并且与离散模块的更新时间相匹配。 例6-6 多速率混合系统 图6-19是由连续模块和离散模块组成的混合系统,模型中的Unit Delay模块的采样时间设置为0.7,Unit Delay1模块的采样时间设置为1.1,这样系统就是由两种不同的采样时间组成的混合系统,当选择Format菜单下的Sample time colors命令时,模型中的模块和信号线以不同的颜色标识。 在对系统仿真时,设置仿真时间为5个时间单位,并选择变步长ode45求解器,在仿真参数对话框的Workspace I/O选项页内设置输出时间变量为t,输出变量为y1,y2,y3,运行仿真。并在MATLAB窗口使用绘图命令绘制输出结果曲线。 >> plot (t, y1,’*’, t, y2, ‘-‘, t, y3, ‘-‘) >> grid on 从图6-22中的输出曲线可以看到,标为’*’的曲线为积分器模块的输出曲线,它是连续信号,标为绿色’-’的曲线为Unit Delay模块的输出曲线,采样时间为0.7,标为红色’-’的曲线为Unit Delay1模块的输出曲线,采样时间为1.1,后两个信号都是离散数据信号。 图6-22 例6-7 行驶控制系统 要求:已知设定的速度值和测量的速度值,使用一个离散时间PID控制器建立一个汽车行驶控制器,采样时间为20毫秒,PID控制器按下列规律工作: “积分环节”:x (n) = x (n-1) + u (n) “微分环节”:d (n) = u (n) – u (n-1) 系统初始状态值为0 系统PID控制器方程为y (n) = P*u (n)+I*x (n)+D*d (n)。 试算:以正弦波信号作为PID控制器输入,查看当PID控制器中P = 1,I = 0.01,D=0时的控制器输出。 解答: 根据系统要求,选择的Simulink模型组件为: -- Discrete库中的Unit Delay模块,实现差分方程 -- Math Operations库中的Gain模块和Sum模块 -- Sources库中的Sine Wave模块 -- Sinks库中的Scope模块 这里单独建立比例、积分和微分环节,然后将它们相加组合成PID控制器,此外,在所有的Unit Delay模块中设置采样时间Sample time等于0.02,最后的系统模型如图6-23所示。 图6-23 在仿真参数对话框内设置仿真时间为200个时间单位,选择变步长ode45算法,运行仿真,打开示波器观察输出波形,如图6-23所示。 这个PID行驶控制器实际是一个混合系统。如果在这个系统模型中选择Format菜单下的Sample time colors命令,可以清楚地看到系统中不同采样时间的信号线由不同的颜色表示,但大多数信号是连续的,因为它们是由一个连续系统产生的。用户可以在Sine Wave 输入模块后放置一个Zero-Order Hold(零阶保持)模块将连续信号转换成离散信号,并设置零阶保持器的采样时间为0.02s,如图6-24所示,此时系统中的所有模块都具有相同的采样时间。 图6-24 以例4-4中的模型作为汽车行驶控制系统的输入信号,以图6-23中的模型作为系统的PID控制器,以例6-4中的模型作为汽车动力学系统,组成反馈控制系统,整个汽车行驶控制系统模型如图6-25所示。 图6-25 设置PID控制器中比例、积分、微分系数为P=1,I=0.01,D=0,仿真系统12个时间单位,系统的过程曲线如图6-26(a)所示;若设置P=5,I=0.01,D=0,系统的过程曲线如图6-26(b)所示; 图6-26(a) 图6-26(b) 6.5 模型离散化 模型离散化是数字控制器设计和硬件循环仿真中的重要环节,Simulink中的离散化操作有选择地用Simulink中的连续模块替换等效的离散模块,利用这个工具,用户可以把连续模型用在只支持离散模块的Real-Time Workshop Embedded Coder。 模型离散化,可以使用户: 标识模型中的连续模块; 将模块参数由连续改变为离散; 对模型中所有的连续模块或所选模块应用离散设置; 创建包含多个离散化成员和源连续模块的可配置子系统; 在不同的离散化成员之间切换,并求取模型仿真结果; 需要注意的是,要使用模型离散化工具,MATLAB系统中必须安装Control System Toolbox。 6.5.1 模型离散化GUI 若在对模型进行离散化,需要执行下列步骤: 1.启动模型离散化器; 2.指定转换方法; 3.指定采样时间; 4.指定离散化方法; 5.对模块进行离散化。 这里以Simulink中的f14模型为例说明模型离散化的步骤,f14模型如图6-27所示。 图6-27 1.启动模型离散化器 选择模型窗口中Tools菜单下的Model discretizer命令启动模型离散化器,Simulink 的模型离散化器窗口如图6-28所示。另外一种打开离散化器的方式就是利用MATLAB命令窗口中的slmdldiscui函数,如slmdldiscui (‘f14’)。若要从模型离散化器中打开一个新的Simulink模型或模块库,选择File菜单下的Load model命令。 图6-28 2.指定转换方法 转换方法确定了模型离散化过程中使用的算法类型,关于不同转换方法的详细内容, 读者可以参看控制系统工具箱中的有关内容。 转换方法(Transform method)下拉列表中包含如下选项,如图6-29所示。 zero-order hold 对输入的零阶保持,通过将被采样的输入信号保持一个采样时间而产生连续时间信 号。 first-order hold 输入的线性插值,为了将被采样的输入信号转换为连 续信号,在两个采样点之间进行线性插值,这种方法 对平滑输入的系统来说,比零阶保持法更精确。 tustin Tustin 法或者说双线性近似法使用下列近似来描述s-域或z-域的传递函数。 2/12/1s s sT sT sT e z s −+≈=,1 12+−=′z z T s s tustin with prewarping 与Tustin 方法不同,近似公式如下,这种近似法在频率ω处确保连续时间与离散时 间的频率响应更匹配。 1 1)2/tan(+−ωω=′z z T s s matched pole-zero 零极点匹配法,只适用于SISO 系统,转换公式如下: s sT e z = 3.指定采样时间 在Sample time 文本框内输入采样时间。用户可以为离散模块或可配置子系统输入两 元素向量来指定偏差值,第一个元素是采样时间,第二个元素是偏差值。例如,[1.0 0.1] 表示采样时间为1.0s ,带有0.1s 的偏差,如果未指定偏差,则缺省值为0。 4. 指定离散化方法 在Replace current selection with 列表中选择一种离散化方法,如图6-30所示,这些 选项包括: Discrete blocks (Enter parameters in s-domain) 创建一个离散模块,模块参数保留对应连续模块的 参数。采样时间和离散化参数也保存在模块参数对 话框中。 图 6-29 图6-30 模块在执行时作为一个被封装的离散模块处理,在封装初始化代码中用c2d 命令把 连续参数转换为离散参数,关于封装的详细内容,读者可以参看第10章。 图6-31(a)是连续的Transfer Function 模块,图6-31(b)是在s-域中被离散化后的 Transfer Function 模块,每个模块的模块参数对话框也显示如下。 图6-31(a) 图6-31(b) Discrete blocks (Enter parameters in z-domain) 创建一个离散模块,模块参数是由用户直接输入到模块参数对话框中的值。如果需 要,模型离散化器会使用c2d 函数获取被离散化的参数。 图6-32(a)是连续的Transfer Function 模块,图6-32(b)是在z-域中被离散化后的 Transfer Function 模块,每个模块的模块参数对话框也显示如下。 图6-32(a) 图6-32(b) 注意:如果想要在模型离散化操作之后准确恢复源连续参数值,应该在s-域中输 入参数。 Configurable subsystem (Enter parameters in s-domain) 使用s-域值为当前的选择创建多个离散化成员, 一个可配置子系统可以由一个或多个模块组成。 Configurable subsystem (Enter parameters in z-domain) 使用z-域值为当前的选择创建多个离散化成员,一个可配置子系统可以由一个或多个模块组成。 选择这个选项后会激活Location for block in configurable subsystem选项,用户可以利用这个选项创建一个新的可配置子系统或者覆盖一个已存在的可配置子系统。 注意:对于后两个选项,为了在库中保存可配置子系统,当前目录必须是可写的。 可配置子系统被存储在库中,这些库包含离散化成员和源连续模块,库被命名为 如果从相同的模型中创建了多个库,那么文件名会依次加1。例如,从f14模型中创建的第二个可配置子系统的库被命名为f14_disc_lib2。 用户可以在Simulink模型中用鼠标右键单击子系统打开可配置子系统库,并从弹出菜单中选择Link options->Go to library block命令。 5. 对模块进行离散化 若要离散化模块,有两种方法: 一是选择模块,并离散化。在模型离散化器的树浏览面板中选择一个或多个模块,若要选择多个模块,在选择模块的同时按下键盘中的Ctrl键。如果只选择了一个模块,在模型离散化器的Discretize菜单中选择Discretize current block命令;如果选择了多个模块,选择Discretize菜单下的Discretize selected blocks命令。此外,用户也可以单击“离散化”按钮离散化当前模块。 二是保存离散化设置并将设置应用到模型中的所选模块。首先为当前模块输入离散化 设置,然后单击“保存设置”按钮,这会将已进行离散化设置的当前模块添加到预设置的模块组中,对其它模块重复这个过程,最后选择Discretize菜单下的Discretize preset blocks命令。 若要离散化已连接到库中的模块,有两种方法:一是必须在库中离散化模块,用户可以选择File菜单下的Load model命令从模型离散化器中打开库;二是在模型窗口中关闭库连接,用鼠标右键单击模块,从弹出菜单中选择Link options->Disable link关闭库连接。 6. 从可配置子系统中删除离散化成员 若要从可配置子系统中删除离散化成员,在Location for block in configurable subsystem 列表中选择这个成员,然后单击“删除”按钮。若要取消离散化操作,单击 “取消离散化”按钮,也可以选择Discretize菜单下的Undo discretization命令。 6.5.2 查看离散化模型 模型离散化器按层级树排列显示模型,如图6-33中的f14模型所示,在树浏览面板中,当模型中的模块被离散化后,模块图标被高亮显示,并标记有符号“z”。图中显示的是被离散化到可配置子系统中的Aircraft Dynamics Model子系统,这个可配置子系统共有三个离散化成员,f14模型中的其它模块还没有被离散化。 图6-33 图6-34 图6-34显示的是f14模型中的Aircraft Dynamics Model子系统被离散化到可配置子系统,这个可配置子系统包含源连续模型和三个离散化成员。 图6-35显示的是包含Aircraft Dynamics Model可配置子系统的库f14_disc_lib,这个可配置子系统包含源连续模型和三个离散化成员。 图6-35 如果模型改变,可以单击“刷新”按钮刷新模型离散化器的树状浏览面板,或者选择View菜单下的Refresh命令。 6.5.3 从Simulik模型中离散化模块 用户可以用Discretizing库中在s-域内被离散化的等价模块替换Simulink模型中的连续模块,下面以f14模型中的Aircraft Dynamics Model子系统为例,说明如何用Discretizing 库中的被离散化的Transfer Fcn模块替换子系统中的连续Transfer Fcn模块,这个模块使用zero-order hold转换方法,采样时间为2s,在s-域内被离散化。 1.首先打开f14模型。 2.在f14模型中打开Aircraft Dynamics Model子系统,如图6-36所示。 3.在MATLAB命令行中输出discretizing命令打开Library:discretizing窗口,如图6-37所示,这个库包含了Simulink中s-域的被离散化模块。 图6-36 图6-37 4.向Aircraft Dynamics Model子系统窗口中添加Discretized Transfer Fcn模块,打开Aircraft Dynamics Model子系统窗口中的Fransfer fcn1模块的参数对话框,如图6-38所示,再打开被添加的Discretized Transfer Fcn模块的参数对话框,如图6-39所示。 图6-38 图6-39 5.将Fransfer fcn1模块参数对话框中的参数值拷贝到Discretized Transfer Fcn模块参数对话框内,并设置Sample time为2,从Method下拉列表中选择zoh(zero-hold)选项,最后的Discretized Transfer Fcn模块参数对话框如图6-40所示。 6.用Discretized Transfer Fcn模块替换Aircraft Dynamics Model子系统中的Fransfer fcn1模块,最终的Aircraft Dynamics Model子系统模型如图6-41所示。 图6-40 图6-416.6 诊断仿真错误 如果在仿真过程中产生错误,Simulink会终止仿真,如果需要的话,它还会打开产生错误的子系统,并在Simulation Diagnostics Viewer(仿真诊断查看器)中显示这个错误,这一部分介绍如何利用查看器确定产生仿真错误的原因。 6.6.1 仿真诊断查看器 如果模型在仿真过程中有错误产生,Simulink在终止仿真的同时会打开仿真诊断查看器,如图6-42所示,这是在仿真Simulink演示程序“F14”模型时产生的错误,从图中可以看到,错误诊断查看器由两部分组成,上半部是错误摘要列表,详细列出模型仿真过程中出现的所有错误条目;下半部是错误消息说明,单击说明中蓝色的超链接区域可以链接到模型中产生错误的具体位置。 图6-42 1.错误摘要 错误摘要列表列出了造成Simulink终止仿真的所有错误,每条错误都包含并显示了如下信息: Message:显示消息类型,例如,Block error(模块错误)、Warning(警告)或Log(记录)等。 Reported by:报告产生错误的组件,例如,Simulink、Stateflow、Real-Time Workshop 等。 Source:产生错误的模型元素名称,例如,模块名称。 Summary:错误消息,对错误类型的简短描述,可以拉伸对话框查看完整的信息内容。 上面的信息条目在查看器的View菜单下都有相应的命令,若要删除某个错误信息,可以选择View菜单下的相应命令。 2.错误消息 仿真诊断查看器的下半部分显示的是对应于错误摘要列表中所选错误的简要说明,即Summary中的内容,但该说明中对产生错误的模型元素添加了超链接,用户可以单击链接部分直接在模型中显示产生错误的元素。 例如,图6-43是一个系统模型,当运行仿真时,Simulink在模型产生错误时终止了仿真,在打开错误诊断查看器显示仿真错误消息的同时,还高亮显示了产生错误的Integrator 模块。 图6-43 6.6.2 创建用户仿真错误消息 Simulink的仿真诊断查看器显示了仿真运行期间MATLAB错误函数的所有错误输出,包括模块或模型的回调函数以及用户创建的S函数等,当然,用户也可以在回调函数和S 函数中使用MATLAB错误函数或在MATLAB的Function模块中自己创建应用程序特定的仿真错误消息。 例如,图6-44的模型中包含了一个用户定义的MATLAB Fcn模块。 图6-44 MATLAB Fcn模块执行如下函数: function y = check_signal (x) x<0 if error ('Signal is negative.'); else y = x; end 当仿真这个模型时,如果用户设置x值小于0,Simulink会在Simulation Diagnostic Viewer对话框中显示错误消息,并在对话框内添加用户标注的 ‘Signal is negative’错误,如图6-45所示。 图6-45 此外,在创建用户错误消息时,用户也可以创建返回到模型中模块或文本文件以及文 件路径的超链接,这只需要在错误消息中用双引号包含相应的模块名称、路径或目录名即 可,如: error ('Error evaluating parameter in block "check_signal" ') 在错误消息中显示当前模型中模块check_signal 的文本超链接,单击这个超链接会在 模型窗口中显示这个模块,如图6-46所示。 图6-46 error ('Error reading data from "C :/work/test.data" ') 在错误消息中显示到文件test.data 的文本超链接,单击这个链接可以在用户选择的 MATLAB 编辑器内显示这个文件。 error ('Could not find data in directory "C :/work" ') 在错误消息中显示到目录C :/work 的超链接,单击这个链接会打开一个系统命令窗口, 并设置其工作目录为C :/work 。 注意:只有当模型中包含相应的模块,或者用户系统中存在相应的文件或目录时, 文本超链接才会起作用。 6.7 改善仿真性能和精度 对于系统模型来说,模型仿真时的性能和精度受很多因素的影响,包括模型的设计方 案,仿真算法和仿真参数的选取等。 选择了Simulink 中的仿真算法,并使用缺省的参数值进行仿真时,对于大多数模型都 6.7.1 提高仿真速度 影响仿真速度的因素很多,这里给出了减慢仿真速度的一些原因,用户可以根据自己的模型试试改变某些设置,也许可以改进模型的仿真性能。 模型中包括了MATLAB Fcn模块。当模型中包含了MATLAB Fcn模块时,在仿真的每个时间步上,Simulink都会调用MATLAB解释器,这样就大大减慢了仿真速度,因此,只要有可能,可以使用内嵌的Fcn模块或Math Function模块,而避免使用MATLAB Fcn模块。 模型中包含一个M文件的S函数。M文件的S函数也会使Simulink在每个时间步上调用MATLAB解释器,可以考虑把S函数转换为子系统或者转换为C-MEX文件的S函数。 模型中包含了Memory模块。使用Memory模块可以使变阶算法(如ode15s和ode113)在每个时间步上重新设置为1阶算法。 最大步长太小了。如果改变最大步长,试试用缺省值(auto)重新进行仿真。 有可能对精度要求过高。对于大多数模型,缺省的相对误差(0.1%)都足以满足模型精度。但对于那些状态改变到零的模型,如果绝对误差参数太小,模型围绕着那些接近于零的状态值进行仿真,有可能会延长仿真时间。 仿真时间范围可能太长。改变的办法就是减小仿真时间。 模型可能是钢体模型,但却使用了非钢体算法,试试使用ode15s算法。 模型使用的采样时间彼此都不是倍数关系。混合彼此都不是倍数关系的采样时间,令算法使用足够小的步长,以满足模型中各模块的采样时间。 模型中包含代数循环。代数环造成的结果就是在每个时间步上都进行迭代计算,这就大大降低了仿真性能。 模型中将Random Number模块的输出传递给了Integrator模块,对于连续系统,可以使用Sources库中的Band-Limited White Noise模块。 6.7.2 改善仿真精度 若要检查模型的仿真精度,先在一段合理的时间范围内运行一次仿真,然后,或者把相对误差减小到1e-4(缺省时为1e-3),或者减小绝对误差,再重新运行一次仿真,比较这两次的仿真结果。如果仿真结果没有明显的差异,用户可以确信这个仿真结果是收敛的。 如果模型仿真在初始时刻就错过了模型中的某些重要动作,减小初始步长,以保证仿真过程不会越过这些重要动作。 如果仿真结果在一段时间内不稳定,有可能是因为: 系统本身可能就是不稳定的; 第6章 Simulink动态系统仿真 141 如果用户使用了ode15s算法,可能需要把最高阶数到2,或者试试使用ode23s 算法。 如果仿真结果看起来不够精确,有可能是因为: 对于状态值趋近于零的模型,如果绝对误差参数太大,那么在接近于零状态值的区 域附近,系统仿真不需要花费太多时间,因此,可以减小这个参数值,或者在Integrator 对话框内,为某个状态调整参数值。 如果减小绝对误差仍然无法有效地改进仿真精度,可以把相对误差参数的大小减小 到容许误差,并使用更小的仿真步长。