ROS2 :Node 与 Topic 初探(Python)

在 ROS2 中,节点(Node)话题(Topic) 是最基础、最常用的通信机制。掌握如何查询、监控、调试它们,是每一位 ROS2 开发者必备的技能。本文将简单介绍 ROS2 中 Node 和 Topic 的基本操作,包括命令行工具和 Python 代码实现,并教你如何快速定位“谁在发布、谁在订阅”。

1. 概念速览

  • Node:ROS2 图中的一个计算单元,可以完成特定任务(如读取传感器、控制电机)。每个节点都有自己的命名空间。
  • Topic:节点间传递消息的“总线”。节点可以发布(publish) 消息到某个话题,也可以订阅(subscribe) 该话题接收消息。话题采用异步、多对多的通信模式。

2. 常用命令行操作(查询、列表、结构、数据、频率)

以下命令基于 ROS2 Humble,在其他版本中基本一致。

2.1 节点操作

目的命令
列出所有活跃节点ros2 node list
查看节点详细信息ros2 node info <node_name>
列出节点中定义的话题/服务ros2 node info 输出中会显示
$ ros2 node list /talker /listener $ ros2 node info /talker /talker Subscribers: /parameter_events: rcl_interfaces/msg/ParameterEvent Publishers: /chatter: std_msgs/msg/String /parameter_events: rcl_interfaces/msg/ParameterEvent Services: /talker/describe_parameters: rcl_interfaces/srv/DescribeParameters ...

2.2 话题操作

目的命令
列出所有活跃话题ros2 topic list(加 -t 可显示消息类型)
查看话题详细信息(类型、发布/订阅者数量)ros2 topic info <topic_name>
实时打印话题数据ros2 topic echo <topic_name>
查看话题发布频率(Hz)ros2 topic hz <topic_name>
查看话题带宽(B/s)ros2 topic bw <topic_name>
手动发布数据到话题ros2 topic pub <topic_name> <msg_type> '<data>'
查找使用某消息类型的话题ros2 topic find <type_name>
查看话题的消息结构ros2 interface show <msg_type>ros2 topic echo --once
# 列出话题和消息类型 $ ros2 topic list -t /chatter [std_msgs/msg/String] /parameter_events [rcl_interfaces/msg/ParameterEvent] /rosout [rcl_interfaces/msg/Log] # 查看话题详细信息 $ ros2 topic info /chatter Type: std_msgs/msg/String Publisher count: 1 Subscription count: 1 # 实时监控数据 $ ros2 topic echo /chatter data: "Hello ROS2" # 查看发布频率(稳定后才能显示) $ ros2 topic hz /chatter average rate: 10.012 Hz

3. 如何知道谁发布、谁订阅?

两种方法:

  1. 使用 ros2 node info:对每个节点查看其 publishers 和 subscribers 列表。
  2. 使用 ros2 topic info:只告诉你发布者和订阅者的数量,不直接给节点名。要获得节点名,可以结合 ros2 node listros2 node info 逐个查询。

更快捷的技巧
运行 rqt_graph 图形化工具,它会动态绘制出所有节点、话题以及发布/订阅关系。

rqt_graph

4. Python 代码示例:创建一个发布者节点和一个订阅者节点

我们将编写两个简单的 Python 节点:

  • talker:每秒发布一次字符串消息到 /chatter 话题。
  • listener:订阅 /chatter 话题并打印收到的消息。

4.1 创建功能包

source /opt/ros/humble/setup.bash ros2 pkg create --build-type ament_python my_py_nodes --dependencies rclpy std_msgs

4.2 编写发布者节点 talker.py

my_py_nodes/my_py_nodes/ 目录下创建 talker.py

#!/usr/bin/env python3 import rclpy from rclpy.node import Node from std_msgs.msg import String import time class Talker(Node): def __init__(self): super().__init__('talker') # 创建发布者,话题为 /chatter,队列大小10 self.publisher_ = self.create_publisher(String, '/chatter', 10) timer_period = 1.0 # 秒 self.timer = self.create_timer(timer_period, self.timer_callback) self.counter = 0 def timer_callback(self): msg = String() msg.data = f'Hello ROS2, count: {self.counter}' self.publisher_.publish(msg) self.get_logger().info(f'Publishing: "{msg.data}"') self.counter += 1 def main(args=None): rclpy.init(args=args) node = Talker() rclpy.spin(node) node.destroy_node() rclpy.shutdown() if __name__ == '__main__': main()

