☰
PX4 电调遥测消息 EscReport 详解:字段定义、故障位掩码与源码级应用分析
2026/9/27 21:47:19 网站建设 项目流程
  • 嵌入式
  • 物联网
  • 机器人
  • 自动驾驶
  • 智能硬件

【免费下载链接】PX4-Autopilot

PX4 Autopilot Software

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

本文以 PX4-Autopilot 仓库中 EscReport 消息文档 为核心,系统拆解esc_report这一 uORB 话题的全部字段、枚举与常量定义,并结合仓库内 DroneCAN/UAVCAN ESC 驱动、VOXL ESC 驱动、Commander 健康检查模块与 MAVLink 流实现,说明该消息在真实飞控系统中的产生、消费与故障检测闭环。读完本文,你将能够准确读懂 ESC 遥测日志中的每个字段、理解failures位掩码的每一位含义,并掌握 PX4 如何利用它实现电机故障检测与告警。

1. 消息概览:esc_report是什么

esc_report是 PX4 中使用 uORB 发布/订阅机制传递的单台电调(ESC)遥测消息,话题名为esc_report。它承载一台电机电调在运行时的转速、电压、电流、温度、状态、故障位掩码与施加功率等关键遥测数据,是所有 ESC 健康监测、电机故障检测与地面站显示功能的数据基础。

消息定义源文件位于 msg/EscReport.msg,对应的自动生成文档为 docs/en/msg_docs/EscReport.md。在实际系统中,单台电调的esc_report消息会被聚合进容器话题esc_status(定义见 msg/EscStatus.msg),其中包含最多 12 台电调的EscReport[12] esc数组,供上层模块统一订阅。

2. 字段定义与单位说明

EscReport共包含 10 个字段,完整定义如下表。所有字段均带- if supported语义:即只有电调固件/协议支持相应遥测时,该字段才有有效值,否则保持为零。

字段名类型单位说明
timestampuint64us自系统启动以来的时间戳(微秒)
esc_errorcountuint32-ESC 上报的错误计数(若支持)
esc_rpmint32rpm电机转速,负值表示反转(若支持)
esc_voltagefloat32V该 ESC 处测量到的电压(若支持)
esc_currentfloat32A该 ESC 处测量到的电流(若支持)
esc_temperaturefloat32degC该 ESC 处测量到的温度(若支持)
motor_temperatureint16degC电机本体测量温度(若支持)
esc_stateuint8-ESC 状态,具体取值依赖厂商
actuator_functionuint8-执行机构输出功能(Motor1…MotorN 之一)
failuresuint16-指示 ESC 内部故障的位掩码(见 FAILURE 枚举)
esc_powerint8%已施加功率,范围 [0 : 100],负值保留

2.1 关键字段深入解读

timestamp(uint64, us):时间戳是 uORB 消息的通用首字段,用于表示该条遥测数据的采集时刻。在 src/drivers/uavcan/actuators/esc.cpp 中,DroneCAN ESC 驱动以hrt_absolute_time()填充该字段,供上层判断遥测是否超时。

esc_rpm(int32, rpm):电机转速,单位 rpm。负值表示反转——这是分析转向/混控配置时的重要信号。在 VOXL ESC 驱动中,转速取自反馈包fb.rpm(见 src/drivers/actuators/voxl_esc/voxl_esc.cpp 的parse_response实现,_esc_status.esc[id].esc_rpm = fb.rpm)。

esc_voltage/esc_current:电调母线电压与电流。VOXL 驱动中电压以 0.001 V、电流以 0.008 A 的分辨率从反馈包解码(fb.voltage * 0.001f、fb.current * 0.008f)。这两个值也是下文电机欠流/过流故障检测的核心输入。

esc_temperature(float32, degC):ESC 板载温度。注意 DroneCAN 驱动中原始数据为开尔文温标,填充时需转换:esc_report.esc_temperature = msg.temperature + atmosphere::kAbsoluteNullCelsius; // Kelvin to Celsius。

motor_temperature(int16, degC):电机本体温度,由支持该遥测的电调(如 DroneCAN 扩展状态报文)单独上报。

esc_state(uint8):ESC 状态,取值依赖厂商协议,PX4 侧只透传不做解释。

actuator_function(uint8):该 ESC 绑定的执行机构输出功能编号,取值为ACTUATOR_FUNCTION_MOTOR1(101)至ACTUATOR_FUNCTION_MOTOR_MAX(112)之间的 Motor 编号。它把物理 ESC 与混控输出通道对应起来,是上层判断"哪一台电机"的关键索引。

