第3章 ROS2环境搭建与核心概念

说实话,每次带新人入门ROS2,我都要先问一句:你之前用过ROS1吗?

如果用过,那恭喜你——很多概念是相通的。但千万别觉得可以无缝切换。我在一个项目里吃过这个亏,直接把ROS1的节点代码扔到ROS2里编译,结果报错报得我怀疑人生。

如果没用过,那更简单。你直接学ROS2就好,省去了改习惯的麻烦。

3.1 ROS2安装:选对版本,少走弯路

ROS2的版本迭代挺快的。我个人习惯用Humble Hawksbill,它是2022年的LTS版本,支持到2027年。做产品开发,LTS是首选,别追新。

Ubuntu版本 推荐ROS2版本 支持周期
Ubuntu 22.04 Humble(推荐) 2027年
Ubuntu 20.04 Foxy 2023年(已EOL)
Ubuntu 24.04 Jazzy 2029年
⚠ 我曾经踩过的坑: 千万别用apt直接装默认源里的ros2,版本太老。一定要先添加ROS2官方源。

安装步骤其实就四步,我帮你捋清楚:

  1. 设置语言环境——确保系统支持UTF-8
  2. 添加ROS2源——导入GPG密钥,把源写入sources.list
  3. 安装核心包——sudo apt install ros-humble-desktop
  4. 配置环境变量——把source /opt/ros/humble/setup.bash加到.bashrc里
💡 我的习惯: 装完立刻跑一下ros2 run demo_nodes_cpp talker和ros2 run demo_nodes_py listener。如果能通信,说明环境没问题。

3.2 核心概念:节点、话题、服务、参数

ROS2的四个核心概念,说白了就是机器人程序之间怎么说话、怎么干活。我画了张图,你先看个整体结构:

ROS2 核心概念关系图 激光雷达驱动节点 /lidar_driver 运动控制节点 /motor_controller 处理中心节点 /processing_node 话题 /scan 话题 /cmd_vel 服务(Service)—— 请求-响应模式 例如:处理中心请求“启动电机”,运动控制节点响应“已启动” 服务请求 参数(Parameter)—— 运行时配置 例如:激光雷达的扫描频率、运动控制的最大线速度 参数配置 节点是基本单元,话题是数据流,服务是远程调用,参数是配置开关

3.3 节点(Node)

节点就是ROS2里的最小执行单元。每个节点只干一件事,干好一件事。

比如我们的激光雷达项目里:

  • /lidar_driver——只管读取雷达数据
  • /motor_controller——只管给电机发PWM
  • /processing_node——只管做SLAM建图

为什么不能一个程序干所有事?

我在早期项目里试过。一个节点里既读雷达又控电机,结果雷达数据一卡,电机就乱转。拆成独立节点后,每个节点可以单独调试、单独重启,互不影响。

启动一个节点很简单:

ros2 run <包名> <节点名>

查看所有运行中的节点:

ros2 node list

3.4 话题(Topic)

话题是节点之间单向发布-订阅的通信方式。说白了,就是有人喊话,有人听。

举个例子:

  • 激光雷达节点往/scan话题上发布数据
  • 处理中心节点订阅/scan话题,接收数据
  • 处理中心算完路径后,往/cmd_vel话题上发布速度指令
  • 运动控制节点订阅/cmd_vel,执行指令
💡 调试技巧: 用ros2 topic echo /scan可以实时看数据。我曾经靠这个命令排查过一个雷达数据丢帧的问题——发现是USB带宽不够。

常用的话题命令:

命令 作用
ros2 topic list 列出所有话题
ros2 topic echo /topic_name 打印话题数据
ros2 topic info /topic_name 查看话题详情
ros2 topic hz /topic_name 查看发布频率

3.5 服务(Service)

话题是单向的,服务是请求-响应的。你想想看,有时候你需要一个明确的答复,比如:

  • “请启动电机”——“已启动”
  • “请重置里程计”——“已重置”

服务由客户端发起请求,服务端处理并返回响应。我习惯把服务用在那些需要确认的操作上,比如校准、复位、切换模式。

# 调用服务示例
ros2 service call /motor_enable std_srvs/srv/SetBool "{data: true}"
⚠ 注意: 服务是同步的。客户端发请求后会阻塞等待响应。如果服务端处理时间太长,整个流程会卡住。我在一个项目里用服务做路径规划,结果规划耗时3秒,导致控制循环卡死。后来改成话题+异步回调才解决。

3.6 参数(Parameter)

参数就是节点的运行时配置。不用改代码,不用重启节点,就能调整行为。

比如我们的激光雷达节点:

  • scan_frequency——扫描频率,默认10Hz
  • range_min——最小探测距离,默认0.1m
  • range_max——最大探测距离,默认10m

查看参数:

ros2 param get /lidar_driver scan_frequency

设置参数:

ros2 param set /lidar_driver scan_frequency 20.0

我的经验: 参数特别适合做现场调试。有一次在仓库里测试,激光雷达的探测距离不够,我直接远程改了range_max参数,从10米调到15米,问题立刻解决。不用重新编译,不用停机。

3.7 实操:跑通第一个ROS2通信

光说不练假把式。我们来跑一个最简单的例子:

  1. 打开终端1——启动一个发布者节点
ros2 run demo_nodes_cpp talker
  1. 打开终端2——启动一个订阅者节点
ros2 run demo_nodes_py listener

如果看到终端2不断打印I heard: "Hello World",恭喜你,ROS2通信跑通了。

💡 验证一下: 在第三个终端里运行ros2 node list,你会看到/talker和/listener两个节点。再运行ros2 topic list,会看到/chatter话题。这就是节点+话题的完整链路。

嗯,到这里ROS2的核心概念你已经都接触过了。节点是骨架,话题是血管,服务是电话,参数是旋钮。后面的章节里,我们会把这些概念全部用到激光雷达和运动控制的集成开发中。