PX4 固定翼起飞状态消息 FixedWingTakeoffStatus 全解析:uORB 定义、爬升完成判定与 Navigator 协同逻辑

原创2026-09-26 19:44:241,260 阅读
文章标签:嵌入式物联网机器人自动驾驶智能硬件

PX4 固定翼起飞状态消息 FixedWingTakeoffStatus 全解析:uORB 定义、爬升完成判定与 Navigator 协同逻辑

PX4 Autopilot 通过 FixedWingTakeoffStatus uORB 消息在 FixedWingModeManager(固定翼模式管理器)与 Navigator(导航器)之间传递固定翼起飞(takeoff)的状态信息,核心字段 climbout_completed 用于告知导航器"起飞爬升段是否已完成",从而决定进入后续航点飞行阶段。本文基于 docs/en/msg_docs/FixedWingTakeoffStatus.md 展开,结合 PX4 源码深度解析该消息的字段定义、发布/订阅调用链、参数联动逻辑与实际应用价值,帮助开发者理解固定翼自动起飞流程中状态信号如何生成与消费。

一、消息概览:从模式管理器到导航器的状态信号

FixedWingTakeoffStatus 是一条专用于固定翼起飞流程的 uORB 消息,其设计目标非常聚焦:将固定翼起飞的状态信息从 FixedWingModeManager 传递给 Navigator。消息源定义位于 msg/FixedWingTakeoffStatus.msg,对应的完整 uORB 消息文档为 FixedWingTakeoffStatus.msg 文档。

该消息对应的 uORB topic 名称为 fixed_wing_takeoff_status,消息体极其精简,仅包含两个字段:

字段名 类型 单位 说明
timestamp uint64 us 自系统启动以来的时间(微秒),用于标识该状态报告的产生时刻
climbout_completed bool - 起飞爬升段(climbout)是否已完成(按高度判定,或按 FW_TKO_CLMB_T 参数设定的时间判定)

消息的原始定义如下(与仓库 msg/FixedWingTakeoffStatus.msg 完全一致):

# Status of a fixed-wing takeoff
# Passes information from the FixedWingModeManager to the Navigator.

uint64 timestamp # [us] time since system start

bool climbout_completed  # Whether the takeoff climbout is finished (altitude, or time if FW_TKO_CLMB_T is set)

从源码结构看,该消息由 src/modules/fw_mode_manager/FixedWingModeManager.cpp 中的 publishTakeoffStatus() 函数发布,由 src/modules/navigator/navigator_main.cpp 中的 Navigator::fw_climbout_completed() 函数订阅消费,并同时被日志记录模块(src/modules/logger/logged_topics.cpp)纳入默认可选记录话题,便于飞行日志分析。

二、消息发布端:FixedWingModeManager 的爬升完成判定逻辑

2.1 发布函数实现

消息发布端位于 FixedWingModeManager,其成员声明可参见 FixedWingModeManager.hpp:

uORB::Publication<fixed_wing_takeoff_status_s> _fixed_wing_takeoff_status_pub{ORB_ID(fixed_wing_takeoff_status)};

核心发布逻辑在 FixedWingModeManager::publishTakeoffStatus()(见 FixedWingModeManager.cpp):

void
FixedWingModeManager::publishTakeoffStatus(const bool waiting_for_launch, const float clearance_altitude_amsl)
{
	const hrt_abstime now = hrt_absolute_time();

	if (!waiting_for_launch && _time_climbout_started == 0) {
		// the vehicle just started climbing, either off the launcher or off the runway
		_time_climbout_started = now;
	}

	bool climbout_completed = false;

	if (!waiting_for_launch) {
		if (_param_fw_tko_clmb_t.get() > FLT_EPSILON) {
			climbout_completed = hrt_elapsed_time(&_time_climbout_started) >= _param_fw_tko_clmb_t.get() * 1_s;

		} else {
			climbout_completed = _current_altitude >= clearance_altitude_amsl;
		}
	}

	fixed_wing_takeoff_status_s fixed_wing_takeoff_status{};
	fixed_wing_takeoff_status.timestamp = now;
	fixed_wing_takeoff_status.climbout_completed = climbout_completed;

	_fixed_wing_takeoff_status_pub.publish(fixed_wing_takeoff_status);
}

