PX4 WSL2 开发环境搭建笔记

本文是人工可操作的步骤版:每条命令前标注执行位置——【PowerShell】表示在 Windows 的 PowerShell 窗口执行,【WSL 内】表示已通过 wsl 进入 Linux shell 后执行。首次搭建时发行版名叫 Ubuntu-24.04,第 7.3 节再改名为 ub2404-px4。

1. 选型结论

三台机器实测对比(2026-09-23):

机器 实测配置 结论
Win10 本机(i7-13700F / 32G / RTX 3060) WSL2 2.7.3 + WSLg 1.0.73 已预装,只差发行版 ✅ 开发机
YPC-M3 迷你主机(192.168.137.136) i5-8260U 4C8T / 16G,Ubuntu 26.04,x86_64 ❌ PX4 官方不支持 26.04
Jetson AGX Orin 64GB(192.168.137.240) aarch64,Ubuntu 24.04.5,12 核 / 61G / 931G NVMe 留作机载计算机(社区路径)

依据:PX4 官方只支持 Ubuntu 24.04 / 22.04;另有官方 WSL2 文档,且 v1.18 起 make upload 通过 Windows COM 口烧录,不需要 usbipd;WSLg 官方支持 Win10 Build 19044+。

2. 安装 WSL2 + Ubuntu 24.04(E 盘)

不走商店安装(避免首次启动的交互式初始化向导),直接用官方云镜像 rootfs 导入,全部步骤可复制粘贴:

【PowerShell】

mkdir E:\WSL

# 下载 rootfs(约 230MB,走 USTC 镜像)
curl.exe -L -o E:\WSL\noble-root.tar.xz https://mirrors.ustc.edu.cn/ubuntu-cloud-images/noble/current/noble-server-cloudimg-amd64-root.tar.xz

# 校验,输出对照 https://cloud-images.ubuntu.com/noble/current/SHA256SUMS
Get-FileHash E:\WSL\noble-root.tar.xz -Algorithm SHA256

# 导入为 WSL2 发行版(tar.xz 可直接导入)
wsl --import Ubuntu-24.04 E:\WSL\Ubuntu-24.04 E:\WSL\noble-root.tar.xz --version 2

3. 初始配置:建用户、systemd、国内源

【PowerShell】以 root 身份进入:

wsl -d Ubuntu-24.04 -u root

【WSL 内】创建用户并配置免密 sudo(替换”你的密码”):

useradd -m -s /bin/bash -G sudo hxf0223
echo "hxf0223:你的密码" | chpasswd
echo "hxf0223 ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/hxf0223
chmod 440 /etc/sudoers.d/hxf0223

【WSL 内】写 /etc/wsl.conf(启用 systemd、设默认用户与主机名):

cat > /etc/wsl.conf <<'EOF'
[boot]
systemd=true

[user]
default=hxf0223

[network]
hostname=ubuntu2404

[automount]
options="metadata"
EOF

【WSL 内】apt 换 USTC 源、禁用 cloud-init,然后退出:

sed -i -E 's#https?://(archive|security)\.ubuntu\.com/ubuntu#https://mirrors.ustc.edu.cn/ubuntu#g' /etc/apt/sources.list.d/ubuntu.sources
touch /etc/cloud/cloud-init.disabled
exit

【PowerShell】重启发行版使配置生效;此后日常进入就用这条命令(exit 退回 PowerShell):

wsl --terminate Ubuntu-24.04
wsl -d Ubuntu-24.04

【WSL 内】pip / uv 换清华源(此时已是普通用户):

mkdir -p ~/.config/pip ~/.config/uv
printf "[global]\nindex-url = https://pypi.tuna.tsinghua.edu.cn/simple\n" > ~/.config/pip/pip.conf
printf "[[index]]\nurl = \"https://pypi.tuna.tsinghua.edu.cn/simple\"\ndefault = true\n" > ~/.config/uv/uv.toml

4. 网络与代理(GitHub 必需)

背景:GitHub 直连不通;Windows 上的代理客户端监听 127.0.0.1:7890 并开启”允许局域网连接”。WSL 的 NAT 网关就是 Windows 本机,所以 WSL 里经 网关IP:7890 即可使用代理。

【WSL 内】让 git 走代理:

git config --global http.proxy "http://$(ip route show default | awk '{print $3}'):7890"

WSL 重启后网关 IP 可能变化,装一个登录时自动修正的脚本:

