基于DQN的无人机三维避障航迹规划:从状态设计到参数调优

发布时间:2026/9/1 7:43:37
基于DQN的无人机三维避障航迹规划:从状态设计到参数调优 简介基于DQN的三维无人机避障航迹规划资源包提供一套可运行的Python实现面向强化学习与无人机路径规划方向的研究者或开发者。包内共15个文件整体大小仅2.01MB其中6个.py脚本覆盖环境搭建UAV.py、env.py、DQN模型结构model.py、经验回放replay_buffer.py与训练主程序DQN.py2个.pth权重文件可直接加载预训练模型另有2个gif演示路径效果、2张jpg框架与航迹图、2个md说明文档及license结构清晰便于按需查阅。目前已有785人学习具备较高参考价值。通过运行代码读者可完整复现DQN训练无人机在三维障碍环境中避障并规划航迹的过程结合可视化文件直观理解算法收敛与路径选择逻辑也便于在此基础上进行算法改进或迁移到其他自主导航场景。 先说一个可能反直觉的结论用 DQN 做无人机三维避障航迹规划在算法圈子里已经算不上“新”但我依然强烈建议任何一个刚开始接触这个方向的人先从 DQN 入手。原因很简单——它的每个机制都能拆开理解、单独调试价值网络、经验回放、贪心探索每一步都不是黑盒最后拼到一起就是一个能跑的闭环。这篇文章把我从环境搭建到训练收敛过程中踩过的关键坑都梳理了一遍包括状态空间和动作空间怎么定、奖励函数怎么避免“漏洞”、网络结构怎么搭、以及哪些超参数最容易让训练原地打转。适合正在做毕业设计、准备数学建模竞赛或者刚入门无人机路径规划算法的同学参考。1. 从问题说起为什么无人机三维避障不简单1.1 三维避障真正的难点到底在哪二维平面上的路径规划很多经典几何算法其实已经能做得很好。地图已知、障碍物固定A* 或者 RRT 跑出来的路径质量并不差甚至可以直接用在轮式小车上。但无人机一旦上了三维问题就变味了。三维空间带来的第一个麻烦是状态爆炸。同样是 100 米见方的区域二维栅格化可能只需要 10000 个格子三维栅格化直接到 100 万个搜索空间呈指数增长。第二个麻烦是运动约束。无人机不是只在一个几何曲面上滑动它有俯仰、滚转、偏航这三个角度的姿态变化还要考虑最大爬升角、最小转弯半径、速度连续性和加速度限制。简单说规划出来的航迹不能只是“不撞障碍物”还必须是一条无人机真正飞得出来的路径——这在二维路径规划里经常被忽略。还有一个更实际的难点真实环境中的障碍物信息往往是不完整、不精确的。传感器只能探测到一定范围内的物体障碍物后面是什么完全未知。这种“部分可观测 动态变化”的组合恰恰是传统规划算法最吃力的地方。几年前我试过用人工势场法做三维避障一开始效果还行跑了几次就发现容易陷入局部极小点——无人机卡在几个障碍物之间的力平衡点上前后左右都在震荡就是飞不出去。这也是我后来转向强化学习路线的重要原因。1.2 为什么选择 DQN 而不是更“高级”的算法现在做强化学习避障很多文章一上来就上 PPO、SAC、TD3 这些连续控制算法理由是无人机动作空间本来就是连续的用离散动作太粗糙。这话理论上没错但对于一个刚起步的项目我认为 DQN 依然是性价比最高的选择。DQN 本质是价值学习它把“状态-动作”映射成一个 Q 值代表“在这个状态下采取这个动作预期能拿到多少累计奖励”。在三维避障场景里这意味着我们不需要直接计算策略梯度只需要让网络学会“评估”每个离散动作的好坏然后每次选择 Q 值最高的那个。训练过程更稳定调参也更直观。相比之下PPO 和 SAC 虽然能输出连续的控制量比如期望速度、角速度但他们对奖励函数设计和超参数更敏感训练过程中策略网络和价值网络之间的相互作用也更复杂。刚开始接触这个方向的人很容易陷入“训练崩溃”然后完全不知道问题出在哪里的窘境。我个人的经验是先用 DQN 把整个框架跑通理解状态、动作、奖励这三个要素之间的耦合关系之后真想换连续算法也清楚要在哪里动手改。2. 仿真环境与状态动作空间的设计这个环节想不明白后面全是坑2.1 环境选型AirSim 还是自建轻量环境无人机强化学习的仿真环境主流选择是 AirSim、Gazebo 这类带物理引擎的平台。它们的优势是渲染真实、传感器模型丰富能模拟相机、激光雷达、IMU 等设备。但缺点也明显环境启动慢、训练速度上不去一个回合跑下来经常要几十秒甚至几分钟做一次 10 万步的实验能熬到怀疑人生。我的做法是分两步走。第一步先在自建的轻量数学仿真环境里训练和验证算法环境中只保留最核心的运动学模型和障碍物碰撞检测一秒钟能跑上百个回合迭代效率非常高。第二步等算法稳定了再把训练好的模型搬到 AirSim 里做高保真验证检查在更真实的传感器数据下还有没有偏差。轻量环境里我用的运动学模型非常简单无人机视为一个质点状态包括三维坐标和速度动作直接改变速度方向或加速度方向空间范围设定为 100m × 100m × 50m障碍物随机生成 10 到 20 个球体。这个模型忽略了一些物理细节但在算法验证阶段完全够用——如果你一开始就在复杂动力学上较劲很可能会被噪声和误差掩盖掉算法本身的问题。2.2 状态空间10 维向量足矣别盲目堆维度状态空间的设计直接决定了训练难度。我的第一版实验里状态包含了无人机的位置、欧拉角、速度、角速度、目标相对位置、所有障碍物的相对位置算下来接近 30 维。结果训练非常慢而且收敛后行为也很奇怪——无人机经常做一些无意义的机动动作。后来我把状态精简到 10 维无人机当前三维坐标3 维目标点相对于无人机的三维偏移3 维距离最近障碍物的方向向量3 维无人机当前速度大小1 维为什么够用因为在这个场景里无人机决策避障方向时最重要的信息就是“目标在哪”和“最近的障碍物在哪个方向”。其他传感器信息虽然丰富但和决策的相关性并不高反而会引入大量无关方差让 Q 网络的拟合变得更难。这就是典型的“少即是多”——每加一个无关维度训练难度都会显著上升。如果你的无人机带有激光雷达障碍物信息可能是一组距离值而不是单一方向向量。这种情况下可以把最近障碍物的方向向量替换成几个固定方向的距离值比如前、后、左、右、上、下六个方向的距离效果也很不错。2.3 动作空间连续问题离散化是工程妥协无人机实际是连续控制系统但 DQN 要求动作空间离散。我的做法是把三维空间的基本运动方向划分成 6 个主方向——前、后、左、右、上、下——再加上一个悬停动作总共 7 个离散动作。每个动作改变无人机的速度方向速度大小由一个基础巡航速度决定。有些人会加更多动作比如带偏航角的 26 邻域方向或者不同的速度档位。我不建议第一版就这么干因为动作空间越大Q 网络需要区分的动作越多收敛难度成倍增加。6 1 这个粒度在三维避障里已经能完成大部分机动前方有障碍就上升或左右绕行前方和上方都有障碍就减速悬停等待或后退。当然离散动作的代价是航迹不平滑无人机转向时经常出现“折线”而不是“弧线”。这个问题可以在后处理阶段加一个平滑模块比如 B 样条曲线拟合来解决也可以在训练结束后用连续控制算法做微调。第一版不用太纠结这个问题先让无人机能飞、能避障、能到目标点策略的“平滑”属于锦上添花。3. 奖励函数设计避障效果好不好七成看这里3.1 一套能直接用的奖励公式奖励函数是强化学习的“指挥棒”无人机最终学成什么样完全取决于你怎么设置奖励。我的第一版奖励函数用了四个部分结构如下事件奖励值设计意图到达目标点100给予明确的正向强化告诉无人机“这个行为是对的”碰到障碍物-100强惩罚让无人机学会避开障碍每一步存活-0.05小步长惩罚避免无人机绕远路或在半空徘徊靠近目标距离差当前距离 - 上一步距离提供稠密梯度引导无人机逐步朝目标方向移动核心逻辑是“距离差奖励”如果这一步之后无人机与目标的距离比上一步近了就获得正奖励离得更远就获得负奖励。这个设计与 DQN 的时序差分更新配合起来非常顺滑网络能感觉到每一个动作对目标距离的影响而不是稀里糊涂地试错到终点。3.2 为什么不能只用稀疏奖励稀疏奖励的残酷现实第三个部分我特意提一下因为它很重要。有人会说既然到达目标有 100那无人机自然会去学怎么到达目标。理论上是这样但现实中三维空间那么大初始阶段无人机随机探索可能几万步都到不了一次目标。奖励全是碰撞、步数惩罚没有一次正向结果Q 网络根本学不到有效信息训练过程就像是在黑洞里找出口。这就是稀疏奖励问题。距离差奖励本质上是一种奖励塑形把“到达目标”这个遥远目标拆成一个连续渐变的目标让网络在每个时刻都知道该往哪个方向走。这里要特别提醒一点奖励塑形必须保留真正目标信号的存在感也就是“到达 100”必须足够大、碰撞惩罚必须足够重否则无人机可能会学会“不断靠近目标但在碰壁前折返”这种钻漏洞行为。3.3 奖励漏洞复盘无人机为什么会“贴着障碍物蹭”训练过程中最容易出现的奖励漏洞是无人机学会了贴着障碍物边缘滑行。原因很典型“靠近目标”的距离差奖励是正向的而障碍物只要没碰上就没有惩罚于是无人机宁可贴着障碍物飞也不愿意绕道——因为绕道会让它暂时远离目标拿到负奖励。解决思路是给障碍物设置一个“危险距离”缓冲区。当无人机进入障碍物半径外 1.5 米的范围内就对每一步施加一个额外的惩罚让无人机潜意识里离障碍物远一点。另一个方法是加大悬停动作的惩罚权重防止无人机在障碍物前不敢动用悬停来躲避惩罚。真实项目中我见过不少无人机学会在半路原地悬停一百步的“摆烂”策略都是奖励函数里给了悬停漏洞。4. 网络结构与训练流程DQN 里那些容易忽视的实现细节4.1 网络结构全连接网络就够用了很多初学者一上来就想着用卷积神经网络觉得这样更高级。但在我们的 10 维状态向量场景里卷积神经网络纯属杀鸡用牛刀还白白增加训练负担。我的网络结构非常简单输入层 10 维两个隐藏层各 256 个神经元激活函数用 ReLU输出层维度等于动作数 7输出每个动作的 Q 值。如果状态里包含了栅格地图或传感器图像数据那才需要考虑 CNN 来提取空间特征。但在单机仿真环境里手工特征已经完全够用。训练中我对比过 128 和 256 两种隐藏层宽度256 的收敛速度明显更快再往上加到 512 就没太大收益了训练时间反而显著增加。4.2 经验回放、目标网络、Double DQNDQN 里三个最常见的补丁模块我建议都加上它们实现成本很低但对训练稳定性帮助很大。经验回放池我设置的容量是 50000 条经验状态、动作、奖励、下一状态每次训练从池中随机采样 64 条。这样做的好处是打破样本之间的时间相关性避免网络被连续几帧相似状态带偏。训练时可以看到无人机偶尔动作会很激进但整体不会因为局部波动就崩溃。目标网络Q 网络的更新目标如果一直由自身生成会产生“追着自己尾巴跑”的问题——因为更新方向总在变。我采用每隔 500 步把主网络参数同步给目标网络的做法让更新目标在短时间内保持稳定。这种方式实现简单效果也足够好。Double DQN 的改动更是只有几行代码在计算目标 Q 值时先用主网络选出最优动作再用目标网络计算这个动作的 Q 值。原始 DQN 直接取目标网络输出最大值容易高估 Q 值导致过估计。加上 Double DQN 之后我训练出的模型明显更稳定无人机也没有出现“迷之自信”地冲进障碍物的情况。4.3 超参数与训练收敛的判据下面是我实际用下来的一组参数可以直接作为起点参数数值说明学习率3e-4过高会导致 Q 值震荡过低收敛太慢折扣因子 γ0.99让无人机更关注长期收益ε 初始值1.0开始阶段充分探索ε 最小值0.05保持一定随机性防止策略固化ε 衰减步数30000 步从 1.0 线性衰减到 0.05经验池容量50000足够大保存更多历史样本批量大小64常用值偏差方差平衡目标网络同步间隔500 步不要频繁同步否则失去稳定性判断训练是否收敛不要只看平均奖励曲线。我一般同时观察三个指标每回合平均奖励、每回合碰撞率、每回合到达目标率。只盯着奖励曲线容易误判因为奖励可能因为某个阶段的探索行为而暂时波动。当平均奖励趋于稳定、碰撞率降到一个较低水平、到达率保持在一个较高水平才说明策略真正稳定了。我训练到大约 2000 个回合的时候到达率稳定在 90% 以上碰撞率降到 5% 以下基本可以认为模型可用。5. 仿真测试与问题排查收敛之前我踩过的坑5.1 训练曲线到底该怎么解读训练初期平均奖励大概率是负的因为无人机在随机探索阶段不断碰撞障碍、拿步数惩罚这是完全正常的。有些同学看到奖励为负就慌了开始魔改网络和参数其实没必要。我习惯把训练过程分成三个阶段看前期约前 500 回合策略基本随机碰撞率居高不下奖励曲线像过山车。中期约 500-1500 回合经验池里积累了足够多样本网络开始学到避障意图碰撞率缓慢下降奖励曲线整体呈上升趋势但仍有起伏。后期超过 1500 回合策略逐步固化碰撞率明显降低到达率开始稳步爬升。如果到了 3000 回合以上奖励仍然在低位震荡、没有向上的趋势那多半不是训练步数不够而是设计层面出了问题。此时优先检查状态空间是否包含足够信息奖励函数是否有冲突或漏洞而不是盲目加训练轮数。5.2 三个典型的失败案例与根因第一个案例是训练前期梯度爆炸。现象某个回合后奖励突然从 -10 变成 -10000之后所有输出变成 NaN。问题出在奖励值量级太大Q 值更新时发生梯度爆炸。解决方法有两个把奖励值做归一化例如到达奖励从 1000 改成 100或者调整梯度裁剪参数。第二个案例是后期持续震荡。现象训练到 1500 回合时碰撞率已经降下来了但之后不仅没继续变好反而反复横跳有时候一回合表现得很好下一回合又连续碰撞。这是 ε 没有衰减到位导致的。我一开始把 ε 衰减设置在 100000 步持续太久导致后期仍有大量随机探索策略始终不稳定。把衰减周期改成 30000 步后震荡明显减少。第三个案例是局部最优。现象无人机学会了避障但走了明显绕远的路径永远从某一个固定的方向绕行。比如所有障碍物都在正前方时它总会选择从右侧绕即使左侧更近。这个问题的本质是目标距离奖励不足导致无人机没有足够的动机去寻找更短路径。我把“靠近目标”的奖励权重提高了 1.5 倍后路径明显更合理了。5.3 参数调试手记一次只改一个变量训练出现问题的时候最容易犯的错误是一口气改三四个参数结果问题没解决还不知道是哪个参数起的作用。我自己调试时有一个固定流程记录当前版本的行为表现 → 提出一个假设比如“可能是 ε 衰减太慢”→ 只修改和这个假设相关的参数 → 重新训练并对比。我用 v1、v2、v3 这样的版本号管理每次改动。v1 是初始版本到达率 70%路径经常绕远路v2 增大了距离奖励权重到达率提升到 85%路径明显更合理v3 把 ε 衰减周期从 100000 缩短到 30000训练稳定性变好碰撞率进一步下降。把所有版本的数据记录下来你会很清楚每一步调整带来了什么变化而不是像无头苍蝇一样乱试。6. 从仿真到实机还有多远的路要走6.1 Sim2Real 的三大鸿沟仿真里训练出来的模型直接搬到真机上是跑不了的这个问题叫 “Sim2Real Gap”。我总结下来有三道鸿沟第一是状态延迟。仿真中状态是即时可用的但真机上传感器采集、数据处理、通信链路都有延迟从获取状态到执行动作之间可能相差几百毫秒无人机这段时间里已经飞出了一段距离。处理方法是在仿真里加入人为延迟训练时让无人机适应这种滞后。第二是传感器噪声。仿真里的距离传感器数据是精确的真机上激光雷达或视觉里程计都会引入噪声和漂移。强化学习对状态噪声比较敏感策略在带噪输入下可能会产生完全不同的行为。我会在仿真的状态观测里加入高斯噪声模拟传感器的误差。第三是执行误差。仿真里动作指令会被完美执行真机上电机响应、空气阻力、风力扰动都会导致实际飞行轨迹和预期不同。这个问题的应对思路是让无人机不是“直接飞向目标方向”而是把 DQN 输出的动作作为上层导航指令交给底层的 PID 控制器去执行。6.2 域随机化与后续扩展方向现在工程上从仿真迁移到真机最常用的技术是域随机化Domain Randomization在训练时随机改变环境中的物理参数比如无人机质量、电机推力系数、障碍物大小让策略在多种“环境变体”里学习从而增强泛化能力。用这种方式训练出来的模型在真机上表现会稳健得多。从 DQN 这个起点出发后续的扩展方向主要有三条一是把动作空间改成连续控制换成 DDPG、TD3 或 SAC让航迹更平滑二是在状态空间中加入历史信息比如用 LSTM 处理过去几帧的传感器数据提升部分可观测环境下的决策能力三是做多无人机协同避障让多个智能体共享环境信息同时避免冲突。但不管往哪个方向走DQN 这套“状态-动作-奖励-网络-训练”的框架都是地基把这套地基打扎实了后面才能不慌。最后再说一个我自己的体会这个项目里最重要的时间投入不是写代码而是设计状态空间和奖励函数。如果你赶时间就先把这两个部分打磨好比堆训练步数有用得多。我这边后期打算把决策层和底层控制解耦做一个标准的接口这样换算法的时候只需要替换决策模块就行不需要每次都重新搭环境。这个方向值得继续往下做。本文还有配套的精品资源点击获取