1. SITL仿真环境深度搭建:从源码编译ArduPilot SITL,配置自定义机型与传感器模型

各位同学,欢迎来到《进阶SITL仿真》的第一章。

做飞控开发,尤其是姿态调参,最怕什么?怕炸机。真机炸一次,几千块没了,还得提心吊胆查日志。所以我的习惯是——先在SITL里把参数跑透,再上真机。今天我们就从最底层开始,把SITL环境彻底搭明白。

1.1 为什么非要自己编译SITL?

很多人图省事,直接下载别人编译好的二进制文件。说实话,日常用用没问题。但你要做自定义机型、改传感器模型、甚至调底层姿态估计算法,没有源码在手,寸步难行。

我自己踩过这个坑。有一次想给四旋翼加一个非对称的载荷分布,结果二进制SITL根本不支持自定义混控器。折腾了两天,最后还是老老实实从源码编译。嗯,从那以后,我每换一台电脑,第一件事就是拉源码编译一遍。

核心观点:源码编译让你拥有对仿真环境的完全控制权。你可以修改任何一行C++代码,然后立刻看到效果。

1.2 环境准备:Ubuntu + 依赖库

我推荐用 Ubuntu 22.04 LTS。其他发行版也行,但依赖包名可能不一样,自己折腾去。

先把基础工具装上:

sudo apt update
sudo apt install git wget python3-pip python3-dev
sudo apt install build-essential pkg-config
sudo apt install libtool autoconf automake

然后是ArduPilot编译的核心依赖:

sudo apt install g++-arm-linux-gnueabihf
sudo apt install libc6-armhf-cross libc6-dev-armhf-cross
sudo apt install libpython3.10-dev

小技巧:如果你网络不好,建议先配好国内pip镜像。我习惯用清华源:pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

1.3 拉取源码与编译流程

找个干净的目录,开始拉代码:

git clone https://github.com/ArduPilot/ardupilot.git
cd ardupilot
git submodule update --init --recursive

这一步会下载所有子模块,包括MAVLink、DroneKit等。网络慢的话,可以分步执行:

  1. git submodule init
  2. git submodule update --recursive

接下来安装Python依赖:

pip install -r requirements.txt

然后编译SITL。以四旋翼为例:

./waf configure --board sitl
./waf build --target bin/arducopter

第一次编译大概要10-15分钟。别急,去泡杯咖啡。编译成功后,你会看到类似这样的输出:

Waf: Leaving directory `/home/user/ardupilot/build/sitl'
'build' finished successfully (12m 34s)

注意:如果编译报错,90%是依赖没装全。检查一下 g++-arm-linux-gnueabihf 和 libpython3.10-dev 是否真的装上了。我曾经因为少装了一个 libtool,卡了整整一下午。

1.4 启动你的第一个SITL实例

编译成功后,启动仿真:

cd ardupilot
./Tools/autotest/sim_vehicle.py -v ArduCopter --map --console

你会看到三个窗口弹出来:

  • 终端窗口:显示飞控启动日志
  • 地图窗口:显示飞机当前位置
  • 控制台:可以输入MAVLink命令

输入 arm throttle 解锁,然后推油门。飞机应该能飞起来了。如果不行,检查一下仿真时间是否在走——有时候系统时间同步问题会导致仿真卡住。

1.5 自定义机型:从零写一个混控器

这才是本章的重头戏。默认的SITL只支持标准四旋翼、固定翼等常见机型。但你要做姿态调参策略研究,往往需要奇奇怪怪的构型。

举个例子:我想做一个 X型四旋翼,但电机安装角度不是标准的45度,而是30度。怎么办?

找到混控器文件:libraries/AP_Motors/AP_MotorsMatrix.cpp

在 setup_motors() 函数里,添加你自己的机型:

// 自定义30度X型四旋翼
case MOTOR_FRAME_CUSTOM_X30: {
    add_motor(AP_MOTORS_MOT_1, -0.5,  0.5, 1.0, 1);  // 右前
    add_motor(AP_MOTORS_MOT_2,  0.5, -0.5, 1.0, 2);  // 左后
    add_motor(AP_MOTORS_MOT_3, -0.5, -0.5, 1.0, 3);  // 左前
    add_motor(AP_MOTORS_MOT_4,  0.5,  0.5, 1.0, 4);  // 右后
    break;
}

然后重新编译:

./waf build --target bin/arducopter

启动时指定机型:

./Tools/autotest/sim_vehicle.py -v ArduCopter --frame=custom_x30

关键点:混控器矩阵的四个参数分别是:Roll系数、Pitch系数、Yaw系数、电机编号。正负号决定旋转方向,数值大小决定力矩权重。

1.6 传感器模型配置:让仿真更真实

默认的SITL传感器太理想了。没有噪声,没有延迟,没有漂移。这会导致你在仿真里调好的参数,上真机就炸。

我建议你至少改三个地方:

传感器 默认参数 推荐修改值 说明
IMU加速度计 无噪声 SIM_ACCEL_NOISE=0.1 模拟真实加速度计噪声
IMU陀螺仪 无噪声 SIM_GYRO_NOISE=0.05 模拟真实陀螺仪噪声
GPS 理想定位 SIM_GPS_NOISE=1.0 模拟GPS水平误差1米
气压计 无延迟 SIM_BARO_DELAY=0.1 模拟气压计100ms延迟

这些参数可以在启动时通过 --sim-param 传入:

./Tools/autotest/sim_vehicle.py -v ArduCopter \
    --sim-param SIM_ACCEL_NOISE=0.1 \
    --sim-param SIM_GYRO_NOISE=0.05 \
    --sim-param SIM_GPS_NOISE=1.0

我的经验:先加小噪声,再慢慢加大。加太猛的话,你会发现飞机根本稳不住——那不是你PID的问题,是传感器太烂了。我一般从真机实测的噪声水平开始,然后上浮20%作为安全余量。

1.7 本章知识体系总览

下面这张图,帮你把整个SITL环境搭建的逻辑串起来:

SITL仿真环境搭建知识体系 SITL仿真环境搭建核心流程 环境准备 Ubuntu + 依赖库 源码获取 git clone + submodule 编译SITL waf configure + build 启动与验证 sim_vehicle.py + 解锁测试 自定义机型 修改混控器矩阵 传感器模型配置 噪声/延迟/漂移参数 目标:高保真自定义仿真环境 支持任意机型 + 真实传感器特性 注意 每次修改源码 必须重新编译

1.8 避坑指南

最后,分享几个我踩过的坑:

  • 子模块下载失败:国内网络经常连不上github。解决办法是用代理,或者提前把子模块的仓库clone好,手动放到对应目录。
  • 编译报错找不到头文件:检查一下 git submodule status,看看子模块是不是空的。我遇到过好几次子模块没拉全的情况。
  • 仿真启动后飞机不动:看看终端有没有报 EKF check fail。通常是传感器噪声设太大,或者GPS信号没模拟好。先关掉所有噪声,确认基础仿真能跑,再一点点加回去。
  • 自定义机型不生效:确认你修改的是 AP_MotorsMatrix.cpp 而不是 AP_MotorsMatrix.h。别问我怎么知道的...