sudo tee /etc/profile.d/git-proxy.sh >/dev/null <<'EOF'
gw=$(ip route show default | awk '{print $3}')
[ -n "$gw" ] && git config --global http.proxy "http://$gw:7890"
EOF

代理客户端没开时的备选(ghfast 镜像前缀,用回代理时记得移除):

git config --global url."https://ghfast.top/https://github.com/".insteadOf "https://github.com/"

【WSL 内】验证——几秒内返回一串 commit hash 即通:

git ls-remote --heads https://github.com/PX4/PX4-Autopilot.git main

5. 安装 PX4 工具链 + Gazebo

【WSL 内】克隆仓库(子模块浅克隆加速,约 2.6G;主仓库建议拉取完整历史以保留版本 Tag):

git clone --recursive --shallow-submodules -j8 https://github.com/PX4/PX4-Autopilot.git ~/PX4-Autopilot
cd ~/PX4-Autopilot

注意(版本号坑与解决方案):若主仓库使用了 --depth 1 浅克隆,Git 历史截断会导致 CMake 无法回溯识别到版本 Tag,自动将固件版本回退识别为 v0.0.0,后续 QGC 连接时会提示 「模型没有运行最新的稳定固件!运行 0.0.0,最新稳定是 1.14.4」。 若已浅克隆,可执行解浅拉取完整历史修复:

git fetch --unshallow
cmake -B build/px4_sitl_default
ninja -C build/px4_sitl_default

若此后 ninja 在 uxrce_dds_client 报 /usr/local/microcdr-2.0.1/lib 权限错误,是增量重配置丢失安装前缀所致,处理方法见第 8 节排障条目。

有个坑要先处理:ubuntu.sh 会从 GitHub 下载 ESP32 工具链,直连会挂起导致脚本中断,先把脚本里的 GitHub 地址改成代理前缀:

sed -i 's#https://github.com/#https://ghfast.top/https://github.com/#g' Tools/setup/ubuntu.sh

安装(约 20-40 分钟、下载约 2GB;Gazebo Harmonic 来自 OSRF 源,国内可直连):

bash Tools/setup/ubuntu.sh

装完包含:SITL 依赖、NuttX 交叉工具链(arm-none-eabi)、ESP32 Xtensa、Gazebo Harmonic。

6. 编译与仿真验证

【WSL 内】

cd ~/PX4-Autopilot
make px4_sitl             # 只编译
make px4_sitl gz_x500     # 编译 + 启动仿真,桌面弹出 Gazebo 窗口(WSLg)

启动日志依次出现以下三行即健康,退出按 Ctrl+C:

INFO  [init] Gazebo world is ready
INFO  [init] Spawning Gazebo model
INFO  [tone_alarm] home set     ← GPS + EKF 位置估计正常

无界面模式(更省资源):HEADLESS=1 make px4_sitl gz_x500

6.1 构建原理解析(Make、CMake 与 Ninja 的关系)

PX4 根目录下的 Makefile 本质上是一个高层封装脚手架(Wrapper)。当执行 make px4_sitl gz_x500 时,背后实际上按序执行了以下三步流水线:

  1. 配置阶段(CMake):

    cmake -B build/px4_sitl_default
    
    • 作用:解析根目录 CMakeLists.txt,探测系统编译器、依赖库、提取 Git Tag 版本,评估各模块编译开关。
    • 产物:在 build/px4_sitl_default/ 下生成底层 Ninja 构建规则(build.ninja),此阶段不编译 C/C++ 源码。
  2. 编译阶段(Ninja):

    ninja -C build/px4_sitl_default
    
    • 作用:读取 build.ninja,榨干所有 CPU 核心并行调用编译器编译源码并链接,生成飞控二进制文件 build/px4_sitl_default/bin/px4。
  3. 仿真运行与环境注入(make 独有能力):

    • 这是单独调用 cmake / ninja 所不具备的步骤。make 会自动注入 Gazebo 相关环境变量(如模型路径 GZ_SIM_RESOURCE_PATH、机型参数 PX4_SIM_MODEL=gz_x500、通信端口等),随后拉起 Gazebo 物理仿真世界与 px4 飞控进程进行闭环交互。

日常开发选择建议:

  • 只编译不跑仿真(快速验证语法 / 代码重构):执行 make px4_sitl 或更直接的 ninja -C build/px4_sitl_default,速度最快、消耗系统资源最少。
  • 刷新版本号 / 重新生成构建规则:执行 cmake -B build/px4_sitl_default。
  • 完整仿真调试:始终使用 make px4_sitl gz_x500。

