2. 日志时间戳对齐与多源时钟偏差校正

问题拆解:三类日志的时间基准并不相同

车载ATP、DMI、BTM的日志时间戳来源不同:ATP通常记录的是自身主控周期计数换算出的系统时间,DMI记录的是人机交互时刻(常带操作员可见的秒级时间),BTM则记录射频事务的触发/响应时刻。三者可能分别来自不同的晶振、不同的上电起点,甚至存在整秒级偏移。直接按字符串排序会把“BTM先检测到应答器、ATP后进入模式转换”这类因果顺序颠倒。因此本例的任务是:解析各源时间戳 → 估计相对偏差 → 统一到同一时间轴。

时间戳解析:先统一成可比较的数值

假设三类日志的典型行格式如下(示例数据,非实测):

# ATP 事件日志(相对上电毫秒 + 日期)
2024-03-11 08:12:03.412 [ATP] MODE_CHANGE C2->C3 t_ms=183412

# DMI 操作日志(本地时间,秒级)
2024-03-11 08:12:04 [DMI] BTN_MODE_CONFIRM

# BTM 事务日志(设备内部计数,单位 10ms)
2024-03-11 08:12:02.980 [BTM] TX_BALISE id=0451 tick=1832980

解析时把每条记录转成“源内数值时间”:ATP用 t_ms,BTM用 tick×10 得毫秒,DMI用本地时间转毫秒。注意DMI只有秒级精度,对齐时其不确定度为±500ms,不能当作精确锚点。

偏差估计:用共现事件做锚点

校正的关键是找到同一物理事件在不同日志中的“共现记录”。例如ATP记录“BTM应答器报文接收完成”,BTM记录“RX_BALISE id=0451”,二者是同一事务的两端,时间差即两设备时钟偏差的观测值。对多个锚点求差的中位数,可抑制单次抖动:

import re, statistics
from datetime import datetime

def parse_atp(line):
    m = re.search(r'(\S+ \S+) \[ATP\].*t_ms=(\d+)', line)
    return int(m.group(2)) if m else None

def parse_btm(line):
    m = re.search(r'\[BTM\].*tick=(\d+)', line)
    return int(m.group(1)) * 10 if m else None

def parse_dmi(line):
    m = re.search(r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) \[DMI\]', line)
    if not m: return None
    dt = datetime.strptime(m.group(1), '%Y-%m-%d %H:%M:%S')
    return int(dt.timestamp() * 1000)

# 锚点对:(atp_ms, btm_ms),来自同一应答器事务
anchors = [(183412, 1832980), (241905, 2417470), (302118, 3019600)]
offsets = [a - b for a, b in anchors]   # ATP相对BTM的偏差
bias_atp_btm = statistics.median(offsets)  # 示例:约 432 ms

得到 bias_atp_btm ≈ 432ms 后,把BTM时间加上该偏差即可映射到ATP时间轴。DMI因精度低,只用于粗对齐(如整秒级校验),不参与毫秒级偏差估计。

偏差估计至少需要3个以上锚点;若锚点差值离散度(如极差)超过50ms,说明存在丢帧或锚点误配,应先排查再校正。

对齐结果与判读

校正后按统一时间轴重排,可验证因果链是否合理:BTM应答器接收应早于ATP模式转换,DMI确认操作应晚于ATP状态变化。若校正后仍出现“结果早于原因”,说明锚点选择有误或存在未识别的时钟跳变(如设备重启导致计数归零),需回到解析阶段检查上电起点。

多源时钟偏差校正与统一时间轴 ATP 时间轴 (t_ms) 183412 模式转换 C2→C3 BTM 时间轴 (tick×10) 1832980 应答器 0451 接收 DMI 时间轴 (本地秒) 08:12:04 模式确认操作 偏差 ≈ 432 ms 校正后统一时间轴 BTM 应答器 ATP 模式转换 DMI 确认 因果顺序:应答器接收 → 模式转换 → 操作确认

可复用的校正检查清单

检查项判断依据异常处理
锚点数量≥3 个共现事件不足则扩大时间窗搜索
偏差离散度极差 ≤50ms剔除误配锚点后重算
DMI 精度仅秒级,±500ms不参与毫秒级偏差估计
计数归零tick 出现回退分段校正,识别重启点
因果一致性原因早于结果回查锚点与上电起点