4. 日志格式与标准化

无人系统的任务日志来源非常杂:飞控通过 MAVLink 上报状态,机载计算机用 ROS bag 记录话题,传感器固件可能吐二进制帧,任务管理软件写文本日志,而自研模块往往用自定义协议。如果每种日志各写各的,复盘时就要在五六个工具之间来回切换,时间戳对不齐、字段名不一致、单位混乱,最后连"这条航迹点到底对应哪次控制指令"都说不清。因此,理解常见日志格式的适用边界,并设计一套统一的标准化字段,是执行复盘的基础工程。

一、五类常见日志格式的定位

文本日志是最易读的一类,通常按行记录,形如 2024-06-11T09:23:41.512Z [NAV] wp=7 lat=31.23041 lon=121.47370 alt=52.3 mode=AUTO。优点是可直接 grep、肉眼排查,缺点是解析依赖格式约定,浮点精度和二进制字段(如图像帧号、校验和)表达不便,高频数据写入时体积膨胀快。

二进制日志以固定或变长结构体连续存储,典型如 PX4 的 ULog、ArduPilot 的 BIN。它写入开销小、适合高频 IMU 与控制量,但必须依赖对应的解析工具和消息定义(如 ULog 的 .msg 定义)才能还原字段,跨版本兼容性需要额外管理。

ROS bag 是机器人领域的事实标准,按话题(topic)存储带时间戳的消息,天然保留多传感器的时间关系。它适合记录点云、图像、TF 变换等复杂消息,但 bag 文件体积大,且回放依赖相同的消息类型定义(msg/srv),跨 ROS 版本或自定义消息变更时容易失效。

MAVLink 是无人机链路协议,日志中常见的是按消息 ID 记录的遥测帧,如 ATTITUDE、GLOBAL_POSITION_INT、STATUSTEXT。它的优势是字段语义由协议标准定义、跨厂商通用,但采样率受链路带宽限制,且不记录机载内部中间变量。

自定义协议常见于自研载荷或专用链路,通常由帧头、长度、消息类型、负载、校验组成。灵活但最易失控——一旦没有文档和版本号,几个月后连作者自己都难以解析。

五类日志源 → 标准化字段 → 统一复盘视图 文本日志 可读 / grep / 精度弱 二进制日志 ULog / BIN / 高频紧凑 ROS bag 话题 / 多传感器 / 体积大 MAVLink 协议标准 / 跨厂商 / 带宽限 自定义协议 灵活 / 需文档 / 易失控 标准化字段(统一 Schema) ① 时间基准 ts_utc / ts_boot / 时区与同步源 ② 来源标识 source / node_id / msg_type / seq ③ 空间与姿态 lat / lon / alt / roll / pitch / yaw ④ 任务与状态 mission_id / wp_id / mode / health ⑤ 事件与告警 event_code / severity / detail 统一单位:m / m·s⁻¹ / rad / s / UTC 统一复盘视图 • 时间轴对齐(同一 ts_utc) • 航迹 + 控制量叠加 • 事件标记定位异常点 • 跨源关联(指令↔响应) • 可导出 CSV / 报表 • 版本可追溯 标准化收益 ✓ 一次解析,多源合并 ✓ 字段语义明确,减少歧义 ✓ 单位统一,避免换算错误 ✓ 支持自动化分析与告警 ✓ 长期归档可读可查 ✓ 跨团队协作有共同语言

二、标准化字段设计的核心原则

标准化不是把所有日志强行改成一种格式,而是定义一套公共字段语义,让不同来源的记录在复盘时能对齐。设计时抓住五组字段即可覆盖绝大多数无人系统场景。

时间基准是最关键的一组。建议同时保留 ts_utc(UTC 毫秒时间戳)和 ts_boot(自系统上电的毫秒数)。前者用于跨设备对齐,后者用于分析启动阶段和链路延迟。若系统有 GPS/PTP 授时,应记录同步源与同步误差;无授时则明确标注"未同步",避免误判因果顺序。

来源标识用于区分"谁说的"。至少包含 source(如 fc、companion、payload)、node_id、msg_type 和 seq(消息序号)。序号能帮助发现丢包和乱序,这在 MAVLink 和自定义协议中尤其重要。

空间与姿态字段必须统一坐标系和单位。建议位置用 WGS-84 的 lat/lon(度)与 alt(米,明确是椭球高还是海拔高),姿态用 roll/pitch/yaw(弧度,明确是 NED 还是 ENU 参考)。参照系一旦定义,全文和图示必须一致,切换时必须显式说明。

任务与状态字段把日志和任务语义绑定:mission_id、wp_id(当前航点)、mode(飞行/驾驶模式)、health(健康标志位)。没有这组字段,复盘时只能看到"飞机在动",却不知道"它在执行哪条指令"。

事件与告警字段用于快速定位异常:event_code(如 E101 航点超时)、severity(info/warn/error)、detail(补充描述)。事件应与时间戳和任务字段关联,形成"何时、何任务、何异常"的完整记录。

三、落地实现:从原始日志到标准记录

实际工程中,通常采用"采集层保留原始格式 + 转换层输出标准记录"的两段式结构。采集层不动原始日志,保证可追溯;转换层按上述 Schema 解析并输出统一格式(推荐 JSON Lines 或 Parquet)。

以一条 MAVLink 的 GLOBAL_POSITION_INT 消息为例,原始字段为 time_boot_ms、lat(1e7 度)、lon(1e7 度)、alt(毫米)、relative_alt(毫米)、vx/vy/vz(厘米/秒)、hdg(厘度)。转换后应输出:

{
  "ts_utc": 1718097821512,
  "ts_boot": 482310,
  "source": "fc",
  "node_id": 1,
  "msg_type": "GLOBAL_POSITION_INT",
  "seq": 20481,
  "lat": 31.230410,
  "lon": 121.473700,
  "alt_m": 52.30,
  "rel_alt_m": 12.80,
  "vel_ned_mps": [1.20, -0.35, 0.02],
  "yaw_rad": 1.5708,
  "mission_id": "M20240611-03",
  "wp_id": 7,
  "mode": "AUTO",
  "health": "OK",
  "event_code": null,
  "severity": "info"
}

转换时要注意三个易错点:一是单位换算,MAVLink 的 lat 需除以 1e7、alt 需除以 1000;二是时间基准,time_boot_ms 是自飞控上电的毫秒数,需结合日志起始的 UTC 时间推算 ts_utc;三是坐标系,MAVLink 速度默认 NED,若下游分析用 ENU,需显式转换并记录。

建议为标准化 Schema 维护一个版本号(如 schema_version: "1.2"),并在每条记录中携带。字段增删时升级版本,避免历史日志解析错位。

四、验证标准化是否有效

判断标准化是否成功,可以用三个可操作的检查:第一,能否用同一条时间轴同时绘制飞控姿态、机载任务状态和载荷事件,且时间偏差在可接受范围内(如授时同步时小于 10 ms);第二,能否用 mission_id + wp_id 直接筛选出某航点的全部相关记录,无需人工翻找;第三,能否在不打开原始日志工具的情况下,仅凭标准记录回答"第 7 航点为何超时"这类问题。若三条都能满足,说明字段设计已经支撑起复盘需求。

不要为了"统一"而丢弃原始日志。标准化记录是分析视图,原始日志是证据链。两者应同时归档,并记录转换脚本的版本,否则一旦转换逻辑有误,将无法回溯。

总结来看,文本、二进制、ROS bag、MAVLink 和自定义协议各有适用场景,标准化字段的价值在于用统一的时间、来源、空间、任务和事件语义把它们串起来。设计时优先保证时间基准和来源标识的可靠性,再逐步完善其余字段,最终形成可解析、可对齐、可追溯的复盘数据底座。