本节书摘来自华章出版社《信息物理融合系统(CPS)设计、建模与仿真——基于 Ptolemy II 平台》一书中的第2章,第2.3节,作者:[美]爱德华·阿什福德·李(Edward Ashford Lee),更多章节内容可以访问云栖社区“华章计算机”公众号查看
2.3 层次结构和复合角色
Ptolemy II 支持(和鼓励)层次化模型。这种模型包含了本身就是模型的组件。这些组件称为复合角色(composite actor)。
考虑一个从噪声通道中恢复一个信号的典型信号处理问题。使用Ptolemy II,创建一个复合角色进行一个有噪声通信通道的建模,并在更大的模型中使用该角色。
为了创建复合角色,从Utilities库中拖出一个CompositeActor。如图2-15所示,在上下文菜单(通过右击复合角色获得)中,选择[Customize→Rename]给该复合角色一个适当的名称,如Channel。(注意,你也可以提供一个Display name(显示名称)参数,它可以是任意文本,它将替代原角色名的显示内容。)然后,再使用上下文菜单,选择Open Actor。如图2-16所示,它将打开一个新的图形编辑器窗口。注意,原始的图形编辑器依然是打开的。可通过拖动新窗口的标题栏来移动新的图形编辑窗口,将其显示。也可以单击工具栏中向上指向的三角形返回原始图形编辑器。
![f19139e50a78297c5ed1faf773919dafbd1175e7](https://i-blog.csdnimg.cn/blog_migrate/4ac5c6be9765dbc40fa2940315f061ec.png)
图2-15 重命名角色
![3 3](https://i-blog.csdnimg.cn/blog_migrate/03658c9f93fb9e4c437a5ecf9cd63ec7.png)
图2-16 打开一个新的复合角色,它显示了空的角色内部
2.3.1 复合角色端口添加
新创建的复合角色需要输入和输出端口。可采用多种方法来添加输入输出端口,最简单的一种是单击工具栏上的端口按钮。如图2-17中所示,端口按钮显示为工具栏中白色或黑色的箭头。可以通过将鼠标停留在每个按钮上来探索工具栏中的按钮,将弹出描述这些按钮的工具提示。
图2-17 创建新端口的工具栏按钮总结
创建一个输入端口和输出端口,通过右击端口并选择 [Customize→Rename] 来重命名input(输入)和quput(输出)。如图2-18所示,注意,无论一个端口是输入端口,还是输出端口或是多端口都也可以右击复合角色的背景并选择[Customize→Ports] 来添加、移除或改变。弹出的对话框也可进行端口类型的设置,即使通常你不需要设置端口类型,因为Ptolemy II 从端口连接(connection)中决定端口类型。也可以指定端口的方向并且指定是否在图标外部指定端口名字(默认为否),或者端口是否显示。
图2-18 右击背景会出现一个对话框,它可以用来配置端口
使用这些端口,创建如图2-19所示的模型。利用在Random库中的高斯(Gaussian)角色,创建服从高斯分布的随机变量。如果返回上层模型,能够很轻松地创建如图2-20所示模型。Sinewave角色在Sources→SequenceSources下,SequencePlotter角色在Sinks→SequenceSinks下。
Sinewave角色也是一个复合角色(可以打开该角色)。如果执行该模型(可以给interation参数设置一个合理的值,如100),可以看到类似图2-20所示的图。
![523e295dff87e04585608dfe4e3ad3e90d12c3fa](https://i-blog.csdnimg.cn/blog_migrate/a1452aef675339e8a3561b1902508c64.png)
![3 3](https://i-blog.csdnimg.cn/blog_migrate/43496098417f721d0850e7ca54790338.png)
图2-20 一个简单的信号处理例子,在正弦信号中加入噪声
2.3.2 端口类型设置
在上述例子中,无需定义端口类型。它们的类型可以从模型中的连接(connection)和常量中推断出,该问题将在第14章中解释。然而,偶尔也需要进行端口类型的设置。注意图2-18中的对话框有一列可进行端口类型的指定。比如,若要指定端口为布尔类型,你可以输入boolean即可。但是,仅当端口属于不透明的复合角色(有自己的指示器)时,这样做才有效。但在已经建立的模型中,Channel复合角色是透明的,所以对它的端口类型进行设置将没有实际作用。透明复合角色仅仅是为了表述上的方便简洁,在模型执行中它们的复合端口不起实际作用。
通常使用的类型包括、complex、double、fixedpoint、float、general、int、long、matrix、
object、scalar、short、string、unknown、unsignedByte、xmlToken、arrayType(int)、arrayType(int, 5)、[double] 以及{x=double, y=double}。类型的详细描述在第14章。
在Ptolemy II 的表达语言中,矩阵使用方括号,数组使用大括号。数组是任意类型令牌的有序列表。一个Ptolemy II 矩阵是包含数值类型的一维或二维的结构。例如,若指定端口为双精度矩阵类型,使用下面的表达式:
[double]
这个表达式建立了一个1×1的矩阵,它包含了一个double类型(具体值暂不讨论)。它是指定双精度矩阵类型的一个原型。类似地,我们可以指定一个复数类型的数组为:
{complex}
一条记录可以有任意数量的数据元素,它们中的每一个都有自己的名字和值,其中值可以是任意形式。若一条记录包含一个名为“name”的字符串和一个名为“address”的整数,可使用下面的表达式来指定:
{name=string, address=int}
关于数组、矩阵和记录的细节将在第13章给出。
2.3.3 多端口、总线和层次结构
如上面的2.1.3节所解释的那样,一个多重端口(multiport)处理多个独立的信道。在类似的方式中,一个关系(relation)可以处理多个独立的信道。一个关系(relation)有一个width(宽度)参数,在默认情况下设置为Auto,意味着可以通过上下文来推断宽度。如果宽度不统一,将会出现图2-21所示的情况:关系(relation)上的一条斜线旁边标注了一个数字。这样的连接称为总线,因为它装载多个信号。在图2-21的例子中,如果设置的复合角色的关系宽度为2,那么只使用了复合角色的2/3的信道。
![808d4899497e2d80c82108c0652f1a0f4b7dd2ab](https://i-blog.csdnimg.cn/blog_migrate/1cd72c1bd476ec5f3107f568e0bafefb.png)
在大多数情况下,关系的宽度可从具体使用中来推断(Rodiers and Lickly,2010),但偶尔显式地设置它也是很有必要的。通过使用BusAssembler角色也可以显式地构造一个总线,或者使用BusDisassembler角色从总线中分离部分信道,两个角色都可以在FlowControl→Aggregators库中找到。