基于 TJU-Aerial-Robotics/YOPO 的二次开发版本。 在原版基础上新增了随机动态障碍物、飞向无人机的障碍物、时序深度图融合、动态安全损失函数等功能,用于在障碍物密集的动态环境中训练和测试基于学习的无人机自主导航规划器。
- 项目简介
- 主要特性
- 系统架构
- 项目结构
- 环境依赖
- 安装步骤
- 测试策略
- 训练策略
- 动态障碍物系统
- 时序深度融合
- 损失函数设计
- 网络架构
- 轨迹优化参数
- TensorRT 部署
- RKNN 部署
- RViz 可视化
- 硬件平台
- 常见问题
- 引用
YOPO 是一种基于学习的无人机一次性规划器(one-stage planner),能将传统规划器的三个阶段——感知与建图、前端路径搜索、后端轨迹优化——统一整合到一个神经网络中。 本版本在此基础上进行了以下核心扩展:
- 动态障碍物支持:在 CUDA 加速的仿真器中引入随机移动障碍物和飞向无人机的障碍物,使训练和测试能在更具挑战性的动态环境中进行。
- 时序深度图融合:通过多帧深度图的指数衰减合成,产生类似"拖影"的效果,使得网络能感知动态障碍物的运动趋势。
- 动态安全损失:新增球体距离模型的安全损失函数,在训练时惩罚轨迹与动态障碍物的碰撞。
- 一键启动脚本:提供
start_yopo.sh脚本,一键启动 Controller、TF_ASSIST、Simulator、YOPO Planner 和 RViz 所有模块。
- 运动基元锚框(Motion Primitive Anchors):参考单阶段目标检测器 YOLO 的思路,采用一组运动基元覆盖搜索空间,网络预测基元的偏移量和评分来选择最优轨迹。
- 梯度直接反传训练:不同于模仿学习(给专家示范)或强化学习(试错探索),本方法直接将轨迹代价(ESDF 距离、平滑度、目标引导等)的梯度反传到网络权重,训练简单、精确、不依赖在线仿真交互。
| 特性 | 说明 |
|---|---|
| CUDA 加速仿真 | GPU 版本深度图渲染 > 1000fps(RTX 3060),支持无限延伸地图 |
| 动态障碍物 | 随机移动障碍物 + 飞向无人机障碍物,双栅格架构,无侵入式设计 |
| 时序深度融合 | 多帧深度拖影合成,运行时和数据采集/训练三端一致 |
| 动态安全损失 | 球体距离模型,支持梯度反传的动态碰撞代价 |
| 多种地图类型 | 溶洞、柱子、迷宫、随机森林、房间、墙面(maze_type 1-7) |
| 多传感器 | 深度相机 + 16线激光雷达,参数全配置化 |
| 部署加速 | 支持 TensorRT(NVIDIA GPU)和 RKNN(Rockchip NPU)部署 |
| 一键启动 | start_yopo.sh 一键启动所有模块 |
| RViz 多视角 | 5 种预设视角:第一人称、第三人称远/近、俯视选点、XY 跟随 |
┌─────────────────────────────────────────────────────────────────┐
│ ROS 通信框架 │
├──────────────┬──────────────────┬──────────────┬────────────────┤
│ Controller │ Simulator │ YOPO Net │ RViz 可视化 │
│ │ │ │ │
│ 四旋翼动力学 │ CUDA 加速渲染 │ ResNet-18 │ 深度图 │
│ SO3 姿态控制 │ 静态地图生成 │ Backbone │ 点云 │
│ 干扰观测器 │ 动态障碍物管理 │ YopoHead │ 轨迹 │
│ PID 位置控制 │ 深度图 + 雷达 │ 时序深度融合 │ 动态障碍物 │
│ │ 数据集采集 │ 5阶多项式 │ 多视角 │
└──────────────┴──────────────────┴──────────────┴────────────────┘
数据流:
深度图 (/depth_image) ──→ 时序融合 ──→ ResNet-18 Backbone ──→ YopoHead ──→ 轨迹评分+端点状态
↑ ↓
里程计 (/sim/odom) ──→ 状态归一化+基元变换 ──→ 状态特征 5阶多项式插值
↓
控制指令 (/so3_control/pos_cmd)
overlap_YOPO/
├── README.md # 本文档
├── start_yopo.sh # 一键启动脚本
├── LICENSE # MIT License
│
├── YOPO/ # 核心规划器代码
│ ├── config/
│ │ ├── config.py # 全局配置管理
│ │ └── traj_opt.yaml # 轨迹优化参数(速度、代价权重、基元参数等)
│ ├── policy/
│ │ ├── models/
│ │ │ ├── backbone.py # 视觉主干网络(ResNet-18 / ResNet-14)
│ │ │ ├── head.py # 预测头(3层 1x1 卷积)
│ │ │ └── resnet.py # ResNet 实现
│ │ ├── yopo_network.py # 网络前向传播与推理
│ │ ├── yopo_trainer.py # 训练器(训练循环、验证、保存)
│ │ ├── yopo_dataset.py # 数据集(时序深度合成 + 动态障碍物)
│ │ ├── primitive.py # 运动基元(lattice primitive)
│ │ ├── state_transform.py # 状态变换(体坐标 ↔ 基元坐标 ↔ 世界坐标)
│ │ └── poly_solver.py # 5阶多项式轨迹求解器
│ ├── loss/
│ │ ├── loss_function.py # 总损失函数(组合所有代价)
│ │ ├── safety_loss.py # 静态安全损失(ESDF 查询)
│ │ ├── dynamic_safety_loss.py # 动态安全损失(球体距离模型)
│ │ ├── smoothness_loss.py # 平滑度损失(Jerk + 加速度)
│ │ └── guidance_loss.py # 引导损失(目标方向投影)
│ ├── control_msg/
│ │ └── _PositionCommand.py # 控制消息定义
│ ├── train_yopo.py # 训练入口
│ ├── test_yopo_ros.py # ROS 测试入口(仿真 / 实飞)
│ ├── yopo_trt_transfer.py # PyTorch → TensorRT 模型转换
│ ├── yopo_rknn_transfer.py # PyTorch → RKNN 模型转换
│ ├── test_yopo_rknn_ros.py # RKNN 推理测试
│ ├── visualize_training.py # 训练结果可视化(权重分布 + loss 曲线)
│ ├── requirements.txt # Python 依赖
│ ├── saved/ # 预训练权重和 TensorBoard 日志
│ │ ├── YOPO_1/epoch50.pth # 预训练权重(静态环境)
│ │ ├── YOPO_2/ # 其他训练结果
│ │ ├── YOPO_3/
│ │ └── YOPO_4/
│ └── yopo.rviz # RViz 配置文件
│
├── Simulator/ # CUDA 加速仿真器
│ ├── src/
│ │ ├── config/config.yaml # 仿真器参数(地图、传感器、动态障碍物)
│ │ ├── include/
│ │ │ ├── sensor_simulator.cuh # CUDA 头文件(GridMap、DynamicObstacle 结构体)
│ │ │ ├── sensor_simulator.h # 仿真器头文件
│ │ │ ├── maps.hpp # 地图生成
│ │ │ └── perlinnoise.hpp # Perlin 噪声生成
│ │ ├── src/
│ │ │ ├── sensor_simulator.cu # CUDA 渲染核心(raycast + 动态栅格)
│ │ │ ├── sensor_simulator.cpp # ROS 节点主程序
│ │ │ ├── test_simulator_cuda.cpp # GPU 版仿真器(含动态障碍物管理)
│ │ │ ├── dataset_generator.cpp # 数据集采集(含时序深度 + 动态障碍物)
│ │ │ └── maps.cpp # 地图生成实现
│ │ └── readme.md # 仿真器详细文档
│ ├── DYNAMIC_OBSTACLES_README.md # 动态障碍物功能说明
│ └── dynamic.md # 动态障碍物代码文档
│
├── Controller/ # 四旋翼控制器
│ └── src/
│ ├── so3_control/ # SO3 姿态/位置控制器
│ │ ├── src/SO3Control.cpp # SO3 控制算法
│ │ └── src/NetworkControl.cpp # 神经网络控制接口
│ ├── so3_quadrotor_simulator/ # 四旋翼动力学仿真
│ │ ├── launch/
│ │ │ ├── simulator_attitude_control.launch # 姿态控制模式
│ │ │ └── simulator_position_control.launch # 位置控制模式
│ │ └── src/dynamics/Quadrotor.cpp # 动力学模型
│ └── utils/ # ROS 消息定义、TF 工具等
│
├── dataset/ # 采集的训练数据
│ ├── 0/ ~ 9/ # 每张地图的深度图(PNG)
│ ├── pose-0.csv ~ pose-9.csv # 对应的位姿标签(位置 + 四元数)
│ ├── obs-0.csv ~ obs-9.csv # 动态障碍物标签(球心 + 半径)
│ └── pointcloud-0.ply ~ pointcloud-9.ply # 点云地图(用于构建 ESDF)
│
├── hardware/ # 开源硬件设计
│ ├── hardware_list.pdf # 硬件清单
│ ├── carbon_main_frame.STEP # 碳纤维主框架
│ ├── carbon_bottom_plate.STEP # 碳纤维底板
│ ├── camera_mount (0-degree).STL # 相机支架(0°)
│ └── camera_mount (15-degree).STL # 相机支架(15°)
│
├── docs/ # 文档图片
│ ├── new_env.gif # 新环境演示
│ ├── click_in_rviz.gif # RViz 目标点选择
│ ├── simple_demo.gif # 简单演示
│ ├── sim2real.gif # Sim-to-Real 迁移
│ └── ...
│
└── RVIZ_VIEWS_GUIDE.md # RViz 多视角使用指南
| 依赖 | 版本/说明 |
|---|---|
| Ubuntu | 20.04 |
| CUDA | ≥ 11.8 |
| ROS | Noetic |
| Python | 3.8 |
| PyTorch | 2.4.1+cu118 |
| Conda | Miniconda / Anaconda |
| GPU | NVIDIA GPU(RTX 3060 及以上推荐) |
主要 Python 包:
torch==2.4.1+cu118
torchvision==0.19.1+cu118
opencv-python==4.11.0.86
scipy==1.10.1
numpy==1.22.3
tensorboard==2.14.0
open3d==0.19.0
rich==14.0.0
ruamel-yaml==0.17.21
git clone --depth 1 <仓库地址>
cd overlap_YOPOconda create --name yopo python=3.8
conda activate yopo
cd YOPO
pip install -r requirements.txtconda deactivate
cd Controller
catkin_makeconda deactivate
cd Simulator
catkin_makeCUDA 编译问题:如果
cuda_select_nvcc_arch_flags自动检测失败,请在Simulator/src/CMakeLists.txt中手动设置 CUDA 架构,例如 RTX 5060 GPU:set(ARCH_FLAGS "-gencode arch=compute_120,code=sm_120")详见 Simulator 说明。
./start_yopo.sh该脚本会依次在 gnome-terminal 中启动以下模块:
| 终端 | 模块 | 说明 |
|---|---|---|
| Controller | 四旋翼模拟器 | ROS Master + 动力学 + 姿态控制 |
| TF_ASSIST | TF 变换发布 | 使 RViz 能跟随无人机 |
| Simulator | 传感器模拟器 | CUDA 深度图 + 雷达 + 动态障碍物 |
| YOPO | 轨迹规划器 | 神经网络推理 + 轨迹发布 |
| RViz | 可视化 | 多视角观察 |
步骤 1:启动 Controller
cd Controller
source devel/setup.bash
roslaunch so3_quadrotor_simulator simulator_attitude_control.launch步骤 2:启动 TF_ASSIST(可选,用于 RViz 视角跟随)
cd Controller
source devel/setup.bash
roslaunch uav_utils tf_assist.launch步骤 3:启动 Simulator
cd Simulator
source devel/setup.bash
rosrun sensor_simulator sensor_simulator_cuda步骤 4:启动 YOPO Planner
cd YOPO
conda activate yopo
python test_yopo_ros.py --trial=1 --epoch=50参数说明:
--trial:训练编号(对应saved/YOPO_{trial}/)--epoch:使用的训练轮数--use_tensorrt=1:启用 TensorRT 加速推理
步骤 5:启动 RViz
cd YOPO
rviz -d yopo.rviz在 RViz 中点击工具栏的 2D Nav Goal,在地图上点击即可设置目标点(地图无边界,目标点可自由设置)。
通过在随机地图中随机重置无人机位姿来高效采集数据(深度图、位姿、点云地图、动态障碍物标签)。采集 100,000 个样本仅需 1-2 分钟,且只需采集一次。
cd Simulator
source devel/setup.bash
rosrun sensor_simulator dataset_generator数据采集的关键参数(在 Simulator/src/config/config.yaml 中配置):
| 参数 | 默认值 | 说明 |
|---|---|---|
env_num |
10 | 生成的地图数量 |
image_num |
10000 | 每张地图采集的深度图数量 |
temporal_history_frames |
10 | 每个样本沿轨迹渲染帧数(时序深度) |
temporal_decay_half_life |
0.8 | 拖影衰减半衰期(秒) |
dataset_dynamic_num |
2 | 每段轨迹生成的动态障碍物数量 |
dataset_obs_size_min/max |
0.4 / 0.8 | 动态障碍物尺寸范围(米) |
dataset_obs_speed_min/max |
0.5 / 1.5 | 动态障碍物速度范围(m/s) |
maze_type |
5 | 地图类型:1=溶洞 2=柱子 3=迷宫 5=森林 6=房间 7=墙面 |
采集的数据保存在 ./dataset/ 目录:
dataset/
├── 0/ ~ 9/ # 深度图(16-bit PNG,归一化到 0-65535)
├── pose-0.csv ~ 9.csv # 位姿标签:x, y, z, qw, qx, qy, qz
├── obs-0.csv ~ 9.csv # 动态障碍物标签:[cx, cy, cz, radius] × K
└── pointcloud-0.ply ~ 9.ply # 点云地图(用于训练时构建 ESDF)
cd YOPO
conda activate yopo
python train_yopo.py训练参数:
- 学习率:1.5e-4
- 批量大小:16
- 优化器:AdamW(fused=True)
- 默认训练 50 个 epoch
在 RTX 3080 + i9-12900K 上训练 100,000 个样本的 50 个 epoch 约需 1 小时。
性能提示:如果 CPU 采用 P-core + E-core 混合架构,建议绑定到 P-core:
taskset -c 1,2,3,4 python train_yopo.py
查看训练日志:
cd YOPO/saved
conda activate yopo
tensorboard --logdir=./TensorBoard 中可查看的指标:
Train/TrajLoss/Train/ScoreLoss:训练损失Eval/TrajLoss/Eval/ScoreLoss:验证损失Detail/SmoothLoss:平滑度代价Detail/SafetyLoss:静态安全代价Detail/DynamicLoss:动态安全代价Detail/GoalLoss:目标引导代价Detail/AccelLoss:加速度代价
cd YOPO
conda activate yopo
python visualize_training.py --checkpoint saved/YOPO_4/epoch50.pth --events saved/YOPO_4/events.out.tfevents.*生成权重直方图、逐层 L2 范数、各 loss 曲线等可视化图表。
动态障碍物系统采用双栅格架构(Dual-Grid Architecture),将静态地图和动态障碍物分离管理:
┌──────────────────────────────────────────┐
│ Raycast 渲染 │
│ mapQuery(x, y, z) = static OR dynamic │
├──────────────────┬───────────────────────┤
│ 静态栅格 │ 动态栅格 │
│ (map_cuda_) │ (dynamic_map_cuda_) │
│ ↑ 地图生成时写入 │ ↑ 每帧 CUDA 并行更新 │
│ 固定不变 │ 根据障碍物位置重写 │
└──────────────────┴───────────────────────┘
- 在指定范围内随机初始化位置和速度方向
- 碰到边界自动反弹(完全弹性碰撞)
- 小概率随机改变运动方向,增加不可预测性
- RViz 中显示为半透明红色立方体(Topic:
/dynamic_obstacles)
# config.yaml 配置
enable_dynamic_obstacles: true
num_dynamic_obstacles: 4
obstacle_size_min: 0.8 # 最小尺寸 (米)
obstacle_size_max: 1.5 # 最大尺寸 (米)
obstacle_speed_min: 1.0 # 最小速度 (m/s)
obstacle_speed_max: 3.0 # 最大速度 (m/s)
obstacle_spawn_x_range: 20 # X 方向生成范围 (±米)
obstacle_spawn_y_range: 20 # Y 方向生成范围 (±米)
obstacle_spawn_z_min: 1.0 # 最小高度
obstacle_spawn_z_max: 5.0 # 最大高度- 在无人机周围 360° 球面上随机生成
- 速度方向指向无人机当前位置
- 靠近或远离无人机后自动消失并重新生成
- RViz 中显示为半透明蓝色立方体(Topic:
/incoming_obstacles)
# config.yaml 配置
enable_incoming_obstacles: true
num_incoming_obstacles: 4
incoming_obstacle_size_min: 0.4 # 最小尺寸 (米)
incoming_obstacle_size_max: 0.6 # 最大尺寸 (米)
incoming_obstacle_speed_min: 0.5 # 最小相对速度 (m/s)
incoming_obstacle_speed_max: 1.0 # 最大相对速度 (m/s)
incoming_spawn_distance_min: 8.0 # 最小生成距离 (米)
incoming_spawn_distance_max: 10.0 # 最大生成距离 (米)
incoming_despawn_distance: 0.5 # 靠近后消失距离 (米)
incoming_despawn_distance_max: 8.0 # 远离后消失距离 (米)| 技术要点 | 说明 |
|---|---|
| AABB 碰撞检测 | 轴对齐包围盒,高效判定体素占据 |
| CUDA 并行更新 | 每个线程处理一个体素,动态栅格更新 < 1ms |
| 物理仿真 | 欧拉积分 + 弹性碰撞反弹 |
| 球面均匀采样 | 飞来障碍物在 360° 任意方向生成 |
| 无侵入式设计 | 不修改 CUDA raycast 核心逻辑 |
// 添加动态障碍物
grid_map->addDynamicObstacle(int id, Vector3f position, Vector3f size);
// 更新障碍物位置
grid_map->updateDynamicObstacle(int id, Vector3f new_position);
// 移除障碍物
grid_map->removeDynamicObstacle(int id);
// 清空所有障碍物
grid_map->clearDynamicObstacles();| 指标 | GPU (RTX 3060) |
|---|---|
| 深度图渲染 | ~1ms (> 1000fps) |
| 动态栅格更新 | < 1ms (10个障碍物) |
| 对 raycast 的性能影响 | < 5% |
| 最大支持障碍物数量 | 100 |
更多技术细节参见:
动态障碍物在单帧深度图中表现为瞬时快照,缺乏运动方向信息。通过将多帧深度图按时间指数衰减合成,产生类似"拖影"的效果:
有效深度 = 1.0 - (1.0 - 当前深度) × exp(-ln2 / half_life × Δt)
合成结果 = min(所有帧的有效深度) # 逐像素取最近读数
- 障碍物侵入量
(1 - depth)随时间指数衰减 - 半衰期
half_life(默认 0.8 秒)控制拖影消退速度 - 最终结果保留了障碍物运动方向信息,有助于网络进行动态避障
时序深度融合在以下三处保持一致:
| 环节 | 实现位置 | 说明 |
|---|---|---|
| 运行时 | test_yopo_ros.py → compute_temporal_depth() |
实时缓冲多帧,指数衰减合成 |
| 数据采集 | dataset_generator.cpp |
沿模拟轨迹渲染多帧,保存合成结果 |
| 训练时 | yopo_dataset.py → __getitem__() |
从同一地图随机采样伪历史帧,模拟拖影 |
| 参数 | 默认值 | 说明 |
|---|---|---|
temporal_history_frames |
10 | 历史帧数(采集时) / 5(训练时) |
temporal_decay_half_life |
0.8 | 拖影半衰期(秒) |
max_buffer_time |
2.0 | 运行时保留过去多少秒的帧 |
traj_sim_duration |
0.5 | 采集时轨迹段总时长(秒) |
运行时通过 RViz 订阅 /yopo_net/temporal_depth_visual 话题(Image 类型)可查看合成的时序深度图。深色表示近/障碍物,浅色表示远/无障碍。
训练采用 5 个代价函数的加权和,直接反传梯度到网络权重:
Total Loss = w_s × Smoothness + w_c × Static Safety + w_d × Dynamic Safety + w_g × Guidance + w_a × Acceleration
- 公式:轨迹 Jerk(三阶导数)的时间积分 ∫ jerk² dt
- 作用:使轨迹更平滑、减少急转急停
- 速度归一化:按
vel_scale⁵归一化,确保不同速度下代价一致 - 权重:
ws = 10.0
- 方法:从采集的点云构建 ESDF(欧几里得签名距离场),在轨迹采样点查询距离
- 代价函数:
cost = exp(-(d - d0) / r),其中d0 = 1.2m(安全距离),r = 0.6(衰减因子) - 批量 ESDF 裁剪:使用
get_batch_sdf()裁剪到轨迹覆盖区域,平衡内存和速度 - 权重:
wc = 1.0
- 方法:将每个动态障碍物近似为球体,计算轨迹采样点到最近障碍物表面的距离
- 代价函数:与静态安全相同的指数代价
exp(-(d - d0) / r) - Sentinel 处理:
radius = 0的障碍物不计入代价(视为无效) - 无障碍物处理:
K = 0时直接返回零代价 - 权重:
wd = 1.0
- 方法:将轨迹方向投影到目标方向上,鼓励轨迹朝向目标飞行
- 两种模式:
distance_loss:L1 距离,更精确但速度略慢similarity_loss(默认):投影长度 + 垂直偏移,速度更快
- 垂直约束:
perp_weight = 0.5,允许一定的横向探索 - 权重:
wg = 0.15
- 公式:轨迹加速度的时间积分 ∫ acc² dt
- 作用:减少过大的加速度,提高飞行舒适性
- 速度归一化:按
vel_scale³归一化 - 权重:
wa = 1.0
每条候选轨迹还预测一个评分(score),标签为各代价之和的 detach 值,使用 Smooth L1 Loss 监督。推理时选择评分最低的轨迹执行。
输入: 输出:
深度图 [1, 96, 160] ─→ ResNet-18 Backbone ─→ 特征图 [64, V, H]
↓
concat [73, V, H]
↓
状态 [9] → 归一化 → 基元变换 → 状态特征 [9, V, H] ─→ YopoHead (3×Conv1x1)
↓
[10, V, H] → endstate [9, V, H] + score [V, H]
| 模块 | 实现 | 说明 |
|---|---|---|
| Image Backbone | ResNet-18(修改第一层为单通道输入) | 提取深度图特征 |
| State Backbone | Identity(直通) | 状态已在 prepare_input 中变换 |
| YopoHead | 3 层 1×1 卷积(256→256→10) | 预测每个基元的端点状态偏移 + 评分 |
| 输出 endstate | tanh 激活 → 9 个通道 |
相对于基元的偏移(Δyaw, Δpitch, Δradio, vx, vy, vz, ax, ay, az) |
| 输出 score | softplus 激活 → 1 个通道 |
轨迹质量评分(越低越好) |
| 参数 | 默认值 | 说明 |
|---|---|---|
horizon_num |
5 | 水平方向基元数 |
vertical_num |
3 | 垂直方向基元数 |
radio_num |
1 | 径向基元数(当前仅支持 1) |
| 总基元数 | 15 | 5 × 3 × 1 = 15 条候选轨迹 |
horizon_camera_fov |
90° | 水平搜索视场角 |
vertical_camera_fov |
60° | 垂直搜索视场角 |
radio_range |
5.0m | 规划半径 |
vel_max_train |
6.0 m/s | 训练最大速度 |
acc_max_train |
6.0 m/s² | 训练最大加速度 |
基元在极坐标系下均匀分布,网格布局(从底部右侧开始编号):
+---+---+---+---+---+
| 14| 13| 12| 11| 10|
+---+---+---+---+---+
| 9| 8| 7| 6| 5|
+---+---+---+---+---+
| 4| 3| 2| 1| 0|
+---+---+---+---+---+
轨迹优化参数在 YOPO/config/traj_opt.yaml 中配置:
| 参数 | 默认值 | 说明 |
|---|---|---|
velocity |
4 m/s | 测试时的飞行速度 |
vel_max_train |
6.0 m/s | 训练时的最大速度 |
acc_max_train |
6.0 m/s² | 训练时的最大加速度 |
| 权重 | 默认值 | 含义 |
|---|---|---|
wg |
0.15 | 引导代价(朝向目标) |
ws |
10.0 | 平滑度代价(Jerk 最小化) |
wa |
1.0 | 加速度代价 |
wc |
1.0 | 静态碰撞代价(ESDF) |
wd |
1.0 | 动态碰撞代价(球体模型) |
| 参数 | 默认值 | 说明 |
|---|---|---|
d0 |
1.2m | 安全距离阈值 |
r |
0.6 | 指数衰减因子 |
使用 TensorRT 加速推理(NVIDIA Orin NX 上:ResNet-14 约 1ms,ResNet-18 约 5ms):
1. 安装依赖
conda activate yopo
pip install -U nvidia-tensorrt --index-url https://pypi.ngc.nvidia.com
git clone https://github.com/NVIDIA-AI-IOT/torch2trt
cd torch2trt
python setup.py install2. 模型转换
cd YOPO
conda activate yopo
python yopo_trt_transfer.py --trial=1 --epoch=503. 推理
cd YOPO
conda activate yopo
python test_yopo_ros.py --use_tensorrt=1- 将
test_yopo_ros.py中的深度图话题改为你的相机话题 - 将里程计话题改为你的 VIO/VINS 话题(NWU 坐标系)
- 配置相机分辨率匹配训练配置(预训练权重:16:9,90° FOV)
- 如需使用位置控制器,修改
plan_from_reference: True
支持在 RK3566/RK3588 平台的 NPU 上部署。在 RK3566(1 TOPS NPU)上,INT8 量化后推理约 20ms(ResNet-14 Backbone)。
# 模型转换
python yopo_rknn_transfer.py
# RKNN 推理测试
python test_yopo_rknn_ros.py| 话题 | 类型 | 说明 |
|---|---|---|
/depth_image |
Image | 深度图 |
/lidar_points |
PointCloud2 | 雷达点云 |
/yopo_net/best_traj_visual |
PointCloud2 | 最优预测轨迹 |
/yopo_net/trajs_visual |
PointCloud2 | 所有候选轨迹(带评分) |
/yopo_net/lattice_trajs_visual |
PointCloud2 | 运动基元轨迹 |
/yopo_net/temporal_depth_visual |
Image | 时序融合深度图 |
/dynamic_obstacles |
MarkerArray | 随机移动障碍物(红色) |
/incoming_obstacles |
MarkerArray | 飞向无人机障碍物(蓝色) |
本项目配置了 5 种 RViz 预设视角,详见 RViz 多视角使用指南:
| 视角 | 类型 | 距离 | 用途 |
|---|---|---|---|
| 第一人称 | FPS | 0m | 沉浸体验,查看前方视野 |
| 第三人称(近) | Follow | 15m | 默认推荐,日常观察 |
| 第三人称(远) | Follow | 30m | 全局观察,查看飞行轨迹 |
| 俯视图(选点) | Orbit | 50m | 使用 2D Nav Goal 选择目标点 |
| XY 平面跟随 | XYOrbit | 40m | 保持固定俯仰角跟随 |
Left: Random Forest (maze_type=5); Right: 3D Perlin (maze_type=1).
无人机硬件由 @Mioulo 设计,完全开源。
- 硬件清单:hardware_list.pdf
- 碳纤维主框架:carbon_main_frame.STEP
- 碳纤维底板:carbon_bottom_plate.STEP
- 相机支架:0° 和 15° 两个版本
使用随机训练场景、图像和状态来增强泛化能力。使用真值深度图训练的策略可零样本迁移到立体相机和未见场景:
- 确认
config.yaml中enable_dynamic_obstacles: true或enable_incoming_obstacles: true - 在 RViz 中添加对应的 MarkerArray 话题
- 确认 Fixed Frame 为
world
- 检查 CUDA 版本和 GPU 架构是否匹配
- 手动在 CMakeLists.txt 中设置 CUDA 架构
- 详见 Simulator 说明
- ESDF 从点云构建,仅在训练开始时执行一次
- 确保
dataset_path中的.ply文件存在 - 可通过调整
voxel_size(默认 0.2m)控制精度和速度
- 建议使用 TensorRT 加速
- 检查是否有 GPU 可用(
torch.cuda.is_available()) - 关闭
visualize: True可减少不必要的计算
- 修改
YOPO/config/traj_opt.yaml中的velocity参数 - 预训练权重在 6 m/s 下训练,0-6 m/s 范围内表现稳定
- 当前动态障碍物实现不检测与静态地图的碰撞,仅检测边界
- 如需碰撞检测,可修改
updateDynamicObstacles()函数
- 设置
config.yaml中enable_map: false
如果本工作对你有帮助,请引用原论文:
@article{YOPO,
title={You Only Plan Once: A Learning-based One-stage Planner with Guidance Learning},
author={Lu, Junjie and Zhang, Xuewei and Shen, Hongming and Xu, Liwen and Tian, Bailing},
journal={IEEE Robotics and Automation Letters},
year={2024},
publisher={IEEE}
}- 原始 YOPO 项目:TJU-Aerial-Robotics/YOPO
- 部分地图生成基于:HKUST-Aerial-Robotics/mockamap
- 控制器修改自:HKUST-Aerial-Robotics/Fast-Planner
本项目采用 MIT License。



