编写简单的发布器和订阅器(Python)

目标 使用 Python 创建并运行一个发布者和订阅者节点。

辅导水平: 初学者

时间 20 分钟

背景介绍

在本教程中,您将创建 结点 以字符串信息的形式相互传递信息。 主题.这里使用的示例是一个简单的 "说者 "和 "听者 "系统;一个节点发布数据,另一个节点订阅主题以便接收数据。

这些示例中使用的代码如下 这里.

先决条件

在前面的教程中,您学习了如何 创建工作区创建软件包.

建议对 Python 有基本了解,但并非完全必要。

任务

1 创建软件包

打开一个新终端,然后 为您的 ROS 2 安装提供源代码 以便 玫瑰2 命令即可运行。

导航进入 ros2_ws 目录中创建的 上一个教程.

回顾一下,软件包应在 来源 目录,而不是工作区的根目录。因此,导航到 ros2_ws/src然后运行软件包创建命令:

ros2 pkg create --build-type ament_python --license Apache-2.0 py_pubsub

您的终端将返回一条信息,验证是否创建了软件包 py_pubsub 及其所有必要的文件和文件夹。

2 写入发布节点

导航进入 ros2_ws/src/py_pubsub/py_pubsub.请注意,该目录是 Python 软件包 与嵌套在其中的 ROS 2 软件包同名。

输入以下命令下载通话代码示例:

wget https://raw.githubusercontent.com/ros2/examples/jazzy/rclpy/topics/minimal_publisher/examples_rclpy_minimal_publisher/publisher_member_function.py

现在将有一个名为 publisher_member_function.py 毗邻 __init__.py.

使用您喜欢的文本编辑器打开文件。

舶来品 rclpy
 rclpy.node 舶来品 节点

 std_msgs.msg 舶来品 字符串


 最小出版商(节点):

    捍卫 启动(自我):
        棒极了().启动('minimal_publisher';)
        自我.出版商_ = 自我.创建出版商(字符串, '主题';, 10)
        定时器周期 = 0.5  # 秒
        自我.定时器 = 自我.创建计时器(定时器周期, 自我.定时器回调)
        自我.i = 0

    捍卫 定时器回调(自我):
        信息 = 字符串()
        信息.数据 = '你好,世界: %d' % 自我.i
        自我.出版商_.发布(信息)
        自我.get_logger().信息('出版:";%s"'; % 信息.数据)
        自我.i += 1


捍卫 主要(参数=):
    rclpy.启动(参数=参数)

    最小出版商 = 最小出版商()

    rclpy.后旋(最小出版商)

    # 明确销毁节点
    # (可选,否则将自动完成
    # 当垃圾回收器销毁节点对象时)
    最小出版商.destroy_node()
    rclpy.关闭()


如果 姓名____ == '__main__';:
    主要()

2.1 检查代码

注释后的第一行代码导入 rclpy 因此 节点 类可以使用。

舶来品 rclpy
 rclpy.node 舶来品 节点

下一条语句导入了内置字符串信息类型,节点使用这种类型来构建在主题上传递的数据结构。

 std_msgs.msg 舶来品 字符串

这些线条代表节点的依赖关系。请注意,必须将依赖关系添加到 package.xml您将在下一节中完成这一操作。

接下来是 最小出版商 类的子类。 节点.

 最小出版商(节点):

下面是该类构造函数的定义。 super().__init__ 调用 节点 类的构造函数,并给出节点名称,在本例中为 最小出版商.

创建出版商 声明节点发布类型为 字符串std_msgs.msg 模块),在名为 主题队列大小 "为 10。队列大小是一个必要的 QoS(服务质量)设置,如果用户接收信息的速度不够快,它就会限制排队信息的数量。

接着,创建一个定时器,每 0.5 秒执行一次回调。 self.i 是回调中使用的计数器。

捍卫 启动(自我):
    棒极了().启动('minimal_publisher';)
    自我.出版商_ = 自我.创建出版商(字符串, '主题';, 10)
    定时器周期 = 0.5  # 秒
    自我.定时器 = 自我.创建计时器(定时器周期, 自我.定时器回调)
    自我.i = 0

定时器回调 创建一条附加了计数器值的信息,并用 get_logger().info.

捍卫 定时器回调(自我):
    信息 = 字符串()
    信息.数据 = '你好,世界: %d' % 自我.i
    自我.出版商_.发布(信息)
    自我.get_logger().信息('出版:";%s"'; % 信息.数据)
    自我.i += 1

最后是主函数的定义。

捍卫 主要(参数=):
    rclpy.启动(参数=参数)

    最小出版商 = 最小出版商()

    rclpy.后旋(最小出版商)

    # 明确销毁节点
    # (可选,否则将自动完成
    # 当垃圾回收器销毁节点对象时)
    最小出版商.destroy_node()
    rclpy.关闭()

首先是 rclpy 库初始化,然后创建节点,然后 "旋转 "节点,以便调用其回调。

2.2 添加依赖项

导航一级回到 ros2_ws/src/py_pubsub 目录中的 setup.py, setup.cfgpackage.xml 文件已为您创建。

开放 package.xml 使用文本编辑器。

正如 上一个教程请确保填写 <描述>;, <维护者>;许可证 标签

<描述>;实例  极少 出版商/订户 使用 rclpy</description>;
维护者 电子邮件="[email protected]";>;您的 名称维护人员</maintainer>;
许可证Apache-2.0</license>;

在上面的行之后,添加以下与节点的导入语句相对应的依赖关系:

执行依赖关系;rclpy</exec_depend>;
执行依赖关系;std_msgs</exec_depend>;

这就声明了软件包需要 rclpystd_msgs 当其代码被执行时。

确保保存文件。

2.3 添加入口

打开 setup.py 文件。同样,匹配 维护者, 维护者电子邮件, 描述许可 字段到您的 package.xml:

维护者='YourName';,
维护者电子邮件='[email protected]';,
描述='使用 rclpy 的最小发布者/订阅者示例';,
许可='Apache-2.0';,

控制台脚本 括号内的 入口 field:

入口={
        'console_scripts';: [
                'talker = py_pubsub.publisher_member_function:main';,
        ],
},

别忘了保存。

2.4 检查 setup.cfg

的内容 setup.cfg 文件应该会自动正确填充,就像这样:

[发展]
script_dir=$base/lib/py_pubsub
[安装]
install_scripts=$base/lib/py_pubsub

这只是告诉 setuptools 将可执行文件放在 lib因为 玫瑰2 运行 将在那里寻找它们。

你可以现在就构建你的软件包,获取本地设置文件,然后运行它,但让我们先创建用户节点,这样你就能看到整个系统的运行情况。

3 写入用户节点

返回 ros2_ws/src/py_pubsub/py_pubsub 来创建下一个节点。在终端中输入以下代码

wget https://raw.githubusercontent.com/ros2/examples/jazzy/rclpy/topics/minimal_subscriber/examples_rclpy_minimal_subscriber/subscriber_member_function.py

现在目录中应该有这些文件:

__init__.py publisher_member_function.py subscriber_member_function.py

3.1 检查代码

打开 subscriber_member_function.py 使用文本编辑器。

舶来品 rclpy
 rclpy.node 舶来品 节点

 std_msgs.msg 舶来品 字符串


 最小订阅者(节点):

    捍卫 启动(自我):
        棒极了().启动('minimal_subscriber';)
        自我.订阅费 = 自我.创建订阅(
            字符串,
            '主题';,
            自我.监听器回调,
            10)
        自我.订阅费  # 防止未使用的变量发出警告

    捍卫 监听器回调(自我, 信息):
        自我.get_logger().信息('我听说:";%s"'; % 信息.数据)


捍卫 主要(参数=):
    rclpy.启动(参数=参数)

    最小订阅者 = 最小订阅者()

    rclpy.后旋(最小订阅者)

    # 明确销毁节点
    # (可选,否则将自动完成
    # 当垃圾回收器销毁节点对象时)
    最小订阅者.destroy_node()
    rclpy.关闭()


如果 姓名____ == '__main__';:
    主要()

订阅者节点的代码与发布者几乎完全相同。构造函数使用与发布者相同的参数创建订阅者。回顾 主题教程 发布者和订阅者使用的主题名称和信息类型必须匹配,才能进行通信。

自我.订阅费 = 自我.创建订阅(
    字符串,
    '主题';,
    自我.监听器回调,
    10)

订阅者的构造函数和回调函数不包含任何计时器定义,因为它不需要。一旦收到消息,它的回调函数就会被调用。

回调定义只是向控制台打印一条信息消息,以及它收到的数据。回想一下,发布者定义了 msg.data = 你好 世界: %d' % self.i

捍卫 监听器回调(自我, 信息):
    自我.get_logger().信息('我听说:";%s"'; % 信息.数据)

"(《世界人权宣言》) 主要 定义几乎完全相同,只是用订阅者取代了发布者的创建和旋转。

最小订阅者 = 最小订阅者()

rclpy.后旋(最小订阅者)

由于该节点与发布者具有相同的依赖关系,因此没有新的内容需要添加到 package.xml.......。 setup.cfg 文件也可以保持不动。

3.2 添加入口

重新开放 setup.py 并在发布者的入口点下方添加订阅者节点的入口点。用户节点 入口 字段现在应该是这样的:

入口={
        'console_scripts';: [
                'talker = py_pubsub.publisher_member_function:main';,
                'listener = py_pubsub.subscriber_member_function:main';,
        ],
},

确保保存文件,然后你的发布/分站系统就应该准备就绪了。

4 构建和运行

您可能已经拥有 rclpystd_msgs 软件包是 ROS 2 系统的一部分。运行 rosdep 在工作区的根目录 (ros2_ws) 在构建前检查是否缺少依赖项:

rosdep install -i --from-path src --rosdistro jazzy -y

还是在工作区的根目录下、 ros2_ws, 构建您的新软件包:

colcon build --packages-select py_pubsub

打开一个新终端,导航至 ros2_ws并获取设置文件:

source install/setup.bash

现在运行 Talker 节点:

ros2 run py_pubsub talker

终端应该开始每 0.5 秒发布一次信息,就像这样:

[INFO] [minimal_publisher]:Publishing: "Hello World: 0";
[INFO] [minimal_publisher]:Publishing: "Hello World: 1";
[INFO] [minimal_publisher]:Publishing: "Hello World: 2";
[INFO] [minimal_publisher]:Publishing: "Hello World: 3";
[INFO] [minimal_publisher]:Publishing: "Hello World: 4";
...

打开另一个终端,从里面获取设置文件的源代码 ros2_ws 然后启动监听节点:

ros2 运行 py_pubsub 监听器

监听器将开始向控制台打印消息,从发布者当时的消息计数开始,就像这样:

[INFO] [minimal_subscriber]:我听到: "Hello World: 10";
[INFO] [minimal_subscriber]:我听到: "Hello World: 11";
[INFO] [minimal_subscriber]:我听到: "Hello World: 12";
[INFO] [minimal_subscriber]:我听到: "Hello World: 13";
[INFO] [minimal_subscriber]:我听到: "Hello World: 14";

进入 Ctrl+C 以阻止节点旋转。

摘要

您创建了两个节点,用于通过主题发布和订阅数据。在运行它们之前,您在软件包配置文件中添加了它们的依赖关系和入口点。

下一步工作

接下来,您将使用服务/客户端模型创建另一个简单的 ROS 2 软件包。同样,你可以选择用 C++Python.