4. 联合仿真测试的意义
好,咱们进入实战环节。前面几章把环境搭好了,概念也理清了,现在该让代码跑起来了。这一章我带你走一遍 ArduPilot SITL 的完整流程——从源码编译到起飞测试。
说实话,我第一次搞 SITL 时也踩了不少坑。编译报错、端口冲突、飞机死活不听话……这些我都经历过。所以这一章我会把关键节点和避坑点都给你点出来。
本章核心目标:在本地运行一架虚拟的四旋翼,通过 MAVProxy 连接它,然后发送起飞、悬停、降落指令,验证整个仿真链路是否通畅。
4.1 编译 ArduPilot SITL 固件
ArduPilot 的 SITL 本质上是一个在 PC 上运行的模拟固件。它用本机的计算资源模拟飞控硬件,跑的是和真实飞控一模一样的代码。
编译过程其实很简单,但有几个细节要注意。
4.1.1 获取源码与切换分支
如果你按我上一章的指引操作,源码应该已经 clone 到 ~/ardupilot 目录下了。我个人习惯用 Copter-4.5 分支,这个版本比较稳定,文档也全。
cd ~/ardupilot
git checkout Copter-4.5
git submodule update --init --recursive
嗯,这里有个坑——submodule update 这一步很容易因为网络问题卡住。我建议你提前配好 Git 代理,或者用国内镜像源。我曾经在客户现场演示时,网络不好,submodule 拉不下来,场面一度很尴尬……
4.1.2 执行编译
ArduPilot 用 waf 作为构建系统。编译 SITL 只需要一条命令:
./waf configure --board sitl
./waf copter
这里解释一下:
--board sitl指定目标板为 SITL 模拟器copter是目标固件类型,你要编译固定翼就换成plane
第一次编译会比较慢,大概 10-20 分钟,取决于你的机器配置。编译完成后,你会在 build/sitl/bin 目录下看到 arducopter 这个可执行文件。
小技巧:如果你只想测试,不想等编译,可以直接用 ArduPilot 官方提供的预编译 SITL 二进制文件。但我还是建议你走一遍编译流程——后面调试代码时你会感谢自己的。
4.2 启动 SITL 仿真
编译好了,咱们启动它。
4.2.1 基本启动命令
最简单的启动方式:
cd ~/ardupilot
sim_vehicle.py -v ArduCopter --map --console
这条命令做了三件事:
- 启动 SITL 固件(默认四旋翼模型)
- 打开 MAVProxy 控制台(
--console) - 打开地图窗口(
--map)
启动后你会看到控制台里刷出一堆参数,最后出现 Ready to fly 字样。这时候虚拟飞控已经跑起来了,默认在 UDP:127.0.0.1:14550 端口监听 MAVLink 连接。
注意:如果你之前启动过 SITL,可能会遇到端口占用错误。用 lsof -i :14550 查一下,把旧进程 kill 掉再试。我有一回忘了关之前的仿真,折腾了十分钟才发现是端口冲突……
4.2.2 常用启动参数
实际项目中,我很少用裸启动命令。下面这个表格是我常用的参数组合:
| 参数 | 作用 | 示例 |
|---|---|---|
--vehicle |
指定机型 | --vehicle ArduCopter |
--frame |
指定机架类型 | --frame quad |
--map |
显示地图窗口 | --map |
--console |
显示 MAVProxy 控制台 | --console |
--out |
额外输出 MAVLink 到指定地址 | --out 192.168.1.100:14550 |
--speedup |
仿真倍速(默认 1x) | --speedup 10 |
举个例子,如果你想启动一架四旋翼,并且把 MAVLink 数据同时发给地面站和另一个调试工具:
sim_vehicle.py -v ArduCopter -f quad --map --console --out 127.0.0.1:14551
4.3 通过 MAVProxy 连接与控制
SITL 启动后,MAVProxy 控制台就是你的主战场。说白了,它就是一个命令行版的 Mission Planner,所有操作都可以通过键盘完成。
4.3.1 确认连接状态
在 MAVProxy 控制台输入 status,你会看到类似这样的输出:
AP: ArduCopter V4.5.0 (e1f2c3d4)
Frame: QUAD
GPS: 3D Fix (2.0m)
Battery: 12.5V 100%
Mode: STABILIZE
Armable: YES
看到 Armable: YES 就说明一切正常。如果显示 Armable: NO,检查一下是不是有传感器报错或者参数没配好。
4.3.2 解锁与起飞
好,现在让飞机飞起来。MAVProxy 里操作很简单:
# 切换到 GUIDED 模式(这样才能用指令控制)
mode guided
# 解锁电机
arm throttle
# 起飞到 10 米高度
takeoff 10
你会看到地图上的飞机图标开始上升,控制台里高度数值在增加。等高度稳定在 10 米左右,飞机就悬停住了。
个人经验:第一次起飞时,我建议把 --speedup 1 加上,用实时速度跑。这样你能直观感受飞机的响应。等熟悉了再开 10 倍速跑长航时测试。
4.3.3 基础飞行指令测试
飞机悬停在空中了,咱们试试几个常用指令:
| 指令 | 作用 | 示例 |
|---|---|---|
rc 3 1500 |
设置油门通道(1000-2000) | rc 3 1600 增加油门 |
mode loiter |
切换到 Loiter 模式(定点悬停) | mode loiter |
mode rtl |
切换到 RTL 模式(自动返航) | mode rtl |
land |
原地降落 | land |
set param |
修改飞控参数 | set param ARMING_CHECK 0 |
试试这个流程:
- 起飞到 10 米
- 用
mode loiter切换到定点模式,观察飞机是否稳定 - 用
rc 3 1500把油门回到中位 - 用
mode rtl触发返航,看飞机是否自动飞回起飞点并降落
为什么会先切换到 Loiter?因为 GUIDED 模式下飞控完全听你指令,Loiter 模式会自己维持位置和高度,更接近真实飞行场景。我一般测试时都会先切 Loiter 确认 GPS 定位没问题。
4.4 核心流程梳理
这一套流程走下来,你其实已经完成了 ArduPilot SITL 的完整闭环。下面这张图帮你把整个链路串起来:
4.5 常见问题与避坑
走完上面的流程,你大概率会遇到一些问题。我把最常见的几个列出来:
问题1:编译报错 "Python module not found"
原因:缺少 MAVProxy 或 dronekit 等 Python 依赖。解决:pip install mavproxy dronekit。我曾经在 Ubuntu 20.04 上遇到过 Python 3.8 和 3.10 混装导致的依赖冲突,最后用虚拟环境解决的。
问题2:启动后飞机显示 "Bad GPS"
原因:SITL 默认模拟 GPS,但有时仿真时间同步有问题。解决:在 MAVProxy 里输入 module load sim 然后 sim_opt gps_disable=0 重新启用。或者直接忽略——SITL 的 GPS 模拟不影响飞行测试。
问题3:takeoff 指令后飞机不上升
原因:最常见的是没有先切 GUIDED 模式。另一个可能是 ARMING_CHECK 参数阻止了解锁。解决:set param ARMING_CHECK 0 临时关闭安全检查。注意,这只是为了测试,真机千万别这么干。
4.6 本章小结
这一章我们走通了 ArduPilot SITL 的完整链路:编译 → 启动 → 连接 → 起飞 → 指令测试。你现在应该能在自己的电脑上跑起一架虚拟四旋翼,并且通过 MAVProxy 控制它飞行了。
说实话,SITL 的价值远不止于「让飞机飞起来」。它是你后面做协同仿真、调参、算法验证的基础。我当年做无人机编队项目时,80% 的调试工作都是在 SITL 里完成的——真机上天一次成本太高了。