ArduPilot 开源飞控完整指南:一套代码如何驱动无人机、飞机与机器人
【免费下载链接】ardupilotArduPlane, ArduCopter, ArduRover, ArduSub source项目地址: https://gitcode.com/GitHub_Trending/ar/ardupilot
ArduPilot 是开源自动驾驶飞控软件,2010 年起持续演进,让多旋翼、固定翼、地面车、水下机器人共用同一套控制代码自动飞行。本文帮你 10 分钟建立整体认知,并给出从 SITL 仿真到硬件编译的最短上手路径。
自研飞控有多难?ArduPilot 替你接住三件事
当你想让一架四轴无人机稳定悬停时,要自己写的不只是"电机转多快"。你至少得处理三件事:
- 传感器读数互相矛盾。陀螺仪会漂移,气压计怕风吹,GPS 有抖动——单独信任何一个都不行。
- 控制必须快。姿态环每秒要计算几百次,晚几毫秒飞机可能就翻了。
- 出错时必须有兜底。遥控信号断了、指南针坏了,系统要自己决定是返航还是降落。
ArduPilot 的思路是把这三件事拆到不同层,各写一次、全平台复用:底层是硬件抽象层(HAL,即让上层代码"不知道底下是什么芯片"的接口层),中间是共享的滤波、导航、安全库,最上面才是一架架载具自己的逻辑。所以你在仓库里会看到 ArduCopter/、ArduPlane/、Rover/、ArduSub/ 几个目录并列,但它们背后调的是同一批libraries/里的模块。
这张四轴示意图对应 ArduCopter 形态:四个电机分别控制滚转、俯仰、偏航与升力,正是下一节要拆解的控制对象。
硬件抽象、EKF 融合与实时调度:核心机制拆解
硬件抽象层:换个芯片不改算法
所有串口、SPI、I2C、PWM、存储访问都收在 libraries/AP_HAL/ 及其各平台实现(如 libraries/AP_HAL_ChibiOS/)里。每块飞控板有一份硬件定义(hwdef),写明引脚怎么接、时钟怎么配,文件在 libraries/AP_HAL_ChibiOS/hwdef/。适配新板子的成本就集中在这份定义上,控制算法一行不用动。
这是 AEDROX H7 飞控板的引脚图:电机、串口、CAN、I2C 各占哪些脚一目了然,正是 hwdef 文件在纸面上的样子。
有些平台还会做物理拆分。下图中 CM4Pilot 由左侧 FMU(飞行管理单元,管实时控制)和右侧 CM4(计算模块,跑相机、视觉等非实时任务)两块板组成,两者经 USB/SD 通信:实时性任务和算力需求被物理隔开,互不抢占。
EKF:把一堆噪声读数融成一份可信状态
系统用一种叫扩展卡尔曼滤波(EKF,一种"用统计方法不断修正估计值"的算法)的做法,把惯性测量单元(IMU,测角速度与加速度)、GPS、气压计、磁力计的读数融合成一份姿态、位置、速度估计。实现见 libraries/AP_NavEKF3/,另有 libraries/AP_NavEKF/ 等可选版本。设计动机很实际:任何一个单传感器都会漂、会坏,滤波器同时盯着它们的方差,谁的数据开始不可信就降低它的权重。
调度器与姿态环:谁在什么时候跑
libraries/AP_Scheduler/ 让每个控制任务按固定频率注册执行:姿态环最高频,导航、日志、通信依次降频。高优先级任务保证准时跑完,低优先级任务让路。这层之上,libraries/AC_AttitudeControl/ 里的 PID 控制器把"想要的姿态"和"当前姿态"的差值变成扭矩指令,libraries/AP_Motors/ 再把总扭矩分配给每个电机,输出 PWM。链路是:传感器 → EKF 状态 → 姿态 PID → 电机混合,整条在毫秒级闭环。
多形态差异:同一套代码,四种载具行为
各平台共享传感器融合与调度核心,但"怎么动"完全不同:
| 载具 | 代码目录 | 核心控制逻辑 | 特色模块 |
|---|---|---|---|
| 多旋翼 ArduCopter | ArduCopter/ | 油门直接产生升力,可悬停 | 起飞检测、翻转、自动调参 |
| 固定翼 ArduPlane | ArduPlane/ | 不能停,靠速度换高度,用 TECS(总能量控制)协调空速与高度 | 自动着陆、降落伞、四旋翼复合翼 |
| 地面车 Rover | Rover/ | 控制转向角与巡航速度,支持自学习 | 平衡车、帆船模式 |
| 水下 ArduSub | ArduSub/ | 油门控垂直方向,水线浮力靠 Surface 模式平衡 | 底部检测、水线跟踪 |
这是 ArduPlane 的仿真渲染:固定翼离地后必须保持最低速度,因此它的自动模式逻辑与多旋翼的"悬停-升降"是两套写法。
任务航线由 libraries/AP_Mission/ 统一解析,导航库(如 libraries/AC_WPNav/)则按载具类型给出不同的"到达航点"判定——这是"共享核心、平台差异"的典型例子。
安全机制如何防止炸机:解锁预检与故障应急
🧭 ArduPilot 把安全做成了一道道关卡,而不是一个开关:
- 解锁预检:电机锁定在 libraries/AP_Arming/ 与各平台实现(如 ArduCopter/AP_Arming_Copter.cpp)中,IMU、罗盘、电池、气压等任一不达标就不让解锁,GCS 端会看到具体原因。
- 失效保护(failsafe):每个平台有独立的
failsafe.cpp。遥控信号丢失、GPS 丢失、电量过低会分别触发不同响应——多旋翼通常是自动 RTL(返航)或降落,固定翼倾向继续飞完航点再返航,因为固定翼不能像多旋翼那样直接停下。 - 地理围栏:libraries/AP_Fence/ 的 AC_Fence 在飞机越出设定范围(圆形、多边形或高度)时强制干预,是人为判断失误时的最后防线。
- 极端手段:ArduPlane 提供降落伞(ArduPlane/parachute.cpp),触发后放弃飞机保载荷与人员。
对你来说要注意两条:解锁前逐项处理 GCS 报出的预检失败,不要盲目强制解锁;围栏参数要在首飞前设好,它只在"你忘了"时救你,不替你做规划。
五步跑通 ArduPilot:从克隆到 SITL 仿真
🔧 最短实践路径如下,全程不需要硬件:
- 克隆仓库(记得带子模块,HAL 和 MAVLink 都在子模块里):
git clone --recurse-submodules https://gitcode.com/GitHub_Trending/ar/ardupilot - 配置并编译仿真版:
./waf configure --board sitl然后./waf copter,产出物是 build 目录下的可执行文件。 - 用 Tools/autotest/ 下的
sim_vehicle.py启动软件在环(SITL,把整个飞控跑在 PC 仿真器里)仿真,它会自动拉起载具进程并连上地面站。 - 在地面站里观察:切换模式、解锁、起飞、执行一条简易航线,确认日志正常。
- 想上真机时,用
./waf list_boards查支持的板子,换--board重新编译,再对照该板的 hwdef 接好传感器烧录。
读代码建议从 ArduCopter/Copter.cpp 的初始化流程进,顺着 scheduler 注册的任务逐个点开,比从目录列表硬读快得多。
ArduPilot 用"HAL 隔离硬件、EKF 融合感知、调度器保证实时、预检与围栏兜底"四层回答了一个问题:同一套代码如何安全地飞起五种完全不同的载具。下一步建议:跑通上面的 SITL 五步,再打开 BUILD.md 查更多编译选项,遇到具体问题到 ArduPilot 官方支持论坛搜索或提问。
【免费下载链接】ardupilotArduPlane, ArduCopter, ArduRover, ArduSub source项目地址: https://gitcode.com/GitHub_Trending/ar/ardupilot
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考