这段代码揭示了 climbout_completed 的完整判定逻辑:

  1. 爬升起始时刻记录:当 waiting_for_launch 为 false(即车辆已完成发射/滑跑、正在爬升)且 _time_climbout_started 仍为 0 时,将当前时刻记录为爬升开始时间。注释明确说明"the vehicle just started climbing, either off the launcher or off the runway"——即无论是弹射/手抛发射还是跑道滑跑起飞,均从这一时刻起计。
  2. 时间判定模式:当参数 FW_TKO_CLMB_T > 0 时,climbout_completed 判定为"距爬升开始的时间 ≥ FW_TKO_CLMB_T 秒"。
  3. 高度判定模式:当 FW_TKO_CLMB_T 为 0(默认值)时,climbout_completed 判定为"当前高度 ≥ 通过参数传入的 clearance 高度(起飞净空/安全高度)"。
  4. 等待发射阶段:若 waiting_for_launch 为 true(例如跑道滑跑尚未离地),climbout_completed 恒为 false。

2.2 调用时机

publishTakeoffStatus() 在 FixedWingModeManager 的两个关键路径中被调用(见 FixedWingModeManager.cpp 与 FixedWingModeManager.cpp):

  • 自动起飞控制路径(control_auto_takeoff 相关):在跑道滑跑起飞流程中,以 _runway_takeoff.runwayTakeoffEnabled() 等条件计算 waiting_for_launch,并将起飞净空高度 clearance_altitude_amsl 传入。
  • 无导航自动起飞路径(control_auto_takeoff_no_nav):以当前 setpoint 高度作为高度判据传入。

此外,reset_takeoff_state()(见 FixedWingModeManager.cpp)会在起飞状态重置时清空 _time_climbout_started、复位跑道起飞与发射检测器,并记录当前高度作为 _takeoff_ground_alt(起飞地面高度),保证每次起飞的状态统计都是独立干净的。

2.3 相关参数联动

climbout_completed 的两种判定模式由以下参数决定(定义位于 fw_mode_manager_params.yaml):

参数 默认值 单位 说明
FW_TKO_CLMB_T 0.0 s 起飞爬升持续时间。车辆开始爬升后经过该秒数即结束爬升段,替代"达到起飞高度才结束"的判定。设为 0 时,爬升段在达到起飞高度时结束
FW_LAUN_CLR_ALT - m 发射爬升净空高度:低于该高度时飞机保持风补偿的发射航向(而非常规航迹跟踪),且滚转限制从发射点 0 线性增加到该高度处的 FW_R_LIM,避免不良航向估计或糟糕发射在低空引发大坡度。仅对启用了 FW_LAUN_DETCN_ON 的手抛/弹射起飞有效
FW_LAUN_DETCN_ON 0 (bool) - 启用基于测量加速度的自动发射检测,用于手抛或弹射起飞,与跑道起飞不兼容

其中 FW_TKO_CLMB_T 的完整参数定义(fw_mode_manager_params.yaml)为:

FW_TKO_CLMB_T:
  description:
    short: Takeoff climbout duration
    long: |-
      Ends the takeoff climbout this many seconds after the vehicle started climbing, instead of
      when the takeoff altitude is reached.

      If set to 0, the climbout ends at the takeoff altitude.
  type: float
  default: 0.0
  unit: s
  min: 0.0
  decimal: 1
  increment: 1.0

参数类绑定可在 FixedWingModeManager.hpp 等处找到,分别以 _param_fw_tko_clmb_t、_param_fw_laun_clr_alt、_param_fw_t_clmb_max 形式在模块内访问。

三、消息消费端:Navigator 如何利用爬升完成标志

消息订阅端为 Navigator,其订阅对象声明于 navigator.h:

uORB::Subscription _fw_takeoff_status_sub{ORB_ID(fixed_wing_takeoff_status)};	/**< fixed-wing takeoff status subscription */

消费函数为 Navigator::fw_climbout_completed()(见 navigator_main.cpp):

bool Navigator::fw_climbout_completed(float fallback_altitude_amsl)
{
	if (_pos_sp_triplet.current.type != position_setpoint_s::SETPOINT_TYPE_TAKEOFF) {
		// no takeoff is being flown, for example because the mode was entered while already in air,
		// so the mode manager does not report anything and the altitude decides as it did before
		return _global_pos.alt >= fallback_altitude_amsl;
	}

	fixed_wing_takeoff_status_s fixed_wing_takeoff_status;

	if (_fw_takeoff_status_sub.copy(&fixed_wing_takeoff_status)) {
		// the report has to be newer than the setpoint, as it could otherwise still refer to a previous takeoff
		return fixed_wing_takeoff_status.climbout_completed
		       && fixed_wing_takeoff_status.timestamp > _pos_sp_triplet.timestamp;
	}

	return false;
}

这段消费逻辑包含三个关键设计:

  1. 类型守卫:仅当当前航点类型为 SETPOINT_TYPE_TAKEOFF(起飞航点)时才依赖该消息;若不在起飞流程中(例如在飞行中直接切入该模式),则回退到传统的高度比较判定 _global_pos.alt >= fallback_altitude_amsl,保证兼容性。
  2. 新鲜度校验:要求消息的 timestamp 必须晚于当前 position setpoint 三元组的 timestamp,防止消费到上一次起飞遗留的旧状态报告(注释明确说明"the report has to be newer than the setpoint, as it could otherwise still refer to a previous takeoff")。
  3. 双条件收敛:climbout_completed 为真且时间戳新鲜,两者同时满足才认为爬升完成。

该返回值用于导航器决定何时结束起飞航点、转入后续航段(如航点巡航、返航等),是固定翼自动起飞→巡航状态机切换的关键信号。

四、消息在日志系统中的记录

fixed_wing_takeoff_status 被注册为默认的日志记录可选话题,见 logged_topics.cpp:

add_optional_topic("fixed_wing_takeoff_status", 100);

这意味着在标准飞行日志(ULog)中会以 100 Hz 的采样率记录该话题(实际采样受话题发布频率限制),开发者可以通过飞行日志分析工具直接查看 fixed_wing_takeoff_status.climbout_completed 的时间序列,用于事后判断起飞爬升段在何时被判定完成、与实际高度/时间曲线是否吻合,从而辅助调参(例如验证 FW_TKO_CLMB_T 或起飞净空高度设置是否合理)。

五、消息在固定翼起飞流程中的整体作用

综合发布端与消费端源码,可以梳理出该消息在 PX4 固定翼起飞流程中的完整数据流:

  1. 起飞开始:飞机进入自动起飞模式,FixedWingModeManager 运行起飞控制逻辑(跑道滑跑或发射检测)。
  2. 离地/发射爬升:waiting_for_launch 变为 false,publishTakeoffStatus() 记录 _time_climbout_started,随后在每个控制循环中发布 fixed_wing_takeoff_status,其中 climbout_completed 按 FW_TKO_CLMB_T 时间模式或 FW_LAUN_CLR_ALT/净空高度模式动态计算。
  3. Navigator 消费:导航器在起飞航点执行期间通过 fw_climbout_completed() 读取该消息,结合时间戳新鲜度判断爬升完成。
  4. 状态机切换:一旦判定爬升完成,导航器即可推进到后续航点/巡航逻辑,起飞流程结束。

这一"模式管理器发布状态 → 导航器消费并决策"的解耦设计,使得起飞状态的判定逻辑集中在固定翼模式管理器中统一实现(包括发射检测、跑道起飞、净空高度等),而导航器只需关注"爬升是否完成"这一个布尔信号即可完成航段切换,职责边界清晰。

六、扩展阅读

登录后查看全文
PX4-Autopilot