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、1 | timestamp | 每个视频帧 |
/ego/imu/0/quat | timestamp | 融合姿态样本 |
/ego/imu/0/raw | first_sample_time | 该批 IMU 样本中第一个的时间 |
/ego/system_health | timestamp | 另有 realtime,见下文 |
/ego/audio/0 | timestamp | 音频块的起始(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 频道与网络速查。