3、轨迹数据格式详解:TUM格式、KITTI格式、EuRoC格式、ROS bag中的/tf与/odom话题

做SLAM轨迹评估,第一关就是搞懂数据格式。

我见过太多同学,算法写得飞起,结果栽在格式转换上。明明轨迹是对的,评估工具就是不认。说白了,就是没搞清楚这些格式到底在表达什么。

今天咱们就把四种最常见的轨迹格式掰开揉碎讲清楚。你想想看,搞懂了这些,后面做评估才能得心应手。

3.1 TUM格式:最直观的轨迹表示

TUM格式来自慕尼黑工业大学。我个人习惯把它叫做「时间戳+位姿」格式。为什么?因为它太直白了。

# 每一行:timestamp tx ty tz qx qy qz qw
# 示例:
1.234567890 1.0 2.0 3.0 0.0 0.0 0.0 1.0
2.345678901 1.1 2.1 3.1 0.01 0.01 0.0 0.9999

格式很简单:时间戳 + 平移 + 四元数。时间戳单位是秒,平移单位是米。

关键点:四元数的顺序是 qx qy qz qw,不是 qw qx qy qz。这个顺序搞反了,轨迹直接飞掉。

我在项目中遇到过一件事。有个同学用evo评估,结果轨迹误差大得离谱。查了半天,原来是四元数顺序写反了。嗯,这种坑踩一次就记住了。

3.2 KITTI格式:自动驾驶的标配

KITTI格式是自动驾驶领域的标杆。它不存时间戳,只存位姿。为什么?因为KITTI的数据采集频率是固定的10Hz,时间信息可以从帧号推算。

# 每一行:3x4变换矩阵,按行展开
# 示例:
1.0 0.0 0.0 1.0 0.0 1.0 0.0 2.0 0.0 0.0 1.0 3.0

这个矩阵是 R|t 的形式。前三列是旋转矩阵,最后一列是平移向量。

小技巧:KITTI格式没有时间戳。如果你需要时间信息,得自己维护一个时间戳列表。我一般会单独存一个timestamp.txt文件。

我曾经在评估KITTI数据集时,发现轨迹和真值对不上。后来才意识到,KITTI的坐标系是「右-下-前」,而我的算法用的是「右-前-上」。坐标系不统一,评估结果就是废的。

3.3 EuRoC格式:视觉惯导的宠儿

EuRoC格式和TUM格式很像,但多了一个东西:协方差矩阵。

# 每一行:timestamp, p_x, p_y, p_z, q_x, q_y, q_z, q_w, cov_matrix(6x6)
# 示例:
1.234567890 1.0 2.0 3.0 0.0 0.0 0.0 1.0 0.01 0.0 0.0 0.0 0.0 0.0 ...

协方差矩阵是6x6的,对应位置和姿态的不确定性。这个信息在做融合或者滤波时特别有用。

注意:EuRoC的协方差矩阵是上三角存储的。解析时别搞成下三角,否则结果完全不对。

我个人习惯在评估EuRoC轨迹时,会先检查协方差矩阵的对角线元素。如果数值特别大,说明这个位姿估计不太靠谱,我会考虑把它剔除掉。

3.4 ROS bag中的/tf与/odom话题

ROS bag是实际工程中最常见的格式。但也是最容易出问题的。

/tf话题:坐标变换树

/tf话题发布的是坐标变换关系。每个变换包含:

  • frame_id:父坐标系
  • child_frame_id:子坐标系
  • transform:平移+旋转
  • timestamp:时间戳

举个例子,如果你看到:

frame_id: "odom"
child_frame_id: "base_link"
transform: [1.0, 2.0, 3.0, 0.0, 0.0, 0.0, 1.0]

这表示base_link在odom坐标系下的位姿。

核心要点:/tf发布的是相对变换,不是绝对位姿。要得到完整轨迹,你需要从tf树中提取出连续的变换序列。

/odom话题:里程计数据

/odom话题包含的信息更丰富:

  • pose:位姿(位置+姿态)
  • twist:速度(线速度+角速度)
  • covariance:协方差矩阵

我建议优先使用/odom话题做评估。为什么?因为它自带协方差信息,而且数据更完整。我在项目中遇到过,/tf话题有时候会丢帧,但/odom话题一般不会。

3.5 格式对比与选择建议

格式 时间戳 位姿表示 协方差 适用场景
TUM 有 四元数+平移 无 通用评估
KITTI 无 3x4矩阵 无 自动驾驶
EuRoC 有 四元数+平移 有 视觉惯导
ROS bag 有 多种形式 可选 实际工程

选哪种格式?我的建议是:

  • 做学术评估,用TUM格式。工具支持最好。
  • 做自动驾驶,用KITTI格式。行业标准。
  • 做视觉惯导,用EuRoC格式。协方差信息很有用。
  • 做实际工程,从ROS bag里提取。最贴近真实场景。

3.6 格式转换实战

实际工作中,你经常需要在不同格式之间转换。我分享一个常用的转换思路:

# TUM转KITTI示例(Python伪代码)
def tum_to_kitti(tum_file, kitti_file):
    with open(tum_file, 'r') as f:
        lines = f.readlines()
    
    with open(kitti_file, 'w') as f:
        for line in lines:
            # 解析TUM格式
            parts = line.strip().split()
            t = float(parts[0])
            tx, ty, tz = float(parts[1]), float(parts[2]), float(parts[3])
            qx, qy, qz, qw = float(parts[4]), float(parts[5]), float(parts[6]), float(parts[7])
            
            # 四元数转旋转矩阵
            R = quaternion_to_matrix(qx, qy, qz, qw)
            
            # 构建3x4矩阵
            T = np.eye(4)
            T[:3, :3] = R
            T[:3, 3] = [tx, ty, tz]
            
            # 按行展开写入
            f.write(' '.join(map(str, T[:3, :].flatten())) + '\n')

避坑指南:我曾经在转换时忘记处理时间戳对齐。TUM格式的时间戳是浮点数,KITTI没有时间戳。如果你需要时间信息,记得单独保存。

3.7 本章知识体系

下面这张图展示了四种轨迹格式的核心关系:

轨迹数据格式核心关系图 轨迹评估 TUM格式 时间戳+四元数 KITTI格式 3x4变换矩阵 EuRoC格式 带协方差矩阵 ROS bag /tf /odom 格式选择建议 • 学术评估 → TUM格式(工具支持最好) • 自动驾驶 → KITTI格式(行业标准) • 视觉惯导 → EuRoC格式(协方差信息) • 实际工程 → ROS bag(最贴近真实场景)

搞懂了这些格式,你就能在评估工具和实际数据之间自由切换。嗯,这就是做轨迹评估的第一步。

总结一下:格式只是载体,核心是位姿数据本身。不管用什么格式,确保时间戳对齐、坐标系统一、四元数顺序正确,评估结果才可信。

可可精品资料库