news 2026/9/28 2:36:50

PX4-Autopilot ModeCompleted uORB 消息详解:模式完成结果发布机制与源码实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PX4-Autopilot ModeCompleted uORB 消息详解:模式完成结果发布机制与源码实现
  • 嵌入式
  • 物联网
  • 机器人
  • 自动驾驶
  • 智能硬件

【免费下载链接】PX4-Autopilot

PX4 Autopilot Software

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

导读

ModeCompleted 是 PX4-Autopilot 飞控固件中用于发布飞行模式完成结果的 uORB 消息。当一个自动飞行模式(如自动起飞、降落、返航、任务飞行)在正常流程下执行完毕时,由该模式的执行器(Navigator 模块)发布一条 ModeCompleted 消息,通知订阅方"某模式已完成,结果是成功还是失败"。本文以 docs/en/msg_docs/ModeCompleted.md 为骨架,结合仓库中 msg/versioned/ModeCompleted.msg、msg/versioned/VehicleStatus.msg 及 src/modules/navigator 的源码实现,完整讲解该消息的字段定义、常量语义、发布调用链、订阅消费场景与局限边界,使读者既能看懂消息结构,也能在真实源码中追踪其生命周期。


一、消息定位:它是什么、谁在发、什么时候不发

1.1 消息定义

在 PX4 中,ModeCompleted 是一条典型的"事件型" uORB 消息,其官方定义为:

Mode completion result, published by an active mode.

即:由处于激活状态的某个飞行模式发布其完成结果。nav_state的取值定义在 VehicleStatus 消息中。需要特别强调的一点是,该消息并非总是发布——例如用户手动切换模式、或触发 failsafe 保护时,都不会发布 ModeCompleted。

1.2 消息拓扑(Topic)

该消息的 uORB Topic 名为mode_completed,在消息定义文件末尾以**TOPICS:** mode_completed明确标注。

1.3 与消息版本控制的关系

ModeCompleted 的源消息位于msg/versioned/目录下(msg/versioned/ModeCompleted.msg),说明该消息参与了 PX4 的**消息版本化(message versioning)**机制。当消息字段发生变化时,通过MESSAGE_VERSION常量跟踪版本,保证飞控与地面站、DDS 桥接层之间的兼容性。


二、字段定义详解

ModeCompleted 消息共包含 3 个字段,结构非常精简:

字段名类型单位 [Frame]Range/Enum描述
timestampuint64——系统启动以来的时间(微秒)
resultuint8——取值必须为RESULT_*系列常量之一
nav_stateuint8——来源模式(取值参照 VehicleStatus 中的定义)

2.1 timestamp:时间戳

类型为uint64,单位为微秒(microseconds),表示"系统启动以来经过的时间"。在发布端(见下文mode_completed()函数)中,该字段由hrt_absolute_time()填充,这是 PX4 的高分辨率时钟接口,返回单调递增的绝对时间。订阅方可以用它判断模式完成事件发生的时刻,以及与其他传感器/状态消息做时间对齐。

2.2 result:完成结果

类型为uint8,取值必须是RESULT_*系列常量。它表达的是"这个模式的执行结果是成功还是失败"。

2.3 nav_state:来源模式

类型为uint8,表示发出该完成事件的那个模式(Source mode)。其取值并非本消息内定义,而是引用 msg/versioned/VehicleStatus.msg 中的NAVIGATION_STATE_*枚举,例如:

  • NAVIGATION_STATE_AUTO_MISSION = 3(自动任务)
  • NAVIGATION_STATE_AUTO_RTL = 5(自动返航)
  • NAVIGATION_STATE_AUTO_TAKEOFF = 17(自动起飞)
  • NAVIGATION_STATE_AUTO_LAND = 18(自动降落)
  • NAVIGATION_STATE_AUTO_PRECLAND = 20(精确降落)
  • NAVIGATION_STATE_AUTO_VTOL_TAKEOFF = 22(VTOL 自动起飞)

完整的NAVIGATION_STATE_*枚举(从 Manual=0 到 NAVIGATION_STATE_MAX=31)见 msg/versioned/VehicleStatus.msg,读者在解读nav_state字段时以该文件为准。


三、常量定义(Constants)

常量名类型值说明
MESSAGE_VERSIONuint320消息格式版本号
RESULT_SUCCESSuint80模式成功完成
RESULT_FAILURE_OTHERuint8100模式失败(通用错误)

