2、无人机日志基础:常见日志格式(ULog、PX4/ArduPilot日志)、数据字段、时间戳含义

无人机日志是飞行控制系统在运行过程中自动记录的数据集合,它如同飞机的“黑匣子”,完整保存了飞控内部状态、传感器原始数据、控制指令输出以及外部输入信号。在无人机调试与故障分析中,日志回放是还原飞行过程、定位异常根因的核心手段。本章将系统讲解无人机日志的常见格式(ULog、PX4/ArduPilot日志)、关键数据字段的组织方式,以及时间戳在数据对齐中的核心作用,为后续章节的日志回放调试打下坚实基础。

无人机日志格式与数据链路 ULog 格式 PX4 原生二进制格式 带类型定义(消息定义) 支持嵌套/数组/位域 自带CRC校验 ArduPilot 日志 自描述文本格式(类似) FMT/MSG/PARAM 定义 字段名+类型+缩放因子 兼容旧版工具链 CSV/文本日志 地面站导出/传感器调试 逗号分隔,可读性强 缺少类型定义 适合快速查看 核心数据字段分类 时间戳 (us/ms) 姿态/角速度 (ATT/IMU) 控制输出 (ACT/OUT) 传感器原始值 (BARO/MAG/GPS) 时间戳对齐机制 硬件时间戳 (传感器中断) 软件时间戳 (任务调度) 回放时线性插值对齐 延迟补偿

上图展示了无人机日志系统的整体框架:左侧为三种主流日志格式,中间为数据字段分类,右侧为时间戳对齐机制。在实际调试中,我们通常需要同时理解这三种格式的差异,并掌握如何从原始日志中提取关键字段进行时间对齐分析。

2.1 核心原理:日志格式的设计哲学与数据组织

无人机日志格式的设计目标是在有限的存储空间内,以尽可能高的效率记录飞行过程中的关键信息。不同飞控系统采用了不同的设计思路,但核心原理相通:通过“定义-数据”分离的方式,减少重复存储,提高写入效率。

2.1.1 ULog格式(PX4原生)

ULog是PX4飞控自v1.6版本起采用的二进制日志格式,其设计借鉴了ROS的bag格式思想,但针对嵌入式环境做了深度优化。ULog文件由三部分组成:

  • 文件头(Header):包含魔数(0x55 0x4C 0x6F 0x67)、版本号、时间戳偏移量等元信息。
  • 定义区(Definitions):以“消息定义”的形式声明后续数据块的结构,包括消息名称、字段名、字段类型、数组维度等。例如,IMU消息定义会声明gyro_rad[3]、accel_m_s2[3]等字段。
  • 数据区(Data):按时间顺序存储实际数据块,每个数据块包含消息ID、时间戳(微秒)和字段值。

ULog的关键优势在于自描述性——即使没有外部数据库,解析器也能通过定义区完整还原数据结构。这使得不同版本的PX4固件产生的日志都能被通用工具(如Flight Review、PlotJuggler)正确解析。

2.1.2 ArduPilot日志格式

ArduPilot(APM)采用基于文本的日志格式,虽然文件体积较大,但具有极高的可读性。其核心结构包括:

  • FMT(Format)消息:定义数据格式,例如FMT, 130, ATT, QIccC, TimeUS, Roll, Pitch, Yaw表示消息ID为130,名称为ATT,包含5个字段(Q表示uint64,I表示int32,c表示int16,C表示uint16)。
  • MSG(Message)消息:记录文本信息,如飞控状态切换、错误提示等。
  • PARAM(Parameter)消息:记录参数值,用于回放时还原飞控配置。
  • 数据消息:以FMT定义的结构存储实际数据,如ATT, 1234567890, -0.01, 0.02, 1.57。

ArduPilot格式的优点是无需专用解析器即可用文本编辑器查看,但缺点是字段类型信息依赖FMT消息,且缩放因子(如将int16转换为实际物理量)需要额外处理。

2.1.3 数据字段的语义分层

无论哪种格式,日志数据字段都可以分为四个层次:

层次典型字段用途
时间基准TimeUS(微秒)、timestamp(毫秒)所有数据对齐的锚点
传感器原始值gyro_rad[0..2]、accel_m_s2[0..2]、mag_ga[0..2]物理量测量值,用于姿态解算和振动分析
状态估计输出Roll、Pitch、Yaw、RollRate、PitchRate、YawRate飞控内部姿态估计结果,用于控制回路
控制输出actuator_controls[0..3]、servo_out[0..7]PWM/电压指令,反映飞控对电机的最终指令

理解字段的语义分层是日志回放调试的基础——当我们需要判断“是传感器噪声导致姿态波动,还是控制输出异常导致电机抖动”时,必须同时查看这三个层次的数据。

2.2 判断方法:如何选择日志格式与提取关键字段

