1. ArduPilot概述与环境搭建

各位同学,欢迎来到《ArduPilot系统化实战训练》的第一章。

说实话,我接触ArduPilot快十年了。从当年在实验室里折腾APM 2.5板子,到现在用Pixhawk跑各种载具,这中间踩过的坑、烧过的板子,真不少。今天咱们就从根上把ArduPilot聊透,再手把手把开发环境搭起来。

1.1 ArduPilot发展史:从航模到工业级

ArduPilot最早是2010年左右由一群航模爱好者发起的。那时候多旋翼刚火起来,大家用的还是Arduino Mega加MPU6050这种组合。我记得最早期的代码量才几万行,跟现在完全没法比。

后来呢?2013年,3DRobotics推出了Pixhawk硬件,ArduPilot正式进入Pixhawk时代。2015年之后,ArduPilot从单纯的飞控,变成了一个支持多旋翼、固定翼、直升机、无人车、无人船、甚至潜艇的通用自动驾驶平台。

现在ArduPilot的代码量已经超过100万行,支持几十种硬件平台。你想想看,一个开源项目能走到这一步,靠的可不是运气。

核心里程碑:

  • 2010年:ArduPilot诞生,基于Arduino平台
  • 2013年:Pixhawk硬件发布,代码迁移至STM32
  • 2015年:支持固定翼、多旋翼、无人车三大载具
  • 2018年:ChibiOS实时系统引入,性能大幅提升
  • 2020年至今:支持无人船、潜艇,进入工业级应用

1.2 核心架构:你写的代码跑在哪一层?

很多新手一上来就盯着代码看,结果被一堆文件夹搞晕了。我建议你先理解架构,再看代码。

ArduPilot的架构,说白了就是三层:

  1. 硬件抽象层(HAL):把不同硬件(STM32、Linux、SITL)的差异封装起来。你写上层代码时,根本不用管底层用的是I2C还是SPI。
  2. 核心库层(AP_XXX):各种功能模块,比如AP_InertialSensor(IMU驱动)、AP_GPS(GPS解析)、AP_Math(数学工具)。这些库是跨载具通用的。
  3. 载具层(ArduCopter / ArduPlane / Rover):每个载具的主循环逻辑。比如多旋翼的混控输出、固定翼的舵面控制,都在这一层。

嗯,这里要注意:你如果想二次开发,大部分时间都在改载具层和核心库层。HAL层基本不用动。

ArduPilot 核心架构分层图 载具层(Vehicle Layer) ArduCopter | ArduPlane | Rover | Sub | Boat 核心库层(Core Library Layer) AP_InertialSensor | AP_GPS | AP_Math | AP_NavEKF AP_Motors | AC_AttitudeControl | AP_Logger 硬件抽象层(HAL Layer) HAL_ChibiOS | HAL_Linux | HAL_SITL 物理硬件(Pixhawk / Linux / SITL) 越往上越接近用户逻辑,越往下越接近硬件

1.3 硬件选型:Pixhawk与Here+

做项目第一步就是选硬件。我见过太多人上来就买最贵的板子,结果发现根本用不上。咱们务实一点。

Pixhawk系列怎么选?

型号 处理器 IMU 适合场景
Pixhawk 1 STM32F427 MPU6000 + LSM303D 入门学习、小型无人机
Pixhawk 4 STM32F765 ICM20689 + BMI055 中型多旋翼、工业应用
Cube Orange+ STM32H753 ICM20948 + ICM20649 高端科研、自动驾驶
Pixhawk 6X STM32H753 ICM20948 + BMI088 最新旗舰、冗余设计

我个人习惯是:新手先用Pixhawk 4,性价比最高。等你要做高可靠性项目了,再上Cube或6X。

Here+ GPS:为什么推荐它?

Here+是ArduPilot生态里最成熟的RTK GPS模块。我在项目里用过好几款GPS,Here+的RTK Fix速度是最快的,一般30秒内就能收敛到厘米级精度。

它用的是u-blox M8P芯片,支持GPS+GLONASS双频。注意,Here+有V1和V2两个版本,V2的电磁兼容性更好,建议直接上V2。

避坑指南: 我曾经遇到过GPS天线安装位置不对,导致RTK一直Float的情况。后来发现是天线离电机太近,电磁干扰太强。记住:GPS天线要远离电机和电源模块,最好装在机臂末端或者机顶中央。

1.4 开发环境搭建:Ubuntu + MAVSDK

环境搭建是很多人放弃的第一步。别怕,跟着我来,半小时搞定。

第一步:安装Ubuntu 22.04 LTS

我建议用双系统或者虚拟机。WSL2也行,但有些硬件调试工具在WSL2下会有问题。如果你只是做SITL仿真,WSL2完全够用。

第二步:安装编译工具链

# 更新系统
sudo apt update && sudo apt upgrade -y

# 安装基础工具
sudo apt install -y git build-essential cmake python3 python3-pip

# 安装ARM交叉编译器(编译Pixhawk固件用)
sudo apt install -y gcc-arm-none-eabi gdb-arm-none-eabi

# 安装SITL依赖
sudo apt install -y libtool libltdl-dev libsdl2-dev libsdl2-image-dev

第三步:克隆ArduPilot源码

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

这里有个坑:submodule更新很慢,因为要下载很多第三方库。我建议你挂个代理,或者直接用国内镜像。

第四步:安装MAVSDK

MAVSDK是ArduPilot的官方SDK,用来写地面站或者控制程序。我习惯用Python版本,开发效率高。

pip3 install mavsdk

# 验证安装
python3 -c "import mavsdk; print(mavsdk.__version__)"

第五步:运行SITL仿真

环境搭好了,先跑个仿真试试手。

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

看到MAVProxy的提示符,说明环境搭建成功了。你可以用键盘控制无人机起飞、悬停、降落。

注意: SITL仿真默认使用UDP 14550端口。如果你同时开了Mission Planner或者QGroundControl,记得改端口,否则会冲突。我一般用14551给地面站,14550留给MAVSDK。

1.5 第一个MAVSDK程序:连接与心跳

环境搭好了,咱们写个最简单的程序,验证MAVSDK能不能正常工作。

import asyncio
from mavsdk import System

async def run():
    drone = System()
    await drone.connect(system_address="udp://:14550")
    
    print("等待无人机连接...")
    async for state in drone.core.connection_state():
        if state.is_connected:
            print(f"已连接到无人机!")
            break
    
    print("获取无人机版本...")
    version = await drone.info.get_version()
    print(f"固件版本: {version.firmware_version}")
    print(f"硬件类型: {version.product_name}")

if __name__ == "__main__":
    asyncio.run(run())

这段代码做了三件事:连接无人机、等待心跳、打印版本信息。你把它跑起来,如果能看到版本号,说明整个环境链路都是通的。

好了,第一章就到这里。环境搭好了,后面咱们就能真刀真枪地写代码了。