esc_power(int8, %):当前施加给电机的功率百分比,范围 [0, 100],负值保留。VOXL 驱动直接取反馈包fb.power。

3. FAILURE 故障枚举:failures位掩码逐位解析

failures是uint16类型的位掩码,每一位对应一种电调内部故障。定义在 msg/EscReport.msg 中以uint8 FAILURE_* = N常量给出位号,实际使用1 << N置位。完整枚举如下:

枚举名位号掩码说明
FAILURE_OVER_CURRENT0(1 << 0)过流
FAILURE_OVER_VOLTAGE1(1 << 1)过压
FAILURE_MOTOR_OVER_TEMPERATURE2(1 << 2)电机超温(临界)
FAILURE_OVER_RPM3(1 << 3)超转速
FAILURE_INCONSISTENT_CMD4(1 << 4)收到不一致指令(如超出边界)
FAILURE_MOTOR_STUCK5(1 << 5)电机堵转
FAILURE_GENERIC6(1 << 6)通用硬件故障
FAILURE_MOTOR_WARN_TEMPERATURE7(1 << 7)电机温度告警
FAILURE_WARN_ESC_TEMPERATURE8(1 << 8)ESC 温度告警
FAILURE_OVER_ESC_TEMPERATURE9(1 << 9)ESC 超温(临界)

3.1 故障位掩码在驱动层的产生方式

故障位掩码的产生有两种典型路径:

路径一:协议级故障映射(DroneCAN/UAVCAN)。src/drivers/uavcan/actuators/esc.cpp中的get_failures()函数将 DroneCAN ESC 状态报文的 fault 码映射到本枚举,例如:状态 3/4 →FAILURE_OVER_CURRENT,状态 5 →FAILURE_OVER_ESC_TEMPERATURE,状态 6 →FAILURE_MOTOR_OVER_TEMPERATURE,状态 8 →FAILURE_OVER_RPM,状态 10 →FAILURE_MOTOR_WARN_TEMPERATURE。若报文含故障但无法具体解析,则回退置位FAILURE_GENERIC。

路径二:飞控侧阈值判断(VOXL ESC)。VOXL ESC 驱动在解析反馈包后,根据参数VOXL_ESC_T_OVER(过温阈值)与VOXL_ESC_T_WARN(告警阈值)自行置位:

if ((_parameters.esc_over_temp_threshold > 0) && (_esc_status.esc[id].esc_temperature > _parameters.esc_over_temp_threshold)) { _esc_status.esc[id].failures |= 1 << (esc_report_s::FAILURE_OVER_ESC_TEMPERATURE); } if ((_parameters.esc_warn_temp_threshold > 0) && (_esc_status.esc[id].esc_temperature > _parameters.esc_warn_temp_threshold)) { _esc_status.esc[id].failures |= 1 << (esc_report_s::FAILURE_WARN_ESC_TEMPERATURE); }

这段代码同时展示了位掩码的标准用法:failures |= 1 << (esc_report_s::FAILURE_XXX)。

4. 消息常量:执行机构功能编号与故障计数

EscReport.msg还定义了三个常量:

常量名类型值说明
ACTUATOR_FUNCTION_MOTOR1uint8101第一个电机执行机构功能编号
ACTUATOR_FUNCTION_MOTOR_MAXuint8112最后一个电机功能编号,即output_functions.yaml中Motor.start + Motor.count - 1
ESC_FAILURE_COUNTuint810故障类型总数(计数器),必须保持在最后一个元素

4.1 常量在源码中的实际使用

ACTUATOR_FUNCTION_MOTOR1/ACTUATOR_FUNCTION_MOTOR_MAX是判断某条esc_report是否属于电机输出的区间边界。多个模块都使用math::isInRange(esc.esc[j].actuator_function, esc_report_s::ACTUATOR_FUNCTION_MOTOR1, esc_report_s::ACTUATOR_FUNCTION_MOTOR_MAX)过滤非电机条目:

  • src/modules/mavlink/streams/ESC_STATUS.hpp:MAVLinkESC_STATUS流只打包电机范围内的 ESC,并通过index = actuator_function - ACTUATOR_FUNCTION_MOTOR1将功能编号映射为 0 起始的数组下标;
  • src/modules/commander/HealthAndArmingChecks/checks/escCheck.cpp:在线检测、故障检测、温度检测前均先跳过未映射的 ESC 条目。

