日志文件格式解析:.bin、.tlog、.ulg 到底存了什么?

做飞控日志分析,第一关就是面对一堆后缀名不同的文件。.bin、.tlog、.ulg……说实话,我刚入行那会儿也被这些格式搞晕过。有一次客户发来一个 .bin 文件,我习惯性用 PX4 的 pyulog 去解析,结果报错一堆。后来才反应过来——那是 ArduPilot 的日志。

所以这一节,咱们就把这三种主流日志格式掰开揉碎,看看它们内部到底长什么样。你搞懂了这些,后面分析问题才能有的放矢。

1. .bin 文件结构(ArduPilot 原生格式)

.bin 是 ArduPilot 的二进制日志格式。说白了,它就是把传感器数据、状态信息一股脑按二进制流写进文件。为什么用二进制?因为省空间、写入快。飞控上的存储资源就那么点,用文本存日志太奢侈了。

核心特点:

  • 紧凑二进制:每条记录按固定格式打包,没有冗余分隔符
  • 自描述头:文件开头有 FMT 消息,定义了后续所有数据类型的格式
  • 消息类型驱动:每个消息有一个 1 字节的 Type ID,最多支持 256 种类型
  • 时间戳:每条消息都带微秒级时间戳,基于系统启动时间

我习惯用 mavlogdump.py 来解析 .bin 文件。这个工具是 ArduPilot 官方提供的,能把二进制转成人类可读的文本。

# 基本用法:查看文件头信息
mavlogdump.py --types FMT flight.bin

# 提取 GPS 数据
mavlogdump.py --types GPS flight.bin

# 导出为 CSV,方便导入 Excel 或 Python 分析
mavlogdump.py --types GPS,IMU --format csv flight.bin > flight.csv

这里有个坑,我曾经踩过——FMT 消息必须在文件开头。如果日志文件被截断,头信息丢失,后面的数据就全废了。所以拿到 .bin 文件,第一件事就是检查 FMT 是否完整。

我的小技巧:用 mavlogdump.py --show-formats flight.bin 可以列出所有已定义的格式。如果输出为空,说明文件头损坏,基本可以放弃治疗了。

2. .tlog 文件结构(MAVLink 原生格式)

.tlog 是地面站(比如 Mission Planner、QGroundControl)录制的 MAVLink 原始数据流。它跟 .bin 最大的区别是:.tlog 记录的是飞控和地面站之间传输的 MAVLink 报文,而不是飞控内部的数据。

你想想看,飞控内部可能以 1000Hz 采集 IMU 数据,但通过 MAVLink 发出来的可能只有 50Hz。所以 .tlog 的数据密度比 .bin 低得多。但它有一个 .bin 没有的优势——记录了地面站发出的指令,比如模式切换、参数修改、航点上传等。

注意:.tlog 文件可能包含多个 MAVLink 系统的数据。如果你在同一个地面站连接了多架无人机,所有飞机的报文会混在一起。解析时一定要按 System ID 和 Component ID 过滤。

.tlog 的结构其实很简单:

  • 文件头:无固定格式,直接就是 MAVLink 报文流
  • 报文流:每个报文由 MAVLink 帧头 + 负载 + 校验组成
  • 时间戳:地面站收到报文时打上的时间戳(不是飞控时间)

解析 .tlog 我推荐用 mavlogdump.py 的 --format tlog 模式:

# 查看所有 HEARTBEAT 消息
mavlogdump.py --types HEARTBEAT --format tlog flight.tlog

# 提取 GPS_RAW_INT 数据
mavlogdump.py --types GPS_RAW_INT --format tlog flight.tlog

# 带时间戳输出
mavlogdump.py --types GPS_RAW_INT --format tlog --timestamps flight.tlog

我个人习惯在分析炸机案例时,同时拿到 .bin 和 .tlog。.bin 看飞控内部状态,.tlog 看地面站发了什么指令。有一次我遇到一个案例,飞控日志显示一切正常,但飞机就是乱飞。后来查 .tlog 才发现,地面站误发了错误的航点指令。光看 .bin 根本发现不了这个问题。

3. .ulg 文件结构(PX4 原生格式)

.ulg 是 PX4 的日志格式,全称是 "uORB Logging"。它跟 .bin 类似,也是二进制格式,但设计上更现代化一些。

