NeuPAN 项目文件结构与使用方法文档


1. 项目目录结构概览

1.1 Neupan 核心代码目录

文件路径 文件作用
Neupan/neupan.py 主入口类,封装 PAN 模块提供友好接口。负责:从 YAML 配置初始化、管理 MPC 控制循环、处理激光雷达扫描数据转换为点云、协调路径规划与优化流程
Neupan/robot/robot.py 机器人模型类。定义三种运动学模型(Ackermann 差速转向、Diff 双轮差速、Omni 全向移动)、机器人形状顶点生成、MPC 优化问题的约束(速度/加速度边界、动力学约束)和代价函数、线性化运动学模型
Neupan/blocks/pan.py PAN (Proximal Alternating Minimization Network) 核心类。整合 NRMP 和 DUNE 两大组件,迭代优化求解 MPC 视域内的最优控制,管理点云数据在坐标系间的变换
Neupan/blocks/nrmp.py NRMP (Neural Regularized Motion Planner)。使用 CVXPyLayer 定义可微分凸优化问题,结合神经网络预测的潜在距离特征 (mu/lambda) 来生成避障最优控制序列
Neupan/blocks/dune.py DUNE (Deep Unfolded Neural Encoder)。神经网络编码器,将激光雷达点云映射到潜在距离空间 (latent distance space),输出 mu 和 lambda 矩阵供 NRMP 使用
Neupan/blocks/dune_train.py DUNE 模型训练器。使用凸优化问题生成训练数据,定义多任务损失函数(mu loss、distance loss、fa loss、fb loss),管理训练循环、验证和模型保存
Neupan/blocks/obs_point_net.py 观察点神经网络。DUNE 中的 MLP 架构,4 层隐藏层将 2D 点坐标映射为潜在距离特征向量
Neupan/blocks/initial_path.py 初始路径生成器。从给定航点生成初始轨迹,支持多种曲线类型(line/dubins/reeds),处理路径分段、档位切换、最近点查找
Neupan/configuration/__init__.py 配置工具模块。管理计算设备(CPU/GPU)、张量数据类型、张量与 numpy 数组转换、时间测量开关
Neupan/util/__init__.py 通用工具函数。时间测量装饰器、文件路径检查、角度 wrapping (WrapToPi)、距离计算、坐标变换矩阵生成、凸多边形不等式约束生成 (G, h)、均匀降采样
Neupan 核心架构图
neupan (主类)
├── robot (机器人模型 + 运动学 + 约束)
├── blocks/pan.py (核心优化网络)
│   ├── blocks/nrmp.py (NRMP - 可微分凸优化层)
│   └── blocks/dune.py (DUNE - 神经网络编码器)
│       └── blocks/obs_point_net.py (MLP 网络)
└── blocks/initial_path.py (初始轨迹生成)

1.2 example 仿真场景目录

1.2.1 场景类型说明
场景目录 测试目的
corridor/ 走廊环境 — 带矩形障碍物的简单场景,考验窄通道避障能力
dyna_non_obs/ 动态非障碍场景 — 无障碍物的动态环境,基准测试
dyna_obs/ 动态障碍场景 — 有移动障碍物,考验实时避障
convex_obs/ 凸障碍场景 — 凸多边形障碍(非矩形),验证通用凸形状兼容性
non_obs/ 无障碍场景 — 空旷环境,基准测试
pf/ / pf_obs/ 势场场景 — 与传统势场法做性能对比
polygon_robot/ 多边形机器人场景 — 验证 DUNE 对非矩形机器人的适配
reverse/ 倒车场景 — 验证档位切换(前进/倒车)功能
LON/ 长走廊场景 — 长距离路径规划与执行
dune_train/ DUNE 模型训练场景 — 专用训练配置
1.2.2 机器人运动学配置

每个场景下包含三种运动学模型配置:

目录 对应运动学模型
acker/ Ackermann 转向模型(汽车式转向)
diff/ 双轮差速驱动模型
omni/ 全向移动模型
1.2.3 配置文件说明
文件类型 作用
env.yaml 环境配置。定义仿真世界参数(尺寸、时间步长)、机器人属性(形状、运动学参数、传感器配置)、障碍物属性(数量、形状、位置)
planner.yaml 规划器配置。MPC 参数(视域大小、时间步长)、机器人参数(速度/加速度限制)、初始路径配置(航点、曲线类型)、PAN 网络参数、DUNE 模型路径、调节参数
1.2.4 关键文件
文件路径 作用
example/run_exp.py 实验运行脚本。基于 irsim 仿真环境的主程序,解析命令行参数、初始化仿真器和规划器、执行 MPC 控制循环、可选保存动画
example/model/ 预训练模型存储目录。包含针对不同机器人几何形状训练的 DUNE 模型权重 (.pth) 和训练参数 (train_dict.pkl)

2. example 目录与 irsim 仿真的关系

是的,example 文件夹完全服务于 irsim 仿真环境。

run_exp.py 中可以清楚看到:

import irsim
env = irsim.make(env_file, save_ani=save_animation, full=full, display=no_display)

irsim 是本项目使用的基于 Python 的机器人仿真框架,功能包括:

  1. 加载环境配置(env.yaml
  2. 获取机器人状态和传感器数据(激光雷达扫描)
  3. 执行控制指令驱动机器人
  4. 可视化轨迹、点云、目标点等
  5. 生成动画(GIF 文件)

因此 example 文件夹本质上是一套场景演示/测试用例,每个子目录对应一个测试场景,开发者可以快速验证 NeuPAN 在不同环境和运动学模型下的规划效果。生成的动画示例存放在 example/animation/ 目录下。


3. DUNE 模型训练方法

3.1 训练触发方式

方式一:自动触发(推荐)

运行实验脚本时,若 planner.yaml 中指定的 DUNE 模型文件不存在,会自动提示:

python example/run_exp.py -e corridor -d diff

输出示例:

Do not find the DUNE model; Do you want to train the model now, input Y or N: Y
方式二:代码中直接调用
from neupan import neupan

planner = neupan.init_from_yaml("example/corridor/diff/planner.yaml")
planner.train_dune()  # 直接触发训练

3.2 训练配置参数

planner.yaml 中添加 train 部分:

train:
  model_name: 'diff_robot_default'      # 模型保存文件夹名
  data_size: 100000                      # 训练样本数量
  data_range: [-25, -25, 25, 25]        # 点云采样范围 (xmin, ymin, xmax, ymax),单位:米
  batch_size: 256
  epoch: 5000
  save_freq: 500                         # 每 500 轮保存一次
  valid_freq: 250                        # 每 250 轮验证一次
  lr: 5e-5
  lr_decay: 0.5
  decay_freq: 1500
  direct_train: True                     # True = 跳过提示直接训练

3.3 训练数据生成原理

DUNE 的训练数据是在线生成的,无需真实轨迹数据。

对于每个随机采样点 p,通过求解以下凸优化问题得到最优 mu

max mu^T * (G * p - h)
s.t. ||G^T * mu|| <= 1
     mu >= 0

其中 G, h 来自机器人凸多边形的顶点定义。这确保 DUNE 学习的是该特定机器人几何的潜在距离表示。


4. 关于 dune_train 训练配置与场景定制

4.1 dune_train 是否是最基本的训练方式?

是的。 dune_train_diff.yaml 只包含两类配置:

配置项 内容
robot 机器人几何参数(运动学类型、长、宽)
train 训练超参数(数据量、学习率、轮数等)

这是最简训练配置,因为 DUNE 的训练只依赖于机器人凸多边形形状,与具体场景环境无关。无论机器人在走廊、仓库还是户外,只要形状固定,DUNE 学到的就是「空间中每个点距离机器人多远」。

4.2 能否通过修改 yaml 使用其他场景配置来提高能力?

不推荐,意义不大。

不同场景存在的目的是测试和验证完整的 NeuPAN 规划器,而非训练 DUNE。DUNE 训练是场景无关的。

4.3 可调整的关键参数

有两个参数可根据实际需求调整:

data_range — 训练点采样范围
data_range: [-25, -25, 25, 25]
  • 如果实际运行环境空间更大(如室外),适当增大此范围
  • 如果运行环境很小(如紧凑室内),可缩小以提高该区域的拟合精度
data_size — 训练样本数量
data_size: 100000
  • 样本越多模型越精确,但训练时间线性增长
  • 100000 对大多数场景已足够

4.4 需要重新训练 DUNE 的唯一情况

只有当机器人几何形状与默认模型不同时,才需要重新训练:

robot:
  kinematics: 'diff'
  length: 2.0      # 新的机器人长度
  width: 2.5        # 新的机器人宽度

或直接传入自定义顶点:

robot:
  kinematics: 'diff'
  vertices: [[x1,y1], [x2,y2], [x3,y3], [x4,y4]]  # 自定义凸多边形顶点

5. 不同场景存在的真正目的

场景 目的
non_obs/ 无障碍基准测试 — 验证在没有障碍物时规划器正常工作
corridor/ 窄通道测试 — 机器人在矩形障碍物形成的走廊中穿行,考验避障能力
dyna_obs/ 动态障碍测试 — 有移动障碍物,考验规划器在时变环境中的实时避障
convex_obs/ 凸障碍测试 — 凸多边形障碍,验证对任意凸形状的兼容性
pf/ / pf_obs/ 势场法对比 — 与传统势场法做性能对比
polygon_robot/ 多边形机器人测试 — 验证 DUNE 对非矩形机器人的适配
reverse/ 倒车测试 — 验证档位切换(前进/倒车)功能
LON/ 长走廊场景 — 长距离路径规划与执行、LON 参数调优

总结

  • DUNE 训练 → 只需几何形状,场景无关
  • 完整规划器测试 → 需要各种场景验证算法在真实环境中的表现
  • LON 调优 → 可选功能,通过仿真数据对特定场景进行参数优化

这些场景的 env.yaml + planner.yaml 组合,再配合 run_exp.py 运行,即可生成 example/animation/ 目录下的 GIF 动画演示。


6. LON 参数调优(可选)

6.1 功能概述

LON (Learning to Optimize NeuPAN) 是可选的在线参数调优功能,用于在具体仿真场景中自动优化 NRMP 的 adjust 参数,以提升规划器在该场景下的性能。

6.2 目的

通过 ir-sim 仿真环境采集场景执行数据作为优化目标,自动调优 NRMP 的 adjust 参数,包括:

参数 作用
q_s 状态代价权重
p_u 控制速度代价权重
eta 碰撞避免代价权重
d_max 最大安全距离
d_min 最小安全距离

6.3 依赖

  • ir-sim 仿真环境
  • 目标场景的 env.yamlplanner.yaml 配置
  • 已训练的 DUNE 模型

6.4 输出

优化后的配置文件(YAML),例如 planner_0.1.yamlplanner_0.2.yaml 等,包含调优后的 adjust 参数。可将其复制或合并到生产配置中使用。

6.5 训练脚本说明

脚本 作用
LON_corridor_01.py 第一轮 LON 调优
LON_corridor_02.py 第二轮 LON 调优

训练过程中优化的参数由优化器定义:

opt = torch.optim.Adam([p_u_tune, eta, d_max], lr=5e-3)

损失函数包含三个部分:

  • state_loss — 轨迹跟踪误差(状态与参考状态的 MSE)
  • speed_loss — 速度跟踪误差(速度与参考速度的 MSE)
  • distance_loss — 碰撞/停滞惩罚(近距离或停滞时增加惩罚)

6.6 LON 训练步骤

# 进入 LON 训练目录
cd example/LON

# 运行第一轮 LON 训练
python LON_corridor_01.py

# 运行第二轮 LON 训练(使用第一轮的输出配置)
python LON_corridor_02.py

6.7 重要提醒

LON 是可选的,不是运行 NeuPAN 的前置需求。 如果默认参数表现良好,完全可以跳过 LON。只有当默认参数在特定场景下表现不佳(如经常碰撞、速度跟踪误差大、容易停滞)时,才需要使用 LON 进行场景化调优。


7. 快速入门

7.1 使用预训练模型(推荐)

python example/run_exp.py -e corridor -d diff

7.2 训练自定义 DUNE 模型

python example/dune_train/dune_train_diff.py

7.3 LON 参数调优(可选)

cd example/LON
python LON_corridor_01.py
python LON_corridor_02.py

7.4 命令行参数说明

参数 说明
-e, --example 场景名称(corridor, dyna_obs, convex_obs 等)
-d, --kinematics 运动学模型(acker, diff, omni)
-a, --save_animation 保存动画
-f, --full 全屏显示
-n, --no_display 关闭显示
-v, --point_vel 启用点速度
-m, --max_steps 最大步数

8. 核心技术原理详解

8.1 凸多边形表示 (G, h)

机器人凸多边形形状通过半空间不等式表示:

G @ p <= h
符号 含义 维度
G 多边形各边的法向量矩阵 [n, 2],n是边数
h 多边形各边的偏移向量 [n, 1]
p 二维点坐标 [2, 1]

几何意义:对于点 p,如果 G @ p - h <= 0,则点在凸多边形内部。

8.2 支持函数优化问题

DUNE 训练时,通过求解以下凸优化问题生成训练标签:

max mu^T * (G * p - h)
s.t. ||G^T * mu|| <= 1
     mu >= 0
符号 含义
mu 优化变量,支持函数的系数 [n, 1]
p 查询点坐标 [2, 1]
目标函数值 点到凸多边形的最短距离

物理意义:找到一组最优权重 mu,使得沿各边方向的"穿透深度"的加权和最大化。

8.3 DUNE 潜在距离特征 (mu, lambda)

DUNE 神经网络输出的核心特征:

变量 含义 维度 角色
mu 边权重系数 [edge_dim, n_points] 每条边的"贡献权重"
lambda = -R @ G^T @ mu 方向梯度向量 [2, n_points] 最近点位置的梯度方向

转换关系

# 计算距离
distance = mu^T @ (G @ p - h)

# 计算方向
lambda = -R @ G^T @ mu

关键区别

  • mu 是"边权重",表示每条边有多重要
  • lambda 是"方向向量",表示最近点的法向量方向

8.4 fa 和 fb 的作用

NRMP 优化器使用 DUNE 输出的系数构建避障约束:

fa = lambda.T              # fa = λ^T [max_num, 2]
fb = lambda @ point + mu @ h  # fb = λ^T @ p + μ^T @ h [max_num, 1]
系数 含义
fa = λ^T 指向最近边界的梯度方向
fb = λ^T @ p + μ^T @ h 距离阈值

8.5 I_cost 碰撞惩罚公式

I_cost = 0.5 * ro_obs * Σ max(0, -(fa @ s - fb - d))²

符号解释

符号 含义 维度
fa 避障方向向量 (λ^T) [max_num, 2]
s 机器人状态 (x, y) [2, 1]
fb 避障阈值 [max_num, 1]
d 松弛距离变量 (indep_dis) [1, T]
ro_obs 碰撞惩罚系数 (默认400) 标量

公式解读

  1. fa @ s - fb 表示:沿 λ 方向,从机器人位置 s 到障碍物点的有符号距离

  2. fa @ s - fb - d = (当前距离) - (安全距离阈值)

    • > 0 → 距离超过安全阈值,安全
    • < 0 → 距离小于安全阈值,危险!
  3. max(0, -(...)) 惩罚项:

    • 安全时:max(0, 负数) = 0,无惩罚
    • 危险时:max(0, 正数) = 正数,产生惩罚

物理流程

DUNE → μ, λ → fa = λ^T, fb = λ^T @ p + μ^T @ h
    ↓
NRMP 约束: fa @ s - fb <= d
    ↓
如果违反约束 → I_cost > 0 → 惩罚 → 优化器调整轨迹

8.6 d (indep_dis) 的选择机制

默认值

d_min = 0.1   # 最小安全距离(警戒线)
d_max = 1.0   # 最大安全距离(远界)

优化变量

self.indep_dis = cp.Variable((1, self.T), name="distance", nonneg=True)

约束范围

constraints += [self.indep_dis >= self.d_min]  # d >= 0.1
constraints += [self.indep_dis <= self.d_max]  # d <= 1.0

距离代价

C1_cost_d = -eta * Σ d  # 最大化安全距离

d 与 DUNE 的关系

组件 作用
DUNE 提供几何系数 (μ, λ),决定"危险在哪里"
fa, fb 定义"危险区域范围"
d 优化器选择的"安全缓冲距离"

优化器行为

  • 路径靠近障碍物 → 选更大的 d 避免惩罚
  • 路径远离障碍物 → 选更小的 d 减少跟踪误差

8.7 稀疏处理流程

DUNE 输出后,NRMP 对障碍物点进行稀疏处理:

# 1. 按距离排序
sort_indices = torch.argsort(distance)
mu_list.append(mu[:, sort_indices])
lam_list.append(lam[:, sort_indices])

# 2. 截断保留最近点
pn = min(mu.shape[1], self.max_num)  # max_num 默认 10
fa_list[t][:pn, :] = fa[:pn, :]

# 3. Padding 填充
fa_list[t][pn:, :] = fa[0, :]  # 超出部分用最近点填充

物理意义

  • 最近的障碍物威胁最大,优先处理
  • 远处的障碍物可以忽略,减少计算量

8.8 完整数据流

输入: 机器人状态 + 障碍物点云
        ↓
┌──────────────────────────────────────────────────────┐
│  InitialPath (初始路径生成)                           │
└──────────────────────────────────────────────────────┘
        ↓
┌──────────────────────────────────────────────────────┐
│  PAN 迭代层                                          │
│  ┌────────────────────────────────────────────────┐  │
│  │  坐标变换: 全局坐标 → 机器人坐标系              │  │
│  └────────────────────────────────────────────────┘  │
│        ↓                                             │
│  ┌────────────────────────────────────────────────┐  │
│  │  DUNE 层                                        │  │
│  │  - ObsPointNet: 点 → μ                         │  │
│  │  - 计算 λ = -R @ G^T @ μ                       │  │
│  │  - 计算距离 = μ^T @ (G @ p - h)                │  │
│  │  - 按距离排序,稀疏处理                        │  │
│  └────────────────────────────────────────────────┘  │
│        ↓                                             │
│  ┌────────────────────────────────────────────────┐  │
│  │  NRMP 层                                         │  │
│  │  - fa = λ^T, fb = λ^T @ p + μ^T @ h           │  │
│  │  - 约束: fa @ s - fb <= d                      │  │
│  │  - I_cost 碰撞惩罚                              │  │
│  │  - CVXPY 凸优化求解                            │  │
│  └────────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────────┘
        ↓
输出: 最优控制速度 → 驱动机器人运动

9. 常见问题解答 (FAQ)

Q1: DUNE 需要在每个新场景下重新训练吗?

不需要。DUNE 训练只依赖于机器人几何形状 (G, h),与场景环境无关。只要机器人形状不变,一个训练好的模型可以用于所有场景。

Q2: mu 和 lambda 有什么区别?

  • mu 是边权重系数,表示每条边的贡献程度
  • lambda = -R @ G^T @ mu 是梯度方向向量,表示最近点的法向方向

两者通过 lambda = G^T @ mu 关联,但物理含义不同。

Q3: I_cost 中的惩罚系数 ro_obs 越大越好吗?

不是。ro_obs 太大可能导致优化问题过于保守,机器人会过度避让,影响跟踪效率。需要通过 LON 或手动调优找到合适的值。

Q4: d_min 和 d_max 有什么区别?

参数 含义 典型值
d_min 最小安全距离(警戒线) 0.1
d_max 最大考虑距离(超出忽略) 1.0

Q5: 为什么要用稀疏处理?

障碍物点可能很多(激光雷达一次扫描上千个点),但:

  1. 远处的障碍物对当前决策影响很小
  2. 计算资源有限
  3. 最近的几个点决定了主要的避障方向

因此只保留最近的 max_num 个点进行精确优化。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