Ubuntu下AirSim与UE4源码编译:自定义无人机仿真场景搭建实战
发布时间:2026/10/2 1:02:37来源:尧图网络
1. 为什么要在Ubuntu上折腾AirSim和Unreal4很多人第一次接触无人机仿真都是先从AirSim的二进制安装包开始的。Windows下装好依赖、跑起例程几分钟就能看到一架无人机在模拟环境里起飞降落。但真到了要自己改场景、换机型和写感知算法的时候Windows的自带环境往往不够用很多研究者手里也只剩Linux环境。AirSim本身是UE4插件而UE4官方在Linux上支持得并不差加上Ubuntu服务器或开发机在深度学习、ROS生态上的天然优势这套组合就成了做视觉导航、路径规划、多机协同实验的常见起点。AirSim是微软开源的无人机与汽车仿真平台底层基于Unreal Engine 4渲染与物理引擎上层提供Python和C API支持高逼真的视觉渲染、IMU/GPS噪声模拟、多机协作和px4/ArduPilot的硬件在环接入。UE4则是Epic Games推出的开源游戏引擎在AirSim里负责画面、碰撞和环境物理。Ubuntu上把两者拼起来整个过程的复杂度比Windows高不少但一旦跑通后面所有实验都会非常顺手。这篇东西面向的是想在Ubuntu 22.04或20.04下从零搭起一套自定义无人机仿真场景的人包括编译UE4、编译AirSim插件、搭建自己的地图、配置无人机参数和通过Python API控制无人机起飞。整个过程踩坑很多我尽量把每个环节的原理、选择和能跳的坑都写清楚。如果你只是想在Windows下快速体验这篇同样有帮助但步骤里涉及Ubuntu部分可以略过。如果你是在服务器上跑没有显示器也没有显卡那最后面关于渲染模式和无人驾驶模式的部分要仔细看很关键。2. 整体设计与方案选型2.1 为什么用源码编译而不是直接下载二进制AirSim官方提供了已编译的UE4插件包但在Windows和Linux下体验差别很大。Linux下官方二进制包更新节奏慢很多时候跟Unreal版本不匹配而且无法自己改AirSim源码去调试。所以我建议在Ubuntu上直接用源码编译。源码编译的过程不会太痛苦但需要装Unreal Engine本身的源码包。这涉及一个很实际的问题Unreal Engine 4有两个安装方式。一个是从Epic Games Launcher安装另一个是从GitHub拉源码。AirSim官方建议用Launcher安装的稳定版UE4因为GitHub源码分支官方没有逐一验证经常遇到一些编译不过的小问题。Ubuntu上Epic Games Launcher可用但它是32位辅助进程的坑很多我自己第一次装的时候花了整整一下午。如果你的Ubuntu是22.04或24.04Launcher的依赖补丁有时会失效。所以我更推荐用GitHub源码加特定版本tag的方式虽然下载大但能保证和AirSim的版本兼容。说到版本匹配这是整套流程的关键。AirSim每个release都会绑定一个UE4版本比如AirSim v1.8.1对应UE4 4.27AirSim v1.7.0对应UE4 4.24。如果你用的是AirSim主分支那就必须用和主分支绑定的UE4 commit。官方文档会标注Recommended Release一般存在AirSim的README里。选版本时不要贪新Unity和UE4互相折腾过的朋友应该懂我的意思同一个版本组合一旦跑通就别轻易升。2.2 Ubuntu版本和服务器/桌面环境的取舍Ubuntu版本直接影响编译工具链和依赖包。AirSim和UE4在Ubuntu 18.04、20.04、22.04上都有成功案例我在20.04和22.04上都跑通过。22.04的GCC和CMake版本较新但对UE4的编译器要求刚好匹配反而是新系统自带的高版本有时会让UE4编译失败需要单独降级GCC。如果你完全没有经验建议直接用Ubuntu 20.04因为官方对20.04的测试最充分。如果你有NVIDIA显卡想做逼真渲染记得在装系统前先确认显卡驱动支持我见过太多人装完显卡驱动后黑屏然后跑回来问是不是UE4的问题其实那是显示驱动的锅。桌面环境方面纯Server版可以让UE4跑起来但你要改场景、拖蓝图节点没有桌面环境会很痛苦。我建议装桌面版Ubuntu或者Server版加一个轻量桌面。远程开发场景下可以用X2Go或者VNC连桌面但延迟会影响操作手感和调参效率能本地跑就本地跑。有意思的是服务器上做实时渲染也不是完全不可能用虚拟显示设备Xvfb可以把渲染画面转到内存再用AirSim的屏幕API取图后面会讲到。2.3 AirSim、UE4、PX4/ArduPilot的关系很多新人对这三个东西之间的关系特别容易混淆。UE4负责游戏级别的地图渲染和物理碰撞AirSim是以UE4插件形式存在的一套无人机动力学模型、传感器模型和多机调度逻辑而PX4、ArduPilot是真正的飞控固件。AirSim可以在无飞控模式下用内置的simple flight模型控制无人机也可以接上PX4做完整软硬件在环仿真。在自定义仿真场景这件事上你至少需要改造两个层面。第一个是地图和景观层由UE4项目承载包括地面、建筑、树木、光照、碰撞体等。第二个是无人机和环境交互层包括无人机起始位置、传感器挂点、物理材质和水面反射等这层有AirSim参与的成分。有些教程只教你放一个场景进去但没告诉你怎么让无人机落在地面上而不是穿模掉进地面以下这些问题在后面真正测试的时候会冒出来。3. 环境准备与依赖安装3.1 安装Unreal Engine 4.27源码版Unreal Engine的源码包需要Epic账号从GitHub拉取。先注册Epic账号然后在个人设置里关联GitHub账号这样才能访问EpicGames/UnrealEngine这个私有仓库。整个过程不难但必须先关联否则git clone的时候会提示仓库不存在。关于UE4版本我强烈建议用4.27的最后一个release tag比如4.27.2-release。AirSim主线对4.27的支持最好而且4.27的Linux版编译问题在社区里积累了大量解决方案遇到问题好搜。下载时不要直接clone主分支那个分支体积巨大而且编译配置可能和AirSim不匹配用以下命令拉指定tag更稳妥git clone -b 4.27.2-release https://github.com/EpicGames/UnrealEngine.git UE4_4.27 cd UE4_4.27 ./Setup.sh ./GenerateProjectFiles.sh make在下载前先检查磁盘空间。UE4源码解压后大约28GB编译完大约增加60到90GB整个流程下来占用100GB以上很常见。如果磁盘不够后面编译到一半会报错而且有些错误提示非常隐晦会让你误以为是源码问题。我建议至少预留150GB可用空间。3.2 编译依赖与常见缺失库在Linux下编译UE4依赖的包相当多包括libx11-dev、libxrandr-dev、libxi-dev、libgl1-mesa-dev、libssl-dev等。官方文档列了一堆但每个Ubuntu版本名称可能不同缺了什么库编译时就报什么错。我整理了一个常见的安装命令组合在Ubuntu 20.04和22.04上实测可用sudo apt update sudo apt install build-essential git unzip python3 python3-pip \ libx11-dev libxrandr-dev libxi-dev libgl1-mesa-dev libglu1-mesa-dev \ libssl-dev libncurses5-dev libcrypto-dev libfreetype6-dev \ libxinerama-dev libxcursor-dev libxdamage-dev libxcomposite-dev \ libasound2-dev libpulse-dev libudev-dev libdbus-1-dev \ libnss3-dev libatk1.0-dev libatk-bridge2.0-dev libcups2-dev \ libdrm-dev libxkbcommon-dev libxcb-keysyms1-dev libxcb-image0-dev \ libxcb-icccm4-dev libxcb-shm0-dev libxcb-render-util0-dev还有几个是UE4自己需要的比如libc-dev和libcabi-dev在部分Ubuntu版本上需要额外装。另外如果你的是Ubuntu 22.04以上可能还需要装Python2环境因为UE4的构建脚本早期依赖Python2新版本虽然换成了Python3但有些辅助脚本还是会有问题。编译UE4本身非常耗时四十分钟到几个小时不等取决于CPU核心数和内存大小。我建议设置MAKEFLAGS来控制并行度避免内存不足导致编译进程被杀。在16G内存的机器上make -j4比较稳定32G内存可以用-j8但再往上就很可能出问题。3.3 安装虚幻引擎插件时需要注意的坑UE4编译完成后需要验证能否正常启动。在终端运行./Engine/Binaries/Linux/UnrealEditor如果启动界面正常弹出说明编译成功。如果启动时提示缺少Vulkan库需要安装libvulkan1和libvulkan-dev。如果你没有GPUUE4也可以运行但只能用OpenGL或者软件渲染模式这种模式下无法做复杂的场景渲染跑AirSim的无人机视觉会比较吃力。编译完UE4后你会得到一个UE4开发环境但它本身并不包含PlacedActors等所有引擎自带资产。这里有个容易忽略的点AirSim作为一个插件要在UE4的插件目录里编译还需要一个UE4的C工程来承载。如果只编译了引擎不建工程AirSim的插件格式验证会失败。所以下一节说的构建UE4工程不是可选项而是必需项。4. 编译AirSim插件并创建UE4无人机工程4.1 拉取AirSim源码与编译AirSim本身不需要单独安装到系统它的核心是UE4插件和一个Python/C客户端库。插件部分要放进UE4工程的Plugins目录里编译Python客户端通过pip安装。首先要拉AirSim源码建议用稳定版本而不是主分支。我用的比较多的是v1.8.1它对UE4 4.27的支持最好git clone https://github.com/microsoft/AirSim.git cd AirSim git checkout v1.8.1 ./setup.sh ./build.shsetup.sh会下载AirSim依赖的第三方库包括MavLinkCom、eigen等。如果网络不稳定这一步会失败多试几次即可。build.sh会先编译AirSim的核心库再编译Unreal插件最后生成一个Unreal/Plugins/AirSim目录这个目录就是后续要放进UE4工程里的插件包。顺便说一句如果你只需要Python API来做控制不打算打开UE4编辑器仍然需要执行setup.sh和build.sh因为Python包内部依赖AirSim编译出的C库。否则调用airsim.Client()时会报找不到libAirSimClient之类的问题。4.2 创建UE4空工程并集成AirSim插件AirSim官方提供了一个模板项目但我不想直接用模板因为自定义场景的需求往往要在模板上大改直接看模板反而容易一头雾水。更好的方式是自己创建一个空的UE4 C工程然后把AirSim插件放进去。打开UE4编辑器选择C类、Basic Code模板。如果是通过命令行创建工程可以用以下命令cd UE4_4.27/Engine/Build/BatchFiles ./RunUAT.sh BuildCookRun -project/path/to/MyProject/MyProject.uproject \ -build -nop4 -utf8output -unattended -cook -stage -package \ -clientconfigDevelopment -serverconfigDevelopment \ -platformLinux -targetMyProject这里要说明一下AirSim要求工程必须至少有一个C类纯Blueprint工程不被插件识别。所以即便你后面全用蓝图拖节点也必须在创建工程时选C模板然后添加一个空的C类到工程里。创建完工程后把AirSim的Unreal/Plugins/AirSim目录复制到工程的Plugins目录下然后关闭编辑器在工程根目录生成并重新编译工程文件cd /path/to/MyProject /usr/bin/env bash Engine/Build/BatchFiles/Linux/Build.sh MyProjectEditor Development Linux \ -project/path/to/MyProject/MyProject.uproject -waitmutex如果没有Engine/Build/BatchFiles这个路径说明你的UE4没有完整编译回到上一节搞定。4.3 配置场景的PlayerStart和无人机关卡无人机仿真的核心逻辑是AirSim用PlayerStart来确定无人机初始位置用GameMode来管理环境规则。自定义场景时你要做三件事。第一打开地图文件把默认的地面体改为AirSim的BlocksEnvironment类型或者建一个空的Level并手动添加一个StaticMesh作为地面否则无人机启动时会掉进一个无底深渊。第二在场景中放置一个PlayerStartActor这决定了无人机的出生点。你可以把它放在屋顶、停车场中央、空地等任意位置但必须保证出生点上方没有遮挡物否则无人机起飞检测会失败或者螺旋桨直接撞到障碍物。经验做法是放在空地上方2米左右AirSim会自动调整高度到地面以上。第三把World Settings中的GameMode Override改为AirSimGameMode否则UE4不会加载AirSim的仿真逻辑。这一步很多人漏掉结果发现无人机模型不显示但日志里没有报错就是这个原因。以上操作在做完后建议先保存地图再运行Play按钮测试。如果运行后看到左下角有一些AirSim的初始化日志说明插件加载成功。如果没看到检查一下是不是没有把AirSim插件放进工程Plugins目录或者工程没有正确识别插件。5. 自定义无人机场景实操从默认地图到真实场景5.1 修改默认地图和增加自定义建筑模型AirSim默认的Blocks地图就是一个建筑街区的样例对大多数测试来说够用但如果你想做更细粒度的场景比如某个工厂厂区、校园广场或者农场环境需要自己加场景模型。UE4里添加自定义模型有两种方式一种是从外部导入FBX或OBJ文件另一种是直接用内置的Basic Shape组件搭建立方体、平面和圆柱。如果你手头有区域的CAD模型或者3D扫描文件用FBX导入是首选。导入时注意单位设置UE4的默认单位是厘米如果源模型单位是米缩放会乱。一个简单的检查方法导入后看模型的包围盒大小一个正常的人模型应该在一米八左右。如果导入的模型特别大说明单位没换算对。用Basic Shape搭场景虽然看起来简陋但很方便用来做避障和导航实验。我记得有一次为了验证无人机的激光雷达检测效果搭了一个由低矮立方体组成的迷宫跑起来比直接用复杂建筑模型还高效。如果你是要做视觉研究可以先用Basic Shape搭一个大致布局再用带贴图的高精度模型替换两者之间的逻辑完全一样。5.2 设置光源、天空盒和碰撞体自定义场景最容易被忽视的就是光照。UE4默认的全动态光照对性能要求很高而且有时会导致场景过曝或过暗AirSim的视觉API取出来图像跟实际环境差别巨大。我建议在自定义地形场景中至少烘焙一次Lightmap或者直接使用定向光加天空球的基础方案。天空球可以手动放置一个BP_Sky_Sphere或者直接用UE4自带的世界设置。这里有个小细节要打开Project Settings Engine Rendering把Auto Exposure关掉否则无人机旋转时相机会自动调整曝光导致视觉里程计算法在剧烈光照变化下崩溃。稳定曝光是无人机视觉仿真中最容易踩坑的地方很多人觉得AirSim的视觉图像不稳定其实不是AirSim的问题是UE4的自动曝光默认开着。碰撞体这方面如果你是从一个空白场景开始记得给地面和建筑加碰撞体否则无人机会直接穿透下去。UE4里StaticMesh默认会有简单的盒体碰撞但有时候不够准确。特别是如果你想模拟激光雷达或者碰撞检测必须手动调整碰撞体的形状和大小否则雷达点云数据会穿过障碍物。5.3 添加多无人机出生点和起始朝向AirSim v1.8.1以后支持多无人机在settings.json的Vehicles中配置多个实例即可。但多无人机在自定义场景中要额外处理队友之间的初始位置和朝向否则刚启动就撞在一起。我在做多机协同实验时会在场景中放多个PlayerStart然后把每个PlayerStart的坐标和朝向写到settings.json里。AirSim会按顺序匹配这些出生点。配置示例{ SettingsVersion: 1.2, SimMode: Multirotor, Vehicles: { Drone1: { VehicleType: SimpleFlight, InitialPosition: {X: 0.0, Y: 0.0, Z: 0.0}, InitialRotation: {Yaw: 0.0, Pitch: 0.0, Roll: 0.0} }, Drone2: { VehicleType: SimpleFlight, InitialPosition: {X: 10.0, Y: 0.0, Z: 0.0}, InitialRotation: {Yaw: 90.0, Pitch: 0.0, Roll: 0.0} } } }这里有个容易迷糊的点InitialPosition是相对PlayerStart位置的偏移不是世界绝对坐标。如果你只在场景中放了一个PlayerStart第二个无人机会在你设置的位置生成但这个位置的参考系是相对第一个PlayerStart的。所以多机实验时最好在所有无人机都放在同一个PlayerStart附近然后用偏移量去区分位置。5.4 保存并启动仿真关卡一切配置好之后在编辑器里点击运行。如果你不需要打开编辑器窗口可以将工程打包成一个独立可执行文件。打包之前建议先用编辑器运行一遍确认无编译错误。独立可执行文件的好处是启动快而且可以在没有UI的服务器上运行只要后端加上-nullrhi参数。如果打包过程中遇到cook失败多半是因为缺少某个资源或者引用了不存在的模型。排查方式是看日志输出中失败的资源路径回到UE4编辑器中打开对应资产确认是否有效。6. AirSim配置文件解析与无人机参数调优6.1 settings.json的完整结构AirSim的配置文件位于~/Documents/AirSim/settings.json这个路径在Linux下就是$HOME/Documents/AirSim/settings.json。文件内容直接影响无人机物理模型、相机参数、云台和传感器配置。最常用的配置块包括{ SettingsVersion: 1.2, SimMode: Multirotor, ClockSpeed: 1.0, PhysicsEngine: FastPhysics, CameraDefaults: { CaptureSettings: [ {ImageType: 0, Width: 640, Height: 480, FOV_Degrees: 90}, {ImageType: 1, Width: 640, Height: 480, FOV_Degrees: 90}, {ImageType: 2, Width: 640, Height: 480, FOV_Degrees: 90} ] } }ImageType 0是场景相机1是深度相机2是分割相机。如果你要做视觉定位建议深度图分辨率至少为640x480如果做语义分割则可以用1280x720分割图的分辨率会影响标注准确性但过高的分辨率也会显著拖慢推理速度。6.2 调整无人机性能与仿真物理参数AirSim默认的无人机参数偏向于中等体型消费级无人机但不同研究需求对动力学特性的要求不同。比如你如果要测试一个高机动控制器默认参数会显得太笨重。调整物理参数时重点关注以下几个字段Mass无人机质量单位kg。默认1.0kg如果负载大需要相应增加。MaxThrust最大推力单位N。这个值影响爬升速率和抗风性能如果设置过小无人机会一直推油门但稳不住高度。MaxAngularVelocity最大角速度单位rad/s。调大可以提高机动性但会让仿真更容易发散。DragCoeff阻力系数影响平飞速度。默认值在低速下表现良好但高速时会过于理想化。这些参数在AirSim源码中的对应位在AirLib/src/vehicles/multirotor/firmwares/simple_flight下如果你熟悉C可以直接改源码重新编译。如果不想碰源码可以在settings.json的Vehicles.Drone1.ParameterSets里用physics设置部分参数但很多参数并没有全部暴露给配置文件此外的工作仍需改源码。6.3 多相机传感器挂载与视角调整无人机视觉实验往往需要不止一个相机AirSim支持在一个无人机上挂载多个相机每个相机可以有不同的姿态角、视场角和渲染模式。配置位置在Vehicles.Drone1.Cameras每个相机用CameraName: {...}定义。相机挂载时有个关键点是姿态角的朝向约定。AirSim里相机的X轴是前方Y轴朝右Z轴朝下这个坐标系统跟ROS中常用的REP-103坐标完全不同。如果你在ROS里用camera optical frame需要额外做一次旋转。我记得第一次接相机数据的时候图像上下左右颠倒查了半天才发现是相机坐标系和ROS坐标系映射的问题。另外如果你想模拟鱼眼相机或者广角相机直接调节FOV_Degrees到180以上是不够的AirSim只支持最大120度视场角的普通透视相机超过这个值会出现畸变严重或者渲染错误。鱼眼效果需要自己改AirSim源码里的相机模型或者在渲染后再做后处理。7. 用Python API控制无人机并验证自定义场景7.1 安装AirSim Python客户端并建立连接AirSim的Python端很简单用pip安装pip install airsim然后在Python脚本中创建客户端。但这里要注意如果你是从源码构建AirSim系统里默认的Python包还是二进制版版本可能不匹配。最好在AirSim源码目录的PythonClient下运行脚本那边的包是刚编译好的或者手动把AirSim/PythonClient加入PYTHONPATH。连接无人机的标准姿势import airsim import time client airsim.MultirotorClient() client.confirmConnection() client.enableApiControl(True) client.armDisarm(True) # 起飞 client.takeoffAsync().join() client.moveToZAsync(-3, 1).join() print(drone took off!)confirmConnection会一直等待仿真器就绪如果连不上大概率是仿真器没开。enableApiControl是夺取控制权的关键如果你不调用它AirSim会认为你只是旁观者遥控器或简单飞行控制器仍然控制无人机。7.2 在自定义场景中巡航测试场景搭建完成后至少要做一次手动飞行和自动飞行测试。自动飞行测试建议先跑一段简单的矩形航线验证无人机能在自建场景中正常移动不会穿模或者撞到未知碰撞体。矩形航线的核心逻辑是逐点移动我用得比较多的是moveToPositionAsync和moveOnPathAsync两个API。前者适合精确到点后者适合批量路径。测试脚本大概长这样import airsim import time client airsim.MultirotorClient() client.confirmConnection() client.enableApiControl(True) client.armDisarm(True) client.takeoffAsync().join() # 起飞后先上到3米高度 client.moveToZAsync(-3, 1).join() points [ airsim.Vector3r(10, 0, -3), airsim.Vector3r(10, 10, -3), airsim.Vector3r(0, 10, -3), airsim.Vector3r(0, 0, -3), ] # 沿路径飞行速度1米每秒 client.moveOnPathAsync(points, 1.0, 5, airsim.DrivetrainType.ForwardOnly, airsim.YawMode(False, 0), 20, 1).join()跑完这个测试你基本能确认场景是否适合飞行。如果无人机在飞行到某个位置时偏离航线大概率是那附近有碰撞体或者地面高度突变。这时候需要回到UE4编辑器里检查场景模型和碰撞体而不是调飞控参数。7.3 用计算机视觉接口获取场景图像自定义场景最终是为了用视觉数据训练和测试算法。AirSim的视觉API支持获取多种图像类型。获取场景图和深度的代码responses client.simGetImages([ airsim.ImageRequest(0, airsim.ImageType.Scene), airsim.ImageRequest(0, airsim.ImageType.DepthPerspective), ]) for response in responses: if response.pixels_as_float: # 深度图 import numpy as np depth np.array(response.image_data_float, dtypenp.float32).reshape(response.height, response.width) # 转成8位显示 depth_image np.clip(depth / 10.0, 0.0, 1.0) else: # 场景图 import numpy as np img np.frombuffer(response.image_data_uint8, dtypenp.uint8).reshape(response.height, response.width, 3)这里有个阿里嘎多但必须注意的点深度图的数值含义。DepthPerspective的深度值表示的是相机光心到环境中点的距离不是点到相机平面的垂直距离。这个区别在做点云重建时很关键如果你直接用深度值当Z坐标点云会变形。只有DepthPlanar的深度值才是垂直距离两者不能混用。我见过不少人在这个坑里浪费了好几天明明仿真数据完全正常但重建出来的点云总是不对就是因为用错了深度类型。7.4 保存图像和时间戳构建自己的数据集做视觉导航实验时光获取一张张图像还不够还需要保存时间戳、无人机姿态、相机内外参等信息。AirSim的图像响应里自带time_stamp字段而姿态和相机参数可以用simGetGroundTruthKinematics和simGetCameraInfo获取。建议在自定义场景中先做一套时间同步的流程。我的习惯是获取一次图像同时获取一次无人机位置和姿态存为一个JSON条目最后把所有JSON合并成一个excel或csv。这样后面做视觉里程计测试时可以直接用时间戳对数据做对齐而不必依赖系统时间。仿真系统有一个ClockSpeed参数如果你设置了非1.0的值系统时间戳和仿真时间戳会不一致直接用系统时间会错乱。下面是一个保存图像和状态数据的示例import json import os import time save_dir ./airsim_dataset os.makedirs(save_dir, exist_okTrue) for i in range(100): responses client.simGetImages([...]) # 获取图像 kinematic client.simGetGroundTruthKinematics() data { timestamp: responses[0].time_stamp, position: {x: kinematic.position.x_val, y: kinematic.position.y_val, z: kinematic.position.z_val}, orientation: {pitch: kinematic.orientation.pitch, roll: kinematic.orientation.roll, yaw: kinematic.orientation.yaw} } # 分别保存图像和元数据 filename os.path.join(save_dir, fframe_{i:05d}) # 保存图像... with open(filename _meta.json, w) as f: json.dump(data, f) time.sleep(0.05)这个方法虽然简单但已经能满足大部分视觉SLAM和无人机导航研究初期的数据需求。更高阶的用simSaveImage接口直接保存png一样可行但速度慢一些批量采集时还是用内存处理快。8. 常见问题与排查技巧实录8.1 编译失败类UE4编译卡死或报错如果你在编译UE4时遇到fatal error: SDL.h file not found之类的报错说明SDL2的开发库没有装好。在Ubuntu 22.04上需要额外安装libsdl2-dev否则UE4音频模块编译不过。这个报错出现的位置非常靠后很容易让人以为编译快完成了实际上还差得远。还有一种情况是编译过程中某个模块出现语法错误但源码本身没问题。这时候首先检查是不是内存不足或者并行编译任务开得太多。make -j8在16GB内存机器上偶尔会被OOM killer干掉日志里没有明显的错误信息但编译进程突然退出。用make -j4重试往往就能解决。8.2 AirSim插件编译后无法在UE4中启用把AirSim插件复制到工程Plugins目录后打开工程如果看不到AirSim插件启用最可能的原因是插件的目标平台与当前编译平台不一致。AirSim在Linux下会编译出libAirSim.so和libVehicles.so如果你的系统缺少某些库插件加载会失败但UE4界面上可能只显示一个“禁用”状态不显示根因。排查方式是看UE4编辑器日志通常在~/Library/Logs/Unreal Engine/Editor.log或/var/log/application.log里查找与AirSim相关的关键字。最常见的是缺少libMavLinkCom.so的对齐库这时候去AirSim的build/output/lib目录下看看.so文件是否都有并用ldd检查依赖。8.3 无人机不动、不起飞或者直接掉下去无人机在自定义场景中最常见的故障就是不起飞。先确认是否已经执行了enableApiControl(True)和armDisarm(True)很多新手的代码顺序写反了导致起飞指令被忽略。如果指令顺序没问题但无人机还是不动检查一下当前场景的地面材质。AirSim要求地面必须有碰撞体并且碰撞响应正常。如果你用的地面是UE4里用Landscape地形创建的地面注意Landscape默认碰撞是开启的但有些自定义StaticMesh地面没有开启Collision无人机起飞时虽会显示起飞成功但实际位置在无限掉落。判断的方法是打开UE4编辑器选中地面物体看Details面板里Collision是不是Enable。如果无人机一直下落多半是地面没有碰撞体或者无人机出生点距离地面太远导致重力把无人机拉到了地下。这种时候直接把PlayerStart放到地面上方1到2米处即可。8.4 画面渲染异常或图像全黑全黑问题几乎是每个AirSim新手都会遇到的。首先检查是不是相机朝向你的方向不对比如相机正对天空或正对地面。其次检查相机的CaptureSettings中的ImageType是不是设成了Depth或Segmentation这两种图默认输出灰度图或标签图直接拿来看是黑的。深度图全黑通常是因为深度值太大或太小。AirSim的深度图默认单位是米默认的far plane可能设置得太大导致近处物体深度值映射后很暗。可以设置DepthCameraFOV和DepthTargeted相关参数来调整或者在获取深度图后手动做归一化比如depth depth / 30.0再显示。8.5 仿真卡顿、FPS过低卡顿是仿真最常见的性能问题。如果你的目的是真机移植或者实时交互最好用有GPU的机器并且关闭UE4的实时阴影和某些后期处理效果。在Project Settings里可以把阴影质量调到中低关掉体积云和天空大气散射效果AirSim的视觉质量仍然很高。如果必须用无GPU的服务器或虚拟机跑可以用-nullrhi启动UE4然后改用AirSim的RenderMode设为NoDisplay这样无人机动力学和传感器仍然模拟但不会实际渲染图像。对于算法验证来说这样足够但别指望这种方法能出图像。VMware虚拟机用户要特别留意UE4的渲染在VMware里可能会异常因为VMware的OpenGL支持很弱。如果没有物理GPU直通我的建议是不要在虚拟机里跑AirSim直接在实体机装Ubuntu或者用Docker加上NVIDIA GPU支持都比虚拟机靠谱得多。8.6 无法连接Python客户端这个问题的概率也不低尤其是你在同一台机器上运行UE4和Python脚本时常常因为局域网防火墙或端口冲突导致连接不上。AirSim默认用RPC端口41451如果这个端口被占用仿真器会使用41452等后续端口。排查时可以看UE4日志里提示的实际端口号然后让Python客户端显式指定端口client airsim.MultirotorClient(ip127.0.0.1, port41452) client.confirmConnection()如果是在远程服务器上运行仿真器本地跑Python客户端ip要改成服务器的内网IP或公网IP同时确保防火墙放行TCP 41451端口。AirSim的RPC协议没有加密不推荐直接暴露在公网上实在需要远程访问建议走SSH隧道。9. 场景扩展与二次开发9.1 接入ROS、PX4和ArduPilot自定义场景跑通之后下一步大概率是你想把AirSim接进自己的控制栈里。AirSim官方提供了ROS接口方式有两种一种是在AirSim的ros/src目录里编译airsim_ros_pkgs另一种是通过Python脚本把获取的状态和图像转发到ROS topic。前者性能更好后者实现更快。PX4和ArduPilot的支持方式和ROS略有不同AirSim提供的是UDP连接飞控固件在仿真环境下再通过MAVLink与AirSim通信。这个配置涉及端口和固件参数不建议一上来就搞先把Simple Flight模式跑通再逐步切到PX4。9.2 多机集群仿真多机仿真需要你提前修改场景里多个PlayerStart的位置和朝向还要保证每台无人机有独立的配置文件接口。AirSim支持多Vehicle但Python客户端要分别连接不同的无人机示例可以在PythonClient目录下的multirotor/multi_vehicle_control.py中找到它演示了同时控制多台无人机起飞和移动的方式。多机实验对场景的性能要求更高一台低端GPU可能带不动太多相机流如果只是做动力学和控制可以关闭部分视觉渲染。9.3 天气、风场与动态障碍物如果要测试无人机在环境扰动下的鲁棒性AirSim提供了参数设置包括风、雨、雪等天气选项。其中风参数通过simSetWind接口设置可以指定风速和风向对无人机动力学的影响比较明显。动态障碍物则需要你手动在UE4场景中编写蓝图逻辑比如移动的车辆或行人这已经超出AirSim本身的范畴但UE4的蓝图系统让这块实现成本并不高。我自己的经验是先保证静态场景稳定运行再逐步加入动态元素。一次加太多动态物体很难判断是无人机控制问题还是环境碰撞问题。9.4 自定义传感器添加激光雷达、摄像头与视觉传感器AirSim内置了激光雷达配置方式是在settings.json中给Vehicle添加Lidar配置。但自定义高精雷达需要改源码或者用APIAirSim没有完全开放雷达模型的点云处理逻辑。如果你只是想测Lidar点云数据建议直接用内置Lidar它的点云格式和ROS兼容性较好可以减少很多绕弯的功夫。视觉传感器方面AirSim的相机模型比较简化没有畸变参数。如果你在做相机标定相关研究可能需要在后端加上自己的失真模型。这个确实麻烦但AirSim本身不是相机标定软件它的定位是仿真数据生成和算法验证平台作用域不同。10. 写在最后的实操经验我花了这么多篇幅讲流程其实里面最值钱的不是步骤本身而是你做每一步时能不能理解它后面的逻辑。无人机仿真场景搭建这件事本质上是把真实世界的无人机实验搬到一个可复现的虚拟环境里。你在场景里填的每一个建筑、放的每一棵树都在影响视觉算法看到的数据分布所以我在实际做项目时一直强调“场景要和最终应用场景尽量对齐”。如果只是算法的跑通验证那就用默认Blocks场景就够了如果是要验证视觉导航算法的真实表现那我建议你花时间做一个与最终部署环境相似度足够高的自定义场景。AirSim在Ubuntu上其实并没有官方“图形化一键安装”的方式每个环节都是命令行和配置文件堆出来的但这也给了我们最大的灵活性。你可以把一个场景封装成Docker镜像也可以把场景参数散落到配置文件里用脚本批量生成不同难度的实验环境。如果你在搭建过程中卡住了先别急着怀疑AirSim有问题。我的经验是绝大多数问题都出在UE4版本、编译参数、场景碰撞体配置这三块。把这三块逐一确认清楚整个框架跑通大概率只是时间问题。最后说一句不管你是想跑视觉SLAM、多机协同还是高机动控制一个你没亲手搭过的仿真环境可能比一个没调参的控制器更让你头疼。听话先从自定义场景开始别一上来就惦记着PX4和集群。
网站建设高端定制企业官网