- 嵌入式
- 物联网
- 机器人
- 自动驾驶
- 智能硬件
【免费下载链接】PX4-Autopilot
PX4 Autopilot Software
导读
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 | 描述 |
|---|---|---|---|---|
timestamp | uint64 | — | — | 系统启动以来的时间(微秒) |
result | uint8 | — | — | 取值必须为RESULT_*系列常量之一 |
nav_state | uint8 | — | — | 来源模式(取值参照 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_VERSION | uint32 | 0 | 消息格式版本号 |
RESULT_SUCCESS | uint8 | 0 | 模式成功完成 |
RESULT_FAILURE_OTHER | uint8 | 100 | 模式失败(通用错误) |
值得注意的细节是,源消息文件 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);注意两个细节:
- 默认参数:
result默认值为RESULT_SUCCESS,即调用方不传失败结果时,默认发布"成功完成"。 - 发布器成员:在 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.cpp | mission_result->finished为真 |
| 自动降落(Land) | land.cpp | mission_result->finished为真 |
| VTOL 自动起飞 | vtol_takeoff.cpp | mission_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会递增,订阅方应按版本号做兼容解析。
六、发布边界与局限(文档明确说明)
原文档明确强调:这不是一个"总会发布"的消息。具体而言:
- 用户手动切换模式时不发布——例如飞行员通过遥控器或地面站主动从 Auto 模式切到 Position 模式,此时没有"完成结果"可言;
- failsafe 激活时不发布——当系统触发 failsafe(如返航、悬停、终止)而中断当前模式时,模式是被强制的、非正常退出,因此不产生完成事件;
- 失败原因粒度粗——目前只有
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
相关推荐
PX4-Autopilot uORB 消息详解:ActuatorServosV0(actuator_servos_v0)舵机归一化控制消息
PX4 Autopilot uORB 消息详解:ActuatorServosV0(actuator_servos_v0)舵机归一化控制消息 ActuatorSe
嵌入式物联网机器人自动驾驶智能硬件AsyncAwaitBestPractices MVVM实战:AsyncCommand和AsyncValueCommand的完整教程
AsyncAwaitBestPractices MVVM实战:AsyncCommand和AsyncValueCommand的完整教程 在.NET开发中,异步编程
开发工具软件架构PX4-Autopilot LogMessage(log_message)UORB 消息详解:文本日志的采集、发布与落盘机制
PX4 Autopilot LogMessage(log_message)UORB 消息详解:文本日志的采集、发布与落盘机制 本篇技术指南围绕 PX4 Auto
嵌入式物联网机器人自动驾驶智能硬件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考