ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

深度强化学习与无人机动态避障:NavRL原理与工程实践解析

深度强化学习与无人机动态避障:NavRL原理与工程实践解析 开年以来我一直在折腾无人机自主导航这块刚好 CMU 放出了 NavRL 的开源项目圈子里讨论热度不低。刷了几遍源码之后又自己跑通了一遍训练流程今天把这段经验整理成文。如果你是做无人机避障、路径规划或者强化学习落地的这篇应该能帮你少踩几个我踩过的坑。NavRL 的核心是用深度强化学习把感知-决策压进同一个网络里无人机在仿真环境里不断试错学会怎么根据传感器输入主要是深度图和自身状态输出一个可飞的控制指令从而在动态障碍物之间穿行。它解决的核心问题是传统几何规划器在面对非预设、非线性、高速移动的障碍物时容易卡死或反应迟钝的毛病。适合想入门 RL 导航、或者已经在做无人机感知但决策部分还在用手写规则的朋友。1. 项目概述与核心思路1.1 NavRL 是什么用强化学习替代手写规则导航先交代下背景。NavRL 不是一套像 PX4 那样开箱即用的飞控固件它更像是一个训练和部署的框架加配套的仿真环境。它的目标场景很明确四旋翼在室内或城市峡谷这样障碍物密集的 GPS-denied环境里飞行周围还有移动的人和车无人机要在不撞上去的前提下到达目标点。这属于典型的部分可观测马尔可夫决策过程POMDP因为单个深度图中无法看到被遮挡区域的障碍物只能靠历史帧和当前观测做推断。传统的做法大致是两条路线一是基于占栅格地图的规划先建图再搜路径最后生成轨迹二是基于局部反应式避障比如 DWA 直接在前向模拟里搜索可行的速度指令。这两条路线在结构化环境里都很成熟但在有大量动态障碍物、计算平台又很小的场景里会暴露问题——地图更新有延迟、动态障碍物建模不准、规划周期跟不上高速接近的物体。NavRL 的思路是干脆不显式建图用端到端网络从观测直接映射到控制指令让智能体在成千上万次仿真碰撞里自己学出一套反射式避障策略。我个人的理解是这其实有点像人类飞行员的学习方式我们不先建立全量环境模型再决策而是看到前方有人影晃动就本能地侧转。学习到的策略本质上是一套从视觉特征到机动动作的映射它的响应速度可以做到毫秒级因为它不需要执行完整的建图-规划-跟踪管线。NavRL 在框架设计上把这个问题拆成了几个层次感知预处理、策略网络、控制接口这也方便后续大家对某个模块单独做二次开发。1.2 为什么动态避障是硬骨头传统方法的三个坎动态避障多年以来都是小型无人机自动飞行里最头疼的部分。原因可以浓缩成三点。第一感知有延迟和噪声。不管是视觉里程计还是激光雷达传感器数据到达决策模块时障碍物的真实位置已经和测量值有偏差。动态障碍物速度越快这种测量滞后越致命。DWA 这类局部规划器通常假设当前速度能保持一段时间一旦目标突然转向规划出的轨迹往往已经失效。第二全局规划和局部反应之间存在耦合矛盾。严格的全局规划要求完整的代价地图但无人机在小算力平台上很难实时维护高频更新的动态代价地图。退一步说就算地图能更新搜索算法的计算开销也会随着地图规模增长导致决策频率上不去。实际测试中单纯依赖 DWA 的无人机在遇到快速横穿的障碍物时经常出现看到物体-评估碰撞-重新规划的循环还没跑完物体已经冲到跟前了。第三多障碍物同时逼近时没有优雅的优先级策略。传统规划器在很多情况下会退化为保守的急停但无人机是没法急停的——没有足够的升力冗余稳定悬停或者风扰导致姿态失稳。所以一个合格的避障策略必须学会主动修正航向而不是停在原地。NavRL 绕开这些问题的切入点简单粗暴既然手写规则很难覆盖所有动态场景那就用海量仿真数据做监督让网络自己发现规律。这个方法对有飞行经验的人来说反直觉因为传统控制理论的基础是模型精确、状态可测而 RL 的做法是行为正确即可内部状态不管。实际效果我在仿真和真机上对比过——在特定场景下学到的策略的响应时延确实远低于传统折线预测方案。1.3 方案选型对比端到端RL、NMPC、DWA拿一个具体的对比来说。假设无人机以 3 m/s 前进正前方 5 米处一个行人以 1.5 m/s 横向穿越你需要在 1 秒内做动作。用 DWA 的思路首先要估计行人的速度通常用卡尔曼滤波跟踪然后以当前速度和角速度为轴暴力搜索下一时刻的可行指令空间。在搜索窗口内对每组速度采样做前向模拟评估模拟轨迹经过的栅格是否有障碍物占据。计算上单步没问题但窗口的长度决定了预测的深度窗口太短反应不过来窗口太长又会因为行人速度估计不准确而出现大量误判。而且每个控制周期都做全量搜索在树莓派级别的平台上一般只能跑到 10~20 Hz 的规划频率。用 NMPC 的思路需要把无人机动力学模型和障碍物预测轨迹写进优化问题里。这在理论上是全局最优的但求解非线性规划的开销很大通常控制在 20~50 Hz 已经算不停迭代后的上限而且还要处理局部最优、约束不可行等一堆问题。更重要的是NMPC 对障碍物的运动模型很敏感模型给不准时优化出来的轨迹往往很愣生硬不做预判。端到端 RL 的策略前向推理就是一次网络推理在 Jetson NX 上跑轻量级 CNN 可以轻松到 50 Hz 以上。它不依赖障碍物的显式运动模型因为仿真中已经见过各种运动模式网络内部隐式地编码了看到什么模式就该做什么反应的经验。代价是训练成本高、可解释性差而且需要认真做真机迁移。下表是我实测的粗略对比方案决策频率(Hz)对动态障碍物建模要求计算平台要求调试难度可解释性DWA20~30中需要跟踪预测低低高NMPC20~50高需要精确运动模型高高中NavRL50无训练时隐式学习中中低选 RL 不是因为它万灵而是它在动态密集场景下把反应延迟压到了最低。后面所有章节都是围绕这个决策展开的。2. 技术架构与关键设计2.1 观测空间与动作空间定义NavRL 输入侧的观测空间分成三块深度图像、无人机自身状态、目标相对位置和速度。深度图像会先经过一个裁剪和降采样再送入一个轻量级卷积网络提取特征。自身状态一般是 IMU 融合后的速度、姿态角速率目标信息则用目标在机体坐标系下的相对位置向量和相对速度向量表示。整体上观测向量拼接卷积特征和状态特征后再进过几层全连接网络输出动作。动作空间可以设计成底层控制命令姿态角速率和油门或者中层控制命令速度指令和偏航角速度。NavRL 的做法偏中层——输出期望机体速度再由底层姿态控制器跟踪这样比较容易把 RL 策略和现有飞控系统接到一起。实际在 Gazebo/Unreal 仿真里输出的速度指令通过 MAVROS 发给 PX4 的 offboard 模式飞控负责姿态环和角速度环。用中层控制的好处是降低训练难度的同时保住了避障机动性如果直接输出油门和角度训练收敛会慢非常多而且学到的东西经常让飞控无法跟踪。做这个小节是想说明一个容易忽略的点强化学习环境的观测动作怎么定义极大程度上决定了你能不能在真机上跑起来。很多人卡在仿真很好但真机跑不了回头发现是动作空间的抽象层级和飞控接口不匹配。NavRL 在这一点上做得很克制它没有把控制器的活抢过来而是在AD 控制输入和底层飞控之间留了一条清晰的边界这条边界就是实际部署的切入口。2.2 奖励函数怎么设计奖励设计是 NavRL 这类项目里最玄学也最关键的部分。它大体用了四类奖励项的加权组合。第一项是速度奖励鼓励无人机朝目标方向快速移动。一般取无人机在目标方向的速度投影或当前速度与期望速度的差简单做法是每一步给一个和目标距离负相关的奖励增量。第二项是碰撞惩罚在发生碰撞或接近障碍物时给一个较大的负奖励。要注意接近怎么定义——距离很近但没有碰撞的情况如果也罚容易学出过于保守的策略如果完全不罚学出的策略会贴着障碍物擦过去真机上一个噪声就撞上了。NavRL 的做法是设置两层碰撞圈内圈给大惩罚外圈给小惩罚相当于软约束。第三项是光滑性惩罚惩罚动作的一阶差分过大约束加速度和角加速度。控制指令太抖会让飞控吃不消也会让电机磨损变快。最后一项是时间惩罚避免无人机为了绕开障碍物在原地打转每步给一个小负值鼓励尽快到达目标。整体表达式类似$$\text{reward} \alpha \cdot r_{\text{goal}} - \beta \cdot \mathbb{1}{\text{collision}} - \gamma \cdot \mathbb{1}{\text{near}} - \delta \cdot \lVert a_t - a_{t-1}\rVert^2 - \eta$$这些系数不是一次调好的。我一开始把碰撞惩罚拉得太大结果训练出来的策略是无人机打死不往有障碍物的方向飞全程悬停不动每步虽然拿不到速度奖励但也不会撞相当于在解一个最稳妥的废物策略。后来把接近圈的惩罚调小、把时间惩罚拉高它才学会既要快速到达又要安全绕行的平衡。奖励工程没有银弹必须一个一个权重试观察训练曲线和仿真回放。2.3 训练环境与仿真器NavRL 的训练环境主要在 Gazebo 或者升级后的仿真器里构建。它对场景做的抽象很有参考价值每个 episode 随机生成一个无人机起点、目标点以及若干静止和动态障碍物障碍物速度、方向和出现频率都采样自一个分布保证智能体在每个 episode 看到的场景都不一样防止过拟合到固定路线。仿真器设置有两个我特别想强调的细节。一个是渲染和物理频率要解耦。Gazebo 里如果物理频率和相机渲染频率碰撞深度图会非常卡RL 训练稳定性会直线下降。NavRL 的配置里把物理频率固定为 200 Hz视觉信息以 15~20 Hz 的频率下发控制指令每 50 ms 推理一次。另一个是动态障碍物不能太完美它们要有加速度约束和最小转弯半径否则学到的策略在真机遇到人类行人时完全不适用因为人类不会像仿真里的物体那样带完美匀速直线运动。训练采用异步并行收集数据。每台机器可以起几十个并行的仿真环境收集经验统一交给训练进程更新策略网络再定期把最新策略权重同步回去。这本质上就是 PPO 的经典实现模式。官方的做法基于 Stable-Baselines3 或者自研的 RL 库我在复现时主要用 SB3 的 PPO稍微调整了下网络层数。如果你自己也打算跑建议先在一两个环境下把训练流程通一遍确认能拿到下降的 loss 曲线再上并行规模不然很容易一堆环境同时死锁然后怀疑人生。3. 实操过程与部署实现3.1 环境搭建与依赖我的流程是在 Ubuntu 20.04 下跑的硬件是单张 RTX 3080。核心依赖有 ROS Noetic、Gazebo 11、PX4-Autopilot、MAVROS训练端是 PyTorch 和 Stable-Baselines3。官方仓库里给了 Docker 镜像但我建议有经验的人还是手动装因为真机部署时 Docker 和宿主的 USB 串口、显卡透传搞起来更麻烦。安装顺序我踩过一次坑必须先装好 ROS 和 Gazebo再装 PX4 固件最后装 MAVROS。顺序反了的话PX4 的 MAVLink 消息定义会和 MAVROS 的版本对不上后面跑 offboard 模式会莫名其妙报 message ID 错误。装好之后先启动仿真器确认无人机能起飞跑一下基础的 offboard 例程再考虑跑 RL 训练。依赖安装这块建议开一个独立的虚拟环境给 PyTorch用 conda 管理。Gazebo 和 ROS 最好保持在系统级 Python 环境里因为 ROS 的 catkin 工具链对 Python 环境切换很敏感。这一步看似不起眼实际能避免后续在 conda 环境里 import rospy 失败这类基础问题。3.2 训练流程与关键命令训练整体分三个环节启动仿真环境、启动训练脚本、监控训练数据。先启动一个仿真世界作为数据源通常一个物理进程绑定一个仿真世界如果开并行收集就用 Python 脚本多进程各启动一个空闲的 Gazebo 实例。NavRL 风格的框架里每个仿真进程独立运行互不共享除策略外的数据。训练脚本的核心配置项大概这些学习率 3e-4gamma 0.99GAE lambda 0.95clip range 0.2每个 iteration 采样 4096 条 stepmini-batch 大小 512。奖励权重配置项集中在 reward.yml 里网络结构是特征提取 CNN两层卷积每层 32 个 filter加 3 层 256 维全连接。跑起来之后重点盯三个指标平均 episode 回报、每个 episode 到达率、平均碰撞次数。我在前 50 万步时回报曲线波动很大一直在 -800 到 -100 之间来回跳。这是正常的因为随机初始化的策略前期基本就是在乱飞撞墙。到了 150 万步左右回报稳定到正值区间300 万步之后碰撞次数明显下降。这里要说一句训练时间表因人因环境差异很大不要拿别人的收敛步数当标准只看自己环境的曲线趋势。官方给的预训练权重只适合 benchmark不适合你自己的任务场景直接迁移。用 GPU 跑 4~8 个并行环境实测训练 100 万步大约 40 分钟到一个小时。如果不开并行单个环境可能要 6 小时以上所以并行环境的搭建值得花时间做。仿真器中动态障碍物的数量和质量是整个训练质量的关键别在一两个固定场景里自嗨一定要做 domain randomization。3.3 真机迁移与部署要点仿真到真机sim-to-real是这类 RL 导航项目的头号难题。NavRL 的工程实现里给出了一些手段这里把我的使用心得展开讲。第一输入分布要对齐。仿真里深度图的尺度、噪声模型、失真参数和真机红外深度相机有差距训练时如果不加随机噪声和遮挡干扰策略拿到真机深度图会完全不认识。我的做法是训练中给深度图随机加高斯噪声、随机抹掉部分像素模拟传感器盲区效果立竿见影。第二动力学响应要打折扣。仿真模型总是比真机飞行器理想我在部署前都会给指令加一层低通滤波把速度期望的变化率限制住不然真机会出现高频抖动飞控日志里全是震荡波形。第三速度闭环要稳。RL 策略输出的速度指命要由底层 PID 跟踪如果底层速度环没调好策略的输出再好也会在真机上表现得像喝醉了建议先在 PX4 的 offboard 模式下跑匀速直线验证速度环跟随能力再上避障。最后是关于安全策略。我建议真机测试时加一道保护逻辑RL 网络给出的指令通过之后再叠一层基于碰撞时间的安全检查和急停覆盖。这道逻辑可以直接判断未来 0.5 秒是否会和检测到的近距离障碍物相撞是的话就强制减速。原因是 RL 策略在训练分布之内很稳健但真机永远有训练分布之外的 corner case保护层是最后底线。4. 常见问题与排查技巧4.1 训练不收敛怎么办我第一次跑 NavRL 式的训练时遇到的最典型问题是 reward 一直上不去甚至越来越低。排查顺序一般是这样的。先看传感器输入是否正常。把训练环境里的深度图和状态量可视化确认没有 NaN 或者全黑图像。Gazebo 偶尔会出现渲染 bug 导致深度图全零这时智能体等于闭着眼飞策略必然学歪。再看动作输出是否越界。如果网络输出的速度指令超过无人机动力学极限仿真里会出现无人机原地鬼畜晃动难以学到有效策略。解决方法是在动作输出层加 tanh 再乘以最大速度而不是训练中依赖 clip 导致梯度路径断裂。最后看奖励比例是否合理尤其检查接近惩罚和碰撞惩罚的比例。如果接近惩罚太大智能体宁可绕远也不靠近障碍物表现为轨迹过于保守如果碰撞惩罚太小策略会一路莽过去。还可以打开 policy entropy 曲线——如果熵降得太快说明策略过早锁死在某个局部最优上可以考虑调大 PPO 的 entropy coefficient或者换更大的 actor 网络。如果熵一直不降说明训练根本没在学多半是奖励信号传导有问题。4.2 仿真表现好但真机很拉胯这是 End-to-end 视觉导航最普遍的玻璃天花板。我上一节提过的 domain randomization 是第一个防火墙还有一个经常被忽略的点是传感器时延对齐。训练时我在仿真里默认深度图是当前时刻的但真机相机从曝光到数据到达推理模块之间的延迟可能有 30~50 ms飞控状态估计也有滤波延迟。真机上相当于拿着 50 ms 以前的观测做决策策略自然会反应过度或反应不足。解决手段是训练时故意给观测加随机延迟 1~3 个控制步让策略学会在陈旧观测下做鲁棒决策。这个技巧我试过之后真机性能提升非常明显。另外真机和仿真中无人机惯性参数不一致也会导致策略动作大步子走小步子看似在仿真里能飞出的轨迹真机飞不出来。建议在真机测试前至少校准质量、惯量和推重比并在仿真中把参数调到和真机一致而不是用官方默认值。4.3 动态障碍物响应慢的排查响应慢有两种表现一是策略网络推理本身慢二是决策频率够但动作太软。推理慢的话首先要看模型有没有跑在 GPU 上。Jetson 这类嵌入式平台如果不启用 TensorRT 加速一个轻量 CNN 也可能需要 30 ms 以上加上前后处理就超过了控制周期。建议导出成 ONNX再用 TensorRT 转成 FP16 推理实测可以跑到 5 ms 以下。动作太软则大概率是奖励里速度权重不够策略出于保守选择了慢慢挪。对策是提高速度奖励比例并适当降低接近惩罚的半径让它察觉到离障碍物还有安全距离时就可以加速。还有一个小坑是动态障碍物的运动学仿真设置。如果仿真里动态障碍物的速度范围远大于真机场景中的真实速度训练出的策略会把所有移动物体都当成即将瞬间冲过来的鬼影过度规避表现就是轨迹弯弯绕绕且飞行速度很慢。这时应把训练分布和真实场景分布对齐别贪多图全。5. 总结与经验心得按我跑通这个流程的经验最值得记住的一点是先小后大、先简后繁。别一上来就在大型城市环境里训练先用 3~5 个障碍物的小场景把训练管线全部打通确认从仿真到真机的基本链路都有数了再逐步增加障碍物数量和动态复杂度。NavRL 这类框架最大的价值不是给你一份开源代码而是给你一套可以拆装、替换、实验的工程模板框架本身只是起点。最后再分享一个具体的小技巧保存 checkpoints 时刻不要只存网络权重把训练环境的配置、奖励权重、domain randomization 参数一起存成一个完整实验记录。后期你想复现某个效果时单纯有权重而没有配置等于完全没有记录。我做项目曾经踩过一次这个坑拿着新代码加载老权重行为完全不对查了半天最后发现是奖励权重变了。如果你正准备用 NavRL 做无人机动态避障我的建议是花半天时间把官方例程跑通花两天时间把训练流程和可视化工具用好再花一周时间做 domain randomization 参数调优最后才考虑真机飞行。这个节奏看起来慢实际是推进最稳的路线。飞控无小事多留冗余多做保护。
返回列表