4.3 编写订阅者节点 listener.py

在相同目录下创建 listener.py

#!/usr/bin/env python3 import rclpy from rclpy.node import Node from std_msgs.msg import String class Listener(Node): def __init__(self): super().__init__('listener') # 创建订阅者,话题为 /chatter,回调函数为 callback self.subscription = self.create_subscription( String, '/chatter', self.callback, 10 ) self.subscription # 防止被垃圾回收 def callback(self, msg): self.get_logger().info(f'I heard: "{msg.data}"') def main(args=None): rclpy.init(args=args) node = Listener() rclpy.spin(node) node.destroy_node() rclpy.shutdown() if __name__ == '__main__': main()

4.4 修改 setup.py

entry_points 中添加两个可执行程序:

entry_points={ 'console_scripts': [ 'talker = my_py_nodes.talker:main', 'listener = my_py_nodes.listener:main', ], },

4.5 编译与运行

colcon build --packages-select my_py_nodes source install/setup.bash

终端1(启动发布者):

ros2 run my_py_nodes talker

终端2(启动订阅者):

ros2 run my_py_nodes listener

现在应该能看到订阅者终端打印出发布者发送的消息。

5. 调试与监控实例

在运行上述两个节点后,可以实践之前的命令:

# 查看所有节点 ros2 node list # 输出: /talker /listener # 查看话题列表 ros2 topic list -t # 查看 /chatter 的发布/订阅关系 ros2 node info /talker # 看到 Publisher: /chatter ros2 node info /listener # 看到 Subscriber: /chatter # 实时打印话题数据 ros2 topic echo /chatter # 查看话题发布频率(发布者以 1Hz 发送) ros2 topic hz /chatter # 输出:average rate: 1.000 Hz

6. 进阶操作:ros2 topic pub 手动发布

即使没有发布者节点,也可以手动向话题发送消息。例如:

ros2 topic pub /chatter std_msgs/msg/String "{data: 'Manual message'}" --once

如果希望以固定频率重复发送,加 --rate 2 参数(每秒2次)。

7. 常见问题与技巧

  • 话题消息类型不匹配:使用 ros2 topic info 查看期望类型,再与你的消息对比。
  • 看不到数据:检查是否所有节点使用了相同的 ROS_DOMAIN_ID(默认0)。
  • 频率不稳定:检查回调函数是否执行耗时操作,或者使用 create_wall_timer 控制发布频率。
  • 查看消息结构ros2 interface show std_msgs/msg/String

8. 总结

通过本文,你应该已经掌握了:

  • 使用 ros2 noderos2 topic 命令行工具查询节点、话题的列表、类型、发布/订阅关系、数据内容和频率。
  • 如何快速找到“谁发布了哪个话题,谁订阅了它”。
  • 用 Python 编写发布者和订阅者节点,并运行、调试。
  • 手动发布测试消息的方法。

这些技能是构建和调试复杂 ROS2 机器人系统的基础。在实际项目中,你还可以结合 rqt_graphros2 bag 录制话题数据等工具进一步提升效率。现在,去构建你自己的 ROS2 应用吧!

                                                老徐,2026/04/04

Read more

FPGA 项目开发完整流程及常用工具梳理(工程向,收藏专用)

FPGA 项目开发完整流程及常用工具梳理(工程向,收藏专用)

