跳到主要内容

7.2 时间戳与 Unix 时间

EGO1 / EGO1GS 录制中的每条消息都有时间戳,但时间戳默认不是 Unix 时间——它们走设备的单调时钟(自设备开机起的纳秒数)。本页解释其格式,并给出换算成 Unix(挂钟)时间的方法。

两种时钟​

时钟含义出现位置
单调时钟(开机)设备上电以来的纳秒数。永不跳变。每条消息的时间戳,以及 MCAP 的封装层
实时时钟(Unix)自 1970 年起的秒 + 纳秒(挂钟)。仅在 /ego/system_health 消息内

一段新录制的起始单调值通常只有几百秒(开机以来的时间),而不是 Unix 时间戳的约 17 亿秒——这是你正在看单调时钟的明显标志。

时间戳在哪里​

MCAP 封装层(log_time / publish_time)与消息负载携带相同的单调值(纳秒)。负载中它是一对 { seconds, nanos }(合并为 seconds * 1e9 + nanos):

Topic时间戳字段说明
/ego/camera/0、1timestamp每个视频帧
/ego/imu/0/quattimestamp融合姿态样本
/ego/imu/0/rawfirst_sample_time该批 IMU 样本中第一个的时间
/ego/system_healthtimestamp另有 realtime,见下文
/ego/audio/0timestamp音频块的起始(EGO1GS)
底层分辨率是微秒

传感器时间戳来自微秒级时钟,因此纳秒值以 000 结尾。只有主机生成的消息带有完整纳秒精度。这不影响下面的换算。

换算成 Unix 时间​

/ego/system_health 消息(约 1 Hz)同时携带两种时钟:单调的 timestamp 与 Unix 纪元的 realtime。两者之差是一个固定的偏移量,把一种时钟映射到另一种:

offset = realtime_ns − monotonic_ns (整段录制内恒定)
unix_ns = any_monotonic_ns + offset

因此做法是:读一条 /ego/system_health,算一次偏移量,然后加到任意其它消息的时间戳上。

from visio_schema import read_mcap

def to_ns(t): # { seconds, nanos } 时间戳 -> 纳秒
return t.seconds * 1_000_000_000 + t.nanos

# 1. 从任意一条 system_health 消息求出 单调 -> Unix 的偏移量。
offset_ns = None
for msg, channel in read_mcap("capture.mcap"):
if channel.topic == "/ego/system_health":
offset_ns = to_ns(msg.realtime) - to_ns(msg.timestamp)
break

# 2. 把它加到任意消息的时间戳上。
for msg, channel in read_mcap("capture.mcap"):
if channel.topic == "/ego/imu/0/quat":
mono_ns = to_ns(msg.timestamp)
unix_ns = mono_ns + offset_ns
unix_s = unix_ns / 1e9
print(unix_s) # 例如 1782802423.004(一个 Unix 时间戳)
break

把 Unix 时间戳转成可读的 UTC 时间:

from datetime import datetime, timezone

print(datetime.fromtimestamp(unix_s, tz=timezone.utc).isoformat())
# 2026-06-30T06:53:43.004+00:00
多取几条求平均可达亚微秒精度

偏移量的稳定性在几微秒之内。想消除这点抖动,可以对多条 /ego/system_health 消息的偏移量取平均,而不是只用第一条。

注意事项​

  • 挂钟精度取决于设备的时钟。 EGO1 与 EGO1GS 都没有电池供电的实时时钟,因此 realtime 反映的是设备被告知的时间(或未设置的时钟)。若时钟从未同步,绝对时间戳可能偏差几分钟、几小时甚至更多——但录制内部的时序(帧间隔、IMU 间隔、相机与 IMU 的对齐)始终准确,因为它们都走同一个单调时钟。设备从未被手机连接过时,录制的时间戳可能停在 1970 年——部署后请用 App 连接每台设备一次。
  • /device_info 不是锚点。 开机时时钟未同步时它的 boot_unix_seconds 字段为 0——请用 /ego/system_health 的 realtime 对。
  • 没有 system_health 就无法换算。 录制中没有 /ego/system_health 消息时,文件内没有到 Unix 时间的联系,只能在开机相对时间下工作。

完整的 topic 与 schema 列表见 7. 工程集成与数据格式与 7.4 频道与网络速查。