ArduPilot Lua 脚本实战用 ahrs-set-origin Applet 手动设定 AHRS/EKF 原点【免费下载链接】ardupilotArduPlane, ArduCopter, ArduRover, ArduSub source项目地址: https://gitcode.com/GitHub_Trending/ar/ardupilot本篇技术指南围绕 ArduPilot 仓库中的 ahrs-set-origin.lua 及其配套文档 ahrs-set-origin.md 展开讲解如何通过 Lua 脚本把 AHRS/EKF 的本地坐标系原点强制设定到指定经纬度与海拔适用于无 GPS 信号、需要固定基准点或希望载具在地图上正确落位的场景。读完本文你将掌握该 Applet 的三个脚本参数AHRS_ORIG_LAT / AHRS_ORIG_LON / AHRS_ORIG_ALT的完整含义、安装启用流程、底层set_origin/get_origin调用链以及相关源码实现细节。什么是 AHRS/EKF 原点为什么要手动设定ArduPilot 的姿态与导航估计由 AHRSAttitude and Heading Reference System与 EKFExtended Kalman Filter负责。EKF 在工作时会建立一个本地坐标系原点origin所有位置、速度、高度估计都相对于这个原点解算。正常情况下EKF 会依据 GPS 首次定位自行确定原点但以下几种场景下手动设定原点非常有价值载具在 GPS 不可用或信号很差的环境室内、隧道、树下中启动需要借助外部位置源或固定基准点完成定位需要在已知地理坐标的位置固定原点使载具的本地坐标系与真实世界坐标严格对齐希望载具上电后立刻以正确位置出现在地面站地图上而不必等待 GPS 收敛。ahrs-set-origin这个 Applet 正是为此设计的它读取三个用户参数在 EKF 原点尚未建立时主动把原点设定为参数指定的位置并通过 GCS 消息屏给出明确反馈。脚本参数说明该脚本通过 Lua 的param:add_table机制注册了一张参数表前缀为AHRS_ORIG_共三个参数。每个参数都由脚本启动时自动注册并绑定见 ahrs-set-origin.lua参数名显示名称含义默认值取值范围AHRS_ORIG_LATAHRS/EKF Origin Latitude原点纬度度0-180 ~ 180AHRS_ORIG_LONAHRS/EKF Origin Longitude原点经度度0-180 ~ 180AHRS_ORIG_ALTAHRS/EKF Origin Altitude原点海拔米MSL00 ~ 10000参数细节可以从脚本内的元数据注释确认ahrs-set-origin.luaAHRS_ORIG_LATAHRS/EKF 原点将设定为此纬度若尚未设定AHRS_ORIG_LONAHRS/EKF 原点将设定为此经度若尚未设定AHRS_ORIG_ALTAHRS/EKF 原点将设定为此海拔高度单位为米海平面以上。需要注意三个参数默认值都为 0。脚本逻辑中有一条非零检查只有当三个参数不全部为 0 时才会执行原点设定ahrs-set-origin.lua因此若你没有修改参数脚本会每 5 秒重试一次而不会误设原点。如何安装与使用1. 启用 Lua 脚本功能ArduPilot 的脚本功能默认关闭。需要先将SCR_ENABLE参数设为 1 并重启飞控且飞控固件必须包含脚本支持官方标准固件已包含。可参考同目录下 Applets 的通用说明 applets/README.md。2. 安装脚本把ahrs-set-origin.lua复制到飞控 SD 卡的APM/scripts目录下然后重启飞控。Applets 的特点是开箱即用与examples目录里的示例不同这些 Applet 不需要用户修改脚本文件本身只需复制安装。3. 设定三个原点参数通过地面站如 Mission Planner / QGroundControl将参数设置为期望位置AHRS_ORIG_LAT 39.908723 AHRS_ORIG_LON 116.397590 AHRS_ORIG_ALT 44.0纬度、经度使用十进制度数海拔使用海平面以上的米数。4. 观察反馈信息脚本启动后会在 GCS 消息屏打印ahrs-set-origin: started。随后当 AHRS 初始化完成且原点尚未建立时若设定成功会看到ahrs-set-origin: origin set Lat:39.9087230 Lon:116.3975900 Alt:44.0此时载具通常会立即以正确位置出现在地图上。常见反馈与含义消息含义ahrs-set-origin: started脚本已加载参数表注册完成ahrs-set-origin: origin set Lat:... Lon:... Alt:...原点已成功设定ahrs-set-origin: EKF origin already setEKF 原点已存在例如 GPS 已定位脚本退出不覆盖ahrs-set-origin: failed to set origin设定失败例如主动 EKF 拒绝该位置脚本工作原理源码级解析该脚本虽短但完整展示了 ArduPilot Lua 脚本的典型结构参数表注册 → 绑定 → 周期性update()轮询 → 调用 AHRS 绑定接口。参数表注册与绑定脚本使用PARAM_TABLE_KEY 87作为参数表键值前缀为AHRS_ORIG_容量为 3 个参数ahrs-set-origin.lualocal PARAM_TABLE_KEY 87 PARAM_TABLE_PREFIX AHRS_ORIG_ assert(param:add_table(PARAM_TABLE_KEY, PARAM_TABLE_PREFIX, 3), ...)bind_add_param依次完成param:add_param注册与Parameter()绑定之后AHRS_ORIG_LAT:get()即可在脚本中随时读取地面站写入的参数值。更新循环与原点设定逻辑update()函数是整个脚本的核心ahrs-set-origin.lua其执行流程为等待 AHRS 初始化若ahrs:initialised()返回 false则 5 秒后重试检查原点是否已存在若ahrs:get_origin()返回有效值说明 EKF 已自行建立原点脚本打印警告后永久退出return不带延迟即停止循环参数非零检查三个参数全为 0 时 5 秒后重试构造 Location 并换算单位local location Location() location:lat(math.floor(AHRS_ORIG_LAT:get() * 10000000.0)) location:lng(math.floor(AHRS_ORIG_LON:get() * 10000000.0)) location:alt(math.floor(AHRS_ORIG_ALT:get() * 100.0))这里体现了 LuaLocation对象与度/米之间的单位换算lat/lng内部使用 1e7 度整数度数 × 10000000alt内部使用厘米米 × 100。调用ahrs:set_origin(location)成功则打印 INFO 级消息失败则打印 WARNING 级消息随后无论成败都退出循环避免反复尝试。脚本绑定接口get_origin与set_origin是 ArduPilot 为 Lua 脚本暴露的标准绑定定义于 bindings.descsingleton AP_AHRS method get_origin boolean LocationNull singleton AP_AHRS method set_origin boolean Location文档生成源 docs.lua 中也同步登记了这两个方法说明它们是受支持的公开脚本接口。底层实现从 Lua 到 EKF 的完整调用链脚本调用的ahrs:set_origin()最终会落到 C 层的AP_AHRS::set_origin()libraries/AP_AHRS/AP_AHRS.cpp。其源码注释明确说明了一个重要前提set the EKFs origin location in 10e7 degrees. This should only be called when the EKF has no absolute position reference (i.e. GPS) from which to decide the origin on its own即只有当 EKF 没有绝对位置参考如 GPS可自行确定原点时才应该调用该接口——这与脚本中先检查get_origin()的逻辑相呼应原点已由 GPS 建立时脚本主动放弃覆盖。AP_AHRS::set_origin()的实现会同时把位置传给 EKF2、EKF3若编译启用以及 External AHRS 后端然后根据当前激活的 EKF 类型判断是否成功。在 EKF3 一侧调用链继续深入NavEKF3::setOriginLLH()libraries/AP_NavEKF3/AP_NavEKF3.cpp会把位置广播给所有 EKF core每个 core 的setOriginLLH()libraries/AP_NavEKF3/AP_NavEKF3_Control.cpp完成原点状态的实际写入对应的读取接口getOriginLLH()libraries/AP_NavEKF3/AP_NavEKF3_Outputs.cpp则供脚本的get_origin()查询使用。值得注意的是EKF3 内部在收到 GPS 首个有效定位时也可能调用setOriginLLH()自动建立原点参见 libraries/AP_NavEKF3/AP_NavEKF3_Measurements.cpp 附近这也解释了为何脚本必须等到ahrs:get_origin()为空时才能生效——一旦 GPS 抢先把原点建立脚本不会去覆盖它。相关参考打印 Home 与 Origin若想验证原点设定结果仓库还提供了一个配套示例脚本 ahrs-print-home-and-origin.lua它每 5 秒通过ahrs:get_home()与ahrs:get_origin()分别打印 Home 与 EKF 原点的经纬度和海拔home ahrs:get_home() origin ahrs:get_origin() if origin then gcs:send_text(0, string.format(Origin - Lat:%.1f Long:%.1f Alt:%.1f, origin:lat(), origin:lng(), origin:alt())) end将该示例与ahrs-set-origin.lua配合使用可以直观对比“Home 点”与“EKF 原点”两个概念Home 是起飞点/任务基准而 EKF 原点是惯性导航坐标系的世界坐标锚点二者在无 GPS 场景下需要被分别管理。使用注意事项小结必须启用脚本功能SCR_ENABLE1并重启飞控脚本才会被加载执行三个参数不能全为 0否则脚本只是每 5 秒重试而不动作只在 EKF 原点未建立时生效若 GPS 已定位或原点已被设定脚本会输出警告并退出纬度经度用十进制度、海拔用米脚本内部会自动完成 1e7 度与厘米的换算无需用户手工转换飞控型号需支持脚本脚本功能依赖于固件编译时是否包含 Lua 支持官方标准固件默认包含。综上ahrs-set-origin是一个结构清晰、开箱即用的 ArduPilot 脚本范例它以最小化的三个参数完成了手动锚定 EKF 原点这一对无 GPS 应用至关重要的功能同时完整演示了参数表注册、周期性轮询、Location 单位换算与 AHRS 绑定接口调用的标准写法是学习 ArduPilot Lua 脚本开发的理想参考。【免费下载链接】ardupilotArduPlane, ArduCopter, ArduRover, ArduSub source项目地址: https://gitcode.com/GitHub_Trending/ar/ardupilot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
