ROS2 中级进阶:从"会写节点"到"能搭系统",看这一篇就够了

摘要:入门阶段你已经学会了怎么写节点、跑话题、用 launch 文件。但真正做项目时,你会发现光会这些远远不够——话题收不到怎么办?坐标对不上怎么办?十几个节点怎么一键启动?参数怎么动态调?本文从通信机制、系统管理、调试工具三大块,系统梳理 ROS2 中级阶段必须掌握的核心知识,覆盖 90% 的日常开发场景。

关键词:ROS2;中级教程;话题;TF;Launch;调试


一、写在前面

入门阶段,你可能已经能跑通官方示例,写一个简单的发布者/订阅者,用 launch 启动两三个节点。但当你真正开始做项目——比如搭一个 SLAM 小车、机械臂抓取系统——你会发现:

  • 十几个节点,一个一个手动启动太麻烦
  • 改了参数要重新编译,效率极低
  • 激光雷达数据收不到,不知道是驱动问题还是 QoS 不匹配
  • RViz 里模型乱飞,TF 坐标对不上

中级阶段的核心目标,就是从**“会写一个节点"进化到"能独立搭建一整套机器人系统”**。

下面从三大块展开:通信机制、系统管理、调试工具。


二、通信机制:三种通信方式

ROS2 有三种通信方式:话题(Topic)、服务(Service)、动作(Action)。入门阶段你可能只接触过话题,中级阶段要把三种都掌握。

2.1 话题(Topic)—— 持续发、持续收

话题是 ROS2 最常用的通信方式,适合传感器数据、控制指令这类持续流动的数据。

常用命令
# 查看当前系统中有哪些话题,-t 显示话题类型
ros2 topic list -t

# 查看某个话题的详细信息:谁在发、谁在收、消息类型
ros2 topic info /scan

# 实时查看话题数据
ros2 topic echo /scan

# 查看话题发布频率(Hz)
ros2 topic hz /scan

# 查看话题带宽占用
ros2 topic bw /scan

# 手动发布一条测试数据(验证订阅者是否正常)
ros2 topic pub /cmd_vel geometry_msgs/msg/Twist "{linear: {x: 0.5}, angular: {z: 0.0}}"
典型场景
  • 激光雷达驱动发布 /scan 话题,SLAM 节点订阅
  • 导航节点发布 /cmd_vel 话题,底盘驱动订阅

2.2 服务(Service)—— 一问一答

服务是同步通信,客户端发请求,服务端处理完返回结果。适合偶尔调用、需要确认结果的场景,比如"开关激光雷达"“获取电池电量”。

常用命令
# 查看当前系统中有哪些服务
ros2 service list -t

# 调用服务
ros2 service call /my_service std_srvs/srv/Trigger

# 查看服务接口的定义(请求和响应分别是什么字段)
ros2 interface show std_srvs/srv/Trigger
典型场景
  • 调用 /clear 服务清除代价地图
  • 调用 /spawn 服务在 Gazebo 中生成一个模型

2.3 动作(Action)—— 长时间任务,能看进度、能取消

动作是 ROS2 独有的通信方式,适合耗时较长、需要中途反馈进度、可以取消的任务,比如"导航到某点"“机械臂抓取物体”。

常用命令
# 查看当前系统中有哪些动作
ros2 action list -t

# 查看动作详情
ros2 action info /navigate_to_pose

# 发送动作目标,并实时查看反馈
ros2 action send_goal /navigate_to_pose nav2_msgs/action/NavigateToPose \
  "{pose: {header: {frame_id: 'map'}, pose: {position: {x: 2.0, y: 1.0}}}}" --feedback

三者对比

通信方式特点适用场景
话题持续发、持续收,不保证送达传感器数据、控制指令
服务一问一答,同步等待结果开关控制、查询状态
动作长时间任务,能反馈进度、能取消导航、抓取、路径规划

一句话总结:话题是广播,服务是打电话,动作是派活(能干一半叫停)。


三、系统管理:把一堆节点组装成系统

入门阶段你可能只跑过两三个节点。但真实项目中,一个机器人系统可能有十几个节点:驱动、感知、规划、控制……中级阶段要学会怎么把它们组织起来。

3.1 TF 坐标变换

机器人身上有激光雷达、摄像头、底盘、机械臂,每个部件都有自己的坐标系。SLAM 建图、导航规划都需要知道它们之间的位置关系,这就是 TF。

常用命令
# 生成坐标树 PDF,直观查看 TF 树是否完整、有没有断开的分支
ros2 run tf2_tools view_frames

# 查看两个坐标系之间的具体变换值(平移 + 旋转)
ros2 run tf2_ros tf2_echo world turtle1

# 监控 TF 发布状态:频率、延迟、是否有断更
ros2 run tf2_ros tf2_monitor

# 发布静态坐标变换(比如激光雷达相对于底盘的位置)
ros2 run tf2_ros static_transform_publisher 0.1 0 0.2 0 0 0 base_link laser_link
典型场景
  • SLAM 建图时需要 map → odom → base_link → laser_link 这条 TF 链
  • RViz 里模型乱飞,大概率是 TF 树断了或者时间戳不一致

3.2 参数(Parameter)

