ROS2话题topic通信怎么用?发布订阅让两个节点传数据的实操

写launch的皮皮开源复现 2026-10-14 08:47:30 13阅读 举报

ROS2里最常用也最容易上手的通信方式就是话题topic。它解决的核心问题是:让机器人系统里不同的节点(比如一个读激光、一个控制底盘)能松耦合地传数据,谁都不用知道对方是谁,只要约好“在哪个话题上传什么类型的数据”就行。这篇文章把自己跑通一个发布订阅的实操流程写给你。

先搞懂三个概念:话题、发布者、订阅者

把机器人想象成一屋子同事,话题就是一块公共白板,发布者就是往白板上写字的人,订阅者就是盯着白板看的人。同一个话题上,可以有很多发布者同时写,也可以有很多订阅者同时读,互不干涉。话题有名字、有固定的消息类型,发布者和订阅者只有“话题名+类型”都一致才能对上话。

这种设计的好处是解耦:底盘节点只负责订阅/cmd_vel话题上的速度指令,它根本不关心是手柄发的、还是导航算法发的,谁发布到那个话题它就听谁的。这就是为什么ROS2能拼乐高式地搭机器人。

用命令行最快感受话题

如果还没写程序,最快上手的方式是用命令行。装好自带turtlesim(龟模拟器),先启动它,再开启turtle_teleop_key用方向键控制那只龟。

这时你新开一个终端敲 ros2 topic list ,就能看到/cmd_vel、/pose这些话题;想看点实际数据,用 ros2 topic echo /turtle1/cmd_vel ;想直接往话题塞数据,用 ros2 topic pub --once /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0}, angular: {z: 1.8}}" ,那只龟就会真的动起来。一个终端发命令、另一个终端看echo,发布订阅的关系感受一下就通了。

写一个Python发布者和订阅者

真正写节点也很直接。发布者这边,先rclpy.init()建个Node,然后用create_publisher(String, 'topic', 10)声明要往话题/topic发字符串消息,10是队列长度,然后每隔0.5秒在定时器回调里publish一条。

订阅者几乎是对称的:create_subscription(String, 'topic', callback, 10)订阅同一话题,一旦收到消息就触发回调打印出来。关键就一条——发布者和订阅者的“话题名+消息类型”必须完全一致,否则就像两个人不在同一个频道,谁也没听见谁。

记得source环境,别忘colcon构建

程序写完要跑起来,有几个前置动作很容易漏:先colcon build构建工作空间,再在每个新终端source安装好的setup脚本(比如 source install/setup.bash ),然后才能用 ros2 run 你的包 你的节点。漏了source,节点往往找不到,报的错五花八门,多数其实是环境没source对。

把最简单的发布订阅跑通,就等于摸到了ROS2的大门。后面上机器人实机,激光、里程计、/cmd_vel这些全是靠话题在节点间串起来的。这层机制懂了,再看那些玩具机器人的架构会豁然开朗。

版权声明:
作者:写launch的皮皮
链接:https://www.aiddithome.com/p/1b0f9625c324b1.html
来源:开源复现
实践版权归作者所有,未经允许请勿转载,若此实践存在违规行为,您可以点击 “举报”。


登录 后发表评论
4条评论

话题名和类型一致这条是核心,我两边名字差个下划线就对不上话

线比代码多
2楼 · 2天前

从命令行到写python节点都讲了,入门ROS2很顺,收藏了

拆开看看再说
3楼 · 2天前

用turtlesim练手那段太直观了,一个终端pub一个echo,发布订阅一下就懂了

source setup.bash 必忘项,不 source 节点怎么都起不来,报错五花八门