news 2026/9/25 3:52:04

PX4 MAVLink 标准模式协议:飞行模式的发现、查询与切换全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PX4 MAVLink 标准模式协议:飞行模式的发现、查询与切换全解析
  • 嵌入式
  • 物联网
  • 机器人
  • 自动驾驶
  • 智能硬件

【免费下载链接】PX4-Autopilot

PX4 Autopilot Software

项目地址:https://gitcode.com/gh_mirrors/px/PX4-Autopilot
点击查看免费下载

本篇基于 PX4 官方文档 standard_modes.md 整理并深入源码。自 PX4 v1.15 起,PX4 实现了 MAVLink 标准模式协议(Standard Modes Protocol),使地面站或外部系统(包括通过 PX4 ROS 2 控制接口创建的外部模式)能够统一地发现所有可用飞行模式、查询当前模式,并以跨飞行栈通用的标准模式枚举来切换模式。读完本文,你将掌握协议涉及的全部消息与命令、各类飞行器(多旋翼 / 固定翼 / VTOL)的标准模式映射表,以及 PX4 中从命令下发到导航状态切换的完整源码实现链路。

协议概述:标准模式与自定义模式

在 MAVLink 体系中,模式分为两类:

  • 标准模式(Standard Modes):各飞行栈普遍支持、行为大致一致的模式,例如位置悬停、定高、任务、降落、起飞、安全返航等。地面站可以只依赖标准模式枚举即可对多种飞行栈的飞行器执行相同的操作;
  • 自定义模式(Custom Modes):飞行栈私有的模式,通过custom_mode整数(在 PX4 中即px4_custom_mode位域编码)表达。

该协议提供的能力包括:

能力所用消息 / 命令
发现系统(PX4 及 ROS 2 侧)支持的全部模式MAV_CMD_REQUEST_MESSAGE请求AVAILABLE_MODES
发现当前模式CURRENT_MODE(周期性发送)
设置标准模式MAV_CMD_DO_SET_STANDARD_MODE(推荐方式)
模式集合变化通知AVAILABLE_MODES_MONITOR

此外,PX4 也支持通过传统SET_MODE消息设置自定义模式(结合AVAILABLE_MODES中的自定义模式信息)。需要注意的是,文档明确说明:在当前版本中MAV_CMD_DO_SET_MODE尚不受支持,切换模式应使用MAV_CMD_DO_SET_STANDARD_MODE(标准模式)或SET_MODE(自定义模式)。

支持的 MAVLink 标准模式及 PX4 映射表

PX4 对外宣称支持下列标准飞行模式——即可以调用MAV_CMD_DO_SET_STANDARD_MODE并传入对应的MAV_STANDARD_MODE枚举值来启动这些模式。PX4 内部将其映射到导航状态(nav_state)。

多旋翼(MC)标准模式

标准模式对应 PX4 模式内部导航状态
MAV_STANDARD_MODE_POSITION_HOLDMC Position 模式POSCTL
MAV_STANDARD_MODE_ALTITUDE_HOLDMC Altitude 模式ALTCTL
MAV_STANDARD_MODE_ORBITMC Orbit 模式POSCTL(实际导航状态 ORBIT)
MAV_STANDARD_MODE_SAFE_RECOVERYReturn 模式AUTO_RTL
MAV_STANDARD_MODE_MISSIONMC Mission 模式AUTO_MISSION
MAV_STANDARD_MODE_LANDMC Land 模式AUTO_LAND
MAV_STANDARD_MODE_TAKEOFFMC Takeoff 模式AUTO_TAKEOFF

固定翼(FW)标准模式

标准模式对应 PX4 模式内部导航状态
MAV_STANDARD_MODE_CRUISEFW Cruise 模式POSCTL
MAV_STANDARD_MODE_ALTITUDE_HOLDFW Altitude 模式ALTCTL
MAV_STANDARD_MODE_ORBITFW Hold 模式AUTO_LOITER
MAV_STANDARD_MODE_SAFE_RECOVERYReturn 模式AUTO_RTL
MAV_STANDARD_MODE_MISSIONFW Mission 模式AUTO_MISSION
MAV_STANDARD_MODE_LANDFW Land 模式AUTO_LAND
MAV_STANDARD_MODE_TAKEOFFFW Takeoff 模式AUTO_TAKEOFF

