ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

给 ArduPilot 加一块“外挂大脑”:用 Lua 自定义指令扩展飞控功能的实战指南

给 ArduPilot 加一块“外挂大脑”:用 Lua 自定义指令扩展飞控功能的实战指南 给 ArduPilot 加一块“外挂大脑”用 Lua 自定义指令扩展飞控功能的实战指南【免费下载链接】ardupilotArduPlane, ArduCopter, ArduRover, ArduSub source项目地址: https://gitcode.com/GitHub_Trending/ar/ardupilot你的任务需求固件里可能早就写死了。想让悬停高度在特定条件下微调、想在电池电压跌破阈值时提前报警、想把一条特殊的轨迹编进自动任务——这些想法如果都要改 C 源码重新编译门槛实在太高。好在 ArduPilot 的自定义指令系统给了另一条路不碰核心固件只用 Lua 脚本就能改变飞行器的行为。这套基于 Lua 脚本的飞控功能扩展机制支持多旋翼、固定翼、车、潜几乎覆盖全部机型。下面按“先跑通、再理解、后实战”的顺序走一遍。把第一条脚本送上飞控最短路径硬件上先确认一点你的飞控芯片要有足够多的闪存官方规则是闪存大于 1MB 的板子STM32F7/H7 系列如 Pixhawk 4、CubeBlack在编译时会自动带上脚本支持无需额外配置。准备环境克隆仓库并安装依赖即可git clone https://gitcode.com/GitHub_Trending/ar/ardupilot cd ardupilot Tools/environment_install/install-prereqs-ubuntu.sh -y启用脚本系统是三个动作用地面站如 Mission Planner把SCR_ENABLE从 0 改成 1重启飞控然后把你的.lua文件放进 SD 卡的APM/scripts目录。开机时飞控会自动扫描这个目录把里面所有 Lua 脚本逐一加载执行。如果先用 SITL 模拟器做验证脚本则放在 ardupilot 主目录下的scripts文件夹里。放一个最小示例进去重启后看地面站控制台每隔两秒弹出一句提示说明链路已通-- 心跳脚本验证脚本系统是否工作 function heartbeat() gcs:send_text(1, Lua scripting is alive) return heartbeat, 2000 -- 每 2 秒重复一次 end return heartbeat, 2000引擎在哪预算给多少理解脚本执行机制脚本引擎的实现在 libraries/AP_Scripting/ 模块里Lua 5.3.6 的源码就内嵌在这个目录下。它单独占一条线程运行默认优先级设得很低——意思是你的脚本再“忙”也不会把飞行控制的实时任务挤到后面去。有三个参数值得结合流程理解而不是死记SCR_HEAP_SIZE给脚本分配的堆内存。默认值按平台分档SITL、Linux 和 1MB 以上内存的板子是 200KB500KB 级板子 100KB再小的板子只有 43KB。改了要重启才生效。SCR_VM_I_COUNT是虚拟机指令执行上限默认 10000。每次回调函数被允许执行的虚拟指令条数超过这个预算就被判定为耗时过多而中止——相当于给死循环上了保险丝。遇到“脚本被掐断”的报错先想到调它。SCR_THD_PRIORITY控制脚本线程优先级默认是 Normal最低档。官方参数说明里写得很直白除非你的应用有实时性需求否则保持最低档调高可能影响飞控整体稳定性。另外地面站里改完 SCR_ENABLE 记得刷新参数再重启这是新手最容易漏的一步。场景一写一条自己的圆形轨迹要解决什么固件自带的 Loiter/轨道模式参数有限你想按任意半径画圈。用到的 APIahrs:get_yaw()拿当前航向角vehicle:set_target_position()下发位置点。原理是把航向角当圆心角算出圆周上的目标坐标。-- 圆形轨迹飞行半径 10 米离地 5 米 function circle_update() local angle ahrs:get_yaw() local radius 10 -- 半径米 local x radius * math.cos(angle) local y radius * math.sin(angle) vehicle:set_target_position(x, y, 5) return circle_update, 100 -- 每 100ms 更新一次 end return circle_update, 100如何验证先在 SITL 里以 Auto 模式起飞观察地图页飞行器是否沿预期半径绕圈再看 DataFlash 日志里位置消息是否连续下发。场景二电池电压的自定义监视要解决什么低电压报警的阈值和动作完全由你定不受固定逻辑约束。用到的 APIbattery:voltage()读总压gcs:send_text()往地面站推消息。-- 电池监视低于 10.5V 持续报警 function battery_watch() local volt battery:voltage() if volt 10.5 then gcs:send_text(0, Voltage low: .. string.format(%.2f, volt)) -- 报警之后可在此衔接自动返航等逻辑 end return battery_watch, 1000 -- 每秒检查一次 end return battery_watch, 1000如何验证地面站控制台应每秒轮询一次SITL 里可用参数把模拟电压拉低确认消息等级0 为最高严重级按预期弹出。场景三接住任务里自定义的指令要解决什么自动任务中插入一条固件不认识、但脚本能处理的指令。用到的 API任务指令处理机制。脚本侧响应自定义指令 ID地面站端在任务中写入对应编号。指令如何进入脚本这条链路实现在 libraries/AP_Mission/AP_Mission_Commands.cpp 的start_command_do_scripting一带值得翻一遍源码。-- 响应自定义任务指令 function handle_mission_cmd(cmd) if cmd.id 100 then gcs:send_text(0, Custom cmd, param1: .. cmd.param1) -- 在这里展开你自己的任务逻辑 end end -- 注册任务处理函数 mission:register_handler(handle_mission_cmd) return handle_mission_cmd, 100如何验证用 Mission Planner 造一条含自定义指令的任务回放执行过程确认脚本端正确打印了 param1。踩坑与调优脚本把 CPU 吃满了现象是主控日志报指令数超限、脚本被中止。三个常见原因回调周期设得太密100ms 以下要谨慎、单次回调里做了重计算、循环写得收不住。解法按顺序试拉长回调间隔、把复杂计算拆成多次小步执行、把 SCR_VM_I_COUNT 调到合理值范围 1000~1000000步长 10000而不是无脑拉满。上传的脚本被拦下无法解锁现象是地面站报“脚本校验和不匹配”并拒绝解锁。这是校验机制在起作用SCR_LD_CHECKSUM 要求已加载脚本的 CRC32 异或值与参数一致SCR_RUN_CHECKSUM 同理约束运行中的脚本-1 表示关闭校验。生产机上建议保留它调试期临时设 -1别忘了调回来。内存告警现象是运行一段时间报堆内存不足。把 SCR_HEAP_SIZE 调大最大可到 1MB 级改后重启并在关键脚本里手动collectgarbage()别在高频回调里反复创建大对象。接下来可以做的事想看更完整的成品仓库里 libraries/AP_Scripting/examples/ 是官方教学示例目录applets/下则是拿来就能用的完整应用各自带一份说明文档。想上真机之前先用 SITL 把脚本跑一遍是性价比最高的安全网一条命令就能起模拟器。脚本跑通了只是起点——把你的任务逻辑搬进 Lua剩下的交给飞控去执行。【免费下载链接】ardupilotArduPlane, ArduCopter, ArduRover, ArduSub source项目地址: https://gitcode.com/GitHub_Trending/ar/ardupilot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表