6.2 SITL Mission:任务文件的加载与执行

先分清两件事:任务文件格式(QGC 用 .plan,JSON,含任务项 + 电子围栏 + rally 点;ArduPilot 用 .txt/.waypoints,每行一条命令,两者不通用)与任务传输方式。PX4 飞控本身没有”任务文件”的概念——任何客户端都是通过标准 MAVLink 任务协议(MISSION_COUNT → MISSION_ITEM_INT → MISSION_ACK,见 src/modules/mavlink/mavlink_mission.cpp)把任务项传上去,所以 QGC、MAVProxy、MAVSDK 三条路都通。

SITL 的 MAVLink 端口(定义在 ROMFS/px4fmu_common/init.d-posix/px4-rc.mavlink):18570 是 GCS 链路(QGC/MAVProxy 连这里),14540 是 offboard/API 链路(MAVSDK 连这里)。

【WSL 内】以合肥为例启动仿真——home 坐标必须与任务坐标匹配,否则任务不可达;三个变量必须同时给:

cd ~/work/px4/PX4-Autopilot
PX4_HOME_LAT=31.8206 PX4_HOME_LON=117.2272 PX4_HOME_ALT=30 make px4_sitl gz_x500

三种加载方式按习惯选:

方式一:QGC 图形界面。Plan 视图打开/绘制 .plan → Upload → Fly 视图点 Start Mission(自动切 Mission 模式并解锁)。QGC 连接方法见第 8 节(UDP link 指向 WSL_IP:18570),上传后航点自动画在地图上;QGC 上传时会把电子围栏、rally 点一并传上去。

方式二:MAVProxy 命令行(ArduPilot 习惯直接平移,.txt 航点文件零转换可用——MAVProxy 自己解析文本再发 MAVLink,PX4 接受相对高度帧):

pip install MAVProxy
mavproxy.py --master=udp:127.0.0.1:18570
# 进入控制台后:
wp load mission.txt    # 上传
wp list                # 查看
wp clear               # 清除

注意 MAVProxy 的模式名映射是 ArduPilot 的,对 PX4 启动任务请用下面的 commander 命令,不要用它的 mode。

方式三:MAVSDK 脚本(工具已备好在 px4-dev-env 仓库,含 .plan 坐标平移脚本 move_plan.py):

cd ~/work/px4/px4-dev-env && source .venv/bin/activate
./mission_import.py hefei_mission_geofence_avoid.plan --start   # 上传 + 解锁 + 起飞 + 打印进度

--start 之外,手动启动任务(PX4 控制台或 QGC 的 MAVLink Console):

commander mode auto:mission   # 切任务模式(QGC "Start Mission" 按钮等价于此 + 解锁)
commander arm                 # 解锁,任务随即开始执行

多旋翼任务建议首项 Takeoff、末项 RTL/Land;MAVSDK 脚本只传任务项,电子围栏需经 QGC 上传。

World 与”地图”的关系:Gazebo world(PX4_GZ_WORLD 可选 default/baylands/forest 等 14 个)是 3D 场景(地形/障碍/物理);QGC 地图是在线瓦片图。两者只靠经纬度对齐——每个 world SDF 内嵌地理参考(default.sdf 绑定苏黎世),启动时的 PX4_HOME_* 只是改写这个参考、把场景原点”钉”到指定经纬度,地形本身不会变成合肥的真实地貌,做航线/避障逻辑测试用默认平地即可。

7. 常用增强(可选但推荐)

7.1 GPU 硬件加速渲染

前提:Windows 端 NVIDIA 驱动升级到新版本(2026-09 实测 616.92 可用;旧的 536.40 会导致 d3d12 初始化失败、只能软渲染)。

【WSL 内】让 Mesa 默认走 d3d12 后端:

sudo tee /etc/profile.d/gpu-d3d12.sh >/dev/null <<'EOF'
export GALLIUM_DRIVER=d3d12
export MESA_D3D12_DEFAULT_ADAPTER_NAME=NVIDIA
EOF
echo '. /etc/profile.d/gpu-d3d12.sh' | sudo tee -a /etc/bash.bashrc >/dev/null
sudo apt install -y mesa-utils

【PowerShell】重启 WSL 使配置生效(会断开所有 WSL 会话):

wsl --shutdown
wsl -d Ubuntu-24.04

【WSL 内】验证,期望输出 D3D12 (NVIDIA GeForce RTX 3060) 和 Accelerated: yes:

