UE4+AirSim无人机强化学习导航与跟踪:从环境搭建到PPO训练
发布时间:2026/10/2 9:13:37来源:尧图网络
简介面向计算机相关专业的课设、大作业与毕业设计场景这份资源提供了基于UE4和AirSim环境的无人机自主导航与目标跟踪强化学习完整实现解决了从仿真环境搭建到算法训练验证的链路问题适合有Python和C基础、希望快速上手项目实战的学生使用。压缩包共646个文件含191个Python脚本、167个C头文件、16个cpp源文件以及116张PNG图像、65个Markdown说明文档另有构建脚本、参考配置与配置文件等整体148.98MB结构清晰便于按模块检索。核心代码经历过功能测试可放心下载运行图像与文档可用于理解训练过程和结果分析脚本工具辅助环境部署与数据获取。目前已有190人学习下载作为初期项目立项演示或毕设基础均有较高借鉴价值。1. 这个课设/毕设方向难点根本不只在你以为的那个RL算法如果你选的是“UE4 AirSim 环境下无人机自主导航与目标跟踪的强化学习算法”这类课设/大作业/毕设题我猜你最初的预期是把 DQN 或者 PPO 调通模型学会飞过去找目标就大功告成。但实际做过的人都知道真正花费 60% 时间的地方是前两步——UE4 与 AirSim 的版本匹配以及如何把“导航”和“跟踪”翻译成强化学习能理解的观测与奖励。这篇笔记就是把这三段路完整走一遍先是环境搭建再是状态/动作/奖励设计然后是 PPO 训练的最小可跑代码最后是训练翻车时的排查思路。适合正在做课设、打算拿这套方案当毕设主体、或者想从零快速验证“强化学习能不能驱动无人机”的同学。2. 先把 UE4 和 AirSim 这套环境搭稳版本匹配与模式选择2.1 为什么这套仿真架子比算法本身更难搭AirSim 不是一个独立可执行的程序它本质上是 UE4 的一个插件。也就是说你必须先有一个能打开的 UE4 工程再把 AirSim 插件塞进去编译最后运行出来的那个窗口才是一个“能飞的四旋翼仿真环境”。这里最容易卡住的是 UE4 与 AirSim 版本锁死的问题AirSim 的每个 Release 都明确写了它基于哪个 UE4 版本构建你如果拿 UE4.26 的工程强行配一个只支持 UE4.27 的 AirSim 版本最常见的结局是编译到一半插件动态库崩溃或者 UE4 编辑器里出现一堆重定向的模型断链。我一般会先定 UE4 版本再按这个版本挑对应的 AirSim 版本。课设场景我建议选 UE4.27 这条线因为它的编辑器比较稳定网上能搜到的踩坑记录也最多。另一个需要提前做的决定是操作系统AirSim 在 Windows 下的构建链最顺Linux 下如果强行走 UE4 原生编译会很痛苦需要处理大量的 vcpkg 依赖。不是不能跑是没必要在生产环境里折腾自己。2.2 最小可飞环境从新建 UE 工程到取到第一帧图像常见做法是把 AirSim 仓库克隆到本地然后把它的 Unreal 插件目录塞进一个新的 UE4 工程里再让 UE4 重新编译生成项目文件。下面是 Windows 下我实际会走的步骤。# 假设你已经通过 Epic Games Launcher 装好 UE4.27 # 1. 克隆 AirSim 仓库到本地 git clone https://github.com/microsoft/AirSim.git cd AirSim # 2. 生成并编译 AirSim 插件 python build.py --targetUE4这里做的事情是第一步拿到完整源码第二步用仓库自带脚本生成插件并编译。编译时间取决于机器一般 10 到 30 分钟期间会输出大量 C 编译日志看到“Build succeeded”才算插件这一侧完成。然后新建一个 UE4 的 C 工程把 AirSim 仓库里的Unreal/Plugins/AirSim文件夹整体复制到新工程的Plugins目录下如果没有这个目录手动新建一个即可。接着右键工程文件执行“Generate Visual Studio project files”再用 Visual Studio 打开工程并编译一次。这一步的作用是让 UE4 识别这个第三方插件并把它的编辑器模块加载进当前工程。编译完成后在编辑器的 Play 按钮旁边选择你要启动的地图建议先用默认的空白地图跑通而不是一上来就加载城市街区场景。第一次启动后如果一切正常你会看到右上角出现 AirSim 的 API 状态浮层默认是一辆车的视角。因为我们的目标是无人机所以下一步是修改settings.json把仿真模式切到Multirotor。2.3 settings.json仿真模式和跟踪场景的关键参数settings.json是 AirSim 在启动时读取的配置文件通常在Documents/AirSim下。它决定了整个仿真环境以什么模式运行、传感器开哪些、渲染分辨率多少。这是我的最小可飞配置{ SettingsVersion: 1.2, SimMode: Multirotor, ClockSpeed: 1.0, ViewMode: Fpv, CameraDefaults: { CaptureSettings: [ { ImageType: 0, Width: 640, Height: 480, FOV_Degrees: 90 } ] }, SubWindows: [ { WindowID: 0, ImageType: 0, CameraName: 0, Visible: false } ] }这里的SimMode决定载具类型必须写成Multirotor否则你会拿到一辆车而不是四旋翼。ClockSpeed是仿真时钟倍率训练时可以调到 1.0 甚至更高但要注意它在物理碰撞和动力学采样上会带来额外开销不是越高越好。ViewMode里的Fpv是指把主窗口绑到无人机前视相机视角方便观察目标跟踪效果。CameraDefaults中的ImageType: 0代表场景彩色图1 是深度图2 是分割图视觉阶段经常用深度图训练因为深度图对颜色不敏感。SubWindows这一段是可选的调试时可以在 UE4 窗口里额外挂一个信号画面但训练阶段建议保持Visible: false否则渲染开销会让帧率掉得很惨。改完配置后重启 UE4 工程你应该能在场景里看到一架无人机按F5进入仿真后螺旋桨开始旋转APIControl 状态变为可连接。到这一步环境侧就算立住了。3. 把“自主导航目标跟踪”拆成 RL 能学的状态、动作和奖励3.1 先决定学什么目标跟踪任务的马尔可夫化过程自主导航和目标跟踪在强化学习框架里不是两个独立任务它们可以被统一成一个“给定相对位置与速度输出速度指令”的序贯决策问题。导航阶段的目标是静态的跟踪阶段的目标是运动的但两者在数学形式上都满足马尔可夫性质当前时刻的观测足够决定下一时刻的最优动作不需要回看历史状态。我见过有的同学把“导航”和“跟踪”分成两个完全不同的模型来训练其实没有必要。同一个策略网络可以先用静态目标点做预训练让模型学会“接近目标、悬停、防止越界”然后再把目标点改成随时间移动的轨迹做跟踪的微调。这样做的收敛速度比直接端到端学跟踪快很多因为跟踪任务里目标移动造成的观测变化会让早期奖励非常不稳定。这里可以顺带提一句离线强化学习的热点。现在像 IQL 这类的离线强化学习算法很流行但在这个课设场景里我不建议一开始就上。AirSim 仿真本身足够便宜在线采样成本低没必要先收集数据集再做离线训练在线 PPO 起步往往是最稳的。3.2 观测与动作空间用相对位置而不是全局坐标观测空间设计有一个很关键的原则尽量让策略对不同起点具有平移不变性。如果观测给的是无人机在 UE4 世界坐标系下的全局坐标那么你在位置 A 学会的策略换到位置 B 可能完全不适用因为神经网络的输入分布变了。反过来如果观测给的是目标相对无人机的偏移量和自身速度那么无论起点在哪输入的数值范围都能维持在相对稳定的区间。我一般会把观测设计成 6 维向量依次是目标在 NED 坐标系下的 x、y、z 相对偏移以及机体当前速度的三分量。注意 AirSim 对外提供的位置会有一个坐标系陷阱AirSim 对外 API 用的是 NED 坐标系x 指向北y 指向东z 向下为正。也就是说当无人机实际高度是 5 米时它的 z 值是 -5。很多第一次做 AirSim 强化学习的人就是在这上面翻车他们用正数表示高度配出来的结果要么是模型一直在往下扎要么是把高度控制完全学反了。动作空间方面为了降低控制复杂度不直接输出四路电机转速而是输出三个通道的速度指令x 方向速度、y 方向速度、z 方向速度。这三个量通过moveByVelocityAsync发送给底层控制器由 AirSim 自带的无人机姿态控制器去反解油门和姿态角。这样整体动作空间是连续三维向量范围先归一化到 -1 到 1 之间训练时再缩放成实际速度范围。3.3 奖励设计导航阶段用距离势场跟踪阶段加“视野惩罚”在强化学习里奖励设计几乎决定了训练上限。下面这张奖励参数表是我在自动导航任务里经常拿来当起点的配置多数情况下能先把“从随机位置飞到目标附近”学会。奖励项表达式建议初始参数距离势场-0.1 * distdist 指当前位置到目标点的 NED 距离到达奖励10当dist 1.0时触发并回合结束越界/低高惩罚-20当无人机撞地或飞离任务区域时触发步数代价-0.01每一步扣一点防止模型原地打转这个奖励函数的思路是用负距离当作持续的压力信号让模型每走一步都知道自己离目标更近还是更远到达奖励是一次性事件用于强化“最终收敛”这个事实越界惩罚是安全约束防止模型为了减少距离势场而直接撞地或飞出范围。跟踪任务需要在上面这张表上再加两项。第一项是“动态目标距离变化率”也就是这一帧的相对距离减去上一帧的相对距离。如果距离在缩小就给一点正反馈如果距离在拉大就惩罚。这个项比单纯的距离势场更能帮助模型学会“保持跟随”因为跟踪时目标自身也在运动只看绝对距离会导致模型一直在追滞后值。第二项是“视野惩罚”。目标跟踪如果建立在视觉基础上你需要让奖励与目标是否出现在画面中心挂钩如果目标在画面外给一个明显的负奖励。这样模型学的不只是“靠近目标”而是“在视野里维持目标”。3.4 训练模式选择在线 PPO 起步别急着上复杂 SAC对于这个领域深度强化学习算法其实有不少选择。DDPG 适合连续控制SAC 在样本效率和稳定性上常优于 DDPG还有基于模型强化学习或者多智能体强化学习等更高级的方向。但我自己的建议是如果目的是把课设/毕设跑通并拿出令人信服的效果请从 PPO 开始。原因有三条。第一PPO 对超参数的敏感度相对低在奖励函数不完美的时候也能稳定推进。第二PPO 是稳定性较好的在线策略算法不需要回放缓冲区里的旧数据降低了环境状态分布变化带来的训练震荡。第三社区资料最多出问题时你能搜到同场景的解决方案。SAC 虽然样本效率上限更高但需要调的参数更多而且目标跟踪任务里奖励信号本身就带有噪声SAC 的熵项如果平衡不好会出现长时间不收敛的“假死”状态。先让 PPO 出结果再考虑换 SAC 做对比是性价比最高的路线。4. 用 PPO 把模型跑起来训练脚本、参数表和第一轮调优4.1 把 AirSim 环境包成 Gym 接口无论你用什么库来写 PPO第一步都是把 AirSim 环境包装成 OpenAI Gym 的接口格式。这一步的价值在于把“和仿真器通信”与“算法优化”解耦开。算法端只认obs、reward、done至于这些值是从 UE4 里怎么来的算法不关心。我自己习惯用gymnasium这个库因为它的 API 更规范配合 Stable-Baselines3 可以直接进入训练。下面是一段可以拿去改的基础环境封装代码import gymnasium import airsim import numpy as np from gymnasium import spaces from stable_baselines3 import PPO class AirSimNavEnv(gymnasium.Env): def __init__(self, target_ned(10.0, 10.0, -5.0)): super().__init__() self.client airsim.MultirotorClient() self.client.confirmConnection() self.client.reset() self.client.enableApiControl(True) self.client.armDisarm(True) self.target np.array(target_ned, dtypenp.float32) self.max_dist 100.0 # 观测: 目标相对位置(3) 自身速度(3) self.observation_space spaces.Box( low-1, high1, shape(6,), dtypenp.float32 ) # 动作: 三轴速度指令, 范围归一化到 [-1, 1] self.action_space spaces.Box( low-1, high1, shape(3,), dtypenp.float32 ) def _get_obs(self): state self.client.getMultirotorState() pos state.kinematics_estimated.position vel state.kinematics_estimated.linear_velocity rel np.array([pos.x_val, pos.y_val, pos.z_val]) - self.target rel_normed rel / self.max_dist vel_normed np.array([vel.x_val, vel.y_val, vel.z_val]) / 10.0 return np.clip(np.concatenate([rel_normed, vel_normed]), -1, 1).astype(np.float32) def step(self, action): a np.clip(action, -1, 1) vx, vy, vz a * 3.0 # 映射到 [-3, 3] m/s self.client.moveByVelocityAsync(vx, vy, vz, duration0.5).join() obs self._get_obs() rel np.array([obs[0], obs[1], obs[2]]) * self.max_dist dist np.linalg.norm(rel) reward -0.1 * dist - 0.01 done False if dist 1.0: reward 10.0 done True if dist self.max_dist: reward - 20.0 done True return obs, float(reward), done, False, {} def reset(self, seedNone, optionsNone): self.client.reset() self.client.enableApiControl(True) self.client.armDisarm(True) return self._get_obs(), {}这段代码里有几个细节值得说明。第一个是target_ned里的 z 写成了-5.0对应海拔 5 米千万别写成正数。第二个是moveByVelocityAsync的最后一个参数duration0.5表示速度指令的执行时长。0.5 秒是一个比较稳妥的折中太短会导致控制指令频繁切换仿真器物理求解不稳定太长会让无人机在碰到障碍之前无法及时转向。第三个是观测归一化相对位置除以max_dist速度除以 10让输入落在相对稳定的范围内。这一步看着不起眼但极大影响 PPO 的收敛质量。4.2 PPO 训练的最小代码骨架环境类写好以后训练代码会非常短。这里我直接用 Stable-Baselines3 的 PPO因为它的实现足够可靠课设阶段没必要重复造轮子。env AirSimNavEnv(target_ned(10.0, 10.0, -5.0)) model PPO( MlpPolicy, env, learning_rate3e-4, n_steps4096, batch_size256, n_epochs10, gamma0.99, gae_lambda0.95, clip_range0.2, verbose1 ) model.learn(total_timesteps500_000) model.save(airsim_nav_ppo)这里的n_steps4096表示每次更新策略前先收集 4096 步经验。由于每一步step对应仿真中 0.5 秒一轮更新相当于积累了约 2000 秒的飞行数据。batch_size256表示从这 4096 步里分批采样做梯度更新n_epochs10则是对同一批数据复用 10 次PPO 通过这个多次小步更新来保证策略不会瞬间偏离旧版本太远。gamma0.99是对未来奖励的折扣目标跟踪这类任务中你希望模型稍微看重远期收益所以设置得大一点没问题。clip_range0.2是 PPO 截断范围这个参数通常不需要动它是 PPO 稳定性的核心保障。4.3 超参表与第一轮调优的三个看得见的指标第一次跑的时候不要一上来就追求在 500 万步内收敛。先用 50 万步观察趋势重点看三个指标。第一是平均奖励曲线如果曲线整体在往上走说明奖励函数和观测设计方向是对的。第二是回合长度曲线导航任务里如果回合长度在逐步下降说明模型越来越快地接近目标。第三是每次更新后新旧策略的 KL 散度如果 KL 散度一直很大说明学习率设高了策略更新太激进需要把learning_rate调小到1e-4或者把clip_range降到 0.1如果 KL 散度趋近于零说明训练停滞可以把学习率提上去一点。第一次调参最大的坑是只看总奖励曲线不看回合长度。这两个指标在某些情况下是矛盾的奖励曲线可能在上升但无人机其实学会了“在原地打转以规避越界惩罚”。所以要交叉验证不能只盯 TensorBoard 里的单条曲线。5. 训练避坑记录五个高频翻车现场与排查方法5.1 UE4 工程打开以后黑屏只有场景没有无人机现象工程能启动场景也在但看不到无人机按 F5 也没有飞行器出现有时看到无人机但相机视角固定在原地无法控制。原因大概率是settings.json里的SimMode写错了或者工程根本没有加载 AirSim 的运行时模块。更隐蔽的一种情况你改了配置但 UE4 启动时读取的是打包目录下残留的配置不是文档目录里那份。解决先检查文档目录下AirSim/settings.json是否存在且格式合法确认SimMode是Multirotor。然后在 UE4 编辑器的 Output Log 里搜索SimMode看启动时实际加载的值是什么。如果配置正确但依然没有无人机就把DefaultEngine.ini里关于游戏默认 Pawn 的设置清空让 AirSim 的载具生成器接管场景。5.2 无人机起飞后立刻掉高度或者原地打转坐标系写反了现象代码明确给了“向上”的速度指令但无人机却往下掉或者轨迹不是直线而是绕圈扩大。原因AirSim 对外 API 的世界坐标系是 NEDz 向下为正。你在代码里写了moveByVelocityAsync(0, 0, 5)在 NED 坐标里这个 5 是向下的速度无人机自然往下扎。绕圈扩大则说明方向控制的分量顺序不匹配x/y 和目标的实际方向对不上。解决统一约定在奖励计算和动作发送时都用 NED 坐标。给高度目标时写成负数如果实在不习惯就在环境接口内部做一个正负号转换只在外层保留“正数代表高度”的语义。坐标系的坑是这套方向里最常见的翻车原因没有任何捷径建议每写一行坐标代码前先明确现在处在哪个坐标系。5.3 训练到后期奖励震荡奖励函数太陡或回合太长现象平均奖励前期上升训练到几万步后开始大幅震荡有时上一轮更新后效果突然变差。原因奖励绝对值太大。比如-0.5 * dist无人机距目标 30 米时每步奖励 -15PPO 的价值网络要拟合的这种负数值区间很宽更新时会因为梯度方向不一致而震荡。另一个原因是回合长度过长导致价值回报跨度过大GAE 估计不稳定。解决把奖励压缩。常见做法是给距离奖励换一个更平坦的函数比如-0.1 * log(1 dist)或者直接用tanh把奖励压在[-1, 1]范围内。同时把回合最大步数限制在 200 步左右超时强制结束。这样价值网络的回归目标范围小很多训练会稳定得多。5.4 训练时帧率掉到个位数图像分辨率和渲染开销现象代码能跑但一帧step耗时几秒一个回合收集完需要几分钟训练几乎无法推进。原因最常见的误用是让 UE4 视口保持高质量实时渲染同时又开了SubWindows里的额外相机画面。图像模式下如果输入给策略的是 1280x720 的彩色图预处理和网络前向都会消耗大量时间。解决训练阶段不要用图像观测先用 6 维状态向量跑通这是最高效的方案。如果你确实需要做视觉目标跟踪就把图像分辨率降到 84x84 或者 64x64并把Settings里的CaptureSettings分辨率调到对应值。另一个技巧是在 UE4 里把视口窗口缩小甚至切到后台运行AirSim 的渲染如果完全不可见帧率会明显改善。5.5 改完 settings.json 不生效配置文件缓存与进程残留现象明明把SimMode从Car改成了Multirotor启动后仍然是车或者改了相机参数画面完全没变化。原因UE4 可能还在运行旧的仿真进程新配置没有机会被载入。更深层的原因是 AirSim 读配置时有时会落在不同路径有的版本优先读工程目录下的配置有的版本读Documents/AirSim两个文件并存时你就会看到“改了但没生效”的诡异现象。解决每次修改配置后先彻底退出 UE4 编辑器再从任务管理器里确认没残留进程。然后统一只保留一个settings.json删除另一处的重复配置。最后在启动日志里搜索 settings 的完整路径确认当前加载的是哪一份文件这一步能省掉大量无效配置时间。6. 验证你的算法真的能飞回放、泛化和视觉扩展6.1 用轨迹回放评估收敛训练结束不能只看 TensorBoard要在 UE4 里实际跑一次推理。写一段单独的评估脚本让训练好的模型从几个固定起点出发记录每一帧的位置和速度然后用轨迹曲线来判断行为合理性。一个合格的策略应该满足路径平滑没有反复画圈到达目标点附近后能悬停而不是在目标点上冲过头全程高度维持在设定高度附近不出现突然爬升或下跌。轨迹记录用 AirSim 的仿真时钟同步加一点误差分析绘制相对距离随时间下降的曲线比奖励曲线更有说服力。6.2 泛化测试换地图和随机起点只在一个固定起点和目标点上跑通不代表算法真的学到了导航能力。我会把评估起点从固定坐标改成随机数再跑 10 次统计成功率。如果目标点是固定的模型可能学到了“先朝某个方向飞多少米”这种短期记忆换起点后直接失效。更好的测试条件是同时更换 UE4 的地图场景让策略面对新的纹理和障碍布局。AirSim 自带了几套不同场景哪怕只是切换一个环境都会显著暴露仿真过拟合问题。课设答辩时拿出多个场景的成功率结果说服力远高于单场景动画。6.3 向视觉目标跟踪扩展状态向量版跑通以后和“目标跟踪”这个关键词接轨的常见扩展是视觉跟踪。你可以先用 OpenCV 目标跟踪或者 YOLOv11 这类检测器得到目标在图像中的包围框把框的归一化中心坐标作为观测的一部分也可以直接把下采样图像交给一个 CNN 编码器再接 PPO 策略网络。后者的训练成本更高但视觉特征更鲁棒。我这里更推荐折中方案检测器给框策略网络继续吃向量状态也就是把目标框中心偏移作为跟踪误差信号加入观测这样既保留了视觉能力又不至于让训练难度翻倍。如果目标是另一台无人机或地面车辆则可以在 AirSim 里通过 API 读取目标真值坐标再把相对位置喂给策略验证纯跟踪制导逻辑。这一整套走下来你会发现真正的收获不见得是那个模型而是你习惯了“先验证环境、再设计奖励、最后才调算法”的排错顺序。我自己后来每次搭新仿真环境第一件事永远是花半小时检查坐标方向对不对第二件事才是写训练循环——这两个习惯帮我省掉的返工时间足够再跑完一个完整课题。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网