值得注意的细节是,源消息文件 msg/versioned/ModeCompleted.msg 中明确注释了# [1-99]: reserved,即值 1~99 被保留,留给未来扩展更细粒度的失败原因。目前实际可用的结果值只有两个:0(成功)与100(通用失败)。这意味着当前实现中失败原因只做了粗粒度区分,如果需要区分"GPS 丢失""高度超限"等具体失败原因,只能由订阅方结合其他消息(如 failsafe 标志)自行判断——这是从当前常量定义可以推断出的设计取向。


四、发布端实现:Navigator 中的 mode_completed()

4.1 发布函数定义

ModeCompleted 的发布由 Navigator 模块统一封装。在 src/modules/navigator/navigator.h 中声明了:

void mode_completed(uint8_t nav_state, uint8_t result = mode_completed_s::RESULT_SUCCESS);

注意两个细节:

  1. 默认参数:result默认值为RESULT_SUCCESS,即调用方不传失败结果时,默认发布"成功完成"。
  2. 发布器成员:在 src/modules/navigator/navigator.h 中,该消息通过uORB::Publication<mode_completed_s> _mode_completed_pub{ORB_ID(mode_completed)}进行发布。

4.2 函数实现

发布逻辑位于 src/modules/navigator/navigator_main.cpp:

void Navigator::mode_completed(uint8_t nav_state, uint8_t result) { mode_completed_s mode_completed{}; mode_completed.timestamp = hrt_absolute_time(); mode_completed.result = result; mode_completed.nav_state = nav_state; _mode_completed_pub.publish(mode_completed); }

该实现与文档字段一一对应:

  • timestamp←hrt_absolute_time()(系统启动以来的微秒数)
  • result← 传入的result参数
  • nav_state← 传入的nav_state参数,即发布方模式自身的状态 ID

4.3 调用点:哪些模式会发布完成事件

从源码检索结果看,mode_completed()目前被以下自动模式在"正常完成"路径上调用(全部位于 src/modules/navigator 目录):

模式源码文件触发条件
自动任务(Mission)mission_base.cpp任务到达终点、设置 end-of-mission 项后
自动起飞(Takeoff)takeoff.cppmission_result->finished为真
自动降落(Land)land.cppmission_result->finished为真
VTOL 自动起飞vtol_takeoff.cppmission_result->finished为真
直接返航(RTL Direct)rtl_direct.cpp_rtl_state == RTLState::IDLE

以 land.cpp 为例,发布前的判定逻辑为:

if (_navigator->get_mission_result()->finished) { _navigator->mode_completed(getNavigatorStateId()); }

这里getNavigatorStateId()返回该模式实例在构造时绑定的导航状态 ID,定义于 navigator_mode.h:

uint8_t getNavigatorStateId() const { return _navigator_state_id; }

而各模式的导航状态 ID 在构造时通过NavigatorMode/MissionBlock基类绑定,例如 land.cpp 中MissionBlock(navigator, vehicle_status_s::NAVIGATION_STATE_AUTO_LAND)、mission.cpp 中MissionBase(navigator, DEFAULT_MISSION_CACHE_SIZE, vehicle_status_s::NAVIGATION_STATE_AUTO_MISSION)、rtl.cpp 中NavigatorMode(navigator, vehicle_status_s::NAVIGATION_STATE_AUTO_RTL)。由此可以推断:nav_state字段在发布时始终等于发布模式自身的导航状态 ID,订阅方凭此即可识别完成事件属于哪个模式。


五、订阅与消费场景

5.1 典型订阅方

mode_completedTopic 的典型消费场景包括:

  • 外部地面站 / 机载电脑:通过 MAVLink 或 DDS 桥接层接收该消息,用于任务编排、状态机推进(例如:检测到"自动起飞完成"后再下发后续任务)。
  • uXRCE-DDS / Zenoh 桥接:仓库中 src/modules/uxrce_dds_client/dds_topics.yaml 与 src/modules/zenoh/dds_topics.yaml 均将mode_completed列入桥接 Topic 列表,说明该消息可通过 uXRCE-DDS 与 Zenoh 中间件在飞控与 ROS 2 / 外部进程之间传输。

5.2 消息版本兼容

MESSAGE_VERSION = 0表示当前字段布局为初始版本。由于消息参与版本化管理(源文件位于msg/versioned/),后续若新增字段(例如更细粒度的失败枚举),MESSAGE_VERSION会递增,订阅方应按版本号做兼容解析。


六、发布边界与局限(文档明确说明)