glxinfo -B | grep -E "renderer|Accelerated"

7.2 SSH 登录(MobaXterm 等)

云镜像默认没有 sshd,且有两个坑:缺主机密钥(服务反复启动失败)、默认禁用密码登录。

【WSL 内】

sudo apt install -y openssh-server
sudo ssh-keygen -A
sudo sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config.d/60-cloudimg-settings.conf
sudo systemctl enable --now ssh

之后 MobaXterm 连 hxf0223@localhost(地址稳定,推荐)或 WSL IP(hostname -I 查询,WSL 重启后会变)。

注意分工:SSH 会话里没有 DISPLAY,跑 GUI 程序请从 PowerShell wsl 进入;SSH 只用于无界面操作。

7.3 重命名发行版(如 ub2404-px4)

WSL 没有官方 rename 命令;导出再导入的方案慢、且会被 MobaXterm 自动重连锁住 VHDX 文件。直接改注册表最快:

【PowerShell】先查自己发行版的 GUID:

reg query HKCU\Software\Microsoft\Windows\CurrentVersion\Lxss /s /v DistributionName

【PowerShell】用查到的 GUID 改名(下面是本机的示例值):

wsl --shutdown
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Lxss\{216d3a8b-36ba-456b-bca0-d0a3f62b0360}" -v DistributionName -t REG_SZ -d ub2404-px4 -f
wsl -l -v    # 应显示新名字

说明:E:\WSL\Ubuntu-24.04 这个文件夹名只是装饰,不影响功能,不必改。开多个 PowerShell 窗口时,每个窗口各自执行 wsl -d ub2404-px4 即可,所有窗口进入的是同一个虚拟机。

8. 排障速查

  • QGC 提示”模型没有运行最新的稳定固件!运行 0.0.0,最新稳定是 1.14.4”:
    • 原因:主仓库克隆时若使用了 --depth 1 浅克隆,Git 提交历史截断导致 git describe 匹配不到上游 Release Tag,CMake 编译时回退将固件版本标为 v0.0.0,QGC 误判为旧固件(此提示不影响正常仿真飞行)。
    • 解决方案:取消浅克隆拉取完整历史:

      git fetch --unshallow
      cmake -B build/px4_sitl_default
      ninja -C build/px4_sitl_default
      

      重新编译后固件版本将自动正确识别为真实主线版本(如 v1.18.0-dev-...),QGC 告警自动消除。

  • 增量重配置后 ninja 报 file cannot create directory: /usr/local/microcdr-2.0.1/lib:
    • 原因:uxrce_dds_client 的依赖(micro-XRCE-DDS-client / micro-CDR)是多层嵌套 ExternalProject,其 “install” 本应把静态库暂存进 build 树(外层已显式传入 CMAKE_INSTALL_PREFIX,见 src/modules/uxrce_dds_client/CMakeLists.txt)。但 cmake -B 重新配置会让内层项目检测到缓存参数变化并删缓存重配(日志特征:You have changed variables that require your cache to be deleted),重配时父层传入的前缀等参数丢失,回落到 CMake 默认 /usr/local,叠加 microcdr 的版本号后缀后无权限写入而失败。
    • 解决方案(勿用 sudo,会污染系统目录):整体删除 build 目录重建;或只清理该子项目增量重编:

      rm -rf build/px4_sitl_default/src/modules/uxrce_dds_client
      ninja -C build/px4_sitl_default
      
  • 不要直接运行 build/px4_sitl_default/bin/px4:缺 make 注入的 GZ 环境变量,会一直卡在 “Waiting for Gazebo world”,始终用 make 入口。
  • /tmp 重启后清空:WSL 空闲自动关机后 tmpfs 清空,调试日志放 ~ 下。
  • QGC(Windows 版)连 SITL:WSL IP 会变,在 QGC 手动添加 UDP link 指向 WSL_IP:18570。
  • 真机固件:make px4_fmu-v6x_default;v1.18 起 make upload 走 Windows COM 口,无需 usbipd。
  • 电脑重启后 WSL 不自启:先 wsl -d ub2404-px4 拉起一次,SSH 和仿真才能用。
  • 仓库目录调整:笔者后来把 PX4-Autopilot 移到了 ~/work/px4/PX4-Autopilot,与本文的 ~/PX4-Autopilot 路径不同,注意按实际路径操作。

9. 参考资料




Enjoy Reading This Article?

Here are some more articles you might like to read next: