3. 搭建ROS2开发环境与ROV仿真工作空间

ROV仿真不是打开一个软件就能直接跑起来的,它依赖一条完整的软件栈:操作系统 → ROS2 发行版 → 工作空间 → 功能包 → 构建产物。本节把这条栈从底向上搭好,并规划出后续章节要反复使用的 ROV 仿真功能包结构。环境搭建阶段最容易出问题的地方往往不是命令本身,而是版本匹配和路径配置,所以下面会明确给出推荐组合与判断依据。

一、Ubuntu 与 ROS2 发行版的版本对应关系

ROS2 的每个发行版都绑定特定的 Ubuntu 版本,装错组合会在编译或运行阶段出现大量难以定位的依赖错误。课程以 Ubuntu 22.04 LTS + ROS2 Humble 作为基准环境,这是目前水下机器人仿真生态(Gazebo、ros_gz、xacro、robot_state_publisher 等)支持最完整的长期支持组合。如果你的机器是 Ubuntu 24.04,则应改用 ROS2 Jazzy,但后续部分功能包的 API 细节会有差异,建议优先使用 22.04。

ROS2 发行版对应 Ubuntu支持状态本课程适用性
Humble Hawksbill22.04 LTSLTS,至 2027推荐,仿真生态最完整
Jazzy Jalisco24.04 LTSLTS,至 2029可用,注意 API 差异
Iron Irwini22.04 LTS非 LTS,已停止维护不建议

安装方式推荐使用官方 apt 源,而不是源码编译。先配置 locale 与软件源,再安装桌面版:

# 1. 设置 UTF-8 本地化(ROS2 日志与中文路径依赖)
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

# 2. 添加 ROS2 apt 源
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

# 3. 安装 ROS2 Humble 桌面版与构建工具
sudo apt update
sudo apt install ros-humble-desktop ros-dev-tools

安装完成后必须验证,而不是“装完就算”。打开一个新终端执行 source /opt/ros/humble/setup.bash,然后运行 ros2 run demo_nodes_cpp talker 与 ros2 run demo_nodes_py listener,若 listener 终端持续打印 I heard: [Hello World: N],说明 DDS 通信、Python 与 C++ 运行时均正常。这一步同时验证了 ROS2 的发布/订阅链路,是后续 ROV 话题通信的基础。

把 source /opt/ros/humble/setup.bash 写入 ~/.bashrc 可以省去每次手动加载,但要注意:工作空间的 setup.bash 必须在其之后 source,否则工作空间内的功能包不会被覆盖到环境变量中。

二、创建工作空间与 colcon 构建

ROS2 使用 colcon 作为构建工具,它按目录约定工作:源码放在 src/,构建中间产物在 build/,安装结果在 install/,测试日志在 log/。工作空间本身没有“创建”命令,建好目录结构即可:

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

--symlink-install 对仿真开发非常关键:它让 install 目录中的 Python 脚本、launch 文件、URDF/xacro 模型以符号链接方式指向 src 中的源文件,修改后无需重新 build 即可生效,只有 C++ 代码变更才需要重新编译。构建成功的判断依据是终端输出 Summary: N packages finished 且无 failed 项,同时 install/ 下出现对应包目录。

常用构建参数需要按场景选择:只编译某个包用 --packages-select rov_description;编译某包及其下游依赖用 --packages-up-to rov_bringup;并行度不足导致内存溢出时用 --parallel-workers 2;清理单个包用 --packages-select ... --cmake-clean-cache。养成“改完先 build 再 source”的习惯,可以避免大量“找不到包”的假故障。

三、ROV 仿真功能包结构规划

功能包划分决定了后续章节的可维护性。把模型、仿真世界、控制算法、启动文件混在一个包里,会导致依赖膨胀、编译变慢、复用困难。推荐按职责拆分为五个包,形成清晰的依赖方向:描述层 → 仿真层 → 控制层 → 应用层,由 bringup 统一编排。

~/rov_ws 工作空间与功能包依赖 rov_ws/ ├─ src/ ├─ build/ ├─ install/ └─ log/ colcon 目录约定 rov_description urdf/ xacro 模型 meshes/ 螺旋桨与舱体 rviz/ 显示配置 纯资源包,无运行节点 rov_gazebo worlds/ 水池环境 models/ 水下道具 config/ 物理与浮力参数 依赖 description rov_control 推力分配节点 深度/姿态控制器 参数 yaml 订阅传感器,发布推力 rov_bringup launch/ 一键启动 参数组合与命名空间 rviz 与 ros_gz 桥接 编排层,不含算法 rov_msgs msg/ 自定义消息 srv/ 服务定义 被 control 与 bringup 引用 接口层,先编译 构建顺序与验证 colcon build --symlink-install --packages-up-to rov_bringup 验证:ros2 pkg list | grep rov → 应列出 5 个包;ros2 launch rov_bringup sim.launch.py 可启动水池与 ROV 箭头方向表示依赖:被指向的包需要先构建

各包的职责边界需要说清楚。rov_description 只放 URDF/xacro 与网格模型,不包含任何可执行节点,它被其他包通过 package:// 路径引用;rov_gazebo 存放水池世界文件、水下道具模型以及浮力、阻尼、水阻等物理参数配置;rov_control 实现推力分配与深度/姿态控制,订阅传感器话题、发布推进器推力指令;rov_msgs 定义自定义消息与服务,被控制层和编排层共同引用,因此必须最先编译;rov_bringup 是编排层,用 launch 文件把模型、世界、控制器、ros_gz 桥接和 RViz 组合起来,本身不含算法逻辑。

创建包时用 ros2 pkg create 并显式声明依赖,例如描述包:

cd ~/rov_ws/src
ros2 pkg create rov_description --build-type ament_cmake \
  --dependencies urdf xacro
ros2 pkg create rov_msgs --build-type ament_cmake \
  --dependencies rosidl_default_generators
ros2 pkg create rov_control --build-type ament_python \
  --dependencies rclpy std_msgs rov_msgs

注意 rov_msgs 需要在 package.xml 中补充 <member_of_group>rosidl_interface_packages</member_of_group>,否则消息生成不会生效。构建时若出现“找不到 rov_msgs”,通常就是漏了这一行,或没有先单独编译接口包。

不要把所有内容塞进一个包再靠 --packages-select 绕过依赖问题。包拆分带来的编译隔离和复用收益,在后续加入多机器人、不同水池场景时会非常明显。另外,工作空间路径不要包含中文或空格,colcon 与部分 CMake 脚本对此处理不佳。

完成上述步骤后,用一条命令做整体验收:ros2 pkg list | grep rov 应输出五个包名;ros2 pkg executables rov_control 应能看到控制节点;ros2 interface list | grep rov_msgs 应列出已生成的消息类型。三项都通过,说明操作系统、ROS2、工作空间、构建工具与包结构已经形成可用闭环,可以进入模型与仿真世界的具体搭建。