在实际调试中,我们经常需要根据飞控平台和调试目标选择合适的日志工具。以下是具体的操作流程:

  1. 确认飞控固件类型:PX4使用ulog文件,ArduPilot使用.bin或.log文件。可通过飞控参数SYS_AUTOSTART或地面站连接信息确认。
  2. 配置日志记录级别:PX4通过SDLOG_MODE和SDLOG_PROFILE参数控制记录内容;ArduPilot通过LOG_BITMASK参数选择需要记录的组别(如ATTITUDE_FAST、IMU、CTUN等)。
  3. 导出日志文件:通过USB连接飞控,使用QGroundControl或Mission Planner下载日志。
  4. 使用解析工具:PX4推荐使用Flight Review(在线工具)或PlotJuggler(本地工具);ArduPilot推荐使用Mission Planner的“数据闪存日志”页面或MAVExplorer。
  5. 提取关键字段:根据调试目标选择字段。例如,排查电机响应延迟时,需要同时提取actuator_controls(控制指令)和actuator_outputs(实际输出)以及vehicle_attitude(姿态响应)。
经验提示:在PX4中,使用ulog_info命令行工具可以快速查看日志中包含的消息类型和持续时间。例如:ulog_info flight.ulg会输出所有消息ID、名称和记录时长,帮助快速定位可用数据。

2.3 案例拆解:一次电机响应延迟的日志分析

下面通过一个实际案例,演示如何利用日志格式知识定位问题。

背景与约束:某四旋翼无人机在悬停时出现轻微低频抖动(约2Hz),飞控为PX4 1.13,使用标准ULog日志。用户反馈“飞机像在呼吸一样上下起伏”。

初始现象与目标:悬停油门输出在35%~45%之间周期性波动,姿态角(Pitch/Roll)波动幅度约±2°。目标是通过日志回放确定抖动来源是传感器噪声、姿态估计延迟还是控制参数不当。

关键输入数据:下载的flight.ulg文件,包含以下消息:sensor_combined(IMU原始数据)、vehicle_attitude(姿态估计)、actuator_controls_0(控制指令)、actuator_outputs(PWM输出)。

分析判断过程:

  1. 使用PlotJuggler加载日志,将actuator_controls_0[1](Pitch控制指令)和vehicle_attitude[1](Pitch角)绘制在同一时间轴。
  2. 观察发现:Pitch角波动峰值出现在控制指令峰值之后约80ms。这个延迟明显高于正常值(通常应小于20ms)。
  3. 进一步检查sensor_combined中的陀螺仪数据,发现其时间戳与vehicle_attitude时间戳存在约30ms的固定偏移。
  4. 查看PX4参数IMU_GYRO_RATEMAX(陀螺仪采样率)和ATT_W_ACC(加速度计权重),发现采样率设置为500Hz,但实际日志中陀螺仪数据间隔不均匀,存在丢帧现象。

实际操作步骤:

# 使用ulog_info检查消息时间戳分布
ulog_info flight.ulg | grep "sensor_combined"
# 输出显示:sensor_combined, 500Hz, 12000 messages, 24.0s duration

# 使用Python脚本分析时间戳间隔
import ulog
ulog_file = ulog.ULog("flight.ulg")
for msg in ulog_file.data_list:
    if msg.name == "sensor_combined":
        timestamps = msg.timestamps
        diff = np.diff(timestamps)
        print(f"平均间隔: {np.mean(diff)/1000:.2f}ms, 最大间隔: {np.max(diff)/1000:.2f}ms")
# 输出:平均间隔 2.01ms, 最大间隔 8.5ms(存在明显抖动)

结果对比与风险:通过将IMU_GYRO_RATEMAX从500Hz降低到400Hz,并启用IMU_GYRO_DNF_EN(动态低通滤波),重新飞行后抖动幅度从±2°降低到±0.5°。但代价是高频振动信息丢失,需要后续通过FFT分析确认是否影响其他频段。

复盘经验:日志时间戳的均匀性是判断传感器数据质量的重要指标。当发现控制指令与姿态响应之间的延迟异常时,应首先检查时间戳对齐情况,而非直接调整PID参数。

2.4 常见误区与总结复盘

在日志格式理解与使用中,初学者常犯以下错误:

风险警示:
  • 误区一:混淆时间戳单位。PX4的ULog时间戳单位为微秒(us),而ArduPilot的TimeUS也是微秒,但部分CSV导出工具会转换为毫秒(ms)。若直接混用,会导致时间轴缩放错误,误判数据延迟。
  • 误区二:忽略消息定义中的缩放因子。ArduPilot的FMT消息中,字段类型为c(int16)时,实际物理量需要乘以缩放因子(如0.001)。直接使用原始整数值会导致量纲错误。
  • 误区三:只关注控制输出,忽略传感器原始数据。当电机响应异常时,可能是传感器噪声导致姿态估计错误,进而引发错误的控制指令。必须同时查看传感器层和控制层数据。
  • 误区四:认为日志记录是“无损”的。飞控在CPU负载高时可能丢帧,导致时间戳不连续。回放时应检查时间戳间隔,必要时进行插值处理。

总结复盘:掌握日志格式的核心在于理解“定义-数据”分离的存储哲学,以及时间戳作为数据对齐锚点的关键作用。在实际调试中,建议遵循以下流程:

  1. 确认日志格式与版本,选择合适的解析工具。
  2. 检查时间戳的连续性和单位,确保数据对齐可靠。
  3. 按“传感器→状态估计→控制输出”的链路逐层分析,定位异常环节。
  4. 记录每次调试的参数修改和日志特征,建立问题-现象-根因的映射库。