VTOL 标准模式

VTOL 飞行器支持的标准模式同样取决于当前是作为多旋翼飞行还是作为固定翼飞行,行为随构型切换而变化:

标准模式对应 PX4 模式内部导航状态
MAV_STANDARD_MODE_ALTITUDE_HOLDFW Altitude 模式ALTCTL
MAV_STANDARD_MODE_SAFE_RECOVERYReturn 模式AUTO_RTL
MAV_STANDARD_MODE_MISSIONMission 模式AUTO_MISSION
MAV_STANDARD_MODE_LANDLand 模式AUTO_LAND
MAV_STANDARD_MODE_TAKEOFFTakeoff 模式AUTO_TAKEOFF

注意:VTOL 理论上还可在旋翼/固定翼构型下分别支持MAV_STANDARD_MODE_POSITION_HOLD(MC)、MAV_STANDARD_MODE_CRUISE(FW)与MAV_STANDARD_MODE_ORBIT,但文档明确指出这部分尚未实现——这与下文源码中映射函数对 VTOL 的保守处理一一对应。

全飞行器通用标准模式

以下标准模式对所有飞行器类型都有映射:

标准模式对应 PX4 模式内部导航状态
MAV_STANDARD_MODE_SAFE_RECOVERYReturn 模式AUTO_RTL
MAV_STANDARD_MODE_MISSIONMission 模式AUTO_MISSION
MAV_STANDARD_MODE_LANDLand 模式AUTO_LAND
MAV_STANDARD_MODE_TAKEOFFTakeoff 模式AUTO_TAKEOFF

源码解析(一):标准模式 ↔ 导航状态双向映射

文档指向的核心实现位于 src/lib/modes/standard_modes.hpp。该头文件定义了与 MAVLinkMAV_STANDARD_MODE枚举完全对齐的 C++ 枚举:

// src/lib/modes/standard_modes.hpp enum class StandardMode : uint8_t { NON_STANDARD = 0, POSITION_HOLD = 1, ORBIT = 2, CRUISE = 3, ALTITUDE_HOLD = 4, SAFE_RECOVERY = 5, MISSION = 6, LAND = 7, TAKEOFF = 8, };

映射逻辑由两个内联函数完成,均需要飞行器类型(vehicle_type)与是否 VTOL(is_vtol)作为输入:

1.getNavStateFromStandardMode()(L104-L152)——标准模式到导航状态的转换,这是"设置标准模式"路径的核心:

static inline uint8_t getNavStateFromStandardMode(StandardMode mode, uint8_t vehicle_type, bool is_vtol) { switch (mode) { case StandardMode::SAFE_RECOVERY: return vehicle_status_s::NAVIGATION_STATE_AUTO_RTL; case StandardMode::MISSION: return vehicle_status_s::NAVIGATION_STATE_AUTO_MISSION; case StandardMode::LAND: return vehicle_status_s::NAVIGATION_STATE_AUTO_LAND; case StandardMode::TAKEOFF: return vehicle_status_s::NAVIGATION_STATE_AUTO_TAKEOFF; case StandardMode::ALTITUDE_HOLD: // VTOL 或 纯 MC / 纯 FW 均支持 if (is_vtol || vehicle_type == ROTARY_WING || vehicle_type == FIXED_WING) { return vehicle_status_s::NAVIGATION_STATE_ALTCTL; } break; case StandardMode::POSITION_HOLD: // 仅非 VTOL 的多旋翼支持(VTOL 未实现,与文档说明一致) if (!is_vtol && vehicle_type == ROTARY_WING) { return vehicle_status_s::NAVIGATION_STATE_POSCTL; } break; case StandardMode::CRUISE: // 仅非 VTOL 的固定翼支持 if (!is_vtol && vehicle_type == FIXED_WING) { return vehicle_status_s::NAVIGATION_STATE_POSCTL; } break; case StandardMode::ORBIT: if (vehicle_type == ROTARY_WING) { return vehicle_status_s::NAVIGATION_STATE_ORBIT; } if (vehicle_type == FIXED_WING) { return vehicle_status_s::NAVIGATION_STATE_AUTO_LOITER; // FW 的 Orbit 即 Hold/Loiter } break; default: break; } return vehicle_status_s::NAVIGATION_STATE_MAX; // 不支持时返回 MAX }

几个关键细节:

  • 返回值NAVIGATION_STATE_MAX表示该标准模式对当前飞行器类型不适用,调用方据此给出失败应答;
  • MC 的ORBIT与POSITION_HOLD都最终落到 POSCTL 类导航状态,但ORBIT有独立的NAVIGATION_STATE_ORBIT;FW 的ORBIT则映射为AUTO_LOITER(即 Hold/Loiter),这解释了文档中"Orbit 在 MC 上是 Orbit 模式、在 FW 上是 Hold 模式"的说法;
  • VTOL 的保守处理:POSITION_HOLD与CRUISE均要求!is_vtol,因此 VTOL 请求这两个标准模式会返回NAVIGATION_STATE_MAX——正是文档中"VTOL 可支持但未实现"备注的代码依据。

2.getStandardModeFromNavState()(L59-L99)——导航状态到标准模式的反向转换,用于把 PX4 自身的自定义模式"包装"成标准模式上报给地面站(例如CURRENT_MODE消息中的standard_mode字段)。无法对应任何标准模式的导航状态返回NON_STANDARD。

这种"双向映射"设计意味着:PX4 对外用标准模式呈现自身能力,对外部则同时保留完整的自定义模式视图。

源码解析(二):命令处理链路与两条 MAVLink 消息流

设置标准模式:Commander 中的命令分发

当地面站发出MAV_CMD_DO_SET_STANDARD_MODE时,MAVLink 模块将其转换为vehicle_command_s传入 Commander。处理逻辑位于 src/modules/commander/Commander.cpp:

case vehicle_command_s::VEHICLE_CMD_DO_SET_STANDARD_MODE: { mode_util::StandardMode standard_mode = (mode_util::StandardMode) roundf(cmd.param1); uint8_t nav_state = mode_util::getNavStateFromStandardMode(standard_mode, _vehicle_status.vehicle_type, _vehicle_status.is_vtol); if (nav_state == vehicle_status_s::NAVIGATION_STATE_MAX) { answer_command(cmd, vehicle_command_ack_s::VEHICLE_CMD_RESULT_FAILED); } else { if (_user_mode_intention.change(nav_state, getSourceFromCommand(cmd))) { answer_command(cmd, vehicle_command_ack_s::VEHICLE_CMD_RESULT_ACCEPTED); } else { answer_command(cmd, vehicle_command_ack_s::VEHICLE_CMD_RESULT_TEMPORARILY_REJECTED); } } }

从源码结构可以确认完整的处理语义:

  1. param1即MAV_STANDARD_MODE枚举值(见上一节的映射表),Commander 将其转换为内部导航状态;
  2. 若该飞行器类型不支持该标准模式(映射结果为NAVIGATION_STATE_MAX),直接应答VEHICLE_CMD_RESULT_FAILED;
  3. 否则请求用户模式意图变更(_user_mode_intention.change),该路径还记录了命令来源(getSourceFromCommand),成功则应答ACCEPTED,失败(例如被其他控制源抢占或状态不允许)则应答TEMPORARILY_REJECTED。

发现模式:AVAILABLE_MODES消息流

模式发现通过MAV_CMD_REQUEST_MESSAGE请求AVAILABLE_MODES消息触发,实现在 src/modules/mavlink/streams/AVAILABLE_MODES.hpp:

  • 请求参数:param2为mode_index。传0表示请求全部模式(遍历vehicle_status.valid_nav_states_mask中所有有效导航状态逐一发送);传1..N表示只请求第 N 个模式(request_message(),L144-L198)。
  • 每条AVAILABLE_MODES消息携带的字段(send_single_mode(),L86-L142):
    • custom_mode:PX4 的px4_custom_mode位域编码(get_px4_custom_mode(nav_state)),供传统SET_MODE使用;
    • standard_mode:由mode_util::getStandardModeFromNavState()计算,若该导航状态无法对应标准模式则为MAV_STANDARD_MODE_NON_STANDARD;
    • mode_name:非标准模式的名字来源——内部模式取自mode_util::nav_state_names[]静态表;外部模式(External modes)来自register_ext_component_reply主题,即可由 ROS 2 组件动态注册的模式名;
    • properties:包含MAV_MODE_PROPERTY_ADVANCED(高级模式,由mode_util::isAdvanced()判定)与MAV_MODE_PROPERTY_NOT_USER_SELECTABLE(不可由用户选择,当vehicle_status.can_set_nav_states_mask中该导航状态未置位时设置)。
  • 低速链路的保护:全部模式逐一发送时按链路速率计算每帧之间的延迟,且以MAX_DELAY_US = 2500000 / NAVIGATION_STATE_MAX(注释说明:为所有可能模式预留最多 2.5 秒,避免地面站 ACK 超时)为上限,L62-L65。
  • 模式集合变化通知:update_data()(L200-L255)持续监视register_ext_component_reply、valid_nav_states_mask与can_set_nav_states_mask三类动态变化;一旦变化就递增seq,随后send()发出带有序列号的AVAILABLE_MODES_MONITOR消息,地面站收到后应重新请求全部AVAILABLE_MODES。这正是协议中"模式集合变化通知"的实现。

这一机制是 PX4 将ROS 2 外部模式纳入标准模式协议的入口:通过 PX4 ROS 2 控制接口 注册的外部模式会出现在AVAILABLE_MODES列表中并带有注册时的模式名;若某外部模式尚未注册(不可选择),列表中会以(Mode not available)占位。

查询当前模式:CURRENT_MODE消息流

当前模式的周期性上报由 src/modules/mavlink/streams/CURRENT_MODE.hpp 实现:

mavlink_current_mode_t current_mode{}; current_mode.custom_mode = get_px4_custom_mode(vehicle_status.nav_state_display).data; current_mode.intended_custom_mode = get_px4_custom_mode(vehicle_status.nav_state_user_intention).data; current_mode.standard_mode = (uint8_t) mode_util::getStandardModeFromNavState(vehicle_status.nav_state_display, vehicle_status.vehicle_type, vehicle_status.is_vtol);

值得注意的三个字段语义:

  • custom_mode:基于nav_state_display(当前实际导航状态);
  • intended_custom_mode:基于nav_state_user_intention(用户意图模式),用于区分"期望进入"与"实际处于"的模式;
  • standard_mode:通过同一套mode_util::getStandardModeFromNavState()映射,若当前为 PX4 私有模式则上报NON_STANDARD。

从 src/modules/mavlink/mavlink_main.cpp 中各通道流注册表可以确认默认发送频率:AVAILABLE_MODES约 0.3 Hz,CURRENT_MODE约 0.5 Hz。

其他可切换模式的 MAVLink 命令

除标准模式协议外,一些标准模式与自定义模式还可通过更早的传统命令设置,尤其在消息允许附带额外参数时更为便利。PX4 支持下列模式切换命令(部分仅限特定飞行器类型):

命令对应模式
MAV_CMD_NAV_TAKEOFFTakeoff 模式
MAV_CMD_NAV_RETURN_TO_LAUNCHReturn 模式
MAV_CMD_NAV_LANDLand 模式
MAV_CMD_DO_FOLLOWMC Follow 模式
MAV_CMD_DO_FOLLOW_REPOSITION从新位置发起的 Follow 模式
MAV_CMD_DO_ORBITMC Orbit 模式
MAV_CMD_NAV_VTOL_TAKEOFFVTOL 专用起飞模式
MAV_CMD_DO_REPOSITION重定位
MAV_CMD_DO_PAUSE_CONTINUE将飞行器置入 Hold/Loiter 以暂停任务
MAV_CMD_MISSION_START启动任务

文档特别提示了一个容易踩坑的语义差异:这些命令早于标准模式协议出现,映射到的是"飞行器类型特定的自定义模式",而非标准模式。也就是说,即使某个标准模式对多类飞行器通用,传统命令也可能只对特定飞行器生效。原文给出的例子:Orbit 标准模式在 MC 上映射为 Orbit 模式、在 FW 上映射为 Hold/Loiter;但截至文档撰写时,MAV_CMD_DO_ORBIT只会在 MC 上启动 Orbit 模式,在 FW 上会被忽略。

小结

PX4 v1.15 引入的标准模式协议,让地面站/外部系统能够以飞行栈无关的方式完成"发现 → 查询 → 切换"飞行模式的闭环:MAV_CMD_REQUEST_MESSAGE+AVAILABLE_MODES完成模式发现(含 ROS 2 外部模式),CURRENT_MODE周期上报当前模式(标准 + 自定义双视图),MAV_CMD_DO_SET_STANDARD_MODE完成标准模式切换,AVAILABLE_MODES_MONITOR保证模式集合变化时的同步。实现侧的核心只有三处:映射函数 src/lib/modes/standard_modes.hpp、命令分发 src/modules/commander/Commander.cpp、消息流 src/modules/mavlink/streams/AVAILABLE_MODES.hpp 与 src/modules/mavlink/streams/CURRENT_MODE.hpp。需要注意的前提限制:MAV_CMD_DO_SET_MODE尚不支持、VTOL 对POSITION_HOLD/CRUISE/ORBIT标准模式的支持未实现,且具体支持情况以当前版本固件与地面站(QGroundControl Daily 构建)的实际联调为准。

  • 嵌入式
  • 物联网
  • 机器人
  • 自动驾驶
  • 智能硬件

【免费下载链接】PX4-Autopilot

PX4 Autopilot Software

项目地址:https://gitcode.com/gh_mirrors/px/PX4-Autopilot
点击查看免费下载

相关推荐

上一篇:WebVOWL:基于Web的OWL本体可视化终极指南 🚀
下一篇:gh_mirrors/vi/vivado-library完全解析:FPGA开发者必备的IP核与模块资源库

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/25 3:50:15

AI小说生成:7分钟装好本地长篇写作工具

AI小说生成:7分钟装好本地长篇写作工具 【免费下载链接】AI_NovelGenerator 使用ai生成多章节的长篇小说,自动衔接上下文、伏笔 项目地址: https://gitcode.com/GitHub_Trending/ai/AI_NovelGenerator AI小说生成工具里,AI_NovelGener…

作者头像 李华
网站建设 2026/9/25 3:50:11

旧电脑也能跑NetSurveillance DVR:开源自建监控录像系统指南

简介:面向Windows平台IE浏览器的NetSurveillance DVR插件,是一套通过网络远程访问监控设备的轻量级解决方案,主要针对安防工程人员、运维人员和二次开发者。资源包共61个文件、约1.07MB,核心构成包括ActiveX控件、H.264解码播放库…

作者头像 李华
网站建设 2026/9/25 3:49:58

英文论文常见缩写全解析:w/、i.e.、s.t.、cf.用法与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/25 3:49:56

Java基础学习路线与核心知识点:从环境配置到面向对象实战

1. 别急着刷题:先把Java基础的学习路线走对我见过太多人学Java上来就搞反了:课还没听几节,先下了个面试八股文大全开始背;或者说语法刚看完循环和数组,就直接冲去学Spring Boot。结果呢?两个月后代码写不出…

作者头像 李华