ROS机器人入门第四课:话题通信

文章目录

  • ROS机器人入门第四课:话题通信
    • 一、话题通信概述
      • (一)概念
      • (二)作用
    • 二、话题通信基本操作
      • 需求:
      • 分析:
      • 流程:
      • (一)发布方
        • 解释一些关键的ROS函数和概念:
      • (二)订阅方
      • 关键ROS函数和概念的解释:
      • (三)添加可执行权限
      • (四)配置 CMakeLists.txt
      • (五)执行
      • (六)ROS解耦合

ROS机器人入门第四课:话题通信

一、话题通信概述

话题通信是ROS中使用频率最高的一种通信模式,话题通信是基于发布订阅模式的,也即:一个节点发布消息,另一个节点订阅该消息。话题通信的应用场景也极其广泛,比如下面一个常见场景:

机器人在执行导航功能,使用的传感器是激光雷达,机器人会采集激光雷达感知到的信息并计算,然后生成运动控制信息驱动机器人底盘运动。

在上述场景中,就不止一次使用到了话题通信。

  • 以激光雷达信息的采集处理为例,在 ROS 中有一个节点需要时时的发布当前雷达采集到的数据,导航模块中也有节点会订阅并解析雷达数据。
  • 再以运动消息的发布为例,导航模块会根据传感器采集的数据时时的计算出运动控制信息并发布给底盘,底盘也可以有一个节点订阅运动信息并最终转换成控制电机的脉冲信号。

以此类推,像雷达、摄像头、GPS… 等等一些传感器数据的采集,也都是使用了话题通信,换言之,话题通信适用于不断更新的数据传输相关的应用场景。

(一)概念

以发布订阅的方式实现不同节点之间数据交互的通信模式。

(二)作用

用于不断更新的、少逻辑处理的数据传输场景。

二、话题通信基本操作

需求:

编写发布订阅实现,要求发布方以10HZ(每秒10次)的频率发布文本消息,订阅方订阅消息并将消息内容打印输出。

分析:

在模型实现中,ROS master 不需要实现,而连接的建立也已经被封装了,需要关注的关键点有三个:

  1. 发布方
  2. 接收方
  3. 数据(此处为普通文本)

流程:

  1. 编写发布方实现;
  2. 编写订阅方实现;
  3. 为python文件添加可执行权限;
  4. 编辑配置文件;
  5. 编译并执行。

(一)发布方

这段代码是一个使用ROS(Robot Operating System,机器人操作系统)的Python脚本示例,旨在创建一个名为talker_p的节点,该节点周期性地向名为chatter的话题发送包含字符串的消息。它是一个简单的发布者(Publisher)节点,演示了ROS中发布消息的基本模式。下面对代码进行详细注释,并解释其中使用的关键ROS函数。

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

# 导入 rospy 库,rospy 是 ROS 在 Python 中的客户端库,用于使Python代码能与ROS通信。
import rospy
# 从 std_msgs 包中导入 String 消息类型,std_msgs 包含了许多标准的消息类型,String 是其中用于传输文本信息的一个类型。
from std_msgs.msg import String

# 判断此脚本是直接被执行而不是被导入到其他文件中时,下面的代码块将被执行。
if __name__ == "__main__":
    # 初始化ROS节点,命名为 "talker_p"。
    # 每个ROS节点都必须有一个唯一的名称,这样其他节点就可以与之通信。
    rospy.init_node("talker_p")
    
    # 实例化发布者对象。
    # 这一步创建了一个发布者对象,它能够向名为 "chatter" 的话题发布 String 类型的消息。
    # queue_size 参数是发布队列的大小,用于限制未处理消息的数量,防止内存消耗过大。
    pub = rospy.Publisher("chatter", String, queue_size=10)
    
    # 创建一个 String 类型的消息对象。
    msg = String()
    # 准备消息的前缀文本。
    msg_front = "hello 你好"
    # 初始化计数器,用于生成消息序列。
    count = 0
    
    # 设置消息发布的频率,这里是每秒1次。
    rate = rospy.Rate(1)
    # 在 ROS 节点未被关闭的情况下循环。
    while not rospy.is_shutdown():
        # 拼接字符串,将前缀和计数器的值合成为最终的消息内容。
        msg.data = msg_front + str(count)

        # 发布消息到 "chatter" 话题。
        pub.publish(msg)
        # 根据之前设置的频率暂停,确保按照设定的频率发布消息。
        rate.sleep()
        # 将发布的消息内容记录到 ROS 日志信息中,便于调试和记录。
        rospy.loginfo("写出的数据:%s", msg.data)
        # 更新计数器,为下一条消息准备。
        count += 1
解释一些关键的ROS函数和概念:
  • rospy.init_node("talker_p"):该函数用于初始化一个ROS节点,这是启动任何ROS节点的第一步。这里的"talker_p"是节点的名称,它必须在ROS系统中唯一。

  • rospy.Publisher("chatter", String, queue_size=10):这个函数创建一个发布者对象,用于向特定的话题(这里是chatter)发布消息。String是消息类型,而queue_size参数用于控制发布者消息队列的大小,有助于处理网络延迟或处理速度慢时消息的积压问题。

  • rospy.Rate(1):这个函数创建一个Rate对象,用于控制循环的速率。这里设置为1Hz,意味着循环每秒运行一次。

  • rospy.is_shutdown():这是一个检查ROS节点是否收到了终止信号(如Ctrl+C)的函数。如果是,则返回True,循环将停止。

  • pub.publish(msg):通过之前创建的发布者对象pub调用publish方法来发布消息。msg是要发布的消息对象。

  • rate.sleep():这个方法使当前循环休眠足够的时间,以保持循环运行在设定的频率上。

  • rospy.loginfo():这个函数用于将信息记录到ROS日志里,类似于Python的print函数,但是它提供了更丰富的日志管理功能。


如若不写订阅方的代码想直接查看发布方的消息,可以使用如下命令:
rostopic echo 话题
在这里插入图片描述


(二)订阅方

这段代码展示了如何在ROS(Robot Operating System,机器人操作系统)中创建一个订阅者节点,监听并处理来自特定话题(chatter)的消息。下面对代码进行详细注释,并解释其中使用的关键ROS函数。

# 导入 rospy 库,rospy 是 ROS 在 Python 中的客户端库,允许Python代码与ROS通信。
import rospy
# 从 std_msgs 包中导入 String 消息类型,这是一个用于传输文本信息的标准消息类型。
from std_msgs.msg import String

# 定义回调函数,这个函数将在节点收到新消息时被调用。
# msg 参数是收到的消息对象。
def doMsg(msg):
    # 在 ROS 日志中记录信息,这里记录的是收到的消息内容。
    rospy.loginfo("I heard:%s", msg.data)

# 检查这个脚本是否是主程序,而不是被其他文件导入。
if __name__ == "__main__":
    # 初始化 ROS 节点,节点名为 "listener_p"。
    # 每个节点必须有一个唯一的名称,以便在 ROS 网络中被识别。
    rospy.init_node("listener_p")
    
    # 实例化订阅者对象。
    # 这一步创建了一个订阅者对象,它将监听名为 "chatter" 的话题,
    # 并且每当有新消息时,就会调用 doMsg 函数。
    # String 指定了话题消息的类型,queue_size 用于限制消息队列的大小。
    sub = rospy.Subscriber("chatter", String, doMsg, queue_size=10)
    
    # 进入循环,等待消息到来。
    # rospy.spin() 使得Python脚本保持运行状态,并在收到新消息时调用回调函数。
    # 它是一个阻塞调用,直到节点被明确地关闭或接收到终止信号(例如Ctrl+C)。
    rospy.spin()

关键ROS函数和概念的解释:

  • rospy.init_node("listener_p"):该函数用于初始化一个ROS节点。这是启动任何ROS节点的必要步骤。这里的"listener_p"是节点的名称,它在ROS网络中必须是唯一的。

  • rospy.Subscriber("chatter", String, doMsg, queue_size=10):这个函数创建了一个订阅者对象,用于订阅特定的话题(这里是chatter)并指定当收到新消息时所调用的回调函数(这里是doMsg)。String参数指定了订阅的消息类型,而queue_size参数用于控制消息队列的大小,有助于处理网络延迟或处理速度慢时消息的积压问题。

  • doMsg(msg):这是一个用户定义的回调函数,每当订阅的话题有新的消息时,这个函数就会被调用。msg参数是收到的消息对象。在这个函数内部,使用rospy.loginfo来记录消息内容。

  • rospy.spin():这个函数会让节点进入等待循环,等待并处理回调函数。它是一个阻塞(blocking)调用,意味着除非节点被关闭,否则程序将停在这里。这是订阅者节点保持激活并响应话题消息的常用方法。

  • rospy.loginfo():这个函数用于在ROS日志中记录信息,对于调试和跟踪节点行为非常有用。


注意: 二者需要设置相同的话题

比如上面的发布方和订阅方都订阅了相同的话题:chatter


(三)添加可执行权限

终端下进入 scripts 执行:chmod +x *.py

在这里插入图片描述

(四)配置 CMakeLists.txt

catkin_install_python(PROGRAMS
  scripts/talker_p.py
  scripts/listener_p.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

在这里插入图片描述

(五)执行

  1. 启动 roscore;

  2. 启动发布节点;

  • 先启动命令行source ./devel/setup.bash
  • 再启动命令行rosrun 包名 自定义文件名.py
  1. 启动订阅节点。
  • 先启动命令行source ./devel/setup.bash
  • 再启动命令行rosrun 包名 自定义文件名.py

在这里插入图片描述
运行结果如图所示:

在这里插入图片描述


因为发布方是软起动,需要先在master里注册,注册过程中可能就已经把消息发出去了,即使先打开订阅方,再打开发布方也一样会丢失数据,所以我们可以先确保发布方注册完,再发送信息

即在发布方的代码中设置一个休眠函数rospy.sleep(3),我这里是休眠3秒再发送数据

在这里插入图片描述


注意:可以使用 rqt_graph 查看节点关系。

在这里插入图片描述

(六)ROS解耦合

即便你使用不同的语言编写的节点,那么他们之间也是可以实现数据交换

在话题通信中,只要话题一致,C++和python写的代码就可以相互通信

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/489806.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何使用WordPress插件保护网站的安全

前段时间我们的网站受到了黑客的攻击,网站丢失了一些重要的数据,为了防止这种情况的再次发生,我们准备将网站全部迁移到高防服务器,经过一番对比后,我们选择了Hostease提供的高防服务器。它可以有效地抵御各种类型的网…

网络七层模型:理解网络通信的架构(〇)

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

开箱即用的中后台管理模版,建议收藏!

公众号:程序员白特,欢迎一起交流学习~ 原文作者:前端充电宝 大家好,我是白特。 今天来推荐几款开箱即用的中后台管理模版! Vue Element Admin vue-element-admin 是一个后台前端解决方案,它基于 vue 和 …

WMS仓储管理系统如何优化供应链管理

随着信息技术的快速发展和市场竞争的加剧,优化供应链管理已成为企业提升竞争力的关键。WMS仓储管理系统作为供应链管理的核心工具,其在优化供应链过程中的作用日益凸显。本文将深入探讨WMS仓储管理系统如何优化供应链管理。 首先,WMS仓储管理…

pdfjs 实现给定pdf数据切片高亮并且跳转

pdfjs 实现给定pdf数据切片高亮并且跳转 pdfjs 类的改写基本展示需求的实现高亮功能的实现查询功能分析切片数据处理 pdfjs 类的改写 需求: pdf文件被解析成多个分段,每个分段需要能够展示,并且通过点击分段实现源pdf内容的高亮以及跳转需求…

Oracle数据库入门第三课(函数)

前面二白讲了一些简单的查询语句,仅仅知道查询语句的语法是不够的,要想实现更多的需求,更重要的是函数的使用,这节课我们简单说一下一些函数的使用。 一、函数的分类 什么叫做函数? 函数就是用来实现某种功能的,提前声明好的代…

微博修改密码后无法通过微博开放接口发送微博

生产环境,因密码修改导致授权失效致接口发送微博失效!内部网站编辑完博文后无法发送微博。在修改密码时,有提示授权应用失效,操作人员不清晰情况,直接忽视。 微博应用开放接口----》微博转发博文接口文档 无示例 遗憾…

淘宝API接口推荐:淘宝app商品详情数据接口

淘宝的商品详情API接口是一种技术工具,它允许开发者通过编程的方式获取淘宝平台上商品的详情页面的数据。这些数据对于电商智能决策至关重要,因为它们可以提供关于消费者偏好、商品质量和市场趋势的宝贵信息。 淘宝天猫API列表 item_get 获得商品详情i…

多线程死锁,java内存模型,wait、notify方法

死锁出现的第一种情况 可重入 同一个线程针对同一个锁连续继续加锁多次的行为。如果发生了死锁情况,那就是发生了不可重入,反之不会发生死锁,就是可重入的。 当进行多次加锁会发生什么情况 在这个方法中实现了在外面对方法的加锁(…

操作系统的理解|冯·若依曼体系结构|进程的状态

操作系统的理解 冯诺伊曼体系结构为什么必须通过内存然后到cpu存储金字塔冯诺伊曼结构的改进在哪?我们可不可以全部用寄存器来做存储器在硬件数据流动角度学以致用:解释程序运行为什么要加载到内存程序没被运行之前存在哪里? 操作系统概念广义…

快速熟悉ElasticSearch的基本概念

1.全文检索 全文检索是通过文本内容进行全面搜索的技术。通过全文检索可以快速地在大量文本数据中查找包含特定关键词或者短语的文档,并且返回相关的搜索结果。 检索和查询的区别 检索没有搜索条件边界,检索的结果取决于相关性,相关性计算…

下载安装anaconda和pytorch的详细方法,以及遇到的问题和解决办法

下载安装Anaconda 首先需要下载Anaconda,可以到官网Anaconda官网或者这里提供一个镜像网站去下载anaconda镜像网站 安装步骤可参考该文章:Anaconda安装步骤,本篇不再赘述 注意环境变量的配置,安装好Anaconda之后一定要在环境变量…

Apache Hive的部署与体验

一、Apache Hive概述 什么是分布式SQL计算? 以分布式的形式,执行SQL语句,进行数据统计分析。Apache Hive是做什么的? 很简单,将SQL语句翻译成MapReduce程序,从而提供用户分布式SQL计算的能力。传统MapRed…

碳实践|企业组织碳排放源识别方法、案例分析,及注意事项

在上一章中讲到“界、源、算、质、查”五步法实现企业组织碳的完整核算流程,本章将针对其中的“源”- “识别排放源”这一步骤来展开,主要分析其识别方法、实操案例,并列举注意事项。 企业识别碳排放源是指在组织边界内找到产生碳排放的设施,…

python--函数的参数问题

1.函数的参数: 默认值参数:通过定义函数时,将可能调用时不怎么变化的参数,给定默认值,在调用时方便调用 注意:位置参数不能写在默认值参数后边 可变参数(不定长参数):在开…

mysql日志管理 、备份与恢复

目录 一 MySQL 日志 (一),日志位置 (二)配置文件中 与日志相关的代码 1,错误日志 2,通用查询日志 3,二进制日志(binlog) 4,中继日志 5,慢查询日志…

国内ip地址随意更换的潜在风险和策略

在数字化时代,IP地址是互联网通信的基础,而国内IP地址的随意更换可能带来一系列安全风险和问题。虎观代理小二将探讨国内IP地址随意更换的潜在影响以及如何有效应对这一挑战。 1.什么是国内IP地址? 国内IP地址是指在国内分配和使用的IP地址&…

企事业单位如何判断第三方软件测试机构的专业性和可信度?

第三方软件测试机构,指的是独立于被测试软件开发者和用户的中立测试机构。它们承担着对软件进行全面测试和评估的任务,以确保软件的质量和稳定性。那么,企事业单位在选择时应怎样判断一个第三方软件测试机构的专业性和可信度呢? 一个专业的…

Data.olllo解密:秒数转换为日期格式的神奇技能!

引言: 时间是数据世界中不可或缺的一环,而将秒数转换为易读的日期格式往往是数据处理中的一大挑战。但是,有了Data.olllo,这一任务将变得异常简单! 功能介绍: Data.olllo的秒数转换功能可以让您轻松地将秒…

小折叠手机如何经久耐用?收下这份日常养护指南

不同于普通手机的玻璃屏幕,折叠机出于折叠的特性,使用了柔性屏幕。因此撕除原厂保护膜时,由于贴膜较强的粘合力,很容易就会导致屏幕产生不可修复的损伤。 这也是为什么各大手机厂商都不允许折叠机私自贴膜的原因,并且…