手把手搭建AirSim+UE4无人机仿真环境:从零到自主飞行
1. 项目概述与核心价值如果你对无人机开发、自动驾驶或者机器人仿真感兴趣但又苦于没有真实的硬件设备或者担心在真实环境中测试代码会“炸机”那么今天这个内容就是为你准备的。我将带你从零开始手把手搭建一个基于AirSim和虚幻引擎4UE4的无人机仿真环境。这不仅仅是一个“Hello World”式的简单演示而是一个功能完备、可以连接地面站、执行自主飞行任务的虚拟实验室。整个过程我会把我自己踩过的坑、绕过的弯以及那些官方文档里语焉不详的细节都掰开揉碎了讲给你听。无论你是机器人专业的学生、无人机算法的开发者还是单纯对仿真技术好奇的爱好者这篇指南的目标就是让你在看完之后能够独立复现一个稳定可用的仿真环境并以此为起点开展你的算法验证和功能开发。AirSim是微软开源的一个基于游戏引擎的仿真平台它之所以强大是因为它不仅仅渲染出漂亮的画面更提供了高保真的物理引擎、丰富的传感器模型如摄像头、激光雷达、IMU以及便捷的API接口。而UE4则是为这个虚拟世界提供极致视觉真实感和复杂场景构建能力的基石。两者结合让你能在办公室里就模拟出无人机在城市、森林或室内穿梭的复杂情况极大地降低了研发门槛和风险。接下来我们就从最基础的软件安装开始一步步构建这个世界。2. 环境准备工具链的精确匹配与安装搭建环境是整个过程中最容易出错的环节版本不匹配、依赖缺失、路径错误都可能让你在第一步就卡住几个小时。我的经验是严格遵循经过验证的版本组合不要盲目追求最新版。2.1 核心组件版本选择与 rationale为什么强调版本因为AirSim作为一个连接底层引擎和上层应用的中间件它对UE4的版本、Visual Studio的版本乃至Python的版本都有特定的依赖。用错了版本编译失败是最轻的运行时各种诡异的崩溃才是噩梦。我推荐的“黄金组合”是Windows 10/11这是必须的因为UE4编辑器对Windows支持最完善。Visual Studio 2019版本号选择16.11.27。这是经过大量社区验证能与UE4.22-4.27系列稳定工作的版本。VS2022理论上可以但可能需要额外配置为避免不必要的麻烦我们选择最稳妥的方案。安装时务必勾选“使用C的桌面开发”工作负载以及右侧明细中的“Windows 10 SDK (10.0.18362.0)”或更高版本但不要超过UE4支持的最高版本。Unreal Engine 4.27.2为什么不选UE5AirSim对UE5的官方支持仍在完善中而UE4.27是一个长期稳定版拥有最广泛的插件兼容性和社区资源。我们通过Epic Games启动器安装它。AirSim我们将直接从GitHub克隆其最新稳定分支如master或v1.8的源代码进行编译。Python 3.8.xAirSim的Python API在此版本上测试最为充分。避免使用3.9或3.7-以免遇到pip包依赖问题。注意请务必关闭所有杀毒软件特别是Windows Defender的实时保护或将其设置为信任你的工作目录。编译过程中会产生大量临时文件可能会被误杀导致编译失败。2.2 虚幻引擎4的安装与项目创建首先安装Epic Games启动器注册账号在“虚幻引擎”库页面点击“引擎版本”旁的“”号选择“4.27.2”进行安装。安装路径建议放在空间充足的盘符根目录例如D:\UE4\路径中不要有中文或空格。安装完成后不要急于打开UE4。我们先通过启动器创建一个空的C项目这能帮我们验证基础开发环境是否OK。在启动器选择“游戏”类别点击“新建项目”。选择“C”标签页选择“基本”类型项目模板选“空白”。设置项目位置同样路径无中文空格和名称例如D:\MySimProject\AirSimTest。点击“创建”。这时启动器会调用Visual Studio和UE4编辑器来生成项目文件。如果这个过程能顺利完成没有报错说明你的VS和UE4基础环境是联通的。2.3 获取与编译AirSim源码这是最关键的一步我们将把AirSim作为插件编译并集成到我们的UE4项目中。克隆代码打开Git Bash或命令提示符找一个合适的目录执行git clone https://github.com/microsoft/AirSim.git cd AirSim克隆完成后建议切换到某个发布标签以获得更稳定的版本git checkout v1.8.0 # 或其他最近的稳定版本标签更新子模块AirSim依赖一些子模块如RPCLib。git submodule update --init --recursive编译AirSim插件在AirSim根目录下有一个build.cmd脚本。右键点击它选择“以管理员身份运行”。这个脚本会自动检测你的VS和UE4环境并调用CMake生成解决方案然后用MSBuild进行编译。整个过程在命令行中会有大量输出请耐心等待。关键避坑点如果编译失败最常见的原因是环境变量UE4_ROOT没有正确设置。你可以手动设置它。首先找到你的UE4安装目录通常是C:\Program Files\Epic Games\UE_4.27\。然后在系统环境变量中新建一个用户变量变量名UE4_ROOT变量值就是上述路径。设置完成后重启命令提示符再运行build.cmd。验证编译结果编译成功后在AirSim\Unreal\Plugins\目录下你会看到一个名为AirSim的文件夹。这个就是编译好的插件。同时在AirSim\Unreal\Environments\目录下会有一些预置的UE4场景项目例如Blocks。我们接下来就要把这个插件用到我们自己的项目里。3. 构建你的第一个仿真场景有了编译好的插件我们就可以把它注入到一个UE4项目中并配置我们的无人机了。3.1 将AirSim插件集成到UE4项目我们不用预置的Blocks环境而是自己创建一个这样理解更深刻。复制插件将编译好的AirSim\Unreal\Plugins\AirSim整个文件夹复制到你刚才创建的空白项目AirSimTest的Plugins目录下。如果项目没有Plugins文件夹就自己新建一个。 最终路径应该是D:\MySimProject\AirSimTest\Plugins\AirSim\生成项目文件右键点击AirSimTest.uproject文件选择“Generate Visual Studio project files”。这会重新生成.sln解决方案文件将插件包含进去。编译项目用Visual Studio 2019打开生成的AirSimTest.sln在解决方案配置中选择“Development Editor”解决方案平台选择“Win64”然后点击“生成 - 重新生成解决方案”。这一步会编译整个项目及其插件。打开项目编译成功后直接在VS里按F5启动调试或者去项目目录双击AirSimTest.uproject打开UE4编辑器。首次打开可能会提示“编译缺失模块”点击确定即可。3.2 场景搭建与无人机放置打开UE4编辑器后我们面对的是一个空荡荡的世界。启用插件点击菜单栏的“编辑 - 插件”在搜索框输入“AirSim”确保“AirSim”插件已被勾选启用。可能需要重启编辑器。添加地面在左侧“放置Actor”面板的“基础”类别中拖拽一个“平面”到场景视口中。在细节面板中将其缩放Scale设置为X10, Y10, Z1这样我们就有了一个100m*100m的地面。从Vehicle模板添加无人机这是核心步骤。不要手动拼装模型在内容浏览器中右键点击空白处选择“新建文件夹”命名为AirSimContent。进入这个文件夹再次右键选择“新建 - 蓝图类”。在弹出窗口的“所有类”搜索框中搜索“Pawn”。在结果列表里你会看到一个来自AirSim插件的类名为“AirSimVehiclePawn”具体名称可能因版本略有不同但一定包含Vehicle和Pawn。选中它命名为BP_MyDrone并保存。双击打开这个蓝图。在组件面板你会看到已经预设好的模型组件如Multirotor、相机组件和物理组件。我们几乎不需要修改任何东西这就是AirSim的强大之处——它已经封装好了无人机动力学模型。直接关闭蓝图窗口。回到主编辑器窗口在内容浏览器中找到刚刚创建的BP_MyDrone将其拖拽到场景中放置在地面之上。在细节面板中你可以设置它的初始位置和旋转。设置游戏模式我们需要告诉UE4游戏开始时使用哪个Pawn。点击菜单栏的“设置 - 项目设置”。在左侧找到“地图和模式”在右侧的“默认模式”下将“默认Pawn类”设置为我们的BP_MyDrone。在同一页面下方找到“游戏模式覆盖”为当前地图通常叫“Persistent Level”也选择同一个BP_MyDrone蓝图类作为默认Pawn类。3.3 配置settings.json文件AirSim的所有行为都通过一个JSON配置文件控制。这个文件必须放在你的项目可执行文件.exe所在的目录下。对于开发中的项目就是项目目录\WindowsNoEditor\AirSimTest\Binaries\Win64\。但更简单的方法是放在项目根目录下UE4在打包或运行时会自动处理。在你的AirSimTest项目根目录下创建一个名为settings.json的文件。用文本编辑器如VS Code打开输入以下最基础的配置{ SeeDocsAt: https://github.com/Microsoft/AirSim/blob/master/docs/settings.md, SettingsVersion: 1.2, SimMode: Multirotor, Vehicles: { Drone1: { VehicleType: SimpleFlight, X: 0, Y: 0, Z: -2, Yaw: 0 } } }这个配置做了几件事SimMode: Multirotor设定仿真模式为多旋翼无人机。定义了一个名为Drone1的载具。VehicleType: SimpleFlight使用内置的“简单飞行”模型它易于控制适合初学者。X, Y, Z是载具相对于玩家起始点的初始位置。Z-2意味着在UE4世界坐标中它会悬停在玩家起始点下方2米处UE4的Z轴向上。我们之前把玩家起始点那个小的游戏手柄图标放在了地面上方所以无人机会悬停在地面之上。Yaw: 0初始偏航角机头方向。4. 运行测试与基础控制配置完成后我们就可以首次运行仿真了。在UE4编辑器中点击工具栏上的“播放”按钮或按F8键进入“选中的视口”播放模式。你会看到视图切换到了无人机机载摄像头的视角并且无人机悬停在空中。基础键盘控制在播放模式下你可以使用键盘控制无人机W/A/S/D控制前后左右移动。Q/E控制垂直上升/下降。方向键左/右控制偏航左转/右转。方向键上/下控制俯仰前进/后退的倾斜。数字键1切换到跟随视角第三人称。退格键重置无人机到初始位置。 如果控制没反应请检查输入焦点是否在UE4窗口上并且SimMode确实设置成了Multirotor。连接QGroundControl (QGC) 地面站这是实现半自主/自主飞行的关键。QGC可以通过UDP协议连接到AirSim仿真中的无人机。下载QGC从QGC官网下载Stable版本的安装包并安装。配置AirSim修改settings.json在Vehicles-Drone1配置块内添加UdpPort和ControlPort设置注意端口号不要冲突Drone1: { VehicleType: SimpleFlight, X: 0, Y: 0, Z: -2, Yaw: 0, UdpPort: 14550, ControlPort: 14551 }配置QGC打开QGC点击左上角齿轮图标进入“应用程序设置”。侧边栏选择“Comm Links”。点击“添加”连接类型选择“UDP”。在“监听端口”填入14550与settings.json中的UdpPort一致。点击“OK”保存连接。回到主界面确保右上角连接下拉框选择了你刚创建的UDP连接并点击连接按钮。测试连接重启你的UE4仿真或点击播放。如果一切正常QGC的HUD上应该能显示无人机的姿态、位置、电池等信息。你可以在QGC的“飞行视图”中规划航点任务发送给仿真无人机执行。5. 核心进阶配置与传感器集成一个基础的仿真环境已经搭建完成。但对于算法开发我们通常需要更丰富的传感器数据和更复杂的场景。5.1 添加与配置传感器AirSim支持模拟多种传感器。我们在settings.json中为Drone1添加一个前置摄像头和一个激光雷达。Drone1: { ... // 之前的配置 Sensors: { Camera1: { SensorType: 2, Enabled: true, CaptureSettings: [ { ImageType: 0, Width: 640, Height: 480, FOV_Degrees: 90 } ] }, Lidar1: { SensorType: 6, Enabled: true, NumberOfChannels: 16, Range: 100, PointsPerSecond: 100000 } } }SensorType: 2代表摄像头ImageType: 0代表场景视图RGB图像。你可以设置分辨率、视场角等。SensorType: 6代表激光雷达。这里配置了一个16线、100米测距的激光雷达。5.2 通过Python API获取数据与控制AirSim提供了强大的Python API让我们能用脚本控制无人机并获取传感器数据。安装Python API客户端pip install msgpack-rpc-python pip install airsim注意airsim这个包只是一个轻量级的客户端库不包含仿真器本身。编写一个简单的控制脚本保存为test_drone.py放在项目根目录或任何方便的地方import airsim import time # 连接到仿真器 client airsim.MultirotorClient() client.confirmConnection() # 解锁并起飞 client.enableApiControl(True) client.armDisarm(True) client.takeoffAsync().join() print(已起飞) # 向前飞5米 client.moveToPositionAsync(5, 0, -10, 5).join() # (x, y, z, velocity) print(到达目标点) # 获取摄像头图像 responses client.simGetImages([airsim.ImageRequest(Camera1, airsim.ImageType.Scene)]) if responses: img1d np.frombuffer(responses[0].image_data_uint8, dtypenp.uint8) img_rgb img1d.reshape(responses[0].height, responses[0].width, 3) # 这里可以使用OpenCV显示或保存图像 # cv2.imwrite(drone_view.png, img_rgb) print(图像已获取) # 降落并上锁 client.landAsync().join() client.armDisarm(False) client.enableApiControl(False) print(任务完成)运行脚本确保你的UE4仿真正在运行处于播放模式然后在命令行中运行python test_drone.py。你会看到无人机自动执行起飞、飞行、降落的全过程。5.3 导入自定义3D环境UE4的Blocks环境毕竟简单。我们可以从Epic商城、Sketchfab等网站下载免费的3D场景确保是FBX格式并拥有商业使用许可或者用建模软件自己制作。导入FBX在UE4编辑器内容浏览器中右键点击AirSimContent文件夹选择“导入”。选择你的FBX文件。处理“未发现平滑组”警告这是一个常见坑点。如果导入时提示“未发现平滑组”模型可能会显示为全黑或棱角分明。解决方法是在3D建模软件如Blender中导出FBX时务必勾选“平滑组”或“导出平滑组”选项。如果已经导入可以尝试在UE4中选中导入的静态网格体在细节面板的“常规设置”下勾选“自动生成碰撞”和“计算平滑组”然后重新构建光照。放置与缩放将导入的静态网格体拖入场景使用缩放工具调整到合适大小。注意UE4的单位是厘米cm如果你的模型来自其他软件如Blender默认单位是米可能需要缩放100倍。构建光照复杂场景导入后点击编辑器工具栏的“构建”按钮或按CtrlShift.选择“构建光照”等选项让场景的光照和阴影正确渲染。6. 深度避坑指南与疑难杂症排查即使按照步骤操作你也可能会遇到问题。这里汇总了我遇到过的典型问题及其解决方案。6.1 编译与启动类问题问题现象可能原因解决方案运行build.cmd失败提示找不到cl.exe或MSBuild。Visual Studio 2019未安装或环境变量未正确设置。确保安装了VS2019的“使用C的桌面开发”工作负载。尝试在“开始”菜单找到“x64 Native Tools Command Prompt for VS 2019”并在此命令行中运行build.cmd。编译AirSim时出现大量“无法打开包括文件:CoreMinimal.h”等UE4头文件错误。UE4_ROOT环境变量未设置或设置错误。检查UE4_ROOT是否指向了正确的UE4安装根目录如C:\Program Files\Epic Games\UE_4.27。设置后需重启命令行。打开UE4项目时提示“缺少AirSim模块”或插件显示为“二进制文件丢失”。AirSim插件未成功编译或复制到了错误的位置。确保在AirSim源码目录成功运行了build.cmd且无报错。将AirSim\Unreal\Plugins\AirSim整个文件夹复制到项目的Plugins目录下而不是只复制AirSim.uplugin文件。点击播放后编辑器卡死或崩溃。项目或插件编译配置不匹配如Debug/Development。在Visual Studio中确保解决方案配置为“Development Editor”平台为“Win64”并“重新生成解决方案”。清理中间文件删除项目目录下的Intermediate和Saved文件夹以及.vs文件夹后重试。6.2 连接与通信类问题问题现象可能原因解决方案QGC无法连接提示超时。端口被占用或防火墙阻止。检查settings.json中的UdpPort与QGC中设置的“监听端口”是否一致。关闭可能占用14550端口的其他软件如其他QGC实例、Mission Planner。在Windows防火墙中为UE4编辑器UE4Editor.exe和QGC添加入站规则允许UDP连接。Python脚本连接超时 (airsim.exceptions.TimeoutError)。AirSim仿真器未在播放模式运行或API服务器未启动。确保UE4编辑器已点击“播放”按钮进入仿真模式。检查settings.json中SimMode是否正确。尝试使用client.ping()测试连接。无人机在QGC中显示连接但姿态数据全为零或不动。settings.json中载具初始位置设置不当或默认Pawn未正确设置。检查settings.json中Z坐标是否为负值UE4世界坐标系。确保在项目设置和当前地图的“游戏模式覆盖”中都正确设置了你的无人机蓝图类为默认Pawn。6.3 性能与渲染类问题问题现象可能原因解决方案仿真帧率极低画面卡顿。场景过于复杂或图形设置太高。在UE4编辑器中点击播放旁边的“向下箭头”选择“高级设置”降低分辨率缩放比例和视觉效果。在项目设置中禁用不需要的后期处理效果。考虑使用更简单的场景进行算法测试。无人机物理表现异常如抖动、飘移或穿透地面。物理子步长设置不当或碰撞体有问题。在settings.json中可以尝试调整物理引擎参数例如增加PhysicsEngineWorldTick的频率。检查无人机蓝图中的碰撞体组件通常是Capsule或Box组件是否大小合适并确保地面等静态网格体有正确的碰撞体在细节面板勾选“碰撞”相关选项。自定义FBX模型导入后显示为纯黑。材质丢失或光照UV错误常见于“未发现平滑组”警告。首先在建模软件中确保导出FBX时勾选了“平滑组”。在UE4中为导入的静态网格体创建新的材质球并赋予基础颜色。如果模型复杂可能需要重新展开UV并构建光照。6.4 一个关于“外接设备映射”的特别提醒在网络热词中提到了“ue4外接设备映射”。这指的是将真实硬件如游戏手柄、遥控器、甚至自定义的飞控硬件的输入映射到UE4/ AirSim中的虚拟控制。虽然AirSim内置了基于键盘和SimpleFlight模型的简单控制但如果你想用真实的遥控器手感来飞行或者进行硬件在环HIL仿真就需要此功能。实现思路在UE4中配置输入映射在项目设置的“引擎-输入”部分可以添加“操作映射”如Throttle,Yaw,Pitch,Roll和“轴映射”。这些映射可以绑定到键盘按键或游戏手柄的摇杆轴。在AirSim无人机蓝图中读取输入在你的BP_MyDrone蓝图中可以使用“获取输入轴值”等节点读取UE4输入系统传递过来的值。将输入值传递给AirSim飞行模型这需要修改AirSim插件源码或通过蓝图接口调用更底层的API将摇杆输入转化为SimpleFlight或其他自定义飞行模型能理解的控制指令。这属于相对高级的定制需要你对UE4的输入系统和AirSim的车辆控制接口有更深的理解。一个更简单的替代方案是使用QGC的地面站控制它已经通过MAVLink协议实现了对仿真无人机的控制映射。搭建这个环境的过程就像在虚拟世界里从零开始建造一个风洞和测试跑道。最初的版本冲突、编译错误可能会让人沮丧但一旦打通你会发现面前展开的是一个无限可能的沙盒。你可以在这里安全地测试最激进的路径规划算法可以模拟各种极端天气对视觉SLAM的影响也可以快速生成用于训练深度学习模型的大规模无人机视角数据集。这个环境的价值会随着你投入的深度而指数级增长。我个人的体会是把环境搭建稳定后最好立即用一两个小脚本比如“起飞-画个方形-降落”跑通全流程建立信心。然后再逐步深入传感器数据解析、多机协同、复杂环境建模等更有挑战性的领域。记住仿真的首要目的是快速迭代和验证想法不必在第一步就追求极致的画面真实感功能完整和运行稳定才是王道。