【ROS】如何让ROS中节点实现数据交换Ⅰ--ROS话题通信

news/2025/2/11 2:07:47/

img

Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法…感兴趣就关注我吧!你定不会失望。

目录

  • 0.ROS文件系统及常用指令
  • 1.话题通信概念
  • 2.利用标准消息类型实现话题通信实现(python)
    • 2.1发布方实现
    • 2.2订阅方实现
  • 3.利用自定义消息类型实现话题通信(python)
    • 3.1自定义消息类型话题通信发布方实现
    • 3.2自定义消息类型话题通信接收方实现

在这里插入图片描述

0.ROS文件系统及常用指令

roscore 启动ros核心节点

roscd 将工作空间切换到指定ros功能包

catkin_create_pkg 将工作空间切换到指定ros功能包

**rqt_graph 启动节点间的关系图在这里插入图片描述
rosrun 包名 节点名称 启动节点rosrun turtlesim turtlesim_node

roslaunch 包名 launch文件名称 启动Launch文件

比较常用的目前就这一些,之后的命令现用现学就好了

1.话题通信概念

在ros中,机器人的各个部件(雷达|摄像头等部件)相互之间通信需要用到一种通信方式:话题通信,其理论模型为在这里插入图片描述

这里有一个简单的定义:订阅方与发布方通过同一个话题连接起来相互,发布方提供消息,订阅方获得消息,是一个单向的过程,虽然在这过程中似乎没有出现ros master这个角色,但发布方向订阅方第一次发送消息需要经过rosmaster,再到订阅方.(从上图也可以看出),在此之后就不需要rosmaster了

订阅方与与发布方都可以有多个,启动也无先后顺序

2.利用标准消息类型实现话题通信实现(python)

这里我们采用python实现,在接触到的机器人二次开发中大多用的都是python
当然,二者思想差不多,且ros当中用不同语言写的各个节点之间也是可以直接互相通信的

2.1发布方实现

先来分析下需求

  1. 初始化ros节点
  2. 创建发布者对象
  3. 组织发布逻辑,编写发布数据

接下来总体描述下如何写这段程序,

  1. 导入rospy,其是一个ros python标准包,以及从标准消息中导入String这个类型
  2. 初始化当前节点init_node(节点名称)
  3. 实例化发布对象Publisher(话题名称,消息类型,等待消息队列(可不填 默认10))
  4. 创建消息对象
  5. 实例化Rate对象,设置消息频率Rate(HZ)
  6. 当节点不被关闭时循环执行 is_shutdown()
  7. 将消息对象赋值,利用pub发布对象发布信息publish(消息对象)
  8. 在屏幕上打印出发送信息,实现消息反馈loginfo(字符串)
  9. 设置休眠时间,与上文设置的Rate频率相关
import rospyfrom std_msgs.msg import Stringrospy.init_node("pub")pub=rospy.Publisher("che",String,queue_size=10)msg=String()rate=rospy.Rate(1)i=0while not rospy.is_shutdown():msg.data="hello "+(str)(i)pub.publish(msg)i+=1rospy.loginfo(msg.data)rate.sleep()

最后为这个py文件加上可执行权限,在当前功能包路径下的CMakelist中将刚刚的python文件添加到这里在这里插入图片描述
( 并在catkin_ws也就是ros根目录空间下执行source ./devel/setup.bash)在终端执行rosrun 包名 话题名即可运行
在这里插入图片描述

这就是话题通信的发布方实现,接下来我们再来看看订阅方是如何实现的

2.2订阅方实现

  1. 初始化ros节点
  2. 实例化订阅方对象
  3. 处理订阅到的消息

接下来总体描述下如何写这段程序,

  1. 导入rospy,其是一个ros python标准包,以及从标准消息中导入String这个类型
  2. 初始化当前节点init_node(节点名称)
  3. 实例化接受对象Subsrciber(话题名称,消息类型,回调函数,等待消息队列(可不填 默认10))
  4. 这里的回调函数相当于一个函数指针,实例化这个对象的时候会调用回调函数对消息进行一个处理
  5. 所以回调函数的传入参数就是收到的消息类型,我们把他在屏幕上打印出来就可以了
  6. 使节点一直处于活跃状态,能处理接收到的消息spin()

import rospyfrom std_msgs.msg import Stringdef callback(msg):rospy.loginfo(msg.data)rospy.init_node("sub")sub=rospy.Subscriber("che",String,callback,queue_size=10)rospy.spin()

最后为这个py文件加上可执行权限