硬编码在代码里的值(比如速度、PID 参数)每次改都要重新编译。参数可以运行时动态调整,不用重启节点。

常用命令
# 查看节点有哪些可调参数
ros2 param list /teleop_turtle

# 查看某个参数的当前值
ros2 param get /teleop_turtle scale_linear

# 运行时动态修改参数(无需重启节点)
ros2 param set /teleop_turtle scale_linear 10.0

# 导出当前所有参数到 YAML 文件(方便备份和对比)
ros2 param dump /teleop_turtle | sudo tee teleop_turtle.yaml

# 从 YAML 文件加载参数
ros2 param load /teleop_turtle teleop_turtle.yaml
注意事项
  • 参数值按 YAML 格式解析,off 会被当成布尔值,要写字符串得加引号:'off'
  • 只有动态声明的参数才能用 set 修改,静态参数改了要重启节点

3.3 Launch 文件

一个机器人系统有十几个节点,一个一个手动启动太麻烦。Launch 文件可以一键启动所有节点,还能传参数、设命名空间、编排启动顺序。

常用命令
# 启动 launch 文件
ros2 launch nav2_bringup navigation_launch.py

# 查看 launch 文件支持哪些启动参数
ros2 launch nav2_bringup navigation_launch.py --show-args

# 只打印 launch 文件要启动哪些节点,不实际执行(调试用)
ros2 launch nav2_bringup navigation_launch.py --print-description
学到什么程度
  • 能用 Python 写 launch 文件
  • 会启动节点、传参数、加载 YAML
  • 会用条件启动(比如仿真时才启动 Gazebo)
  • 会设置命名空间(多机器人场景)

3.4 包管理

代码多了要分模块,依赖要管理,编译要配置。

常用命令
# 创建 C++ 包
ros2 pkg create my_pkg --build-type ament_cmake --dependencies rclcpp std_msgs

# 创建 Python 包
ros2 pkg create my_pkg --build-type ament_python --dependencies rclpy

# 查看系统中所有包
ros2 pkg list

# 查看某个包的安装路径
ros2 pkg prefix my_pkg

# 查看包里有哪些可执行文件
ros2 pkg executables my_pkg

# 只编译某个包(节省时间)
colcon build --packages-select my_pkg

# 软链接安装(改 Python 代码不用重新编译)
colcon build --symlink-install

四、调试工具:看系统状态、录数据

4.1 节点管理

# 查看当前系统中有哪些节点在跑
ros2 node list

# 查看某个节点的详细信息:订阅了哪些话题、发布了哪些话题、有哪些服务
ros2 node info /my_node

4.2 数据录制与回放(ros2 bag)

把话题数据录下来,后面反复回放分析,不用每次都跑真机。这在算法调试、数据复现时非常有用。

常用命令
# 录制指定话题的数据
ros2 bag record /scan /odom /cmd_vel -o my_bag

# 查看录制文件的详细信息(话题、消息数量、时长)
ros2 bag info my_bag

# 回放录制的数据
ros2 bag play my_bag
典型场景
  • 采集真实环境的激光雷达数据,在电脑上离线调试 SLAM 算法
  • 复现 bug:把出问题时的数据录下来,反复回放定位问题

4.3 可视化调试

RViz2

3D 可视化工具,可以查看 TF 坐标、激光点云、地图、规划路径等。

rviz2
RQt 工具集
rqt_graph          # 查看节点和话题的连接关系图,一眼看出数据流
rqt_console        # 查看日志,支持过滤和搜索
rqt_plot           # 画数值曲线,比如看速度、角速度随时间的变化
环境诊断
# 检查 ROS2 环境配置是否正常(DDS、网络、依赖等)
ros2 doctor

# 获取完整诊断报告
ros2 doctor --report

五、中级阶段要能做出来的东西

学完上面这些,你应该能独立搭一个这样的系统:

激光雷达驱动 → 发布 /scan 话题
     ↓
SLAM 节点(如 slam_toolbox)→ 发布 /map 话题 + TF 变换
     ↓
导航节点(如 Nav2)→ 发布 /cmd_vel 话题
     ↓
底盘驱动 → 接收速度指令,控制电机

要求:

  • 用 launch 文件一键启动所有节点
  • 参数用 YAML 文件管理,不用硬编码
  • 日志分级输出(INFO/WARN/ERROR)
  • 坐标变换用 TF 管理
  • 能用 ros2 bag 录制数据,离线调试

六、总结

中级阶段的核心就三块:

模块核心内容常用命令
通信机制话题、服务、动作topic list/info/echo/hz、service list/call、action list/send_goal
系统管理TF、参数、Launch、包管理tf2_echo、param list/set、ros2 launch、colcon build
调试工具节点管理、bag、可视化node list/info、bag record/play、rviz2、rqt_graph

入门学的是**“怎么跑起来”,中级学的是"怎么搭系统"**。掌握这三块,你就具备了独立开发机器人项目的能力。


写在最后

ROS2 的知识点很碎,光看文章记不住。建议边学边练,每学一个命令就在终端里敲一遍,跑通一个示例再往下走。有问题欢迎在评论区留言讨论。

觉得有用的话,点赞收藏不迷路! 你的支持是我持续更新的动力~

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