Skip to content

SongangYang/Dynamic_timer_yopo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

YOPO_dynamic


基于 TJU-Aerial-Robotics/YOPO 的二次开发版本。 在原版基础上新增了随机动态障碍物飞向无人机的障碍物时序深度图融合动态安全损失函数等功能,用于在障碍物密集的动态环境中训练和测试基于学习的无人机自主导航规划器。


目录


项目简介

YOPO 是一种基于学习的无人机一次性规划器(one-stage planner),能将传统规划器的三个阶段——感知与建图、前端路径搜索、后端轨迹优化——统一整合到一个神经网络中。 本版本在此基础上进行了以下核心扩展:

  1. 动态障碍物支持:在 CUDA 加速的仿真器中引入随机移动障碍物和飞向无人机的障碍物,使训练和测试能在更具挑战性的动态环境中进行。
  2. 时序深度图融合:通过多帧深度图的指数衰减合成,产生类似"拖影"的效果,使得网络能感知动态障碍物的运动趋势。
  3. 动态安全损失:新增球体距离模型的安全损失函数,在训练时惩罚轨迹与动态障碍物的碰撞。
  4. 一键启动脚本:提供 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

安装步骤

1. 克隆代码

git clone --depth 1 <仓库地址>
cd overlap_YOPO

2. 创建 Python 虚拟环境

conda create --name yopo python=3.8
conda activate yopo
cd YOPO
pip install -r requirements.txt

3. 编译 Controller(控制器 + 动力学仿真)

conda deactivate
cd Controller
catkin_make

4. 编译 Simulator(环境 + 传感器仿真)

conda deactivate
cd Simulator
catkin_make

CUDA 编译问题:如果 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,在地图上点击即可设置目标点(地图无边界,目标点可自由设置)。

在 RViz 中选择目标点


训练策略

1. 数据采集

通过在随机地图中随机重置无人机位姿来高效采集数据(深度图、位姿、点云地图、动态障碍物标签)。采集 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)

2. 训练网络

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:加速度代价

训练日志

3. 训练结果可视化

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 并行更新  │
│  固定不变          │  根据障碍物位置重写      │
└──────────────────┴───────────────────────┘

两类动态障碍物

1. 随机移动障碍物

  • 在指定范围内随机初始化位置和速度方向
  • 碰到边界自动反弹(完全弹性碰撞)
  • 小概率随机改变运动方向,增加不可预测性
  • 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        # 最大高度

2. 飞向无人机的障碍物

  • 在无人机周围 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 核心逻辑

API 接口

// 添加动态障碍物
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.pycompute_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

各代价函数详细说明

1. 平滑度代价(SmoothnessLoss)

  • 公式:轨迹 Jerk(三阶导数)的时间积分 ∫ jerk² dt
  • 作用:使轨迹更平滑、减少急转急停
  • 速度归一化:按 vel_scale⁵ 归一化,确保不同速度下代价一致
  • 权重ws = 10.0

2. 静态安全代价(SafetyLoss)

  • 方法:从采集的点云构建 ESDF(欧几里得签名距离场),在轨迹采样点查询距离
  • 代价函数cost = exp(-(d - d0) / r),其中 d0 = 1.2m(安全距离),r = 0.6(衰减因子)
  • 批量 ESDF 裁剪:使用 get_batch_sdf() 裁剪到轨迹覆盖区域,平衡内存和速度
  • 权重wc = 1.0

3. 动态安全代价(DynamicSafetyLoss)

  • 方法:将每个动态障碍物近似为球体,计算轨迹采样点到最近障碍物表面的距离
  • 代价函数:与静态安全相同的指数代价 exp(-(d - d0) / r)
  • Sentinel 处理radius = 0 的障碍物不计入代价(视为无效)
  • 无障碍物处理K = 0 时直接返回零代价
  • 权重wd = 1.0

4. 引导代价(GuidanceLoss)

  • 方法:将轨迹方向投影到目标方向上,鼓励轨迹朝向目标飞行
  • 两种模式
    • distance_loss:L1 距离,更精确但速度略慢
    • similarity_loss(默认):投影长度 + 垂直偏移,速度更快
  • 垂直约束perp_weight = 0.5,允许一定的横向探索
  • 权重wg = 0.15

5. 加速度代价(AccelerationLoss)

  • 公式:轨迹加速度的时间积分 ∫ acc² dt
  • 作用:减少过大的加速度,提高飞行舒适性
  • 速度归一化:按 vel_scale³ 归一化
  • 权重wa = 1.0

Score 预测

每条候选轨迹还预测一个评分(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 部署

使用 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 install

2. 模型转换

cd YOPO
conda activate yopo
python yopo_trt_transfer.py --trial=1 --epoch=50

3. 推理

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

RKNN 部署

支持在 RK3566/RK3588 平台的 NPU 上部署。在 RK3566(1 TOPS NPU)上,INT8 量化后推理约 20ms(ResNet-14 Backbone)。

# 模型转换
python yopo_rknn_transfer.py

# RKNN 推理测试
python test_yopo_rknn_ros.py

RViz 可视化

话题列表

话题 类型 说明
/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 设计,完全开源。

Sim-to-Real 迁移

使用随机训练场景、图像和状态来增强泛化能力。使用真值深度图训练的策略可零样本迁移到立体相机和未见场景:

Sim-to-Real 迁移


常见问题

Q1: 动态障碍物不显示?

  • 确认 config.yamlenable_dynamic_obstacles: trueenable_incoming_obstacles: true
  • 在 RViz 中添加对应的 MarkerArray 话题
  • 确认 Fixed Frame 为 world

Q2: CUDA 编译错误?

  • 检查 CUDA 版本和 GPU 架构是否匹配
  • 手动在 CMakeLists.txt 中设置 CUDA 架构
  • 详见 Simulator 说明

Q3: 训练时 ESDF 构建很慢?

  • ESDF 从点云构建,仅在训练开始时执行一次
  • 确保 dataset_path 中的 .ply 文件存在
  • 可通过调整 voxel_size(默认 0.2m)控制精度和速度

Q4: 测试时网络推理延迟过高?

  • 建议使用 TensorRT 加速
  • 检查是否有 GPU 可用(torch.cuda.is_available()
  • 关闭 visualize: True 可减少不必要的计算

Q5: 如何调整飞行速度?

  • 修改 YOPO/config/traj_opt.yaml 中的 velocity 参数
  • 预训练权重在 6 m/s 下训练,0-6 m/s 范围内表现稳定

Q6: 障碍物穿透静态地图?

  • 当前动态障碍物实现不检测与静态地图的碰撞,仅检测边界
  • 如需碰撞检测,可修改 updateDynamicObstacles() 函数

Q7: 如何关闭地图只保留动态障碍物?

  • 设置 config.yamlenable_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}
}

致谢

许可证

本项目采用 MIT License

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors