1. 课程导入
ArduPilot 是当前开源无人机与无人车领域应用最广的飞控固件之一,支持多旋翼、固定翼、无人车、无人船等多种载具。它提供了丰富的飞行模式、传感器融合、导航控制与 MAVLink 通信能力。但在真实项目中,我们经常遇到固件原生功能无法直接覆盖的需求:例如按自定义条件触发任务、动态修改飞行行为、读取特殊传感器并参与控制、在飞行中执行自动化巡检逻辑等。传统做法是修改 C++ 源码并重新编译固件,门槛高、周期长、风险大。Lua 脚本能力的引入,正是为了解决这类“定制化但不必改动内核”的问题。
一、为什么选择 Lua:核心价值与原理
ArduPilot 内置了一个轻量级 Lua 解释器,脚本以文件形式存放在飞控 SD 卡或通过 MAVLink 上传,由固件在启动或运行过程中加载执行。脚本运行在飞控主循环之外的独立调度环境中,通过官方提供的绑定接口访问飞控内部对象,例如 ahrs、vehicle、motors、gcs、mission 等。这样既避免了重新编译固件,又能让脚本与飞控状态实时交互。
其价值可以归纳为三点:
- 低门槛定制:无需掌握完整 C++ 飞控架构,用脚本即可实现业务逻辑。
- 快速迭代:修改脚本后重新加载即可验证,不必反复烧录固件。
- 安全隔离:脚本运行在受控沙箱中,异常通常不会直接导致飞控崩溃,但仍需谨慎设计。
需要特别注意的是,Lua 脚本并不是“万能外挂”。它适合做逻辑编排、条件判断、数据转发和轻量控制,不适合替代底层姿态控制或高频实时环路。理解这一点,是后续所有实践的前提。
二、整体知识框架与学习路径
本课程共 30 章,围绕“环境准备 → 语言基础 → 飞控接口 → 自动化实战 → 调试与部署”的主线展开。下图展示了整体知识框架与学习路径,帮助你建立全局认知。
三、典型应用场景与最小示例
为了让你对“脚本能做什么”有直观感受,下面给出一个最小可运行示例。它的逻辑是:当载具解锁并进入 AUTO 模式后,每隔一段时间向地面站发送一条自定义状态消息。这段代码体现了脚本的基本结构:初始化、周期回调、条件判断与通信输出。
-- 最小示例:解锁后周期发送状态
local last_send = 0
function update()
if not arming:is_armed() then
return
end
local now = millis()
if now - last_send < 1000 then
return
end
last_send = now
gcs:send_text(6, "Lua active, mode=" .. vehicle:get_mode())
end
return update, 100 -- 每 100ms 调用一次 update
从这个例子可以看到几个关键点:脚本通过 return 返回回调函数与调度周期;使用 arming、vehicle、gcs 等对象访问飞控状态;通过 gcs:send_text 向地面站输出信息。这些接口将在后续章节逐一展开。
四、常见误区与学习复盘
初学者最容易陷入以下误区,提前了解可以少走弯路:
| 误区 | 表现 | 正确做法 |
|---|---|---|
| 把 Lua 当实时控制环 | 在脚本里做高频姿态控制 | 高频控制交给固件,脚本只做逻辑编排 |
| 忽略脚本调度周期 | 回调设置过小导致 CPU 占用高 | 按需求设置合理周期,通常 50~200ms |
| 直接上真机测试 | 未仿真验证就解锁飞行 | 先 SITL 仿真,再拆桨地面测试 |
| 不处理异常分支 | 传感器无效时脚本报错中断 | 增加 nil 判断与状态检查 |
当你完成本课程后,应当具备独立编写、调试和部署 ArduPilot Lua 脚本的能力,能够把重复性操作、条件触发逻辑和定制化通信需求转化为可靠的脚本自动化方案。接下来,我们将从环境准备与固件支持开始,一步步进入 Lua 脚本开发的世界。