由于Holoocean仿真环境自身开发复杂(基于UE5的引擎开发),本项目并不打算建模新的水下机器人进而实现全Sim2Real流程。本项目旨在借助提供的Hovering AUV搭建Sim端系统框架与算法验证。
- 开发环境
| 項目 | 版本 |
|---|---|
| 操作系統 | Ubuntu20.04 |
| 显卡 | NVIDIA GeForce RTX 4080 super |
| Nvidia Driver | 550.144.03 |
| Python | 3.10.16(ros2使用系统的3.8.10) |
| PyTorch | 2.6.0 |
| CUDA | 12.4 |
| ROS2 | foxy |
| holoocean | 2.0.0 |
- HoloOcean环境
使用的Agent:Hovering AUV(Holoocean中,HoveringAUV与BlueROV2拥有相同逻辑,因此也可使用BlueRov2)
搭载的传感器:坐标系满足右手法则,且一律x向前、y向左,z向上。
| 传感器 | 坐标系 | 数据格式 | 备注 |
|---|---|---|---|
| PoseSensor | n系下表示 | 4x4位姿矩阵 | 传感器安装的位置$R_{nb}(\Theta_{nb})$和$[x^n_{b,n},y^n_{b,n},z^n_{b,n}]$ |
| VelocitySensor | n系下表示 | 传感器安装的位置的速度m/s | |
| IMUSensor | b西 | 4x3矩阵 | 加速度单位:m/s,角速度单位 rad/s |
| DepthSensor | n系下表示 | number | 深度m |
| RangeFinderSensor | b系下表示 | n维向量 | 激光雷达m |
| DVLSensor | n系下表示 | 7维向量 | m/s |
| SingleBeam Sonar | b系下表示 | n纬向量 | 测距用声纳m |
| RGBCamera | 相机坐标系 | 256x256x256x4的ndarray | 左右各一个RGBA相机 |
| RotationSensor | b系相对于n系,n系下表示 | 传感器安装位置的欧拉角,角度单位 | |
预配值的场景在env中定义。可参考Holoocean文档配置自己的场景。
- holoocean 键盘与手柄的快捷键映射
| 键盘 | 手柄 | 备注 |
|---|---|---|
| q | 0/A | 视角下降 |
| v | 1/B | 切换观众模式 |
| c | 3/X | 切换相机模式 |
| e | 4/A | 视角上升 |
| shift | 6/LB | 快速移动视角 |
| esc | 7/RB | 退出 |
| h | 10/return | 切换Hub |
| tab | 11/= | 切换设备 |
| w | Up | 视角前移 |
| s | Down | 视角后移 |
| a | Left | 视角左移 |
| d | Right | 视角右移 |
- ROS2
本项目Holoocean与ROS2独立运行不同的python环境。
Holoocean中单独完成仿真,但是为了使用ROS2中提供的规划、控制功能包,以及后续的接入Dave仿真器,有必要建立ROS2Bridge。
本项目使用Socket在Holoocean客户端与Ros2服务端之间通信。通信节点负责在二者之间转发数据。Ros并不是必需的,所有需要从客户端转发到服务端的数据都通过ros_bridge下client.py文件中定义的Ros2SocketClient类实现,同时在Ros服务端使用python和cpp分别实现(单独运行一个)的SocketServerNode类接收并转发为ROS2通信类型。
在上述方法之外,基于ros_bridge实现的通信更加实用。ROS2中使用到的相关的数据接口定义在holoocean_interface功能包中。
- 使用
Important
命名规定
本项目大多数情况下使用PEP8命名规则:
| 分类 | 推荐写法 ✅ | 不推荐写法 ❌ |
|---|---|---|
| 缩进 | 每层 4 个空格 | 混用 tab 和空格 |
| 行宽 | ≤79 个字符(代码行),≤72(注释/文档) | 过长一行(>120) |
| 空格 | x = a + b |
x=a+b |
spam(ham[1], {eggs: 2}) |
spam( ham[ 1 ], { eggs: 2 } ) |
|
| 空行 | 顶层函数/类之间 2 个空行类中方法之间 1 个空行 | 堆在一起无间隔 |
| 变量命名 | count, get_value, user_name |
Count, GetValue, UserName |
| 函数命名 | def calculate_area(): |
def CalculateArea(): |
| 类命名 | class RobotController: |
class robot_controller: |
| 常量命名 | MAX_SPEED = 5 |
MaxSpeed = 5 |
| 导入顺序 | 先标准库 → 第三方库 → 本地模块 | import sys, os (同一行多个 import) |
| 布尔值 | if is_ready: |
if is_ready == True: |
| 空序列判空 | if not my_list: |
if len(my_list) == 0: |
| 行内注释 | x = x + 1 # 增加计数 |
x = x + 1#增加计数 |
| 文档字符串 | python<br>def func():<br> """说明函数作用"""<br> |
用 # 写函数说明 |
| 换行风格 | python<br>result = (long_function_name(<br> arg1, arg2, arg3,<br> arg4, arg5<br>))<br> |
所有参数写在一行,行超长 |
- 基本测试
在test文件夹下有项目相关的测试脚本,其中基础功能集成在environment.py中,运行以下命名快速开始:
python ./test/environment.py --scenario SimpleUnderwater-Hovering --agent auv0 --controller 0 --showInTerminator 0 --joystick_index 0 --path_auto 0 其中controller提供三种控制模式,使用手柄控制时,需要先查看系统手柄编号(默认为0),运行以下命令查看:
sudo lsusb 使用自动跟踪路径时,支持三种轨迹,使用path_auto参数指定。
-
Ros2测试
首先需要编译ros2_ws:
cd ../ros2_ws
colcon build
source install/setup.bash
ros2 run holoocean_bridge_py socket_server_py 然后就可以运行客户端以建立连接:
# 根目录下
python ./test/controller_test.py --ros2 True --mode 1 --mini_error 0.8 之后建立会自动建立连接,可在另一终端查看话题转发:
ros2 topic echo /action_topic
| 变化方向 | P 增大 | I 增大 | D 增大 |
|---|---|---|---|
| 响应速度 | 提高 | 提高(缓慢) | 减慢 |
| 稳态误差 | 存在(无法消除) | 减少 | 无影响 |
| 震荡风险 | 增加 | 增加(因积累过多) | 减少 |
| 抗干扰能力 | 较差 | 易积累扰动 | 抗短期扰动强 |
| 实时性 | 强 | 慢 | 依赖前后状态差 |
关于holoocean-->Ros2感知信息转换:
odom Frame的初始位置与base_link重合,但当base_link与世界坐标系不重合时会导致 运动异常。
位置发布一律为world下的位置,姿态一律发布欧拉角转换的四元数,速度在world下,角速度在body下,线加速度也在body下。
- gym环境包装
sb3使用的所有环境都需要是gym包装的VecEnv。因此首先需要将holoocean集成到gym。
- 封装holoocean的Gymnasium接口,通过Gymnasium.env_checker检测
- 基于SB3构建控制器实现控制。
- 基于点云构建栅格地图,并进行路径规划。
- 基于协程和线程优化代码