2. 日志文件结构
日志文件,说白了就是无人机飞行时的「黑匣子」。我见过不少新手拿到日志后一脸茫然,不知道从哪下手。今天咱们就把这三种常见格式——.bin、.log、.ulg——彻底讲透。
三种格式的来龙去脉
先说说它们各自的身世。我个人习惯把日志格式分成两派:
- .bin 格式:PX4 固件的原生二进制格式。体积小、写入快,适合长时间飞行。我在项目中遇到过飞了 40 分钟,日志才 12MB,就是用的 .bin。
- .log 格式:ArduPilot 的文本格式。可读性强,但体积大。说白了就是纯文本,用记事本都能打开看两眼。
- .ulg 格式:PX4 的新一代日志格式。比 .bin 更灵活,支持更丰富的数据类型。嗯,这里要注意:.ulg 其实是 .bin 的升级版,但两者不兼容。
核心区别一句话总结:.bin 和 .ulg 是二进制,解析需要工具;.log 是文本,但别指望用记事本分析大数据量。
数据帧与消息类型
日志文件不是乱写的。它像一本日记,每页记录一个「数据帧」。每个数据帧包含一个「消息类型」和对应的数据。
我拿 .bin 格式举个例子。它的数据帧结构是这样的:
// 数据帧头部(固定 3 字节)
uint8_t sync_byte; // 同步字节,固定 0xA3
uint8_t msg_type; // 消息类型 ID
uint16_t msg_length; // 数据长度
// 数据帧负载(变长)
uint8_t payload[msg_length];
// 校验(2 字节)
uint16_t crc16; // 循环冗余校验
为什么会这样设计?你想想看,无人机每秒要记录几百个传感器数据,如果每个数据帧都带一大串描述信息,日志体积会爆炸。所以用消息类型 ID 来索引,解析时查表即可。
常见的消息类型我整理了一张表:
| 消息类型 ID | 名称 | 说明 |
|---|---|---|
| 0x01 | GPS | 经纬度、高度、卫星数 |
| 0x02 | IMU | 加速度、角速度、磁力计 |
| 0x03 | ATT | 姿态四元数、欧拉角 |
| 0x04 | RC | 遥控器通道值 |
| 0x05 | BAT | 电池电压、电流、剩余电量 |
我曾经踩过一个坑:某次飞行日志里 GPS 数据突然中断了 3 秒,但 IMU 数据正常。后来发现是 GPS 模块的串口缓冲区溢出了。嗯,这就是消息类型分析的价值——能帮你定位具体哪个传感器出了问题。
时间戳与同步机制
时间戳是日志分析的灵魂。没有准确的时间戳,你根本没法把 GPS 数据和 IMU 数据对应起来。
三种格式的时间戳机制不太一样:
- .bin 格式:每个数据帧自带微秒级时间戳。但注意,这个时间戳是飞控的本地时间,不是 UTC。
- .log 格式:时间戳以秒为单位,精度较低。我建议做精细分析时别用 .log。
- .ulg 格式:支持纳秒级时间戳,并且可以关联到系统启动时间。
我的小技巧:拿到日志后,先检查时间戳是否单调递增。如果出现时间戳回退,说明飞控的时钟可能有问题,或者日志文件损坏了。
同步机制这块,说白了就是解决「多个传感器数据到达时间不一致」的问题。比如 IMU 数据 1kHz,GPS 数据 10Hz,怎么对齐?
飞控内部的做法是:每个传感器数据到达时,打上当前系统时间戳。分析时,我们根据时间戳做插值或最近邻匹配。我曾经在项目中用 Python 写过一个同步函数:
def sync_sensors(imu_data, gps_data):
"""
将 IMU 数据与 GPS 数据按时间戳对齐
"""
synced = []
for gps in gps_data:
# 找到时间戳最接近的 IMU 数据
nearest_imu = min(imu_data,
key=lambda x: abs(x.timestamp - gps.timestamp))
synced.append((gps, nearest_imu))
return synced
嗯,这里要注意:如果时间戳偏差超过 100ms,基本可以判定同步有问题。我遇到过 GPS 模块的 PPS 信号没接好,导致时间戳差了 200ms,飞控直接报错。
避坑指南:我曾经在分析一次炸机日志时,发现 IMU 和 GPS 的时间戳差了 500ms。一开始以为是传感器坏了,后来发现是飞控的时钟晶振受温度影响漂移了。所以,时间戳同步问题不一定是传感器故障,也可能是硬件时钟问题。
知识体系结构图
下面这张图帮你理清本章的核心逻辑:
这张图从左到右展示了日志分析的三个层次:先识别格式,再解析数据帧,最后处理时间戳。我个人习惯拿到日志后,先看格式,再看时间戳连续性,最后才分析具体数据。
本章核心要点:
- .bin 和 .ulg 是二进制格式,解析需工具;.log 是文本格式,适合快速查看
- 每个数据帧包含消息类型 ID,解析时查表即可
- 时间戳是日志分析的基石,务必检查单调性和同步偏差