2. ROS2基础与开发环境搭建

ROS2 不是一套“仿真软件”,而是一套让机器人各部件彼此通信、协同工作的中间件与工具集合。对海洋无人装备而言,一艘无人艇上可能同时运行姿态解算、GPS 定位、推进器控制、避障感知、任务调度等多个程序,它们需要以松耦合的方式交换数据、请求服务、执行长时任务。ROS2 用节点、话题、服务、动作、参数这五个核心概念来组织这种协作关系。理解它们的分工,是后续搭建控制与仿真系统的前提。

五个核心概念的分工

节点(Node)是 ROS2 中最小的功能单元,一个节点通常只负责一件事,例如“读取 IMU 数据”或“计算航向偏差”。节点之间不直接调用彼此的函数,而是通过通信机制交互,因此可以独立启动、替换和调试。话题(Topic)是单向、异步、多对多的数据流,发布者持续发送消息,订阅者按需接收,适合传感器数据、状态广播这类高频流式信息。服务(Service)是请求—应答式的同步调用,客户端发一次请求、服务端回一次结果,适合“查询当前航点”“切换控制模式”这类短时确定操作。动作(Action)面向耗时任务,支持目标下发、周期反馈和中途取消,例如“航行到指定坐标并持续回报进度”。参数(Parameter)则是节点的可配置项,如控制增益、采样频率,可在运行时查询和修改。

选择哪种通信方式,关键看数据的方向与时长:持续单向流动用话题,一问一答用服务,长任务且需反馈或可取消用动作,配置项用参数。下图把这五种机制放在同一艘无人艇的典型数据链中,便于对照理解它们的连接方向与角色差异。

无人艇 ROS2 通信机制示意 IMU / GPS 节点 传感器发布者 状态估计节点 订阅并融合 推进器控制节点 订阅指令 话题 /sensor/imu 话题 /state/pose 任务调度节点 动作客户端 动作 /navigate_to 目标·反馈·取消 模式管理节点 服务端 服务 /set_mode 参数服务器 增益 / 频率 参数读写 机制对照 话题:单向、异步、多对多,适合传感器流与状态广播 服务:请求—应答,适合短时确定操作,如模式切换 动作:目标 + 周期反馈 + 可取消,适合长时航行任务 参数:节点运行时可读写的配置项,如控制增益与采样频率

在 Ubuntu 上安装 ROS2 Humble

ROS2 Humble 官方支持 Ubuntu 22.04(Jammy),这是当前最稳妥的组合。安装前先确认系统版本与区域设置,然后添加 ROS2 软件源。以下命令以官方文档流程为准,实际执行时需保证网络可访问软件源:

# 1. 确认系统版本
lsb_release -a          # 应显示 Ubuntu 22.04

# 2. 设置 UTF-8 区域
sudo apt update && sudo apt install locales
sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8

# 3. 添加 ROS2 源与密钥
sudo apt install software-properties-common curl
sudo add-apt-repository universe
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \
  -o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] \
  http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" \
  | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null

# 4. 安装桌面版
sudo apt update
sudo apt install ros-humble-desktop

# 5. 配置环境变量
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
source ~/.bashrc

安装完成后,用 ros2 --version 或 ros2 pkg list | head 验证。若命令不存在,多半是环境变量未生效,重新打开终端或手动 source 即可。桌面版已包含 rviz2、rqt 等常用工具,无需单独安装。

工作空间与常用工具

ROS2 的代码组织在“工作空间”中,典型结构是 src/ 放源码包,build/、install/、log/ 由构建工具自动生成。创建并初始化一个工作空间:

mkdir -p ~/marine_ws/src
cd ~/marine_ws
colcon build
source install/setup.bash

colcon 是构建工具,负责按依赖顺序编译包;rosdep 用于自动安装包声明的系统依赖,首次使用需 sudo rosdep init && rosdep update,之后在 src/ 下执行 rosdep install --from-paths src --ignore-src -r -y。rviz2 是三维可视化工具,可显示点云、位姿、TF 坐标变换;rqt 是图形化调试工具集,其中 rqt_graph 能直观看到节点与话题的连接关系,rqt_plot 可实时绘制数值曲线。这四个工具贯穿后续所有实验,建议在第一个实验里就逐一打开熟悉。

第一个节点通信实验

下面用 Python 写一对最小节点,验证话题通信。先创建功能包:

cd ~/marine_ws/src
ros2 pkg create --build-type ament_python marine_demo \
  --dependencies rclpy std_msgs

在 marine_demo/marine_demo/ 下新建 talker.py,以 1 Hz 发布模拟航向角;再建 listener.py 订阅并打印。核心逻辑是:发布者创建 Publisher,在定时器回调里 publish;订阅者创建 Subscription,在回调里读取 msg.data。两个节点使用同一个话题名 /heading 和同一消息类型 std_msgs/Float32,这是能通信的前提。

# talker.py 关键片段
import rclpy
from rclpy.node import Node
from std_msgs.msg import Float32

class Talker(Node):
    def __init__(self):
        super().__init__('heading_talker')
        self.pub = self.create_publisher(Float32, '/heading', 10)
        self.timer = self.create_timer(1.0, self.tick)
        self.angle = 0.0
    def tick(self):
        self.angle = (self.angle + 5.0) % 360.0
        msg = Float32(); msg.data = self.angle
        self.pub.publish(msg)
        self.get_logger().info(f'发布航向: {self.angle:.1f}')

编译并运行:colcon build --packages-select marine_demo,source 后分别在不同终端执行 ros2 run marine_demo talker 与 ros2 run marine_demo listener。若订阅端每秒打印一次递增的航向值,说明话题链路打通。此时再开一个终端执行 ros2 topic echo /heading 可看到原始消息,ros2 topic hz /heading 应显示约 1 Hz,ros2 node list 与 rqt_graph 则能确认两个节点及它们之间的话题连接。

判断实验是否成功的三个依据:订阅端持续收到数据、ros2 topic hz 频率与设定一致、rqt_graph 中出现 talker→/heading→listener 的连接。若订阅端无输出,优先检查话题名是否拼写一致、消息类型是否匹配、是否 source 了工作空间的 install/setup.bash。

这套“建包—写节点—编译—运行—用工具观测”的流程,就是后续所有控制与仿真实验的基本骨架。把五个核心概念与四个工具用熟,才能在无人艇的多节点系统中快速定位问题、扩展功能。