很多刚接触 FPGA 的同学,会下意识把注意力放在“语法”“IP”“例程”上。 但真正做过项目之后就会发现: FPGA 工程从来不是“把代码写对”这么简单。 一个 FPGA 项目能不能顺利交付,往往取决于你是否具备完整的工程视角,而不是会不会某几条 always 块。 从需求理解,到代码实现,再到板级调试,FPGA 工程师的工作,本质上是一条不断自证、不断修正的工程闭环。 下面就从工程实践角度,梳理一套FPGA 项目中常见、且真正有用的开发流程与工具。 一、理解需求与系统背景(不是一上来就写代码) FPGA 项目的第一步,永远不是打开 Vivado / Quartus。 而是把下面几件事搞清楚: * 这个 FPGA 在系统中扮演什么角色 * 数据从哪里来,到哪里去 * 上下游是谁(CPU / ADC / PHY / 传感器

飞书机器人与Claude Code交互:从手机指令到AI处理的全自动流程

飞书机器人与Claude Code交互:从手机指令到AI处理的全自动流程

飞书机器人与Claude Code交互:从手机指令到AI处理的全自动流程 * 一、背景 * 二、实现方案概览 * 三、操作步骤 * 前置准备 * 第一步:创建并进入Claude Code容器 * 配置Claude Code使用本地模型 * 测试Claude Code是否正常工作 * 第二步:安装Python依赖 * 第三步:获取飞书应用的凭证 * 第四步:编写并运行中间件脚本 * 脚本解释 * 运行脚本 * 第五步:在飞书中与机器人对话 * 常见问题 * 总结 一、背景 在日常开发中,我们经常需要快速查询代码问题、生成文档或执行简单的编程任务。如果有一款AI助手能随时响应,就像在电脑终端前一样,那该多方便!本教程将演示如何搭建一个飞书机器人,当你在手机飞书App上发送消息时,该消息会传递给运行在电脑上的Claude Code(一个智能编码助手),Claude Code处理后将结果回复到你的飞书会话中。 通过这个方案,你可以: * 在手机上随时向AI提问编程问题。 * 让AI帮你调试

基于目标偏置与双向APF-RRT*的无人机动态避障轨迹优化

1. 无人机轨迹规划:为什么传统方法在动态环境里“不够看”? 大家好,我是老张,在无人机和机器人路径规划这个领域摸爬滚打了十几年。今天想和大家聊聊一个非常实际的问题:无人机在复杂、动态的环境里,怎么才能规划出一条既安全又高效的飞行路线? 这听起来像是个科幻电影里的场景,但其实是当下无人机物流、巡检、应急救援等领域必须啃下的硬骨头。 想象一下,你操控一架无人机在布满高楼、树木,甚至还有其他飞行器的城市峡谷里穿梭。传统的路径规划方法,比如经典的 RRT(快速探索随机树) 算法,就像是一个蒙着眼睛的探险家。它会在整个空间里随机“扔飞镖”(采样点),然后尝试把飞镖落点连起来形成路径。这种方法虽然能保证最终找到一条路,但效率实在太低了,规划出的路径往往歪歪扭扭,像喝醉了酒一样,而且对动态障碍物反应迟钝。我在早期项目里没少吃这个亏,无人机要么撞上突然出现的飞鸟,要么规划的路径绕了十万八千里,电量耗尽都飞不到目的地。 后来有了 RRT* 算法,它在RRT的基础上增加了“重布线”和“父节点重选”的优化步骤,能让路径长度逐渐逼近最优,算是很大的进步。但它在面对动态环境时,依然有个核心问题:

LazyLLM 测评 | 低代码颠覆 AI 开发!代码专家智能体进阶模块实战

LazyLLM 测评 | 低代码颠覆 AI 开发!代码专家智能体进阶模块实战

摘要: LazyLLM 是商汤大装置推出的开源低代码框架,作为构建和优化多 Agent 应用的一站式开发框架,覆盖应用搭建、数据准备、模型部署、微调、评测等全流程开发环节,提供丰富的工具支持。其以模块化设计打破传统开发壁垒,通过数据流驱动重构开发逻辑,能让开发者用极简代码实现工业级复杂 AI 应用,摆脱冗余编码束缚,聚焦核心业务场景,降低 AI 应用构建成本并支持持续迭代优化。堪称 AI 开发者的 “效率神器”,其技术普惠理念为 AI 开发领域带来新的实践范式,推动了更高效的开发模式。本文将以Python编程为切入点,带你深入了解LazyLLM框架。 LazyLLM 是构建和优化多 Agent 应用的一站式开发工具,为应用开发过程中的全部环节(包括应用搭建、数据准备、模型部署、模型微调、评测等)提供了大量的工具,协助开发者用极低的成本构建 AI 应用,并可以持续地迭代优化效果。 LazyLLM作为商汤大装置推出的开源低代码框架,简直是AI开发者的“效率神器”