3. Gazebo水下仿真环境搭建

要在Gazebo中复现AUV的水下运动,仅安装仿真器是不够的:默认世界是陆地环境,没有水介质、没有浮力、也没有流体阻力。本节围绕四件事展开——安装Gazebo、编写水下世界文件、搭建海洋环境模型、配置浮力与阻力插件,最终得到一个“AUV放进去会按物理规律浮沉与受阻”的可运行场景。

一、安装Gazebo与ROS2桥接组件

本课程以ROS2 Humble + Gazebo Fortress(Ignition)组合为例。推荐使用官方APT源安装,避免源码编译带来的依赖问题。核心包包括仿真器本体、ROS2与Gazebo的桥接包,以及常用的传感器与控制器插件库。

sudo apt update
sudo apt install ros-humble-ros-gz \
                 ignition-fortress \
                 ros-humble-ros-gz-sim \
                 ros-humble-ros-gz-bridge
# 验证安装
gz sim --versions
ros2 pkg list | grep ros_gz

安装完成后,用gz sim shapes.sdf启动一个空世界做冒烟测试,能正常弹出图形界面并加载地面即说明基础环境可用。若在无显示器的服务器上运行,改用gz sim -s -r以无头模式启动,后续通过ROS2话题观察仿真状态。

二、水下世界文件的结构

Gazebo世界文件本质是一个SDF文件,描述“世界里有什么”。水下世界与陆地世界的差别集中在三处:全局物理参数、水介质属性、以及环境模型(海床、水体可视化、洋流)。下面是一个精简但可用的水下世界骨架,示例参数仅作教学参考,实际可按任务调整。

<sdf version="1.6">
  <world name="underwater_world">
    <physics name="1ms" type="ignored">
      <max_step_size>0.001</max_step_size>
      <real_time_factor>1.0</real_time_factor>
    </physics>
    <gravity>0 0 -9.81</gravity>
    <plugin filename="ignition-gazebo-physics-system"
            name="ignition::gazebo::systems::Physics"/>
    <plugin filename="ignition-gazebo-scene-broadcaster-system"
            name="ignition::gazebo::systems::SceneBroadcaster"/>
    <!-- 水介质与海床模型在此插入 -->
  </world>
</sdf>

注意max_step_size取1ms:浮力与阻力插件对时间步长较敏感,步长过大容易导致AUV在水面附近抖动或穿透。这是水下仿真与陆地仿真在配置上的第一个显著差异。

三、海洋环境建模

海洋环境由“看得见的水”和“起作用的水”两部分组成。看得见的部分用可视化模型表达:一个半透明的蓝色水体盒(或平面)覆盖仿真区域,配合海床地形模型,让操作者能直观判断AUV的深度与姿态。起作用的部分则由插件提供:水体密度、粘性系数、洋流速度等参数,供浮力与阻力插件读取。

海床可用gz sim自带的heightmap或简单的地形网格;水体可视化常用一个带透明材质的box或plane,材质颜色设为浅蓝、透明度约0.3。洋流则通过在世界中挂载洋流插件、给定一个三维速度向量(如0.2 0 0表示沿X方向0.2 m/s的均匀流)来实现。下图展示了水下世界各组成部分之间的数据与作用关系。

underwater_world.sdf(世界文件) 全局物理参数 重力 g = 0 0 -9.81 步长 max_step_size = 1 ms 水介质属性 密度 ρ ≈ 1025 kg/m³ 粘性 / 阻力系数 海洋环境模型 海床地形 + 水体可视化 洋流速度向量 浮力插件 读取 ρ 与排水体积 输出向上浮力 F = ρgV 阻力插件 线性/二次阻尼系数 随速度方向产生反向力 洋流插件 施加均匀流速度场 与阻力耦合产生漂移 AUV 刚体模型 蓝色:参数供给 橙色:力/速度作用 最终共同决定AUV的浮沉、姿态与漂移

四、浮力与阻力插件配置

Gazebo本身不内置“水”,浮力与阻力需要借助插件实现。常用做法有两种:一是使用社区的水下插件(如uuv_simulator或asv_wave_sim系列中的浮力/阻力插件),二是在AUV的URDF/SDF中直接挂载ignition::gazebo::systems::Buoyancy与自定义阻力插件。以Buoyancy系统插件为例,它按几何体的排水体积与流体密度计算浮力,配置片段如下:

<plugin filename="ignition-gazebo-buoyancy-system"
        name="ignition::gazebo::systems::Buoyancy">
  <uniform_fluid_density>1025</uniform_fluid_density>
</plugin>

阻力则通常通过ignition::gazebo::systems::Hydrodynamics插件配置,需要给出AUV的线性阻尼与二次阻尼系数。这些系数与艇体外形、迎流面积相关,教学示例中可先取一组合理假设值(如线性阻尼5.0、二次阻尼1.2),再通过仿真观察运动是否平滑、是否出现异常振荡来调整。配置时务必保证插件挂在AUV的<model>内部,且link_name与实际连杆名一致,否则插件静默失效。

判断浮力配置是否正确,可先让AUV在无推力状态下静置:若缓慢上浮至水面并稳定漂浮,说明浮力略大于重力;若持续下沉,说明排水体积或密度参数偏小。这是最直接的验证手段。

五、启动与结果观察

把世界文件与AUV模型组织好后,用gz sim underwater_world.sdf启动,或通过ROS2 launch文件同时拉起ros_gz_bridge,将/model/auv/odometry等话题桥接到ROS2侧。观察要点有三:AUV的深度是否随时间收敛到平衡位置、给定推力后速度是否因阻力而趋于稳定、洋流开启后是否出现预期的横向漂移。若出现抖动,优先检查步长与阻尼系数;若完全不动,检查插件是否被正确加载(终端会打印插件加载日志)。

至此,一个具备水介质、海床、浮力与阻力的水下仿真环境就搭建完成,后续的AUV建模、传感器配置与控制算法验证都将在这个世界中进行。