1-2.3python模块消息传递
本教程介绍如何使用Embedded Python Block读取和写入消息(messages)。
1 消息概述
2 流程图概述
3 多路复用器:定义块
4 多路复用器:定义消息输入端口
5 多路复用器:创建消息处理程序
6 多路复用器:在work()中使用消息
7 选择器控制:定义块
8 选择器控制:定义消息输出端口
9 选择器控件:在work()中发送消息
10 最终流程图
1.消息概述
消息是一种在块之间发送信息(information)的异步方式。消息常用于传递控制数据,保持跨模块的一致状态,并为流程图中的模块提供某种形式的非数据反馈。
消息有几个独特的属性:
消息到达时没有基于采样时钟的保证
消息与特定样本无关,如标签
消息输入输出端口不必在GRC中连接
消息端口使用多态类型 Polymorphic Type (PMT)
消息端口用灰色表示,它们的连接用虚线区分:
2.流程图概述
以下流程图演示了如何:
在Python模块中添加接受和发送消息的端口
发送信息
接收和处理消息
根据收到的消息调整work()函数中的行为
创建两个自定义嵌入式 Python 模块用以:
根据接收消息选择或复用两个输入信号之一
计算样本数并向多路复用块发送消息以切换输入
首先将以下模块添加到流程图并连接它们:
3. Multiplexer: Defining The Block
双击Embedded Python Block并编辑源代码,
example_param不需要,所以从___init()__函数中将其移除;
并删除:
重命名该模块为Multiplexer:
在模块中添加第二个输入:
删除源代码中的乘法:
保存代码 (CTRL+S) 并返回 GRC。模块的名称已更改,并且该模块有两个输入。将噪声源和信号源连接到两个输入:
4.Multiplexer: Defining Message Input Port
返回代码编辑器。需要添加一个消息输入端口。
创建一个变量来保存消息端口名称:
添加一行来创建或注册消息输入端口:
添加一行以将输入端口与消息处理程序连接起来。
保存代码,此时注意到the Embedded Python Block的属性中列出了语法错误:
此错误表示需要导入pmt库。返回代码编辑器并添加正确的导入语句:
Import pmt;
5.Multiplexer: Creating Message Handler
消息处理程序是在收到消息时调用的函数。
必须定义消息处理函数。此消息处理程序根据接收到的消息在两个输入端口之间切换。收到的消息是一个布尔值,它是 True 或 False。
在__init()__下定义一个新变量作为输入选择器,
定义handle_msg()函数:
函数pmt.to_bool()获取消息 PMT,然后将数据类型转换为 Python 的布尔数据类型。PMT 用于将消息传递给抽象数据类型。例如,消息可用于发送和接收字符串、浮点数、整数甚至列表。
6. Multiplexer: Using a Message in work()
多路复用器的外部接口已经创建完整,修改模块的work()函数来添加多路复用操作。
将以下代码添加到work()函数中:
如果self.selector = True则多路复用器模块选择端口0 ,如果self.selector = False则选择端口1。self.selector的默认值在__init()__函数中定义。
保存代码 (CTRL+S) 并返回 GRC。Multiplexer块有一个消息端口selectPort如图所示 :
在继续之前运行流程图以确保一切正确。如简介中所述,不必连接消息端口即可运行流程图。因为self.selector的默认值为True,多路复用器的work()函数将选择端口0并将其发送到输出。QT GUI Time Sink显示噪声:
7.Selector Control: Defining The Block
另一个嵌入式 Python 模块用于计算它接收到的样本数量,然后将控制消息发送到多路复用器模块以切换选择器。
首先在Multiplexer和Throttle之间向流程图添加一个新的Python 块。
编辑Embedded Python Block的代码,更改__init()__函数 中的参数example_param :
更改块的名称:
将Num_Samples_To_Count存储为私有变量:
8.Selector Control: Defining Message Output Port
导入pmt库:
在__init()__函数中创建一个变量self.portName作为输出端口(字符串类型的数据)的名称messageOutput:
通过在__init()__函数 中添加以下行来创建或注册消息端口:
保存代码 (CTRL + S) 并返回 GRC。Selector Control模块有一个消息输出端口:
9.Selector Control: Sending a message in work()
不需要为输出端口定义消息处理程序。但是,需要修改 work()函数以创建发送消息的逻辑。
首先在__init()__中创建两个变量:
添加该行以便调用work()函数时可以统计增加的样本数:
添加代码使得计数超过设定数值后发送消息:
该代码使用pmt.from_bool()函数将self.state的 Python 布尔数据类型转换为 PMT ,然后在消息输出端口上发送消息。随后,self.state变量被切换到它的相反值并且计数器被重置。
保存代码之后返回GRC,在Select Control模块的属性编辑页面中将设定数值赋予32k:
添加Message Debug块并将messageOutput端口连接到它。运行流程图显示消息以每秒一次的速率发送,在#t (True) 和#f (False) 之间交替:
但是,Selector Control的消息输出端口尚未连接到Multiplexer的消息输入端口,因此QT GUI Time Sink仅显示噪声。
10.最终流程图
将Selector Control的消息输出端口连接到Multiplexer的消息输入端口。请注意,虚线连接在两个模块背后,很难看到:
虚拟接收器和虚拟源可用于隐藏一些连接并使流程图更易于理解。单击虚线并将其删除。将Virtual Sink和Virtual Source拖放到工作区中。将Virtual Sink和Virtual Source的Stream ID更改为message,然后在流程图中连接它们:
运行流程图。QT GUI Time Sink显示了Noise Source和Signal Source之间的交替输出: