机器人系统开发ros2 基础学习08 ros2 主题定义及示例

69 篇文章 2 订阅
56 篇文章 50 订阅

topic 在ros 中的作用
主题是 ROS 图的重要元素,充当节点交换消息的总线。

节点实现了机器人各种各样的功能,但这些功能并不是独立的,之间会有千丝万缕的联系,其中最重要的一种联系方式就是话题,它是节点间传递数据的桥梁。

在这里插入图片描述
大家可以想一下,这两个节点是不是必然存在某种关系?没错,节点A要将获取的图像数据传输给节点B,有了数据,节点B才能做这样可视化的渲染。

此时从节点A到节点B传递图像数据的方式,在ROS中,我们就称之为话题,它作为一个桥梁,实现了节点之间某一个方向上的数据传输。

发布/订阅模型

从话题本身的实现角度来看,使用了基于DDS的发布/订阅模型,什么叫发布和订阅呢?

在这里插入图片描述
话题数据传输的特性是从一个节点到另外一个节点,发送数据的对象称之为发布者,接收数据的对象称之为订阅者,每一个话题都需要有一个名字,传输的数据也需要有固定的数据类型。

多对多通信

在这里插入图片描述
大家再仔细想下这些可以订阅的东西,是不是并不是唯一的,我们每个人可以订阅很多公众号、报纸、杂志,这些公众号、报纸、杂志也可以被很多人订阅,没错,ROS里的话题也是一样,发布者和订阅者的数量并不是唯一的,可以称之为是多对多的通信模型。

因为话题是多对多的模型,发布控制指令的摇杆可以有一个,也可以有2个、3个,订阅控制指令的机器人可以有1个,也可以有2个、3个,大家可以想象一下这个画面,似乎还是挺魔性的,如果存在多个发送指令的节点,建议大家要注意区分优先级,不然机器人可能不知道该听谁的了。

查看主题列表

打开一个新终端并运行:

ros2 run turtlesim turtlesim_node

打开另一个终端并运行:

ros2 run turtlesim turtle_teleop_key

rqt_图

在本教程中,我们将用于rqt_graph可视化不断变化的节点和主题,以及它们之间的连接。

turtlesim教程告诉您如何安装 rqt 及其所有插件,包括rqt_graph.

要运行 rqt_graph,请打开一个新终端并输入命令:

rqt_graph

您还可以通过打开rqt并选择Plugins > Introspection > Node Graph来打开 rqt_graph 。

在这里插入图片描述

您应该看到上面的节点和主题,以及图外围的两个操作(现在让我们忽略它们)。如果将鼠标悬停在中心的主题上,您将看到颜色突出显示,如上图所示。

该图描绘了/turtlesim节点和/teleop_turtle节点如何通过主题相互通信。该/teleop_turtle节点正在将数据(您输入的用于移动乌龟的击键)发布到主题/turtle1/cmd_vel,并且该/turtlesim节点订阅该主题以接收数据。

当检查具有许多节点和主题以多种不同方式连接的更复杂的系统时,rqt_graph 的突出显示功能非常有用。

rqt_graph 是一个图形自省工具。现在我们将了解一些用于内省主题的命令行工具。

命令行形式查看

ros2 topic list

在新终端中运行该命令将返回系统中当前活动的所有主题的列表:ros2 topic list

下面几个是运行小乌龟节点的topic list
在这里插入图片描述
ros2 topic list -t将返回相同的主题列表,这次主题类型附加在括号中:

ros2 topic list -t

在这里插入图片描述

ros2 主题回显

要查看某个主题上发布的数据,请使用:

ros2 topic echo <topic_name>

既然我们知道将/teleop_turtle数据发布到/turtlesim该/turtle1/cmd_vel主题,那么让我们来echo 查看该主题:

ros2 topic echo /turtle1/cmd_vel

起初,该命令不会返回任何数据。那是因为它正在等待/teleop_turtle发布一些东西。

返回正在运行的终端turtle_teleop_key并使用箭头移动乌龟。echo同时观察您正在运行的终端,您将看到您所做的每个动作都发布了位置数据:

在这里插入图片描述

查看主题的发布订阅信息

主题不一定只是一对一的交流;它们可以是一对多、多对一或多对多。

ros2 topic info /turtle1/cmd_vel

在这里插入图片描述

主题发布

通过上面的命令可以看到消息结构,接下来就可以使用下面的命令直接将数据发布到主题:

ros2 topic pub <topic_name> <msg_type> '<args>'

参数’'是您将传递到主题的实际数据,采用您在上一节中刚刚发现的结构。

需要注意的是,该参数需要以 YAML 语法输入。输入完整命令,如下所示:

ros2 topic pub --once /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"

– once是一个可选参数,意思是“发布一条消息然后退出”。

海龟(通常是它要模仿的真实机器人)需要稳定的命令流才能连续运行。因此,要让乌龟继续移动,您可以运行:

ros2 topic pub --rate 1 /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"

在这里插入图片描述

这里的区别是删除了该–once选项并添加了该选项,该选项告诉以 1 Hz 的稳定流发布命令。–rate 1 ros2 topic pub

查看主题的赫兹

ros2 topic hz /turtle1/pose

示例:自定义话题消息发布和订阅

了解了话题的基本原理,接下来我们就要开始编写代码啦。

在这里插入图片描述
还是从Hello World例程开始,我们来创建一个发布者,发布话题“chatter”,周期发送“Hello World”这个字符串,消息类型是ROS中标准定义的String,再创建一个订阅者,订阅“chatter”这个话题,从而接收到“Hello World”这个字符串。

如果我们想要实现一个发布者和订阅者,主要流程如下:

  1. 创建功能包
  2. 在功能包下新增发布者代码
  3. 在功能包下新增订阅者代码
  4. 修改功能包下setup.py 的脚本文件
  5. 编译
  6. 运行测试

创建功能包

ros2 pkg create --build-type ament_python learning_topic

用vccode 打开功能包目录结构如下
在这里插入图片描述
在learning_topic 目录下新增 helloworld_pub.py, 代码如下

创建一个topic 为hello 的话题,并发送hello

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import rclpy                                     # ROS2 Python接口库
from rclpy.node import Node                      # ROS2 节点类
from std_msgs.msg import String                  # 字符串消息类型

"""
创建一个发布者节点
"""
class PublisherNode(Node):

    def __init__(self, name):
        super().__init__(name)                                    # ROS2节点父类初始化
        self.pub = self.create_publisher(String, "hello", 10)   # 创建发布者对象(消息类型、话题名、队列长度)
        self.timer = self.create_timer(0.5, self.timer_callback)  # 创建一个定时器(单位为秒的周期,定时执行的回调函数)

    def timer_callback(self):                                     # 创建定时器周期执行的回调函数
        msg = String()                                            # 创建一个String类型的消息对象
        msg.data = 'Hello World'                                  # 填充消息对象中的消息数据
        self.pub.publish(msg)                                     # 发布话题消息
        self.get_logger().info('Publishing: "%s"' % msg.data)     # 输出日志信息,提示已经完成话题发布

def main(args=None):                                 # ROS2节点主入口main函数
    rclpy.init(args=args)                            # ROS2 Python接口初始化
    node = PublisherNode("helloworld_pub")     # 创建ROS2节点对象并进行初始化
    rclpy.spin(node)                                 # 循环等待ROS2退出
    node.destroy_node()                              # 销毁节点对象
    rclpy.shutdown()                                 # 关闭ROS2 Python接口

创建一个监听 helloworld_sub.py

代码如下:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-



import rclpy                      # ROS2 Python接口库
from rclpy.node   import Node     # ROS2 节点类
from std_msgs.msg import String   # ROS2标准定义的String消息

"""
创建一个订阅者节点
"""
class SubscriberNode(Node):

    def __init__(self, name):
        super().__init__(name)                             # ROS2节点父类初始化
        self.sub = self.create_subscription(\
            String, "hello", self.listener_callback, 10) # 创建订阅者对象(消息类型、话题名、订阅者回调函数、队列长度)

    def listener_callback(self, msg):                      # 创建回调函数,执行收到话题消息后对数据的处理
        self.get_logger().info('I heard: "%s"' % msg.data) # 输出日志信息,提示订阅收到的话题消息

def main(args=None):                               # ROS2节点主入口main函数
    rclpy.init(args=args)                          # ROS2 Python接口初始化
    node = SubscriberNode("helloworld_sub")  # 创建ROS2节点对象并进行初始化
    rclpy.spin(node)                               # 循环等待ROS2退出
    node.destroy_node()                            # 销毁节点对象
    rclpy.shutdown()                               # 关闭ROS2 Python接口

修改setup.py

'console_scripts': [
             'helloworld_pub  = learning_topic.helloworld_pub:main',
             'helloworld_sub  = learning_topic.helloworld_sub:main',
        ],

在这里插入图片描述

编译

回到项目空间目录

指定learning_topic 编译

colcon build --packages-select learning_topic

开始编译
在这里插入图片描述
编译成功

在这里插入图片描述
设置环境变量

source install/local_setup.bash

运行测试:

ros2 run learning_topic helloworld_pub

在这里插入图片描述

新建命令窗口运行订阅

ros2 run learning_topic helloworld_sub

监听成功
在这里插入图片描述

  • 25
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小海聊智造

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值