1. SITL 仿真基础与环境搭建

各位同学好,我是你们这门课的老周。做飞控开发这些年,我踩过最多的坑,就是仿真环境没搭好就开始调参。结果呢?电机死活解锁不了,日志一看全是环境变量没配对。今天咱们先把地基打牢——把 SITL 仿真环境完整地搭起来。

一句话说清楚 SITL:SITL(Software In The Loop)就是在你电脑上跑一个虚拟的飞控,不需要任何硬件。它用你本机的 CPU 模拟 PX4 固件,通过 UDP/TCP 跟地面站、SDK 通信。说白了,你的笔记本电脑就是一台“虚拟无人机”。

1.1 SITL 到底能干什么?

我刚开始带团队时,有个同事直接拿真机调 PID,结果飞机翻了个跟头,桨叶全废了。从那以后,我定了个规矩:所有参数必须先过 SITL。它能帮你做三件事:

  • 逻辑验证:检查飞控代码有没有跑飞、状态机切换对不对
  • 参数预调:在虚拟环境里先把 PID、传感器融合参数调个大概
  • 故障注入:模拟 GPS 丢失、磁罗盘干扰、电机堵转——这些在真机上你不敢试

你想想看,如果 SITL 里电机都解锁不了,那真机大概率也起不来。所以这门课的第一个排查点,就是确保你的 SITL 环境是干净的。

1.2 安装 PX4-Autopilot

这是整个仿真的核心。我个人习惯把源码放在 ~/PX4-Autopilot 下,方便多个项目共用。

# 克隆 PX4 固件(建议用 v1.14 稳定版,我踩过 main 分支的坑)
git clone https://github.com/PX4/PX4-Autopilot.git --branch v1.14.3
cd PX4-Autopilot

# 安装依赖(Ubuntu 22.04 亲测)
make px4_sitl_default gazebo-classic

我曾经遇到过:直接 clone main 分支后,Gazebo 模型加载报错,折腾了两天才发现是版本不匹配。所以请务必用 release 标签,比如 v1.14.3 或 v1.13.2。

安装完成后,跑一下这个命令验证:

make px4_sitl_default gazebo-classic

如果看到终端里出现 INFO [commander] Ready for takeoff!,恭喜你,PX4 已经跑起来了。

1.3 安装 MAVSDK

MAVSDK 是我们用代码控制虚拟无人机的桥梁。我建议用 Python 版,调试起来最方便。

pip3 install mavsdk

验证安装:

python3 -c "import mavsdk; print(mavsdk.__version__)"

如果输出版本号(比如 3.0.0),说明装好了。嗯,这里要注意:MAVSDK 默认走 UDP 端口 14540,后面排查电机解锁时,端口对不对是第一个要查的。

1.4 安装 QGroundControl

地面站我推荐 QGC,它跟 PX4 配合最默契。下载 AppImage 文件后:

chmod +x QGroundControl.AppImage
./QGroundControl.AppImage

启动后,你应该能看到 SITL 自动连接上来,状态栏显示“Connected”。如果没连上,八成是端口被占用了——我遇到过好几次,关掉其他地面站就好了。

1.5 配置仿真环境变量

这是最容易出问题的地方。很多同学电机解锁失败,就是因为环境变量没设对。我整理了一个清单:

环境变量 作用 推荐值
PX4_SIM_MODEL 指定仿真机型 iris(四旋翼)
PX4_HOME_LAT 设置起飞点纬度 47.397742
PX4_HOME_LON 设置起飞点经度 8.545594
PX4_HOME_ALT 设置起飞点海拔 488.0
MAV_SYS_ID 飞控系统 ID 1

把这些加到你的 ~/.bashrc 里:

echo 'export PX4_SIM_MODEL=iris' >> ~/.bashrc
echo 'export PX4_HOME_LAT=47.397742' >> ~/.bashrc
echo 'export PX4_HOME_LON=8.545594' >> ~/.bashrc
echo 'export PX4_HOME_ALT=488.0' >> ~/.bashrc
echo 'export MAV_SYS_ID=1' >> ~/.bashrc
source ~/.bashrc

我的小技巧:如果你在调试多机协同,记得把 MAV_SYS_ID 改成不同的值,否则地面站会串数据。我曾经在演示时忘了改,两架虚拟飞机互相抢控制权,场面一度很尴尬。

1.6 验证整个链路

环境搭完,跑一个完整的启动流程:

  1. 打开终端,启动 SITL:make px4_sitl_default gazebo-classic
  2. 打开 QGC,确认连接状态
  3. 写一个简单的 MAVSDK 脚本,读取飞控版本
import asyncio
from mavsdk import System

async def run():
    drone = System()
    await drone.connect(system_address="udp://:14540")
    async for state in drone.core.connection_state():
        if state.is_connected:
            print(f"Connected to {state.uuid}")
            break

asyncio.run(run())

如果打印出 UUID,说明 PX4、MAVSDK、QGC 三者已经打通。这时候你再去解锁电机,成功率会高很多。

1.7 本章知识体系

下面这张图帮你理清 SITL 仿真环境的整体架构:

SITL 仿真环境架构图 PX4 SITL 固件 Gazebo 仿真引擎 MAVSDK 控制接口 QGroundControl 环境变量配置 SITL 通过 UDP 14540 与 MAVSDK 通信,通过 UDP 14550 与 QGC 通信

从这张图你能看到:PX4 SITL 是大脑,Gazebo 提供物理仿真,MAVSDK 是编程接口,QGC 是可视化监控。环境变量则是连接它们的“胶水”。任何一个环节断了,电机都解锁不了。

最后说一句:环境搭建别着急,一步一步来。我见过太多人跳过验证步骤,直接跑解锁脚本,然后回来问我为什么不行。先把基础打牢,后面 29 章你会轻松很多。