.ulg 的结构分为三个部分:

  1. 文件头:12 字节,包含魔数、版本号、时间戳偏移
  2. 定义段:定义所有数据类型和格式(类似 .bin 的 FMT)
  3. 数据段:实际的日志数据,按订阅的主题(topic)组织

.ulg 相比 .bin 的优势:

  • 支持嵌套数据结构(.bin 只支持扁平结构)
  • 支持字符串类型(.bin 只能用枚举或数值表示)
  • 支持多文件追加(.bin 只能单次写入)
  • 自带 CRC32 校验(.bin 没有校验)

解析 .ulg 我主要用 pyulog 工具包:

# 查看日志信息
ulog_info flight.ulg

# 提取传感器数据为 CSV
ulog2csv flight.ulg

# 提取特定主题
ulog2csv --messages sensor_accel,sensor_gyro flight.ulg

# 查看消息频率
ulog_info -v flight.ulg | grep "msg"

嗯,这里要注意一个细节——.ulg 的时间戳是纳秒级的,而 .bin 是微秒级。如果你做时间对齐分析,一定要统一单位。我曾经因为这个吃过亏,把两个日志的时间戳直接相减,结果差了三个数量级,折腾了半天才发现是单位问题。

4. PX4 日志 vs ArduPilot 日志:核心区别

很多初学者会问:PX4 和 ArduPilot 的日志到底能不能通用?答案是不能。虽然它们都基于 MAVLink 协议,但日志格式完全不同。

对比维度 PX4 (.ulg) ArduPilot (.bin)
文件格式 二进制,自描述 二进制,自描述
数据组织 基于 uORB 主题订阅 基于消息类型 (FMT)
时间戳精度 纳秒级 微秒级
数据结构 支持嵌套、数组、字符串 仅支持扁平结构
日志触发 自动记录所有订阅的主题 需手动配置 LOG_BITMASK
文件大小 相对较大(含元数据) 相对较小(紧凑二进制)
解析工具 pyulog, FlightPlot mavlogdump.py, Mission Planner
地面站日志 .tlog (MAVLink 原始流) .tlog (MAVLink 原始流)

我个人在项目中遇到过这样一个场景:客户从 PX4 切换到 ArduPilot,拿着 .ulg 文件想用 Mission Planner 打开,结果打不开。其实不是工具的问题,是格式完全不兼容。你需要用对应的工具链去解析。

我的建议:如果你同时接触两个平台,最好在电脑上同时装好两套工具链:

  • PX4 工具链:pyulog + FlightPlot + QGroundControl
  • ArduPilot 工具链:mavlogdump.py + Mission Planner + MAVExplorer

这样无论拿到什么格式,都能快速上手分析。

5. 三种格式的适用场景对比

搞清楚了结构,咱们还得知道什么时候用哪种格式。我总结了一张图,帮你快速决策:

日志格式选择决策流程 拿到日志文件 .bin 文件 .tlog 文件 .ulg 文件 ArduPilot 原生 飞控内部完整数据 高频率、高密度 用于深度故障分析 MAVLink 原始流 地面站录制 含地面站指令 用于通信问题分析 PX4 原生 飞控内部完整数据 支持复杂数据结构 用于深度故障分析 推荐工具 mavlogdump.py 推荐工具 mavlogdump.py 推荐工具 pyulog 核心原则:.bin/.ulg 看飞控内部,.tlog 看通信链路 炸机分析建议同时获取两种格式

最后说一个实战中的经验:不要只看一种日志。我处理过的炸机案例中,至少有 30% 是单纯看 .bin 或 .ulg 发现不了问题的。比如 GPS 干扰问题,飞控内部日志可能显示 GPS 信号正常,但 .tlog 里能看到地面站收到的 GPS 数据有跳变。两种日志互相印证,才能还原事故全貌。

避坑指南:我曾经遇到一个案例,.bin 文件里 GPS 数据看起来完美,但飞机就是偏航。后来对比 .tlog 才发现,地面站收到的 GPS 数据有周期性丢包。原因是飞控的 GPS 模块输出频率太高,MAVLink 链路带宽不够,导致部分数据被丢弃。飞控内部日志记录的是传感器原始数据,而 .tlog 记录的是实际传输的数据——两者不一致,恰恰暴露了问题所在。