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 时,背后实际上按序执行了以下三步流水线:
-
配置阶段(CMake):
cmake -B build/px4_sitl_default- 作用:解析根目录
CMakeLists.txt,探测系统编译器、依赖库、提取 Git Tag 版本,评估各模块编译开关。 - 产物:在
build/px4_sitl_default/下生成底层 Ninja 构建规则(build.ninja),此阶段不编译 C/C++ 源码。
- 作用:解析根目录
-
编译阶段(Ninja):
ninja -C build/px4_sitl_default- 作用:读取
build.ninja,榨干所有 CPU 核心并行调用编译器编译源码并链接,生成飞控二进制文件build/px4_sitl_default/bin/px4。
- 作用:读取
-
仿真运行与环境注入(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: