2. ArduPilot基础
在开始编写 Lua 脚本之前,必须先理解 ArduPilot 这套飞控软件的整体结构。Lua 脚本并不是独立运行的程序,而是被“挂载”在 ArduPilot 主循环中的一段可执行逻辑。只有弄清楚飞控架构、固件类型、参数系统与飞行模式之间的关系,才能判断脚本应该在哪里介入、能读写哪些数据、以及何时被调度执行。
一、飞控架构:从传感器到执行器的分层
ArduPilot 的固件可以抽象为若干层:底层是硬件抽象层(HAL),负责屏蔽不同飞控板(如 Pixhawk、Cube、Matek)的芯片差异;其上是传感器驱动与姿态估计(EKF),把 IMU、磁力计、气压计、GPS 的数据融合成姿态与位置;再往上是控制律与导航层,把目标姿态、目标位置转换为电机或舵机输出;最上层是飞行模式与任务逻辑,决定“现在该听谁的指令”。
Lua 脚本运行在脚本引擎层,它通过绑定接口访问参数、传感器数据、飞行状态,并能调用部分控制与任务函数。它不直接操作寄存器,也不替代控制律,而是作为“策略层”的扩展,去实现自定义行为、条件判断和外部设备联动。
二、固件类型:不同载具,不同脚本能力
ArduPilot 按载具类型分为多旋翼(Copter)、固定翼(Plane)、无人车(Rover)、潜艇(Sub)、天线跟踪(AntennaTracker)等固件。它们共享大量底层代码,但飞行模式、参数命名和可用 Lua 绑定并不完全相同。例如 Copter 的 vehicle:set_mode() 与 Plane 的模式编号不同,脚本中不能混用。
此外,同一载具还有稳定版(Stable)、测试版(Beta)、最新开发版(Latest)之分。Lua 脚本引擎在较新固件中才逐步完善,部分绑定函数只在 4.3 及以上版本可用。因此写脚本前应确认固件版本与目标载具,避免调用不存在的接口。
| 固件类型 | 典型飞行模式 | Lua 常见用途 |
|---|---|---|
| Copter | Loiter、AltHold、Auto、Guided | 自定义返航条件、载荷投放、编队灯光 |
| Plane | FBWA、Cruise、Auto、Loiter | 航线中继、空投逻辑、发动机保护 |
| Rover | Manual、Auto、Guided、RTL | 避障策略、任务点动态调整 |
| Sub | Manual、AltHold、Auto、Guided | 深度保持、机械臂联动 |
三、参数系统:脚本读写飞控的“公共变量”
ArduPilot 的所有可配置项都以参数形式存在,例如 WPNAV_SPEED、RTL_ALT、FS_THR_ENABLE。参数有名称、索引、类型和默认值,地面站通过 MAVLink 读写。Lua 脚本同样可以读取和修改参数,这是脚本影响飞控行为最直接的方式。
-- 读取参数
local rtl_alt = param:get("RTL_ALT")
-- 修改参数(单位与范围需符合原参数定义)
param:set("RTL_ALT", 3000)
-- 判断参数是否存在
if param:get("MY_CUSTOM_PARAM") == nil then
gcs:send_text(0, "参数不存在")
end
四、飞行模式与 Lua 的介入时机
飞行模式决定了当前由谁控制载具:手动模式直接响应遥控器,Auto 模式执行任务,Guided 模式响应地面站指令,RTL 自动返航。Lua 脚本通常不直接“抢”控制权,而是通过监听模式变化、在特定模式下执行附加逻辑,或调用 vehicle:set_mode() 请求切换模式。
一个典型场景是:在 Auto 模式下,脚本持续读取电池电压,当低于阈值时自动切换到 RTL。脚本并不参与姿态控制,只做条件判断和模式请求,这样既安全又易于调试。
function update()
local mode = vehicle:get_mode()
local volt = battery:voltage(0)
if mode == 3 and volt < 21.0 then
vehicle:set_mode(6) -- 切换到 RTL
gcs:send_text(0, "低电压,触发返航")
end
return update, 1000
end
return update, 1000
五、案例与常见误区
假设要做一个“到达航点后打开相机”的脚本。正确做法是监听任务状态或使用 mission 相关绑定,在到达目标航点时触发一次动作,并设置标志位防止重复触发。常见误区包括:在 update() 中每 100ms 重复执行动作、未判断当前模式就修改参数、以及把脚本逻辑写得过于复杂导致主循环超时。
update() 函数应尽量短小,避免阻塞。耗时操作应拆分到多次调用中完成,或使用定时器控制频率。脚本执行时间过长会影响飞控主循环,进而影响飞行安全。
理解飞控架构、固件类型、参数系统和飞行模式之后,Lua 脚本的定位就清晰了:它是策略层的轻量扩展,通过参数和状态接口与飞控交互,在合适的模式下执行自定义逻辑。掌握这些基础,才能写出稳定、可维护、不干扰飞行安全的脚本。