ESC_FAILURE_COUNT用于保证 PX4 事件枚举与消息位掩码一致。escCheck.cpp顶部有编译期断言:

static_assert(esc_report_s::ESC_FAILURE_COUNT == (static_cast<uint8_t>(esc_fault_reason_t::_max) + 1), "ESC fault flags mismatch!");

即事件系统esc_fault_reason_t的枚举数量必须与ESC_FAILURE_COUNT严格对应,否则编译失败——这从机制上杜绝了消息定义与上层告警逻辑不同步的问题。

5. 消息定义源文件(完整)

EscReport的原始定义位于 msg/EscReport.msg,完整内容如下(与文档中 "Source Message" 折叠块一致):

uint64 timestamp # [us] Time since system start uint32 esc_errorcount # [-] Number of reported errors by ESC - if supported int32 esc_rpm # [rpm] Motor RPM, negative for reverse rotation - if supported float32 esc_voltage # [V] Voltage measured from current ESC - if supported float32 esc_current # [A] Current measured from current ESC - if supported float32 esc_temperature # [degC] Temperature measured from current ESC - if supported int16 motor_temperature # [degC] Temperature measured from current motor - if supported uint8 esc_state # [-] State of ESC - depend on Vendor uint8 actuator_function # [-] Actuator output function (one of Motor1...MotorN) uint8 ACTUATOR_FUNCTION_MOTOR1 = 101 uint8 ACTUATOR_FUNCTION_MOTOR_MAX = 112 # output_functions.yaml Motor.start + Motor.count - 1 uint16 failures # [@enum FAILURE] Bitmask to indicate the internal ESC faults int8 esc_power # [%] [@range 0,100] Applied power (negative values reserved) uint8 FAILURE_OVER_CURRENT = 0 # (1 << 0) uint8 FAILURE_OVER_VOLTAGE = 1 # (1 << 1) uint8 FAILURE_MOTOR_OVER_TEMPERATURE = 2 # (1 << 2) uint8 FAILURE_OVER_RPM = 3 # (1 << 3) uint8 FAILURE_INCONSISTENT_CMD = 4 # (1 << 4) Set if ESC received an inconsistent command (i.e out of boundaries) uint8 FAILURE_MOTOR_STUCK = 5 # (1 << 5) uint8 FAILURE_GENERIC = 6 # (1 << 6) uint8 FAILURE_MOTOR_WARN_TEMPERATURE = 7 # (1 << 7) uint8 FAILURE_WARN_ESC_TEMPERATURE = 8 # (1 << 8) uint8 FAILURE_OVER_ESC_TEMPERATURE = 9 # (1 << 9) uint8 ESC_FAILURE_COUNT = 10 # Counter - keep it as last element!

6. 数据流:esc_report如何进入飞控系统

6.1 聚合容器esc_status

单台电调的esc_report并不会单独被上层订阅,而是由驱动填充进 msg/EscStatus.msg 定义的esc_status_s结构(字段EscReport[12] esc),随容器话题一起发布。esc_status同时携带:

  • counter:写入线程每次存入新数据时自增的计数器;
  • esc_count:连接的 ESC 数量;
  • esc_connectiontype:连接类型枚举(PPM=0、串行总线=1、OneShot=2、I2C=3、CAN=4、DShot=5);
  • esc_online_flags/esc_armed_flags:按电机顺序排列的在线/武装位掩码。

6.2 驱动侧填充示例

以 VOXL ESC 驱动(src/drivers/actuators/voxl_esc/voxl_esc.cpp)为例,其在解析 UART 反馈包后依次填充单条esc_report:

_esc_status.esc[id].timestamp = tnow; _esc_status.esc[id].esc_rpm = fb.rpm; _esc_status.esc[id].esc_power = fb.power; _esc_status.esc[id].esc_state = fb.id_state & 0x0F; _esc_status.esc[id].esc_voltage = _esc_chans[id].voltage; _esc_status.esc[id].esc_current = _esc_chans[id].current; _esc_status.esc[id].failures = 0; // not implemented

DroneCAN 驱动(src/drivers/uavcan/actuators/esc.cpp)则在 status 与 extended status 回调中分别填充遥测与motor_temperature、esc_power,并调用get_failures()完成协议故障映射。

6.3 地面站可见性:MAVLink ESC_STATUS 流

src/modules/mavlink/streams/ESC_STATUS.hpp 将esc_status转发为 MAVLinkESC_STATUS消息(QGroundControl 等地面站即以此显示转速/电压/电流)。其update_data()中通过actuator_function的范围判断和索引映射,将每条esc_report的 rpm/voltage/current 按电机顺序填入 MAVLink 报文,并在遥测超时(ESC_TIMEOUT = 100000 us)时不发送对应槽位。同样地,ESC_INFO.hpp 处理电调身份信息。

7. 消费侧:Commander 健康检查与电机故障检测

esc_status(内含各条esc_report)最重要的消费者是 Commander 的电机/电调健康检查模块 src/modules/commander/HealthAndArmingChecks/checks/escCheck.cpp,其核心逻辑如下:

7.1 ESC 在线检测(checkEscOnline)

通过esc_online_flags位掩码与遥测超时(ESC_TIMEOUT_US)判断电调是否离线。任何一台电机范围内的 ESC 离线即置健康故障位,并在已武装时提示Land now!。

7.2 故障位掩码检测(checkEscStatus)

遍历每条esc_report的failures位掩码,逐位与esc_fault_reason_t事件枚举对应,产生可读的故障原因与建议动作:

  • 温度告警类(motor_warn_temp、esc_warn_temp、over_rpm)→ 建议 "Reduce throttle"(降低油门);
  • 其余严重故障(过流、过压、堵转、临界超温等)→ 建议 "Land now!"(立即降落)。

同时通过static_assert(见 4.1 节)保证该事件枚举与消息定义同步。

7.3 电机欠流/过流检测(checkMotorStatus)

该模块还利用esc_current与混控输出actuator_motors.control[]的对应关系检测电机电气故障:

  • 欠流判据:current < thrust * MOT_FAIL_C2T - MOT_FAIL_OFF;
  • 过流判据:current > thrust * MOT_FAIL_C2T + MOT_FAIL_OFF;

其中MOT_FAIL_C2T(电流-推力系数)、MOT_FAIL_OFF(偏移量)、MOT_FAIL_TIME(迟滞时间)等参数由FD_ACT_EN参数开关控制,并采用"只置位、空中不清除"的迟滞策略,避免误恢复。

7.4 温度告警(checkEscTemperature)

由参数ESC_TEMP_WARN_TH配置告警阈值,找出最热的 ESC 并持续告警(High ESC temperature. Reduce throttle!),温度回落 5 °C 后解除告警状态。

8. 实际调试建议

  • 查看遥测是否到达:若esc_status从未发布,常见原因为连接类型不匹配(见esc_connectiontype枚举)或串口/CAN 参数配置错误;可先确认对应驱动(如voxl_esc、uavcan)已正常 start 并检测到 ESC。
  • 解读日志:飞行日志中的esc_status话题可直接回放各esc_report字段;重点观察failures位掩码——任何非零位都对应上表中的一个具体故障,配合 Commander 事件(如ESC {1}: {2})可快速定位故障电机编号与原因。
  • 温度阈值参数:VOXL 方案下VOXL_ESC_T_WARN/VOXL_ESC_T_OVER决定FAILURE_WARN_ESC_TEMPERATURE/FAILURE_OVER_ESC_TEMPERATURE的置位时机;全局层面ESC_TEMP_WARN_TH决定 Commander 的告警行为。
  • 扩展消息:如需要新增故障类型,必须在 msg/EscReport.msg 中追加FAILURE_*常量并保持ESC_FAILURE_COUNT为最后一个元素,同时同步更新esc_fault_reason_t事件枚举,否则编译期断言会直接报错。

9. 小结

esc_report是 PX4 电调遥测体系的原子消息:10 个业务字段 + 10 位故障掩码 + 3 个系统常量,构成了电机健康监测的最小数据单元。它由各类 ESC 驱动(DroneCAN、VOXL 串行等)填充,经esc_status容器聚合发布,最终被 Commander 健康检查(在线/故障/电流/温度四类检测)与 MAVLink 地面站流(ESC_STATUS)消费,形成"采集 → 聚合 → 检测 → 告警 → 引导处置"的完整闭环。理解这份消息定义,是读懂 PX4 电机遥测日志、定位 ESC 故障和扩展电调能力的第一步。

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

【免费下载链接】PX4-Autopilot

PX4 Autopilot Software

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

相关推荐

上一篇:3步打造Windows任务栏股票监控:TrafficMonitor插件实战指南
下一篇:终极指南:免费解锁Wand专业版功能,告别2小时限制

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询