ROS话题通信详细讲解:从原理到实战
创作时间:
作者:
@小白创作中心
ROS话题通信详细讲解:从原理到实战
引用
CSDN
1.
https://blog.csdn.net/saojiakre/article/details/145529787
ROS(机器人操作系统)的话题通信是其最常用的通信模式,主要用于数据传输。本文将从数据类型、概念原理到具体实现,详细讲解ROS话题通信的方方面面。通过C++和Python两种编程语言的实例,帮助读者全面理解并掌握这一核心技术。
数据类型
在深入讲解ROS话题通信之前,有必要先了解与ROS配套的数据类型包std_msgs中包含的各种类型:
- 整型:int8,int16,int32,int64(有int就有对应的无符号整型uint)
- 浮点型:float32,float64
- 其他:string,time,duration
此外,ROS还支持自定义数据类型,但本文暂不涉及。
话题通信
话题通信是ROS中最常用的通信模式,主要用于数据传输。
概念
话题通信基于发布订阅模式,由四个核心部分组成:
- 发布方:负责在特定话题中发布数据
- 订阅方:负责从特定话题中获取数据
- 管理者:ROS内置组件,负责将发布者和订阅者建立连接
- 话题:可以理解为一个主题或事件,当发布者和订阅者有共同话题时,就可以建立连接
实现原理
- 发布方将话题和RPC地址发布给管理者
- 订阅方将需要的话题发布给管理者,如果管理者有对应的话题,将把发布方信息(RPC地址)传给订阅方
- 订阅方与发布方连接,发布方将TCP地址给订阅方
- 发布方发布的数据订阅方可以接收
实现效果
ROS话题通信实现效果示例
案例实现
接下来,我们将通过一个具体的案例来演示ROS话题通信的实现。要求编写代码实现ROS中消息的发布与订阅:创建一个发布者,每隔100ms依次发送斐波那契数列的数字到话题/fibonacci中;创建一个订阅者,订阅该话题并输出订阅结果。
实操步骤
建立工作空间
打开终端,输入以下命令建立工作空间:
mkdir -p demo02_ws/src cd demo02_ws catkin_make打开VSCode,建立Catkin Package:
- 输入功能包名字
- 依赖包:
roscpp rospy std_msgs
- 修改VSCode配置文件(如果使用集成环境可以跳过):
{ "version": "2.0.0", "tasks": [ { "label":"catkin_make:debug", "type": "shell", "command":"catkin_make", "args": [], "group":{"kind" :"build", "isDefault": true}, "presentation": { "reveal": "always", }, "problemMatcher": "$msCompile", } ] }
C++实现
- 修改配置文件:
- 主要修改"cStandard"和"cppStandard",确保代码有提示
建立发布者实现文件:
#include "ros/ros.h" #include "std_msgs/Int32.h" int main(int argc, char *argv[]) { ros::init(argc, argv, "pub01"); ros::NodeHandle nh; ros::Publisher pub = nh.advertise<std_msgs::Int32>("fibonacci", 10); ros::Rate rate(10); std_msgs::Int32 msg; int num1 = 0; int num2 = 1; ros::Duration(2).sleep(); while(ros::ok()) { int tmp = num2; num2 += num1; num1 = tmp; msg.data = num1; pub.publish(msg); rate.sleep(); ros::spinOnce(); } return 0; }建立订阅者实现文件:
#include "ros/ros.h" #include "std_msgs/Int32.h" void doMsg(const std_msgs::Int32::ConstPtr &msg) { std::cout << msg->data << std::endl; } int main(int argc, char *argv[]) { ros::init(argc, argv, "sub01"); ros::NodeHandle nh; ros::Subscriber sub = nh.subscribe("fibonacci", 10, doMsg); ros::spin(); return 0; }编译与运行:
- 修改CMakeLists.txt文件
- 启动ROS核心:
roscore - 刷新环境变量:
source ./devel/setup.bash - 运行订阅者:
rosrun test1_pub_sub sub01 - 运行发布者:
rosrun test1_pub_sub pub01
Python实现
- 创建文件夹和源文件:
- 在
test1_pub_sub文件夹下创建scripts文件夹 - 建立
pub01.py和sub01.py源文件
发布者实现:
#! /usr/bin/env python import rospy from std_msgs.msg import Int32 if __name__ == "__main__": rospy.init_node("pub01_p") pub = rospy.Publisher("fibonacci", Int32, queue_size = 10) msg = Int32() rate = rospy.Rate(10) rospy.sleep(2) num1 = 0 num2 = 1 while not rospy.is_shutdown(): tmp = num2 num2 += num1 num1 = tmp msg.data = num1 pub.publish(msg) rate.sleep()订阅者实现:
#! /usr/bin/env python import rospy from std_msgs.msg import Int32 def doMsg(msg): rospy.loginfo("%d", msg.data) if __name__ == "__main__": rospy.init_node("sub01_p") sub = rospy.Subscriber("fibonacci", Int32, doMsg, queue_size = 10) rospy.spin()运行测试:
- 添加可执行权限:
chmod +x *.py - 启动ROS核心:
roscore - 刷新环境变量:
source ./devel/setup.bash - 运行订阅者:
rosrun test1_pub_sub sub01.py - 运行发布者:
rosrun test1_pub_sub pub01.py
通过以上步骤,读者可以完整地实现一个ROS话题通信案例,进一步理解ROS的核心通信机制。
热门推荐
在南方,包子和馒头究竟有没有区别?
92号与95号汽油的主要区别是什么?
春晚现场惊现尴尬!岳云鹏遭观众当面开炮,德云社一哥还能否续写辉煌?
如何进行车辆检查?定期车辆检查的重要性是什么?
Oracle数据库表空间创建与管理完全指南
模拟芯片与数字芯片的区别及应用场景解析
李煜的诗歌世界,从帝王到词人的心灵独白
年金险和商业养老保险的差别在哪
基尼系数的计算方法及步骤
管理和维护操作系统更新
这场超高规格的民营企业座谈会,透露出哪些信息?
营业执照使用指南:异地经营、办理流程及正副本悬挂规范
明成祖朱棣五次北伐亲征,均获得成功,为何却没开拓更多的领土?
每班每周一节武术课,还有武术大课间!中山这所小学人人会“打拳”
Excel中多次方运算的多种方法与技巧
心火走嘴、肺火走鼻……发在五官的“火”,根源在内脏
张红甫教你做川味回锅肉家常做法最正宗
全国有多少种“柠檬”?哪个品种最好吃?今天全读懂,来涨知识了
损伤防治:膝关节周围韧带损伤
英国小哥创作国风歌曲讲述中国故事,最喜欢周杰伦的歌
三角函数记忆口诀:正弦、余弦、正切的快速记忆方法
唐代宗李豫:平定安史之乱的帝王,为何晚年却让宦官掌权?
双皮奶是什么材料做成的?详解双皮奶的制作材料与营养功效
食品科学与工程专业哪个学校最好?附全国排名前100强的大学名单
山东人闯关东的历史与文化背景
老人装什么假牙比较好?三种假牙种类及优缺点分析
杏仁有哪些常见的副作用?
2025年中东市场投资前景全面分析:热门行业与抓住风口策略
從生存必需品到現代美食:探討乾果的歷史演變與健康迷思
凤凰古城住宿推荐:古城风情体验