原文档明确强调:这不是一个"总会发布"的消息。具体而言:

  1. 用户手动切换模式时不发布——例如飞行员通过遥控器或地面站主动从 Auto 模式切到 Position 模式,此时没有"完成结果"可言;
  2. failsafe 激活时不发布——当系统触发 failsafe(如返航、悬停、终止)而中断当前模式时,模式是被强制的、非正常退出,因此不产生完成事件;
  3. 失败原因粒度粗——目前只有RESULT_SUCCESS=0与RESULT_FAILURE_OTHER=100两个可用值,1~99 为保留区间,无法表达具体失败类型。

因此,订阅方在使用该消息时必须注意:收到mode_completed意味着模式正常走完生命周期;收不到不代表模式未完成,需要结合vehicle_status的nav_state、failsafe标志等其他消息综合判断系统状态。


七、快速查阅指南

  • 消息文档:docs/en/msg_docs/ModeCompleted.md
  • 源消息文件:msg/versioned/ModeCompleted.msg
  • nav_state 枚举来源:msg/versioned/VehicleStatus.msg
  • 发布实现:navigator_main.cpp
  • 发布器声明:navigator.h
  • 各模式调用点:mission_base.cpp、takeoff.cpp、land.cpp、vtol_takeoff.cpp、rtl_direct.cpp(均位于 src/modules/navigator)
  • DDS/Zenoh 桥接配置:src/modules/uxrce_dds_client/dds_topics.yaml、src/modules/zenoh/dds_topics.yaml

八、总结

ModeCompleted 是 PX4 中一条结构极简、语义清晰的事件型 uORB 消息:三个字段(时间戳、结果、来源模式)配合两个结果常量(成功 0 / 通用失败 100),由 Navigator 模块在自动任务、起飞、降落、返航等模式的正常完成路径上发布。理解这条消息的关键在于把握它的边界——它只在模式"正常走完生命周期"时出现,用户手动切换与 failsafe 中断都不会触发发布。对于构建地面站任务编排、机载决策逻辑的开发者而言,将mode_completed与vehicle_status的nav_state和 failsafe 标志联合使用,才能获得完整可靠的模式状态视图。

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

【免费下载链接】PX4-Autopilot

PX4 Autopilot Software

项目地址:https://gitcode.com/gh_mirrors/px/PX4-Autopilot
点击查看免费下载
上一篇:Awesome-Dify-Workflow:HTML代码渲染最佳实践
下一篇:sentence-transformers 稀疏编码器(SPLADE)损失函数完全指南:SpladeLoss、FLOPS 正则化与蒸馏实战

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

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

基于CNN的人脸表情识别完整项目:从数据到UI的实战指南

简介&#xff1a;这份资源是面向计算机相关专业学生与项目实战学习者的Python期末大作业完整源码&#xff0c;主题为基于CNN的人脸表情识别系统&#xff0c;适合正在准备课程设计、需要中等难度实战案例的人群参考与二次开发。压缩包共23个文件&#xff0c;约19.17MB&#xff0…

作者头像 李华
网站建设 2026/9/28 2:29:41

多尺度多数据融合:遥感图像检测与融合的工程化实践

简介&#xff1a;本资源是一套面向遥感图像处理初学者与科研实践者的MATLAB代码包&#xff0c;聚焦NASA遥感数据的多尺度分析、多源数据融合及地物检测任务&#xff0c;适用于环境监测、灾害评估与土地覆盖分类等实际应用场景。压缩包共5个.m文件&#xff0c;总大小仅3KB&#…

作者头像 李华
网站建设 2026/9/28 2:28:44

C++扫雷可视化实战:SFML图形界面开发入门

简介&#xff1a;本资源是一份面向C初学者与高校课程设计学生的可视化扫雷小程序完整实现源码&#xff0c;适用于《C程序设计》大作业实践与图形界面编程入门学习。项目基于Qt框架开发&#xff0c;包含15个核心文件&#xff1a;4个cpp实现逻辑与界面交互&#xff0c;3个h头文件…

作者头像 李华
网站建设 2026/9/28 2:28:40

Java网上花店系统实战:从部署到二次开发全解析

简介&#xff1a;这份资源是面向Java初学者与毕业设计学生的网上花店系统完整实战包&#xff0c;围绕Java Web开发全流程展开&#xff0c;帮助读者理解Servlet、JSP、JDBC与MVC模式在实际项目中的落地方式。压缩包共5个文件&#xff0c;包含2个zip源码包、2个mp4部署视频和1个s…

作者头像 李华