Ubuntu 20.04下AirSim+UE4仿真环境搭建与自定义场景导入全攻略

AI 时代程序员必备技能

Codex、Claude Code、Cursor、Hermes Agent、OpenClaw等工程化实战专栏 ,讲透 AI 如何接管脏活累活

1. 项目概述与环境准备

在机器人、无人机和自动驾驶的研发领域,一个高保真、可编程的仿真环境是算法迭代和验证的“加速器”。AirSim作为微软开源的仿真平台,凭借其基于物理的传感器模型和与Unreal Engine(UE4)的深度集成,成为了许多研究者和工程师的首选。然而,将AirSim、UE4以及自定义场景在Ubuntu 20.04 LTS这个稳定的生产环境中成功搭建起来,却是一个充满“坑点”的系统工程。这不仅仅是运行几条命令那么简单,它涉及到系统依赖、图形驱动、引擎编译、插件配置等一系列环环相扣的步骤。今天,我就基于自己多次在Ubuntu 20.04上从零搭建环境的实战经验,为你拆解每一步的核心逻辑和避坑要点,特别是最后一步——导入自定义场景时那些官方文档不会告诉你的细节。

为什么选择Ubuntu 20.04 LTS?对于仿真和开发而言,系统的长期稳定性和广泛的社区支持至关重要。20.04作为长期支持版本,其软件库和内核版本在AirSim和UE4所需的依赖兼容性上达到了一个较好的平衡点。而AirSim+UE4的组合,则为我们提供了从简单的API控制到复杂物理渲染的全栈仿真能力。整个流程可以概括为三个核心阶段:首先是打好地基,即准备一个“干净”且驱动完备的Ubuntu系统;其次是构建核心,即编译和配置Unreal Engine 4.27(这是一个与AirSim兼容性经过验证的版本);最后是集成与扩展,即编译AirSim插件并成功导入你自己的3D场景。下面,我们就从最基础的系统环境开始。

1.1 系统基础与显卡驱动:一切的前提

在Ubuntu上玩转UE4这类重型图形应用,一个正确安装且性能释放充分的NVIDIA显卡驱动是绝对的前提。很多新手卡在第一步,就是因为用了系统自带的 nouveau 开源驱动,或者安装了版本不匹配的驱动。

1.1.1 彻底禁用 Nouveau 驱动

Ubuntu默认使用开源Nouveau驱动,它与NVIDIA官方闭源驱动冲突,必须在安装前禁用。

# 打开黑名单配置文件
sudo nano /etc/modprobe.d/blacklist-nouveau.conf

在文件中添加以下两行:

blacklist nouveau
options nouveau modeset=0

保存后,更新initramfs并重启:

sudo update-initramfs -u
sudo reboot

重启后,验证是否禁用成功:

lsmod | grep nouveau

如果没有任何输出,则表示禁用成功。

1.1.2 安装合适的NVIDIA驱动

不要直接使用 ubuntu-drivers autoinstall ,对于开发环境,我们更需要一个特定版本。访问 NVIDIA官网 根据你的显卡型号查找推荐驱动。例如,对于RTX 30系列,470或更高版本的驱动是必须的。这里以安装470版本为例:

# 添加官方PPA仓库(可选,但通常版本更新)
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt update

# 查看可用的驱动版本
ubuntu-drivers devices

# 安装指定版本驱动,例如 nvidia-driver-470
sudo apt install nvidia-driver-470

安装完成后, 必须重启系统 。重启后,使用 nvidia-smi 命令验证驱动和GPU是否被正确识别。你应该能看到显卡型号、驱动版本以及GPU的进程占用情况。

注意: 如果你使用笔记本电脑并且是双显卡(NVIDIA独显 + Intel/AMD核显),情况会复杂一些。你需要确保在运行UE4编辑器时,使用的是高性能的NVIDIA显卡。除了在NVIDIA控制面板( nvidia-settings )中设置外,在终端启动UE4时,可以显式指定:

__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia ./UE4Editor

1.1.3 安装核心系统依赖

UE4编译需要一整套开发工具和库。以下命令一次性安装所需的基础包:

sudo apt update
sudo apt install build-essential software-properties-common cmake git wget zip unzip \
                 libc6-dev libx11-dev libglu1-mesa-dev libgl1-mesa-dev \
                 libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev \
                 libz-dev libssl-dev libudev-dev libpng-dev libsdl2-dev \
                 g++-8 gcc-8 clang-8 lld-8 python3-dev python3-pip \
                 libvulkan1 libvulkan-dev

这里特别强调 g++-8 clang-8 ,因为UE4.27的源码编译对编译器版本有明确要求,使用系统默认的更高版本(如g++-11)极有可能导致编译失败。安装后,我们可以将gcc-8和g++-8设置为默认版本:

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 800 --slave /usr/bin/g++ g++ /usr/bin/g++-8

2. Unreal Engine 4.27 源码编译详解

直接从Epic Games Launcher安装UE4对于Windows用户很方便,但在Linux上,为了获得最好的兼容性和对AirSim插件的支持,从源码编译是推荐且几乎必须的路径。这个过程耗时较长(取决于CPU核心数和磁盘IO,通常1-4小时),但每一步都至关重要。

2.1 获取UE4源码与依赖项

首先,你需要访问 Epic Games的GitHub页面 ,并按照其指引关联你的Epic账户以获得克隆权限。这步是法律授权所需,无法绕过。

# 在一个空间充足的磁盘分区(建议至少预留150GB)克隆代码
git clone https://github.com/EpicGames/UnrealEngine.git -b 4.27
cd UnrealEngine

克隆完成后,不要急于运行编译脚本。我们需要先确保所有子模块都被正确拉取,并且下载所需的二进制依赖。

2.1.1 运行依赖设置脚本

UnrealEngine 目录下,执行:

./Setup.sh

这个脚本会自动下载并配置编译所需的工具链(如特定版本的Clang)和大量的第三方库文件(如.NET Core、OpenSSL等)。它会检查你的系统环境,并下载约10-20GB的数据到 Engine/Extras Engine/Binaries/ThirdParty 等目录。 请保持网络通畅 ,如果中途失败,可以多次运行此脚本,它会尝试续传。

2.2 编译UE4编辑器

依赖配置完成后,就可以开始编译引擎本体了。

./GenerateProjectFiles.sh
make

./GenerateProjectFiles.sh 会生成用于编译的Makefile。 make 命令则开始真正的编译过程。

2.2.1 编译过程中的关键观察点与问题排查

  • 内存与交换空间 :编译UE4是内存消耗大户。如果物理内存不足(例如小于16GB),会大量使用交换分区,导致编译速度极慢甚至卡死。建议确保有32GB以上物理内存,或者设置一个足够大的交换文件(如32GB):
    sudo fallocate -l 32G /swapfile
    sudo chmod 600 /swapfile
    sudo mkswap /swapfile
    sudo swapon /swapfile
    # 永久生效需写入 /etc/fstab
    
  • CPU核心数利用 make 默认会使用所有可用的CPU核心。你可以通过 make -j N 来指定并行编译任务数, N 通常设置为你的CPU物理核心数或略多(如8核CPU用 -j 10 )。但过多的任务可能导致内存不足。
  • 常见编译错误
    • “fatal error: ‘stddef.h’ file not found” :这通常是Clang工具链路径问题。确保 Setup.sh 成功运行,并检查 Engine/Extras/ThirdPartyNotUE/SDKs/HostLinux/Linux_x64 下是否存在完整的工具链。
    • 链接器内存耗尽 :同样是内存不足的表现,增加交换文件大小或减少 -j 参数。
    • 特定模块编译失败 :有时是网络问题导致依赖下载不完整。可以尝试删除 Engine/Binaries Engine/Intermediate 目录,重新运行 ./Setup.sh make

编译成功完成后,你会在 UnrealEngine 目录下看到 Engine/Binaries/Linux/UE4Editor 可执行文件。运行它来验证:

cd Engine/Binaries/Linux
./UE4Editor

首次启动会进行着色器编译等初始化工作,稍等片刻后,你应该能看到Unreal Engine 4.27的编辑器界面。恭喜,最耗时、最复杂的一步已经完成。

3. AirSim插件编译与集成

有了可运行的UE4编辑器,接下来就是将AirSim这个“大脑”集成进去。AirSim以UE4插件的形式存在,我们需要先编译插件,然后将其放入一个UE4项目中。

3.1 编译AirSim插件

AirSim的编译相对独立,它会产生一个 .so 动态库文件供UE4调用。

# 克隆AirSim源码(建议放在独立目录,不要放在UE4目录内)
git clone https://github.com/microsoft/AirSim.git
cd AirSim

# 使用项目提供的脚本搭建编译环境
./setup.sh
./build.sh

setup.sh 会安装AirSim所需的额外Python依赖(如msgpack-rpc-python)和构建工具。 build.sh 则会调用CMake和make进行编译。

3.1.1 编译输出与结构

编译成功后,关键产出在 AirSim/Unreal/Plugins 目录下。你会看到一个名为 AirSim 的插件文件夹。这个文件夹的结构是标准的UE4插件格式,其中 Binaries/Linux/ 下存放着编译好的 libUE4Editor-AirSim.so 等库文件。

3.2 创建UE4项目并集成插件

你不能直接把插件扔进UE4引擎目录。标准的做法是创建一个空项目,然后将插件复制到项目的插件目录。

3.2.1 创建空项目

  1. 启动我们刚才编译好的UE4编辑器 ( ./UE4Editor )。
  2. 在项目浏览器中,选择“Games” -> “Blank”(空白项目)。
  3. 选择“C++”项目( 必须选择C++ ,否则后续无法正确加载插件),设置好项目名称(例如 MyAirSimProject )和存储路径,然后点击“Create”。
  4. UE4会为你生成一个C++项目并自动打开Visual Studio Code或你设置的默认IDE进行初始编译。等待其完成。

3.2.2 集成插件

关闭UE4编辑器。将刚才编译好的整个 AirSim 插件文件夹(即 AirSim/Unreal/Plugins/AirSim ), 完整地复制 到你刚创建的项目目录下的 Plugins 文件夹中。如果项目下没有 Plugins 文件夹,就自己创建一个。

MyAirSimProject/
├── Config/
├── Content/
├── Plugins/       <-- 创建这个文件夹
│   └── AirSim/    <-- 复制整个插件文件夹到这里
├── Source/
└── MyAirSimProject.uproject

3.2.3 重新生成项目文件并编译

由于添加了C++插件,需要重新生成项目文件。

# 进入你的项目目录
cd ~/Documents/Unreal\ Projects/MyAirSimProject

# 使用UE4附带的生成脚本,指定你的UE4引擎根目录
/path/to/your/UnrealEngine/Engine/Build/BatchFiles/Linux/GenerateProjectFiles.sh -project="/path/to/your/MyAirSimProject/MyAirSimProject.uproject" -game

# 然后编译项目
cd /path/to/your/UnrealEngine
make MyAirSimProjectEditor

或者,更简单的方法是:直接双击项目目录下的 MyAirSimProject.uproject 文件。系统会提示你“模块缺失,需要重新编译”,点击确认,它会自动调用UE4的编译系统。

编译成功后再次打开项目,你可以在UE4编辑器的“设置” -> “插件”中,看到“AirSim”插件已被启用。至此,AirSim仿真平台的核心环境就搭建完成了。你可以运行UE4内置的“Blocks”环境来测试:在编辑器中选择“播放”(Play),然后在终端中使用AirSim的Python API示例脚本来控制车辆或无人机。

4. 自定义场景导入:核心流程与深度避坑

使用官方提供的“Blocks”或“Landscape”环境入门后,你一定会想导入自己的3D场景,比如一个用Blender或3ds Max创建的园区、城市模型。这是将AirSim应用于具体研究(如视觉SLAM、路径规划)的关键一步,也是“坑”最多的地方。

4.1 场景资产准备与格式处理

UE4支持多种3D格式,但最通用、问题最少的是 FBX 格式。在从其他软件导出FBX时,设置至关重要。

4.1.1 建模软件导出设置(以Blender为例)

  1. 比例与轴向 :UE4使用厘米(cm)为单位,Y轴向前,Z轴向上。在Blender导出FBX时,务必在“变换”选项中勾选“应用变换”,并设置“前向”为Y Forward,“向上”为Z Up。比例缩放设置为1.0。
  2. 平滑组与法线 :这是导致模型在UE4中显示为“全黑”或“全光滑”的常见原因。在Blender的“几何数据”导出选项中,务必勾选“平滑组”(Smoothing Groups)。如果模型有自定义法线,也可以勾选“导出法线”。
  3. 材质与纹理 :尽量使用简单的原理化BSDF(Principled BSDF)材质。导出时勾选“嵌入纹理”(Embed Textures)可以将贴图打包进FBX,避免路径丢失问题。但更推荐的做法是将纹理图片单独存放,并在UE4中重新指定。

4.1.2 在UE4中导入FBX

在UE4编辑器的Content Browser中右键 -> “导入到 /Game...”,选择你的FBX文件。会弹出导入选项窗口:

  • 材质导入方法 :对于首次导入,选择“不创建材质”(Do Not Create Material)。我们稍后在UE4中创建更可控的材质实例。
  • 自动生成碰撞 :如果你的模型没有碰撞体,可以勾选“自动生成碰撞”(Generate Collision)。但对于复杂模型,自动生成的碰撞体可能效率低下,最好在建模软件中创建简单的碰撞体(命名为 UCX_ 开头)并一并导出。
  • 转换场景 :保持默认。点击“导入”后,你会在内容浏览器中看到新导入的静态网格体(Static Mesh)和可能的材质球。

4.2 构建场景与光照

导入的网格体只是“零件”,需要将其拖放到关卡中组装成“场景”。

4.2.1 创建关卡与放置资产

  1. 新建一个空关卡(File -> New Level -> Empty Level)。
  2. 从内容浏览器将导入的静态网格体拖入视口。使用移动(W)、旋转(E)、缩放(R)工具进行布局。
  3. 重要:将地面重命名为“Ground” 。AirSim的默认设置会寻找名为“Ground”的Actor作为地面参考系。右键点击你的地面网格体Actor -> “重命名”(Rename)。

4.2.2 构建光照与导航网格

  1. 光照 :从模式面板(Modes Panel)拖拽一个“定向光源”(Directional Light)和“天光”(Sky Light)到场景中。选中“天光”,在细节面板中勾选“实时捕获”(Real Time Capture)。然后点击工具栏上的“构建”(Build)按钮(或按 Ctrl+Shift+; )来构建光照。没有构建光照的场景会非常暗。
  2. 导航网格(仅对车辆重要) :从模式面板拖拽“导航网格体边界体积”(Nav Mesh Bounds Volume)到场景,缩放其覆盖整个可行驶区域。然后需要构建AI路径:点击工具栏上的“构建”按钮旁的小箭头,选择“构建AI路径”(Build AI Paths)。对于无人机仿真,这一步不是必须的。

4.3 AirSim设置与场景关联

现在需要告诉AirSim:“这个新场景就是你的仿真世界了。”

4.3.1 配置 settings.json

在你的项目目录下(或用户目录的 ~/Documents/AirSim ),创建或修改 settings.json 文件。一个连接自定义场景的最小配置如下:

{
  "SettingsVersion": 1.2,
  "SimMode": "Car", // 或 "Multirotor" 对应无人机
  "Vehicles": {
    "MyCar": {
      "VehicleType": "PhysXCar",
      "X": 0, "Y": 0, "Z": 0 // 生成初始位置
    }
  },
  "OriginGeopoint": {
    "Latitude": 47.641468,
    "Longitude": -122.140165,
    "Altitude": 122
  }
}

关键点在于,我们不需要像使用“Blocks”环境那样指定 "UdpPort" "ApiServerPort" ,因为现在AirSim插件直接运行在我们的自定义项目进程中。

4.3.2 设置默认关卡并打包

  1. 在UE4编辑器中,打开“项目设置”(Project Settings)-> “项目”(Project)-> “地图和模式”(Maps & Modes)。将“编辑器启动地图”(Editor Startup Map)和“游戏默认地图”(Game Default Map)都设置为你刚创建并布置好的关卡。
  2. (可选但推荐)项目打包 :为了便于分发和稳定运行,可以将项目打包成独立的可执行文件。在编辑器菜单栏选择“文件”(File)-> “打包项目”(Package Project)-> “Linux”。选择一个输出目录,UE4会开始打包过程。打包完成后,你可以在输出目录的 LinuxNoEditor 文件夹下找到可执行文件,它包含了所有依赖,可以在没有安装UE4编辑器的机器上运行。

5. 实战问题排查与性能优化指南

即使严格按照步骤操作,在实际搭建和运行中仍会遇到各种问题。这里我总结了一份“避坑速查表”,涵盖了从环境搭建到场景运行的全链条。

5.1 环境搭建与编译问题

问题现象 可能原因 排查与解决步骤
./Setup.sh 下载极慢或失败 网络连接Epic Games服务器不畅 1. 使用稳定的网络环境,可尝试手机热点。
2. 手动下载依赖:脚本运行时会输出下载链接,可尝试用下载工具获取后放入对应目录。
make 编译UE4时内存不足(OOM Killer) 物理内存和交换空间不足 1. 使用 free -h 查看内存和交换空间。
2. 如前所述,创建足够大的交换文件(32GB+)。
3. 减少并行编译任务: make -j 2
编译AirSim时CMake报错,找不到UE4目录 环境变量 UE4_ROOT 未设置 在运行 ./build.sh 前,先设置环境变量: export UE4_ROOT=/path/to/your/UnrealEngine
UE4编辑器能打开,但启动自带项目(如Blocks)崩溃 显卡驱动问题或Vulkan兼容性问题 1. 确认驱动安装正确 ( nvidia-smi )。
2. 尝试在编辑器启动命令后加 -vulkan -opengl4 切换图形API: ./UE4Editor -vulkan
插件编译成功,但项目中不显示AirSim插件 插件复制路径错误或项目未重新编译 1. 确认插件在 YourProject/Plugins/AirSim/ 下。
2. 删除项目目录下的 Binaries Intermediate 文件夹,重新生成项目文件并编译。

5.2 自定义场景导入与运行问题

问题现象 可能原因 排查与解决步骤
FBX模型导入后全黑 1. 法线问题。
2. 光照未构建。
3. 材质问题。
1. 检查FBX导出时是否勾选“平滑组”。
2. 在UE4中为静态网格体双击打开,在预览窗口检查法线(显示 -> 法线)。
3. 确保场景中有光源并已构建光照(点击构建按钮)。
4. 检查导入的材质,尝试创建一个新的简单材质球赋予模型。
模型在视口中闪烁(Z-fighting) 模型面片距离过近或有重叠 1. 在建模软件中检查并修正模型几何错误。
2. 在UE4的静态网格体编辑器中,略微调整重叠部分的顶点位置。
AirSim API无法连接 1. settings.json 路径错误。
2. 项目默认关卡未设置。
3. 端口冲突。
1. 确认 settings.json 放在 项目根目录 ~/Documents/AirSim
2. 确认项目设置中的“游戏默认地图”是你的自定义关卡。
3. 检查是否有其他程序占用41451端口(AirSim默认API端口)。
车辆/无人机生成后掉入无限深渊 1. 没有名为“Ground”的地面。
2. 生成坐标(Z)设置错误。
3. 地面没有碰撞体。
1. 确认场景中有一个Actor被命名为“Ground”。
2. 在 settings.json 中调整车辆生成点的Z坐标,确保高于地面。
3. 为地面网格体添加碰撞(在静态网格体编辑器中:碰撞 -> 添加简单碰撞或复杂碰撞)。
仿真帧率极低 1. 场景过于复杂,渲染开销大。
2. 光照构建质量过高。
3. AirSim传感器配置过多。
1. 使用UE4的“统计”窗口(Stat FPS)查看性能瓶颈。
2. 降低阴影分辨率、后处理效果等(项目设置 -> 渲染)。
3. 简化场景模型,使用LOD(层次细节)。
4. 在 settings.json 中减少不必要的传感器或降低其分辨率/频率。

5.3 性能优化与工作流建议

  1. 开发阶段使用“开发构建” :在打包项目前,在编辑器内运行和测试。UE4编辑器的“独立进程游戏”(Standalone Game)模式比打包后的版本启动更快,便于快速迭代。
  2. 善用“子关卡”(Sublevels) :对于大型场景,不要把所有资产都放在一个主关卡里。将场景按功能或区域划分成多个子关卡,在编辑器中动态加载和卸载,可以大幅提升编辑效率和运行时性能。
  3. 优化材质和纹理 :避免使用4K以上不必要的超大纹理。使用材质实例(Material Instance)而不是动态材质参数,以减少Draw Call。
  4. AirSim API使用技巧 :在Python脚本中,批量获取传感器数据(如使用 simGetImages 一次获取多个相机图像)比多次调用单次获取API效率高得多。对于不需要每帧都处理的数据,可以降低查询频率。
  5. 版本控制 :将你的UE4项目( Content Source Config .uproject 文件)和AirSim插件目录纳入Git管理。但切记忽略 Binaries Intermediate DerivedDataCache .vs 等由编译和编辑器生成的中间文件和目录。这能让你在环境出错时快速回滚。

整个搭建过程就像搭积木,底层是稳固的Ubuntu系统和显卡驱动,中间是庞大但必须自己构建的UE4引擎,顶层是灵活但需要精细配置的AirSim插件和你的自定义场景。每一步的失败都可能由前一步的疏漏导致,因此耐心和按部就班是关键。当你第一次用自己的场景驱动无人机飞起来,或者让自动驾驶小车循迹时,你会觉得这一切的折腾都是值得的。这个环境将成为你算法研发的强力沙盒,让你在安全的虚拟世界中,无限次地测试、碰撞和优化你的代码。

AI 时代程序员必备技能

Codex、Claude Code、Cursor、Hermes Agent、OpenClaw等工程化实战专栏 ,讲透 AI 如何接管脏活累活

下载代码方式:https://pan.quark.cn/s/e6c2e312b658 在苹果公司的Mac操作系统环境中,当用户尝试安装非原厂驱动程序时,可能会遭遇系统无法正常启动的困境。这种情况常常源于名为.kext的内核扩展驱动程序存在兼容性问题或安装过程中出现失误。这份指南介绍了一种无需重新安装操作系统且能够保护所有用户数据的修复方法,这一方案对于先前许多面临类似挑战的用户而言,曾是极为棘手的情况。文档中提及的“用户模式启动”实际是指单用户模式,这种启动方式仅加载核心系统功能,而忽略图形用户界面及常规应用程序的加载。在单用户模式下,用户能够访问命令行界面,进而执行一系列修复指令。解决此问题的首要环节是验证存储设备是否存在故障,因为这是导致系统无法启动的常见诱因。借助终端指令`/sbin/fsck -f`,可以诊断并纠正文件系统层面的错误。倘若系统在启动过程中检测到文件系统异常,通常会自动执行`fsck`命令,然而,如果系统卡在进度条100%无法继续,手动运行该命令则显得尤为必要。指令`mount -uw /`的功能是将根目录切换为可读写状态,由于系统默认是以只读模式启动的。这一操作的目的是为了在不重新进入正常模式的前提下,对系统进行必要的调整。随后,文档提供了一个关键操作:对存在问题的驱动程序文件进行修改或更名。在Mac系统中,第三方驱动程序一般安装在`/Library/Extensions/`目录下。每个驱动程序都包含一个以.kext为后缀名的文件夹,例如在此案例中的AX88772.kext。通过命令行将故障的.kext文件更名(例如改为.kext.bak),可以临时禁用该驱动程序。这一操作需在命令行环境中完成,首先使用`cd /Library/Exte...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值