在当前功能包路径下的CMakelist中将刚刚的python文件添加到这里(在noetic版本之前不需要执行这一步操作在这里插入图片描述

并在catkin_ws也就是ros根目录空间下执行source ./devel/setup.bash

在终端执行rosrun 包名 话题名即可运行并编译一下

我们也尝试运行下这个代码,方法与上文相同

  1. 先运行一下pub节点在这里插入图片描述

  2. 新打开一个终端,在运行一下sub节点在这里插入图片描述

成功啦,这就是利用标准消息参数进行话题通信。

3.利用自定义消息类型实现话题通信(python)

数据载体是一个较为重要组成部分,ROS 中通过 std_msgs 封装了一些原生的数据类型,比如:String、Int32、Int64、Char、Bool、Empty… 但是,这些数据一般只包含一个 data 字段,结构的单一意味着功能上的局限性,当传输一些复杂的数据,比如: 激光雷达的信息… std_msgs 由于描述性较差而显得力不从心,这种场景下可以使用自定义的消息类型

这部分内容主要代码是与上文相同,仅将std_msgs.msg替换成了自己设定的库,所以主要是修改配置文件的过程。

  1. 首先在当前功能包下创建一个msg的文件夹,里面存放你的自定义消息类型在这里插入图片描述

  2. 创建一个.msg的消息类型,我这里的名字是Person.msg,里面有三个标准类型

    string name

    int32 age

    float32 height

  3. 在功能包目录下的package.xml中加入这两行(54与59)
    在这里插入图片描述

    其中54行的message_generation是编译时的消息软件包
    而59行message_runtime是运行时的消息软件包

  4. 在CMakeList中找到这些地方并修改

    find_package(catkin REQUIRED COMPONENTS
    rospy
    std_msgs
    message_generation
    )
    # 需要加入 message_generation,必须有 std_msgs## 配置 msg 源文件
    add_message_files(
    FILES
    Person.msg
    )# 生成消息时依赖于 std_msgs
    generate_messages(
    DEPENDENCIES
    std_msgs
    )#执行时依赖
    catkin_package(
    CATKIN_DEPENDS  rospy std_msgs message_runtime
    )
    
  5. 编译一下 可以在/工作空间/devel/lib/python3/dist-packages/包名/msg找到刚刚生成的消息类型
    在这里插入图片描述

  6. 之后要使用在这个消息包可以直接在代码中导入就可以了

    # from ros包名.msg import 消息名称
    from lesson2.msg import Person 
    

3.1自定义消息类型话题通信发布方实现

实现方法与之前的标准消息类型话题通信相同,仅在消息内容定义不同,所以这里就不过多赘述。
消息类型初始化的成员名与自定义消息类型中的成员名相同似乎有点废话hhhh

import rospyfrom lesson2.msg import Personrospy.init_node("pub_person")pub=rospy.Publisher("che",Person)p=Person()p.name="奥特曼"p.age=8p.height=1.5rate=rospy.Rate(1)while not rospy.is_shutdown():pub.publish(p)rate.sleep()rospy.loginfo("%s,%d,%f",p.name,p.age,p.height)

3.2自定义消息类型话题通信接收方实现


from lesson2.msg import Personimport rospydef doMsg(p):rospy.loginfo("%s,%d,%.2f",p.name,p.age,p.height)rospy.init_node("sub_person")#话题通信的话题必须与发布方相同
sub=rospy.Subscriber("che",Person,doMsg)rospy.spin()

最后配置下CMakeList就可以运行了(在noetic版本之前不需要执行这部操作)

rosrun lesson2 demo02_pub.py
rosrun lesson2 demo02_sub.py

在这里插入图片描述
在这里插入图片描述

成功啦,这就是利用自定义参数进行话题通信。


http://www.ppmy.cn/news/107422.html

相关文章

2023年上半年信息系统项目管理师上午真题及答案解析

1.“新型基础设施”主要包括信息技术设施、融合基础设施和创新基础设施三个方面。其中信息基础设施包括( )。 ①通信基础设施 ②智能交通基础设施 ③新技术基础设施 ④科教基础设施 ⑤算力基础设施 A.①③⑤ B.①④⑤ C.②③④ D.②…

【JavaSE】Java基础语法(三十六):File IO流

文章目录 1. File1.1 File类概述和构造方法1.2 绝对路径和相对路径1.3 File 类的常用方法1.4 递归删除文件夹及其下面的文件 2. IO2.1 分类2.2 字节输出流2.3 字节输入流2.4 文件的拷贝2.5 文件拷贝效率优化2.6 释放资源2.7 缓冲流2.8 编码表 3. commons-io 工具包3.1 API 1. F…

网络编程_TCP/IP四层协议分层

网络编程_TCP/IP四层协议分层 1. OSI七层协议模型 (open system interconnection)与TCP/IP四层协议分层2. 协议封装3. TCP 协议头部4.三次握手5.滑动窗口正常情况丢包情况 6.四次挥手 1. OSI七层协议模型 (open system interconnection)与TCP/IP四层协议分层 OSI七层协议模型 (…

AI落地:儿童节贺卡

昨天有个朋友Lisa找到我,她是幼儿园的老师,看到我最近搞了个爱落地星球,在研究各行各业AI落地的事情,问我能不能用AI帮她写一百多张贺卡。 说起来写贺卡,我只会写“节日快乐”。现在有了ChatGPT,那就大不一…

阿里一面凉凉,幸获内推华为技术四面,offer到手

上个月,哥们从某小厂离职,转投阿里云,简历优秀,很顺利地拿到了面试通知,但之后的进展却让哥们怀疑人生了,或者说让哥们懵逼的是,面试阿里云居然第一面就被吊打?让哥们开始怀疑自己&a…

数据结构基础-数组

2.1 数组 概述 定义 在计算机科学中,数组是由一组元素(值或变量)组成的数据结构,每个元素有至少一个索引或键来标识 In computer science, an array is a data structure consisting of a collection of elements (values or v…

Win10系统更新时不小心中断了无法启动怎么办?

Win10系统更新时不小心中断了无法启动怎么办?有用户使用的Win10系统电脑在进行系统更新的时候,被自己误触了电脑导致更新进程中断了。那么遇到这样的情况我们怎么去进行问题的解决呢?接下来我们一起来看看以下的解决方法吧。 准备工作&#x…

Strategy策略

本文档参考backtrader官方文档,是官方文档的完整中文翻译,可作为backtrader中文教程、backtrader中文参考手册、backtrader中文开发手册、backtrader入门资料使用。 Strategy策略章节目录 策略(Strategy)策略入门如何买入/卖出/平仓信息位成员属性:成员属性(用于统计/观察者…