3. 轨迹表示方法:时间戳序列、位姿列表、轨迹文件格式

做SLAM评估这么多年,我见过最多的坑,就是轨迹表示不一致导致的评估结果偏差。说白了,你拿TUM格式的轨迹去跑KITTI的评估脚本,结果肯定是一团糟。今天我们就来彻底搞清楚,轨迹到底该怎么表示,不同格式之间有什么区别。

3.1 时间戳序列:轨迹的“时间轴”

轨迹本质上是一个随时间变化的位姿序列。每个位姿都对应一个时间戳,这个时间戳就是轨迹的“时间轴”。

时间戳的精度,我个人习惯用微秒(us)或纳秒(ns)级别。为什么?因为SLAM系统通常运行在10-30Hz,帧间间隔也就33-100ms。如果时间戳精度只有毫秒,多个帧可能共享同一个时间戳,评估时就乱套了。

关键点:时间戳必须单调递增,不能回退。我在项目中遇到过,某个传感器驱动的时间戳偶尔会跳变回几秒前,结果轨迹评估直接报错。

时间戳的格式,常见的有两种:

  • Unix时间戳(浮点数):例如 1234567890.123456,单位是秒。TUM格式就用这个。
  • 系统时间(整数):例如 1234567890123456,单位是微秒或纳秒。EuRoC格式用这个。

你想想看,如果两个轨迹的时间戳基准不一致,比如一个用UTC,一个用系统启动时间,那对齐的时候就会出大问题。所以,拿到轨迹数据的第一件事,就是检查时间戳的基准和单位。

3.2 位姿列表:轨迹的“空间骨架”

每个时间戳对应一个位姿。位姿通常包含位置和姿态两部分。

位置:一般用三维坐标 (x, y, z) 表示。单位通常是米。

姿态:表示方式就多了,常见的有:

  • 四元数 (qx, qy, qz, qw):最常用,无奇异性。TUM和EuRoC都用这个。
  • 旋转矩阵 (3x3):直观,但占空间。KITTI格式用这个。
  • 欧拉角 (roll, pitch, yaw):容易理解,但有万向锁问题。我一般不建议在轨迹评估中用。

我的经验:四元数虽然不直观,但做插值和融合时最稳定。我曾经因为用欧拉角做轨迹插值,结果在俯仰角接近90度时,评估结果完全失真。从那以后,我所有轨迹处理都统一用四元数。

位姿列表的存储,说白了就是一个表格。每一行是一个时间戳+一个位姿。但不同数据集格式,列的排列顺序不一样。这就是我们接下来要讲的。

3.3 三大主流轨迹文件格式

做SLAM评估,你一定会遇到这三种格式。我分别说一下它们的结构和注意事项。

3.3.1 TUM格式

TUM格式是慕尼黑工业大学提出的,非常简洁。每行包含8个字段:

timestamp tx ty tz qx qy qz qw

时间戳是浮点数,单位秒。位置和四元数都是双精度浮点数。

特点:

  • 没有表头,直接是数据行。
  • 时间戳精度高,通常到微秒级。
  • 姿态用四元数,无歧义。

注意:我曾经遇到过,有人把TUM格式的四元数顺序写成了 (qw, qx, qy, qz),结果评估出来的轨迹完全不对。一定要确认顺序是 (qx, qy, qz, qw)。

3.3.2 KITTI格式

KITTI格式来自KITTI数据集,它用旋转矩阵表示姿态。每行包含13个字段:

r11 r12 r13 tx r21 r22 r23 ty r31 r32 r33 tz

注意,KITTI格式没有时间戳!它假设所有位姿是按时间顺序排列的,帧率固定。

特点:

  • 没有时间戳,评估时只能按顺序对齐。
  • 旋转矩阵是3x3,共9个元素,加上位置3个,共12个。但KITTI格式通常写成一行12个数字,或者写成4x4齐次矩阵的12个元素(去掉最后一行)。
  • 单位是米。

避坑指南:KITTI格式的轨迹,通常是从第一帧开始的相对位姿。如果你要评估绝对轨迹误差(ATE),需要先把轨迹转换到全局坐标系下。我刚开始做KITTI评估时,就因为这个吃了亏。

3.3.3 EuRoC格式

EuRoC格式来自EuRoC MAV数据集,它用四元数表示姿态,但时间戳是整数纳秒。每行包含8个字段:

timestamp_ns tx ty tz qx qy qz qw

特点:

  • 时间戳是整数,单位纳秒。范围很大,处理时要注意数据类型,别用32位整数,会溢出。
  • 姿态用四元数,和TUM一样。
  • 通常还包含IMU数据,但轨迹文件只包含位姿。

嗯,这里要注意,EuRoC格式的时间戳是相对于数据集开始的,不是Unix时间戳。所以不同数据集的时间戳不能直接比较。

3.4 格式对比与转换

为了方便你理解,我做了一个对比表:

格式 时间戳 姿态表示 字段数 典型应用
TUM 浮点秒 四元数 (qx, qy, qz, qw) 8 RGB-D SLAM评估
KITTI 无(按顺序) 旋转矩阵 (3x3) 12 自动驾驶SLAM评估
EuRoC 整数纳秒 四元数 (qx, qy, qz, qw) 8 视觉-惯性SLAM评估

格式转换是家常便饭。我常用的转换逻辑:

  • TUM ↔ EuRoC:时间戳单位转换(秒↔纳秒),字段顺序不变。
  • TUM ↔ KITTI:四元数转旋转矩阵(或反过来),时间戳处理(KITTI需要生成虚拟时间戳)。
  • KITTI ↔ EuRoC:旋转矩阵转四元数,时间戳处理。

我的建议:统一用TUM格式作为中间格式。因为TUM格式最简单,而且大多数评估工具(如evo)原生支持TUM。我自己的工具链,都是先把所有轨迹转成TUM,再做后续处理。

3.5 知识体系结构图

下面这张图,帮你理清轨迹表示的核心逻辑:

轨迹表示 时间戳序列 位姿列表 文件格式 Unix时间戳 系统时间 位置(x,y,z) 姿态(四元数/矩阵) TUM KITTI EuRoC 核心:时间戳 + 位姿 = 完整轨迹 格式转换时注意:时间戳单位、姿态表示方式、字段顺序

说白了,轨迹表示就是“时间戳+位姿”的组合。不同格式只是这个组合的不同序列化方式。理解了这一点,你就能轻松应对各种格式的转换和评估。

总结一下:

  • 时间戳是轨迹的灵魂,精度和基准必须统一。
  • 位姿用四元数最稳妥,避免欧拉角的奇异性问题。
  • TUM格式最通用,建议作为中间格式。
  • KITTI格式没有时间戳,评估时要注意对齐方式。
  • EuRoC格式时间戳是纳秒整数,处理时注意数据类型。

好了,轨迹表示这部分就讲到这里。记住,格式转换时多检查一遍字段顺序和单位,能省去后面很多调试时间。我当年就是因为没注意四元数顺序,多花了一整天排查问题。

可可精品资料库