Simulink仿真入门到精通(二) Simulink模块
2.1 Simulink模块的组成要素
用户构建系统模型时无需直接面对成千上万行的代码,而是通过模块化图形界面以模块化的方式构建,能够使理解变得容易,让大脑减负。通过层次化模块分布将系统功能模块化,而将每个功能的细节隐藏在模块内部。
模块的构成元素
- 输入/输出端口:作为模块之间传递数据的纽带,连接输入信号和输出信号。
- 模块外观:通常为矩形或圆形,上面带有说明文字或图像并显示有输出/输出端口名。
- 模块对话框:双击模块外观后弹出的参数GUI,可以在参数控件上进行参数设置。
Ctrl+R顺时针旋转90°
模块的属性及参数
- gcb:获取当前被选中的模块
- gcbh:获取当前被选中的模块的句柄
- get(handle):获取模块的属性信息
- inspect(handle):通过属性观察器方式罗列模块的属性信息
- get_param(block,prop_string):获取block模块的prop_string属性值
- set_param(block,prop_string,prop_value):将block模块的prop_string属性的值设为prop_value。prop_string,prop_value可以多对出现
>> new_system('mymodel') >> open_system('mymodel') >> gcb ans = 'mymodel/Constant' >> get(gcbh) Path: 'mymodel' Name: 'Constant' Tag: '' Description: '' Type: 'block' Parent: 'mymodel' Handle: 1.8170e+03 HiliteAncestors: 'none' RequirementInfo: '' FontName: 'auto' FontSize: -1 FontWeight: 'auto' FontAngle: 'auto' Selected: 'on' MaskType: ''
......
常用属性列表
属性名 | 作用说明 |
Path | 模块在模型中的路径 |
Name | 模块的名字 |
ShowName | 模块的名字是否显示出来 |
BlockType | 模块的类型名 |
Handle | 模块的句柄,double数据表示 |
Position | 模块的边框在当前模型中的位置 |
ForegroundColor | 模块的前景色 |
BackgroundColor | 模块的背景色 |
Sample Time | 模块的采样时间 |
FontAngle | 字体斜度 |
FontName | 字体名 |
FontSize | 字体大小 |
FontWeight | 字体粗度 |
...... |
>> set_param(gcbh,'BackgroundColor','yellow') >> set_param(gcbh,'ForegroundColor','red')
set_param/get_param的第二个参数使用的不是提示标签,而是参数的变量名。
提示标签 | 参数的变量名 |
Constant value | Value |
Interpret vector parameters as 1-D |
VectorParams1D |
Sampling mode | SamplingMode |
Sample time | SampleTime |
常数模块、加减乘除四则运算和增益模块及输入输出端口都拥有Signal Attributes属性配置界面。
Output minimum和Output maximum中默认为空,不对数据输出进行任何检测。一旦设置了数值,模块就会对输出值进行检查,当数值小于Output minimum或者大于Output maximum时就会报错来提醒用户。
Output data type对输出数据的类型提供了一些选项。
模块的注解
右击模块选择Properties选项(以Integrator为例),双击以%<>标示的变量,可以将其转入右边的编辑框中,从而以悬浮文字的方式显示到模型中去。
合理使用模块注解功能能够增强模块的可读性,使得所建立的模型更容易被理解。
2.2 Simulink常用模块库
这些模块不仅存在于Commonly Used Blocks子库中,也分别存在于各自所属的类别库中,它们被集中在Commonly Used Blocks子库中是为了方便用户使用,建模时可以免去从各个分类库繁多的模块中搜寻这些常用模块的繁琐。
2.2.1 输入/输出模块
In
当它存在于子系统模型中时,将为子系统模型增加一个输入端口,是连接上层模型与当前层次模型的接口,将父层模型的信号传递到当前层次模型中来。
当子系统中存在In模块时,子系统模块框图将按照In模块的编号生成端口。
当将Workspace的数据导入模型时,对没有对应数据点的采样时刻进行线性插值的开关选项。
数据导入需要In模块结合Configuration Parameter版面中提供的数Data Import/Export功能共同实现。
注意t是表示时间的列向量。
>> t=[1:0.1:5]'; >> u=sin(3*t);
Out
当它存在于子系统模型中时,为子系统增加一个输出端口,是连接上层模型与当前层次模型的桥梁,将当前层次模型的信号传递到父层模型中去。
2.2.2 常数模块
常数模块在仿真过程中通常输出恒定的数值。
常数模块不仅支持scalar数据作为参数输入,也支持向量、矩阵等多维数据。
2.2.3 波形显示模块
Scope是模型中的示波器,能够显示模型中的信号波形。
可以连接任何类型的实数信号线,不支持复数。
输入端口数,默认值为1,表示仅有一个输入端口,当输入其他正整数N时可以产生对应个数的输入端口。
Structure With Time将Scope获取到的采样信号存储在结构体中,这个结构体包括:
- 存储时间序列的time
- 存储对应采样时间点的采样数据以及相关信息的结构体signals
- 存储模块全路径及名字的变量blockName
signals本身也是一个结构体,访问采样数据的方式是ScopeData.signals.values,采样数据按列排布。
plot(ScopeData.time,ScopeData.signals.values)
Structure存储类型少了time这个时间序列的存储,其他成员相同。
Array为列向量方式存储。
右击图形界面,选择style,可以设置显示风格
右击图形界面,选择Print Display to Figure,可以将波形输出到图窗显示
2.2.4 四则运算模块
Sum
推荐用法:当Sum模块的输入都是同一个时刻的输入时,采用矩形图标;当输入有来自输出的延时反馈时,采用圆形图标。
Product
Multiplication提供两种乘法,Element-wise表示点乘,Matrix表示矩阵乘法。
Divide
Gain
支持标量、向量或矩阵形式的增益。
2.2.5 延时模块
Delay
Delay length和Initial condition分别表示延时的采样点数和输出的初始值。
模块总的延时时间由延时的采样点数和模块采样时间间隔共同决定。
例如,Delay length为3,Sample time设置为0.6,则模块的输出将在1.8s时开始更新,在0~1.8s之间,模块的输出值由Initial condition中指定的初始值决定。
Source中Dialog表示参数在对话框里输入,Input port表示增加一个输入端口,通过信号线传递参数。
External reset选择None以外的选项时为Delay增加一个输入端口,通过此端口的输入信号达到某种条件而将Delay模块的输出值复位,所谓复位即Delay模块的状态值恢复初始状态值。
Level hold表示当前采样时刻的值非零时即复位。Level则包含了Level hold的情况,另外还包括信号从非零跳变到零的采样点。
Input processing包括Element as channels(基于采样)和Columns as channels(基于帧)以及Inherited3个选项,基于采样和基于帧的采样方式区别在于采样数据的组织方式。
勾选Use circular buffer for state选项时,将使用环形缓存存储仿真或代码生成时使用的状态变量,当Delay length值比较大时,勾选此选项有助于提高执行效率。
Unit Delay
是Delay模块的一个特例,即只延时一个采样时间,其参数对话框比较简单,不需要设置Delay length,不需要考虑缓存区使用环形或线性区域,没有复位功能。
设计示例:十进制累加计数器
2.2.6 关系操作模块
9种关系操作符
启用过零检测功能
2.2.7逻辑运算模块
7种逻辑操作
与(AND)、或(OR)、非(NAND)、或非(NOR)、异或(XOR)、异或非(NXOR)、非(NOT)
Icon shape用于选择模块图标的形状。选择rectangular时,模块形状不变,只是在框图中央显示当前所选择的逻辑操作。
选择distinctive时,模块会以IEEE图像符号标准所规定的形式展现出来。
有了逻辑运算模块,Simulink就可以进行数字门电路的逻辑仿真。
2.2.8 Switch模块
Switch模块是一个选择开关模块,可根据判断条件选择多个输入端口中的某个进行输出。
若由第2个端口决定的判断条件为真,则输出口输出第1个端口的信号;否则输出第3个端口的信号。
多路选择:
2.2.9 积分模块
Integrator
External reset:增加一个输入端口,通过外部输入信号的电平或脉冲上下沿进行状态变量的复位。
Initial condition source:初始值的获取方式选择。
Initial condition:模块的初始值。
Limit output:勾选时对输出值的上下限进行限定。
Show saturation port:使能饱和输出端口。1表示输出值超出上限但被上限饱和值限制住,0表示上下限均未达到,-1表示超出下限但被下限饱和值限制住。
Show state port:使能状态输出端口。用于消除代数环。
示例:
示例:求解微分方程
y''(t)+5y'(t)+6y(t)=2x'(t)+8x(t)
x(t)=exp(-t)×u(t)
y(0-)=5,y'(0-)=-4
Discrete-Time Integrator
离散积分模块
Integrator method提供了3中算法和2种工作模式。
- Integration模式下Ts表示采样时间间隔
- Accumulation模式下Ts被固定为1
- Forward Euler:y(n)=t(n-1)+K×Ts×u(n-1),并非直接馈入,输入输出信号之间存在延时
- Backward Euler:y(n)=t(n-1)+K×Ts×u(n),直接馈入
- Trapezoidal:y(n)=t(n-1)+K×Ts×[u(n-1)+u(n)]/2,直接馈入
2.2.10 限幅模块
示例:半波整流
2.2.11 接地模块
此模块没有参数,用于避免仿真时某些模块出现输入端口未连接的警告。
2.2.12 终止模块
用来接收未使用的输出信号。
2.2.13 信号合并与分解模块
Mux模块是一个虚拟模块,虽然视觉上将多个信号合并为一个信号,但是实际上并没有改变其内部数据结构,只是视觉上看起来简洁并且可以同一管理。
在仿真模型中,往往可以使用Mux模块将多个信号汇聚之后显示到同一个scope的同一个坐标系中,这样scope就不需要提供多个输入输出端口了。
Demux模块能将多维信号分解为单维或维数较少的多维信号。
2.2.14 总线创建与总线选择模块
Bus creator模块将输入的一系列信号合并为一个总线。
当Output data type选择为Bus:<object name>,勾选Output as nunvirtual bus时,表示输出信号是非虚拟信号,在C代码生成时将输出总线信号定义为结构体。
a=Simulink.Bus; a.DataScope='Exported'; a1=Simulink.BusElement; a2=Simulink.BusElement; a1.Name='a1'; a2.Name='a2'; a.Elements=[a1,a2];
#ifndef RTW_HEADER_a_h_ #define RTW_HEADER_a_h_ #include "rtwtypes.h" typedef struct { real_T a1; real_T a2; } a; #endif /* RTW_HEADER_a_h_ */
Bus Selector可从总线中选择出一个或一组成员,这个总线信号可来自于Bus Creator、Bus Selector或其他输出Bus object的模块。
2.2.15 向量连接模块
有两种模式:向量和矩阵
向量模式下,使用方式类似于Mux模块,使用时需注意不同朝向下模块输入端口的排列顺序是从左到右、从上到下。
矩阵模式下则多出一个参数,Concatenate dimension设置矩阵合并所用的维数。
1表示输入矩阵列数相同,按照竖直方向合并;2表示矩阵行数相同,按照水平方向合并。
2.2.16 数据类型转换模块
Simulink支持多种数据类型,包括浮点数、固定点数及枚举型数据等,当前一个模块的输出信号与后面的模块的输入端口支持的数据类型不一致时,Simulink将会报错。这时使用数据类型转换模块Data Type Conversion进行数据转换以使模型能够顺利通过仿真并生成代码。
fixdt是MATLAB提供的函数,能够返回simulink.NumericType类型的变量,通过这个变量来描述一种固定数据类型。使用固定点数据类型配置的模型生成的代码相对于浮点数据类型占用较少的内存空间,并能够以更快的速度运行。
固定点数据类型:
- 符号:首位1或0表示有符号或无符号
- 字长:存储单元由多少位二进制构成
- 表示小数的数据位,字长范围内的一部分或全部数据用来表示数的小数部分,这部分数据位于数据的最右端
例如:将数字-2.75表示为一个有符号,字长为8,小数部分使用3位的数据,这个数据类型就可以描述为fixdt(1,8,3)。
Input and output to have equal参数是Data Type Conversion模块独有的参数,表示当输入数据是固定点数据类型时模块处理的方式选择。
Real World Value和Stored Integer分别表示实际值与存储值。RWV会按照所选择的数值进行等值转换,SI直接在8为二进制前补8个1以保证数据达到16位。
2.2.17 子系统模块
子系统就是将一些基本模块及其信号连线组合成一个大的模块,屏蔽其内部结构,仅仅将输入输出个数表现在外的层次性划分。利用子系统有如下优点:
- 可以减少模型窗口中显示的模块数目,使模型外观结构更清晰,增强了模型的可读性。
- 在简化模型外观结构图的基础上,保持了各模块之间的函数关系,使得特定功能 的模块可以拥有一些独立的属性。
- 可以建立层次方框图。
这是一个虚拟模块。
用户可以通过修改In和Out模块的名字达到修改子系统端口名的目的。
2.3 Commonly Used Blocks以外的常用模块
2.3.1 信号源模块
Step
Step time:信号产生阶跃变化的时刻。
Initial value:信号阶跃时刻之前的值。
Final value:信号阶跃时刻之后的值。
Step模块虽然只有一个输出口,勾选Interpret vector as 1-D之后却可以输出多维信号。
此时上面3个参数按照向量方式填写。
周期信号模块
仅有一个输出端口,并将仿真波形显示在模块图标上。
Time values:输入时间序列的采样点,Simulink以此输入作为单元进行周期性延伸赋值。
Output Values:输入对应于Time values时间采样序列的值序列。
Time values里设置的时间序列的跨度(末值减首值)即为波形的周期T。
除了直接输入数值外,在参数对话框里直接输入M代码,即可方便的产生波形信号。
Clock
输出仿真时间
也可以作为一些函数的输入以产生不同的信号源。
正弦信号发生模块
From Workspace
Simin的数据类型可以有:
- 时间序列Timeseries对象。
- 二维矩阵,第一列为仿真采样时间,其余每列为对应采样时刻的信号值。
- 结构体类型,可以包含仿真采样时间序列作为其成员变量,也可以不包含。
>> ts=timeseries(sin([0:0.1:10]),[0:0.1:10]) timeseries 常见属性: Name: 'unnamed' Time: [101x1 double] TimeInfo: [1x1 tsdata.timemetadata] Data: [1x1x101 double] DataInfo: [1x1 tsdata.datametadata]
matrx=zeros(size(repmat([0:0.1:10]',[1 3]))); matrx(:,1)=[0:0.1:10]'; matrx(:,2)=cos([0:0.1:10])'; matrx(:,3)=sin([0:0.1:10])';
struc=struct('time',[0:0.1:10]','signals', ... struct('values',sin([0:0.1:10]'),'dimension',length([0:0.1:10])));
Interpolate data:当某些信号在一些采样时刻点没有对应的采样数据时,是否根据线性插值计算出这个时刻的信号值。当勾选此选项时进行线性插值,否则延用前一个采样时刻的信号值。
From output after final data value by:当模型仿真时间超出From workspace提供的数据的时间范围时,如何对提供的采样时间范围外的信号进行插值预测或默认值输出。
- Extrapolation:外部插值
- Setting to zero:保持0输出
- Holding final value:输出最后一个值
- Cylic repetition:周期循环输出
From file
要求mat文件是MATLAB timeseries object或者矩阵2中数据格式中的一种。
matrx=matrx';
save matrx.mat matrx
2.3.2 信号接收模块
Display
Decimation:表示模块数值更新的频率,所填数字表示每隔几个采样点更新一次模块的数值显示。
Floating display:勾选则将此模块作为浮动显示模块,它将显示被鼠标选中的信号线的值。使用时需要先选中某信号线,再进行仿真。
To workspace
能够在仿真结束时将仿真数据直接存储到MATLAB工作空间中。
输出数据有时间序列、矩阵或结构体类型。
Limit data points to last:设置保存的采样点数,默认值inf表示仿真的数据全部保存。
Decimation:每隔多少个仿真采样点保存一个点到simout中,默认为1即全部保存。
Log fixed-point data as a fi object:勾选以将固定点数据类型作为一个fi对象保存,不勾选将作为double型保存。
To file
Stop Simulation
该模块没有参数,只有一个输入端口,一旦接收非零信号就停止仿真。
示例:检测5个方波上升沿之后停止仿真
检测方波的策略是当前时刻的值为1,上一个采样时刻的值为0,可认为上升沿到来,通过Sum与Delay模块构成的计数器计数。
计数器值与5比较,相等逻辑输出线连接到Stop Simulation模块。通过示波器观察方波、计数器输出和Stop3路信号。
2.3.3 查表模块
所谓查表,就是说目标位一个填满数据的向量或矩阵表格,根据对应维数的输入能够在表中定位一个对应的输出。
1-D Lookup Table
Number of table dimensions:设置查找表维数,可以通过下拉框选择1~4的维数,或者输入1~30的维数。
Table data:查找把表的数值。
Breakpoints 1:查找表第一维输入向量,必须按照从下到大严格单调递增。
Edit table and breakpoints:按下次按钮可以在表格里编辑查找表输入及内容。
Interpolat:
- Flat:使用输入值和相邻两个breakpoint中较小的一个。
- Linear:线性插值法。
- Cubic spline:三次样条插值方法。
Extrapolation:
- Clip:使用breakpoint端点值。
- Linear:线性插值法。
- Cubic spline:三次样条插值方法。
示例:256长度正弦查找表
n-D Lookup Table
2.3.4 其他常用模块
数学函数模块
下拉列表框选项 | 功能 |
exp | 指数计算 |
log | 自然对数计算 |
10^u | 底数为10的指数计算 |
log10 | 底数为10的对数计算 |
magnitude^2 | 赋值/绝对值的平方 |
square | 平方计算 |
pow | u的v此方(2个输入端口) |
conj | 复数共轭计算 |
reciprocal | 倒数计算 |
hypot | 直角三角形边长计算,sqrt(u^2+v^2) |
rem | 求余数计算 |
mod | 求模 |
transpose | 矩阵转置计算 |
hermitian | 复数共轭转置计算 |
matlab的rem()和mod()函数
rem(x,y):求整除x/y的余数
mod(x,y):求模
rem(x,y)=x-y.*fix(x./y); (fix()向0取整)
mod(x,y)=x-y.*floor(x./y); (floor()向左取整,以数抽为准,朝负无穷方向取整)
如果x和y的符号相同(同为‘+’,同为‘-’),那么rem(x,y)=mod(x,y)
当正数与负数取余时,当得到的余数结果的符号希望跟除数(x)一样,用rem()函数;当得到的余数结果的符号希望跟被除数(y)一样,用mod()函数
随机数模块
随机数模块是一个信号源模块,可以产生正态分布的随机信号
Mean:产生随机数序列的均值。
Variance:产生随机数序列的方差。
Seed:用于产生随机数序列的种子,可以是0或正整数,根据种子可以产生周期性的伪随机数。保持参数不变,可以在多次仿真中保持同样的输出结果。
示例:对带有噪声的正弦信号进行滤波
传递函数模块
传递函数是描述线性系统动态特性的基本数学工具之一,经典控制理论的主要研究方法——频率相应法和根轨迹法都是建立在传递函数的基础之上。
Numerator coefficients:传递函数的分子向量。
Denomibator coefficients:传递函数的分母向量。
2.3.5 用户自定义模块
用户可以使用M语言或C语言根据Simulink运行原理编写拥有自定义功能的模块。
Fcn
可输入abs、acso、asin、atan、atan2、ceil、cos、cosh、exp、fabs、floor、hypot、ln、log、log10、pow、power、rem、sgn、sin、sinh、sqrt、tan、tanh组合的函数表达式,输入信号用u表示。当输入信号为多维时,从上到下输入信号的每个维的元素一次用u(1)、u(2)、…表示。
MATLAB Function
双击该模块,可以打开一个M代码编辑窗,它支持的MATLAB内建函数比Fun要广泛很多。
根据Simulink运行机制,每个采样点会调用一次MATLAB Function的函数,两次调用之间,同一个变量的两次计算的终值如何传递到当前计算周期是一个问题。
使用persistent变量可以处理这一问题。
function y = fcn(u) persistent sum_val; if isempty(sum_val) sum_val=0; end sum_val=sum_val+u; y=sum_val;
persistent变量时定义在某个函数内的变量类型,可在函数调用的不同次数间保持上一次退出该函数的值。它同global全局变量的类似之处在于MATLAB为他们创建永久数据区域,不同之处在于它只能被声明它的函数内部识别,目的是免除 此类变量被其他函数或命令修改值而造成用户无法确保其值得困扰。
声明persistent变量时它刚被创建,其内容为空值[ ]。
使用persistent变量需要注意:
- persistent变量不能作为函数的输入输出参数,否则会报错。
- persistent变量不能同当前工作空间中已经存在的变量同名,否则会报错。
- persistent变量不能声明在Command Window中,只能在函数中声明。
示例:自定义3-D绘图函数
function scope_3d(u) % #codegen eml.extrinsic('plot3','scatter3','close','delete'); len=length(u); persistent data; if isempty(data) data=zeros(3,100000); end persistent n; if isempty(n) n=1; else n=n+1; end data(:,n)=u; persistent h; if isempty(h) h=plot3(data(1,1:n),data(2,1:n),data(3,1:n),'o'); else delete(h); h=plot3(data(1,1:n),data(2,1:n),data(3,1:n),'o'); end