4. 绝对轨迹误差(ATE):ATE定义、计算方法、RMSE与均值、中位数指标
各位同学,今天我们来聊聊SLAM评估里最核心的一个指标——绝对轨迹误差(ATE)。
说实话,我刚开始做SLAM那会儿,对ATE的理解就是「把估计轨迹和真值轨迹对齐,然后算差」。但真正上手之后才发现,这里面的门道比想象中多得多。今天我就把我在项目中踩过的坑、总结的经验,一次性讲清楚。
4.1 ATE到底在衡量什么?
ATE的全称是Absolute Trajectory Error,翻译过来就是「绝对轨迹误差」。它衡量的是:估计轨迹与真实轨迹之间,在全局坐标系下的位置偏差。
你想想看,一个SLAM系统跑完一段路,输出了一串位姿。我们拿它和真值(比如动捕系统或高精度激光雷达给的轨迹)对比。但问题是——这两个轨迹的坐标系通常不一样。所以第一步,得先做对齐。
核心定义:ATE = 对齐后的估计位姿与真值位姿之间的欧氏距离(平移部分)。
这里有个关键点:ATE只关心平移误差,不关心旋转误差。为什么?因为在实际应用中,比如AR/VR、机器人导航,位置精度往往比姿态精度更敏感。当然,也有RPE(相对位姿误差)会同时考虑旋转,那是另一回事。
4.2 计算ATE的完整流程
我个人习惯把ATE的计算拆成三步。每一步都有坑,我一个个说。
4.2.1 第一步:时间戳对齐
估计轨迹和真值轨迹的时间戳通常不一致。比如真值是100Hz,估计轨迹可能是30Hz。我们需要找到每个估计位姿对应的真值位姿。
常用的方法是:线性插值。假设估计位姿的时间是t_e,找到真值轨迹中离t_e最近的两个时间戳t1和t2,然后插出一个虚拟的真值位姿。
def interpolate_pose(t, pose1, pose2, t1, t2):
# 线性插值平移
ratio = (t - t1) / (t2 - t1)
trans = pose1.trans + ratio * (pose2.trans - pose1.trans)
# 球面线性插值旋转(SLERP)
rot = slerp(pose1.rot, pose2.rot, ratio)
return Pose(trans, rot)
我的经验:如果两个轨迹的频率差异太大(比如真值200Hz,估计只有10Hz),插值误差会很大。我建议先对真值做降采样,或者用更高阶的插值方法(比如三次样条)。
4.2.2 第二步:轨迹对齐(Umeyama算法)
这是最关键的步骤。我们需要找到一个刚体变换(旋转R、平移t、尺度s),把估计轨迹变换到真值轨迹的坐标系下。
为什么需要尺度?因为有些SLAM系统(比如单目视觉SLAM)存在尺度模糊性。如果不估计尺度,ATE会包含尺度误差,这就不公平了。
Umeyama算法是经典解法。它的核心思想是:最小化对齐后两个轨迹对应点之间的均方误差。
def umeyama_alignment(X, Y):
# X: 估计轨迹点集 (Nx3)
# Y: 真值轨迹点集 (Nx3)
# 返回: R, t, s
# 去中心化
mu_x = np.mean(X, axis=0)
mu_y = np.mean(Y, axis=0)
X_centered = X - mu_x
Y_centered = Y - mu_y
# 计算协方差矩阵
H = X_centered.T @ Y_centered
# SVD分解
U, S, Vt = np.linalg.svd(H)
R = Vt.T @ U.T
# 处理反射情况
if np.linalg.det(R) < 0:
Vt[-1, :] *= -1
R = Vt.T @ U.T
# 计算尺度和平移
s = np.trace(np.diag(S) @ R.T) / np.trace(X_centered.T @ X_centered)
t = mu_y - s * R @ mu_x
return R, t, s
注意:如果估计轨迹和真值轨迹的尺度差异很大(比如单目SLAM的尺度漂移严重),Umeyama算法可能会给出一个不合理的尺度。我曾经遇到过尺度因子s=0.3的情况,这说明SLAM系统已经严重退化。这时候ATE已经失去意义了,应该先修SLAM本身的问题。
4.2.3 第三步:计算每个时间点的误差
对齐之后,我们就可以计算每个时间点的误差了:
errors = []
for i in range(N):
# 对齐后的估计位姿
est_aligned = s * R @ est[i].trans + t
# 真值位姿
gt = gt[i].trans
# 欧氏距离
error = np.linalg.norm(est_aligned - gt)
errors.append(error)
这样我们就得到了一个误差序列:[e1, e2, e3, ..., eN]。接下来就是统计指标的事了。
4.3 RMSE、均值、中位数——该用哪个?
拿到误差序列后,我们需要一个数字来概括整个轨迹的精度。常用的有三个指标:RMSE、均值、中位数。
| 指标 | 公式 | 特点 | 适用场景 |
|---|---|---|---|
| RMSE | √(Σe²/N) | 对大误差敏感,惩罚离群点 | 需要严格评估系统稳定性时 |
| 均值 | Σe/N | 反映整体平均水平 | 快速了解系统性能时 |
| 中位数 | 排序后中间值 | 鲁棒,不受离群点影响 | 数据有噪声或异常值时 |
4.3.1 RMSE——最常用的指标
RMSE(均方根误差)是学术界最常用的指标。为什么?因为它对大误差的惩罚力度大。你想想看,如果一个SLAM系统大部分时间表现很好,但偶尔漂移一下,RMSE会把这个「偶尔」放大。
我个人习惯:在论文或正式报告中,优先使用RMSE。因为它能更严格地反映系统的稳定性。
4.3.2 均值——直观但容易被骗
均值很直观,就是平均误差。但它的缺点也很明显:容易被离群点带偏。比如你有100个点,99个误差是0.1米,1个误差是10米,均值就变成了0.2米——这显然不能反映真实情况。
我的建议:如果数据质量很好(比如在仿真环境中),均值可以作为辅助指标。但在真实场景中,我一般只看RMSE和中位数。
4.3.3 中位数——鲁棒性之王
中位数是排序后中间的那个值。它不受极端值影响。比如上面那个例子,中位数还是0.1米,这才是真实水平。
我记得有一次在室内走廊跑SLAM,中间有一段被行人遮挡,轨迹突然跳了2米。如果用均值,ATE是0.8米;用中位数,只有0.15米。显然中位数更能反映系统在正常情况下的表现。
4.4 知识体系总览
下面这张图总结了ATE的完整知识结构,我建议你保存下来,以后做评估时对照着看:
4.5 实战中的避坑指南
最后,我分享几个我在项目中踩过的坑,希望能帮你少走弯路。
- 坑1:忘记对齐坐标系——我曾经直接把估计轨迹和真值轨迹的坐标相减,结果误差大得离谱。后来才发现,两个轨迹的坐标系原点差了10米。记住:ATE必须在对齐之后计算。
- 坑2:尺度估计不稳定——单目SLAM的尺度会随时间漂移。如果用整个轨迹做Umeyama对齐,得到的尺度是全局平均的,不能反映局部漂移。我建议分段计算ATE,或者用滑动窗口的方式。
- 坑3:只看RMSE不看分布——RMSE是单一数字,它隐藏了误差的分布信息。比如两个系统RMSE都是0.5米,但一个误差集中在0.4-0.6米,另一个有时0.1米有时1.0米。显然前者更稳定。所以,我建议同时看RMSE和中位数,再画个误差分布直方图。
- 坑4:时间戳对齐精度不够——如果真值和估计轨迹的时间戳有固定偏移(比如真值比估计晚10ms),ATE会包含系统误差。我曾经用互相关方法自动校准时间偏移,效果很好。
总结一下:ATE是SLAM评估的基石。计算时注意对齐、插值、统计指标的选择。我个人习惯:正式报告用RMSE,内部调试看中位数,分析问题时看误差分布。三者结合,才能全面评估一个SLAM系统的轨迹精度。
好了,关于ATE就讲到这里。下一节我们会聊相对轨迹误差(RPE),那是另一个维度的评估指标,到时候再细说。