ArduPilot Lua 脚本自定义指令系统完整指南:不动固件跑通第一条脚本
【免费下载链接】ardupilotArduPlane, ArduCopter, ArduRover, ArduSub source项目地址: https://gitcode.com/GitHub_Trending/ar/ardupilot
想给飞控加功能,难道只能改核心固件重新编译?ArduPilot 自定义指令系统(Lua 脚本引擎)就是为解决这个问题存在的:把一个.lua文件放进飞控,就能读传感器、切模式、执行自己的逻辑,不用动一行固件。
📦 Lua 脚本引擎到底在做什么
可以把 AP_Scripting 模块 理解成飞控里装了一台"小型解释器":它负责加载脚本、给脚本分配内存、把脚本线程挂在低优先级上跑,并通过绑定接口(vehicle、ahrs、params、gcs这些对象)让脚本安全地读写飞控状态。你写的脚本不会和飞控主循环抢 CPU——每个脚本单轮能执行的虚拟机指令数有上限,超了会被"叫停",所以就算脚本写得差,也不至于拖垮姿态控制。
脚本的开关和边界全部由SCR_前缀参数控制(源码定义见 AP_Scripting.cpp),常用 6 个:
| 参数名 | 作用 | 建议值 |
|---|---|---|
| SCR_ENABLE | 脚本系统总开关,1=启用 Lua | 1(改后需重启) |
| SCR_HEAP_SIZE | 分配给脚本的堆内存,1KB~1MB | 默认即可;脚本报内存不足时加到 80000+ |
| SCR_VM_I_COUNT | 单轮 VM 指令上限,防脚本占满 CPU | 默认 10000;长脚本调到 100000~200000 |
| SCR_DEBUG_OPTS | 调试位掩码:bit1 打印内存/耗时,bit5 记录脚本校验和 | 调试期设 1,交付前清 0 |
| SCR_THD_PRIORITY | 脚本线程优先级,默认故意设低 | 保持默认 0,别乱抬 |
| SCR_LD_CHECKSUM | 起飞前校验已加载脚本,不匹配禁止解锁,-1=关 | 部署稳定后填入计算值 |
🚁 脚本能直接帮你干成的 3 件事
以下 3 个方向都来自仓库里现成的 applet(libraries/AP_Scripting/applets/,每个都附带.md说明,改个名拷走就能用)。
用通道切脚本:一套飞机多种行为
- 目标:不重传文件,只靠遥控器通道或 GCS 在几组脚本间热切换,比如"作业模式"和"返航护航模式"各挂一个脚本。
- 做法:参考
Script_Controller.lua的套路,脚本里用rc:channel()读通道值决定加载哪个脚本,切换由控制器脚本统一接管,旧脚本先干净退出再加载新的。 - 关键参数:
SCR_ENABLE=1;通道映射用遥控器自身的 AUX 通道设置,不涉及 SCR 参数。
参数上锁:防止远程误改
- 目标:机器交付后,禁止任何人通过 GCS 远程改关键参数(PID、围栏阈值),但本地地面调试不受影响。
- 做法:
param-lockdown.lua会拦截参数写入请求并回 GCS 消息,用一个PARAM_LOCK_ENAB开关随时解除锁定。 - 关键参数:
SCR_ENABLE=1、PARAM_LOCK_ENAB=1;文档提示 ArduPilot 4.7 及以上才建议启用。
电池容量估算:把"标称容量"变成实测值
- 目标:标称容量和老化后的真实容量往往对不上,影响航程判断和降落电量。
- 做法:
BattEstimate.lua在飞行中持续采样电压与电流,落地后把累计放电量写入 DataFlash 日志,几架次下来就能校准真实容量。 - 关键参数:开启对应日志的
LOG_BITMASK位,SCR_HEAP_SIZE保持默认即可(脚本本身很轻)。
第一条 ArduPilot 脚本跑通步骤
- 确认固件带脚本引擎:AP_Scripting_config.h 里,程序空间上限超过 1MB 的构建自动开启脚本支持——ArduCopter、ArduPlane 等标准构建都包含;先在 SITL 模拟器里验证最稳妥(模拟器的脚本放在启动目录下的
scripts/文件夹)。 - 启用:地面站把
SCR_ENABLE设为 1,重启飞控。 - 传脚本:把
.lua文件拷进 SD 卡的APM/scripts/目录(固件启动时会自动建这个目录)。 - 验证:看 GCS 控制台以
Lua:开头的消息——加载成功、报错都会在这里打出来。
需要自己编译时,只跑这一段命令:
git clone https://gitcode.com/GitHub_Trending/ar/ardupilot cd ardupilot Tools/environment_install/install-prereqs-ubuntu.sh -y✅ 参数、性能与安全清单
- 内存:GCS 里看到 "Required SCR_HEAP_SIZE over xxx" 提示就按提示值上调,改后重启。
- 垃圾回收:长时运行脚本里定期调用
collectgarbage(),别等内存吃满。 - 高频回调:用协程返回值控制节奏(
return update, 100表示每 100ms 执行一次),重计算别塞进 100ms 级的循环。 - 调试日志:
SCR_DEBUG_OPTS设 1 可看每个脚本的内存与耗时,定位慢脚本后再归 0。 - SITL 先行:任何新脚本先在模拟器飞一遍,确认不报 "Lua:" 错误再上实机。
- 校验和:部署稳定后用
SCR_LD_CHECKSUM/SCR_RUN_CHECKSUM锁住脚本内容,防止 SD 卡被换、脚本被改。 - 目录开关:
SCR_DIR_DISABLE的 bit1 会关闭APM/scripts目录加载——"脚本没生效"时别漏查它。
脚本没生效?按这个顺序排查
Q:脚本放了但没跑,先查什么?顺序是:SCR_ENABLE是否为 1 且已重启 → 文件扩展名是不是.lua、有没有在APM/scripts/→ GCS 控制台搜Lua:开头的报错 →SCR_DIR_DISABLE是否把目录禁了。
Q:参数改完要不要重启飞控?SCR_ENABLE、SCR_HEAP_SIZE、SCR_THD_PRIORITY、SCR_DIR_DISABLE标注了 RebootRequired,必须重启;SCR_USER1~6、SCR_DEBUG_OPTS这类运行时参数不用。
Q:脚本跑挂会拖垮飞控吗?单轮指令数被SCR_VM_I_COUNT封顶,线程默认最低优先级,脚本异常会被捕获并以Lua:报错显示——它更可能是"不工作"而不是"炸机",但逻辑错误仍可能影响飞行行为,所以坚持 SITL 先行。
Q:任务(Mission)里的 DO SCRIPTING 指令和脚本什么关系?任务项下发脚本启动命令后,AP_Mission 会把脚本挂到任务执行链上,脚本跑完该任务项才算完成,这就是"自定义指令"进入任务规划的标准入口。
下一步:从 libraries/AP_Scripting/examples/ 挑一个最简单的脚本(如hello_world.lua)拷进APM/scripts/,在 SITL 里把第一条Lua:日志跑出来;想直接上功能,翻一遍 applets 目录 的.md说明,多数脚本改几个参数就能装机。更多问答可去 ArduPilot 社区论坛(Discourse)的 Scripting 板块。
【免费下载链接】ardupilotArduPlane, ArduCopter, ArduRover, ArduSub source项目地址: https://gitcode.com/GitHub_Trending/ar/ardupilot
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考