ArduPilot 脚本实战:用 advance-wp.lua 通过 RC 开关推进任务航点
ArduPilot 脚本实战用 advance-wp.lua 通过 RC 开关推进任务航点【免费下载链接】ardupilotArduPlane, ArduCopter, ArduRover, ArduSub source项目地址: https://gitcode.com/GitHub_Trending/ar/ardupilot导读advance-wp.lua是 ArduPilot Lua 脚本体系libraries/AP_Scripting中的一个成熟 applet它允许飞手通过一个 RC 开关随时把当前任务航点推进到下一个航点到达任务末尾时自动回绕到 WP 1并可选地在遥控器遥测屏上周期性播报当前航点的方位角与距离同时利用飞控蜂鸣器按距离变化发出不同音调。本文以 advance-wp.md 为骨架结合 advance-wp.lua 源码与 Lua 脚本 API 文档完整讲解该脚本的安装、参数配置、工作原理、源码级实现细节与典型应用场景。读完本文你将能独立部署该脚本理解其航点推进、航点播报与蜂鸣反馈三大功能的底层调用链并学会如何把它改造成自定义的航点工具。一、脚本是什么一个可随手切换航点的“任务遥控器”在默认的 ArduPilot 任务执行流程中航点由任务逻辑按顺序自动推进。但在某些作业场景下例如测绘布点、巡检打点、RTK 移站复测操作员希望不接触地面站仅靠遥控器上的一个开关就能把当前导航航点“跳”到下一个从而完全自主地控制任务节奏。advance-wp.lua正是为此设计它监听一个映射到Aux Function 300Scripting1的 RC 通道当开关拨到高位0时脚本调用任务 API 把当前航点索引 1并在超出任务末尾时回绕到航点 1随后通过 GCS 文本消息广播新航点号方便飞手在 OSD 或遥测屏上确认。该脚本以PARAM_TABLE_KEY 193、前缀WAYPT_注册了一张参数表向用户暴露四个参数WAYPT_ADVANCE、WAYPT_ANNOUNCE、WAYPT_ANNOUNCE_S、WAYPT_BUZ_ENABLE因此无需修改任何代码即可完成全部配置——这正是libraries/AP_Scripting/applets/README.md所定义的 applet 特性复制即用参数化配置。核心特性一览特性说明触发方式航点推进当前导航航点 1末尾回绕到 WP 1RC 开关高位Aux 300航点播报广播当前航点索引、方位角、距离GCS 文本消息RC 开关高位Aux 301蜂鸣反馈按距离远近改变蜂鸣音调/频率跟随播报开关WAYPT_BUZ_ENABLE1无需地面站Mission Planner 的 Aux Function 页可替代物理 RC 通道—二、安装部署三步启用脚本按照 applets/README.md 的通用安装流程applet 无需用户编辑任何代码只需完成以下步骤拷贝脚本把 advance-wp.lua 复制到飞控 SD 卡的APM/scripts目录。启用脚本引擎将SCR_ENABLE参数设为1。重启飞控重启后脚本会被自动加载执行启动时飞控会通过 GCS 文本消息输出Advance WP Script ActiveINFO 级见 advance-wp.lua确认脚本已在运行。前提条件飞控必须支持 Lua 脚本脚本引擎需有足够 Flash/RAM 资源且固件包含 AP_Scripting 模块。这是所有 applet 的公共前提见 applets/README.md。为 RC 通道绑定辅助功能脚本本身不绑定任何固定物理通道而是通过辅助功能号Aux Function来识别开关把WAYPT_ADVANCE默认 300配置到某一个可用 Aux 功能号例如RC8_OPTION 300表示 8 通道遥控信号为高位时触发推进。推荐使用瞬时开关momentary switch脚本基于“边沿触发”逻辑下文详述瞬时开关可以避免误触发与重复触发。如果不希望占用物理 RC 通道Mission Planner 的 Aux Function 页面RCx_OPTION参数页同样可以完成同样的绑定适合地面站操控场景。三、参数配置四参数读懂脚本行为脚本通过param:add_table(193, WAYPT_, 4)注册了一张包含 4 个参数的表参数名为WAYPT_前缀 下表名称参数类型默认值说明WAYPT_ADVANCE整数300航点推进的 Aux 功能号0或无效时禁用推进功能WAYPT_ANNOUNCE整数301航点播报的 Aux 功能号设为无效值则禁用播报WAYPT_ANNOUNCE_S整数0播报间隔秒0表示禁用播报功能WAYPT_BUZ_ENABLE整数1蜂鸣反馈开关1启用0禁用对应源码中的绑定逻辑advance-wp.luaassert(param:add_table(PARAM_TABLE_KEY, PARAM_TABLE_PREFIX, 4), Advance WP: Could not add param table) local WAYPT_ADVANCE bind_add_param(ADVANCE, 1, 300) local WAYPT_ANNOUNCE bind_add_param(ANNOUNCE, 2, 301) local WAYPT_ANNOUNCE_S bind_add_param(ANNOUNCE_S, 3, 0) local WAYPT_BUZ_ENABLE bind_add_param(BUZ_ENABLE, 4, 1)其中bind_add_param使用assert(param:add_param(...))在脚本启动时校验参数注册是否成功bind_param通过assert(p:init(name))确保参数可被读取若失败会输出形如Advance WP: Could not find %s parameter的错误消息advance-wp.lua。参数表 API 定义见 docs.lua 第 2373-2381 行。关于 Aux 功能号 300/301依据 libraries/RC_Channel/RC_Channel.cpp 中的枚举注释300 对应Scripting1、301 对应Scripting2……316 对应Stop-Restart Scripting。也就是说默认配置下推进与播报分别占用脚本通道 1、2配置时不可与其它脚本通道冲突。四、功能一RC 开关推进航点4.1 使用方式将WAYPT_ADVANCE设为某个 Aux 功能号默认 300。在RCx_OPTION中把该功能号绑定到目标通道优先选择瞬时开关。每次开关拨到高位飞控便把当前导航航点推进一个并在 GCS 输出Advance WP - 新航点号NOTICE 级消息。4.2 源码实现边沿触发 回绕推进逻辑位于 advance-wp.lua 第 106-122 行local adv_sw_pos rc:get_aux_cached(advance_opt) if not adv_sw_pos then return update, RUN_INTERVAL_MS end local num_commands mission:num_commands() if num_commands 1 then return update, RUN_INTERVAL_MS end if adv_sw_pos 0 and adv_sw_pos ~ last_advance_sw_pos then local nav_index mission:get_current_nav_index() local new_index (nav_index 1) % mission:num_commands() mission:set_current_cmd(new_index) gcs:send_text(MAV_SEVERITY.NOTICE, (Advance WP - %d):format(mission:get_current_nav_index())) end last_advance_sw_pos adv_sw_pos or 0关键实现点开关状态读取rc:get_aux_cached(aux_fn)返回指定 Aux 功能号的缓存电平0 为低0 为高不可用时返回 nil该 API 定义于 docs.lua 第 2555-2558 行。脚本运行循环每 100 ms 采样一次因此对开关动作的响应延迟约为 100 ms 量级。边沿触发防抖adv_sw_pos ~ last_advance_sw_pos确保只在开关从低变高的边沿触发一次推进而非持续触发。这就是为什么推荐瞬时开关——按住不会重复跳点。回绕保护(nav_index 1) % mission:num_commands()实现“推进后若越界则回绕到 0”即任务末尾再拨开关会跳回 WP 1。注意num_commands()的语义它返回任务命令总数含索引 0 的 home 位置见 docs.lua 第 2274-2277 行。航点切换mission:set_current_cmd(new_index)让任务直接跳转到指定索引的命令是脚本式跳点的核心 APIdocs.lua 第 2293-2296 行mission:get_current_nav_index()返回当前“导航”命令索引无命令时返回 0docs.lua 第 2298-2302 行。空任务保护num_commands() 1时直接跳过避免对空任务执行越界操作。从源码结构看set_current_cmd与地面站发送 MAVLinkMISSION_SET_CURRENT指令等价但完全由机载脚本自治完成不依赖任何下行链路。五、功能二航点方位/距离播报适合 Yaapu 等遥测屏5.1 适用场景当遥控器使用Yaapu FrSky 遥测或类似仅显示 GCS 文本消息的遥测方案时Lua 脚本中常见的send_named_float命名浮点值并不容易直接展示在屏幕上。此时把“当前航点 方位 距离”作为GCS 文本消息周期性广播是最直观的呈现方式——无论飞行模式或解锁状态如何只要播报开关处于高位就会持续播报。5.2 使用方式WAYPT_ANNOUNCE设为另一个 Aux 功能号默认 301。在RCx_OPTION绑定对应通道。WAYPT_ANNOUNCE_S设为播报间隔秒数0禁用。同样可用 Mission Planner 的 Aux Function 页替代物理通道。5.3 源码实现不依赖任务状态的位置解算播报逻辑位于 advance-wp.lua 第 124-161 行。值得注意的实现细节是脚本并不依赖任务当前是否处于运行状态而是每次直接从任务中取出当前导航索引对应的命令项将其转换为Location后与飞控当前定位ahrs:get_location()做几何计算local nav_index mission:get_current_nav_index() local item mission:get_item(nav_index) local wp_loc get_wp_location(item) local cur_loc ahrs:get_location() if cur_loc then local bearing math.deg(cur_loc:get_bearing(wp_loc)) local distance cur_loc:get_distance(wp_loc) ... if now - last_announce_ms announce_s * 1000 then gcs:send_text(MAV_SEVERITY.NOTICE, (WP %d: %03.0f° / %.3fm):format(nav_index, bearing, distance)) last_announce_ms now end end命令项 → 位置get_wp_location(item)用Location()构造位置对象其中经度/纬度直接取自命令的x()/y()高度取math.floor(item:z() * 100)将命令中的米制高度换算为厘米制见 advance-wp.lua 第 61-67 行。几何计算Location_ud:get_bearing(loc)返回弧度制相对方位docs.lua 第 1169-1172 行经math.deg转为角度Location_ud:get_distance(loc)返回两位置间水平距离米见 docs.lua 第 1208 行 附近。AHRS 无效兜底若ahrs:get_location()返回 nil定位未就绪则输出 WARNING 级消息Advance WP: Invalid AHRS location避免静默失败。节流播报通过now - last_announce_ms announce_s * 1000控制最小播报间隔last_announce_ms用uint32_t(0)初始化以规避毫秒计时器回绕问题advance-wp.lua 第 103 行。播报消息格式为WP 索引: 三位方位角° / 距离m例如WP 3: 045° / 12.500m。由于是 GCS 文本消息它可以同时出现在 Mission Planner 消息窗口、Yaapu 遥测屏、OSD 等所有接收 GCS 消息的终端上。六、功能三蜂鸣器距离反馈无遥测时的“测距仪”6.1 使用方式设置WAYPT_BUZ_ENABLE 1默认即开启启用蜂鸣反馈0关闭。该功能跟随播报开关触发当播报开关处于高位时蜂鸣器会随距离当前航点的远近变化音调——越接近航点蜂鸣频率与音调越高反之越远则越低缓。文档作者将其描述为“针对选定航点的测距仪”在完全没有遥测回传手段的场合尤其有用。6.2 源码实现对数音阶 线性间隔蜂鸣反馈由两个纯 Lua 函数共同完成advance-wp.lua 第 69-93 行1) 音阶映射get_pitch_by_distance(distance)local max_distance 300 local min_distance 0.01 local total_notes 73 ... local scale_factor 105 local log_ratio math.log(max_distance / distance) local max_log_ratio math.log(max_distance / min_distance) local log_distance_scaled log_ratio / max_log_ratio * total_notes * scale_factor / 100 local note_index math.min(math.floor(log_distance_scaled), total_notes - 1) return N .. math.max(1, note_index)距离被钳制在0.01 m ~ 300 m之间。采用对数刻度log(max_distance / distance)把距离压缩到N1~N72的音阶索引再套上scale_factor 105的经验缩放系数以获得“在距离区间内良好的音调铺开”。最终返回形如N42的Tune 音符名称供蜂鸣器播放。2) 蜂鸣间隔get_buzz_interval(distance)local max_distance 100 local min_distance 0.01 local max_interval 2000 local min_interval 250 ... local interval max_interval - (max_interval - min_interval) * ((max_distance - distance) / max_distance) return math.floor(interval)距离越近蜂鸣间隔越短2000 ms远到250 ms近线性递减配合音调升高形成“越近越急促、越尖锐”的听觉反馈。3) 播放与节流if buzz_enable and buzz_enable 0 and now - last_buzz_ms get_buzz_interval(distance) then notify:play_tune(MFT240MSL8 .. get_pitch_by_distance(distance)) last_buzz_ms now endnotify:play_tune(tune)是飞控通知子系统提供的播放 Tune 的 APIdocs.lua 第 3438 行前缀MFT240MSL8规定了音符时长等播放参数间隔由get_buzz_interval动态决定。蜂鸣逻辑紧跟在方位/距离计算之后因此播报开关同时驱动文本播报与蜂鸣反馈两条路径。七、运行机制与循环结构脚本遵循 ArduPilot Lua 的经典update()协程模式advance-wp.lua 第 105-164 行local RUN_INTERVAL_MS 100 function update() ... return update, RUN_INTERVAL_MS end gcs:send_text(MAV_SEVERITY.INFO, Advance WP Script Active) return update, RUN_INTERVAL_MS脚本以100 ms10 Hz周期运行每次update()末尾返回自身与间隔实现自调度协程。多个分支在advance_opt/announce_s等参数无效nil时提前 return实现“功能按配置裁剪”例如WAYPT_ANNOUNCE_S 0时整个播报/蜂鸣分支不再执行。MAV_SEVERITY表advance-wp.lua 第 37-46 行复用了 MAVLink 的严重度枚举NOTICE5、WARNING4、INFO6使文本消息在地面站中的着色/优先级符合标准。脚本头部同时保留了对航点推进与播报功能的完整参数注释advance-wp.lua 第 1-32 行并明确警示本脚本有能力接管/释放飞行器的自主控制使用者自负风险。八、典型应用作者实测的“棱镜杆”改造文档作者在 advance-wp.md 的 Authors Note 中分享了真实用例他用一块闲置飞控 RTK GPS 模块/天线 RC 接收机 数传电台结合本脚本把设备改造成了一套测绘用的“棱镜杆prism pole”定位装置使用 ArduPilot 既有的SaveWP 功能在作业现场保存航点借助本脚本的航点推进在现场逐点切换已保存的航点再通过方位/距离播报与蜂鸣反馈无需任何地面站与遥测屏幕即可将设备精确移动到对应航点位置。这一流程展示了脚本三大功能推进、播报、蜂鸣的组合价值推进用于“选点”方位/距离用于“定向”蜂鸣用于“逼近”。类似的组合也可以延伸到RTK 打点复测、管线巡检定位、农用机具定点投放等需要在现场快速定位指定航点的场景。九、注意事项与扩展建议通道与功能号冲突300/301 分别对应 Aux 功能Scripting1/Scripting2见 libraries/RC_Channel/RC_Channel.cpp同一功能号在全机范围内只能绑定一个通道配置前需检查RCx_OPTION是否有占用。任务为空时的行为推进分支在num_commands() 1时直接跳过播报分支会尝试get_item(nav_index)建议在无任务时保持播报开关断开。触发方式推进采用边沿触发务必使用瞬时开关或将开关逻辑设为“拨动即回位”否则无法连续逐点推进。安全提示脚本可以随时改变飞行器当前执行的导航命令对正在自动任务中的飞行器操作前务必确认周边环境安全作者已在脚本头部加注“AT YOUR OWN RISK”警告。扩展思路参考本脚本的参数表注册param:add_tablebind_add_param与rc:get_aux_cached读取模式可以很容易扩展出“后退一个航点”“跳到指定航点号”“循环扫描多个保存点”等变体Script_Controller.lua 与 MissionSelector.lua 等 applet 也使用了相同的辅助功能绑定思路可作为进一步学习的参照。十、小结advance-wp.lua是一个“小而完整”的 ArduPilot Lua applet 范例它通过 4 个暴露参数 2 个 RC 辅助功能号就实现了航点推进、航点方位/距离播报与蜂鸣距离反馈三组能力全程不依赖地面站链路且对飞行模式、解锁状态、任务是否运行均不敏感。无论你是想给测绘或巡检作业加一个“遥控航点切换”还是想学习 ArduPilot 脚本中 RC 辅助功能、任务 API、位置几何与蜂鸣通知的典型用法这份 advance-wp.md advance-wp.lua 的组合都是一份不可多得的参考材料。将其放入APM/scripts并设置SCR_ENABLE1即可在下一台支持脚本的 ArduPilot 飞控上开始体验。【免费下载链接】ardupilotArduPlane, ArduCopter, ArduRover, ArduSub source项目地址: https://gitcode.com/GitHub_Trending/ar/ardupilot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考