3、数据预处理:时间戳对齐、坐标系转换(WGS84转UTM)、数据插值与去噪

说实话,很多刚入行的朋友觉得轨迹回放嘛,把数据录下来,再放一遍不就完了?

嗯,真这么简单就好了。我见过太多案例——回放出来的轨迹要么跳来跳去,要么跟实际道路对不上。问题出在哪?十有八九是数据预处理没做好。

这一节,我就把我在高速场景下积累的预处理经验,掰开了讲给你听。

3.1 时间戳对齐——让所有传感器说同一种“时间语言”

你想想看,一辆自动驾驶车上,GPS、IMU、摄像头、激光雷达,每个传感器都有自己的时钟。GPS可能用的是UTC时间,IMU用的是板载晶振,相机是触发时间戳。

这些时间如果不统一,回放出来的轨迹就是“各说各话”。

核心原则: 所有传感器的时间戳,统一转换到GPS时间(GPST)或Unix时间戳。

我个人习惯的做法是:

  1. 先找主时钟——通常以GPS时间作为基准,因为它精度高、无漂移。
  2. 计算时间偏移——把IMU、相机的时间戳减去GPS时间戳,得到一个固定的偏移量。
  3. 线性插值对齐——比如IMU是100Hz,GPS是10Hz,那就把GPS的位姿插值到每个IMU时间点上。

我在项目中遇到过一个问题:某款IMU的晶振受温度影响,时间漂移能达到几十毫秒。高速上100km/h,几十毫秒就是将近1米的误差。后来我加了个滑动窗口的时间校准,才把这个问题压下去。

小技巧: 可以用“时间戳差值直方图”来快速检查对齐质量。如果直方图呈现单峰且集中,说明对齐良好;如果出现多峰,说明有丢帧或时钟跳变。

3.2 坐标系转换——WGS84转UTM,把地球“拍平”

GPS给的是经纬度(WGS84坐标系),但我们的轨迹计算、碰撞检测,都是在平面直角坐标系里做的。所以必须把经纬度转成米为单位的UTM坐标。

为什么选UTM?说白了,UTM把地球分成60个带,每个带内变形很小,高速场景下精度足够。

转换公式我就不手写了,直接用现成的库。Python里我常用 pyproj 或 utm 库。

import utm

# 示例:WGS84转UTM
lat, lon = 31.2304, 121.4737  # 上海某点
easting, northing, zone_number, zone_letter = utm.from_latlon(lat, lon)

print(f"UTM坐标: ({easting:.2f}, {northing:.2f})")
print(f"UTM带: {zone_number}{zone_letter}")

这里有个坑,我曾经踩过——UTM带号必须一致。如果轨迹跨越了两个UTM带(比如从上海开到新疆),直接转换会导致坐标跳变。我的做法是:统一使用起始点的UTM带,或者用自定义的局部坐标系。

注意: 高速场景下,UTM转换的误差通常在厘米级,但如果车辆在带边界附近(比如东经120°线),误差会急剧增大。建议提前检查轨迹是否跨带。

3.3 数据插值与去噪——让轨迹“顺滑如丝”

原始数据往往有两个问题:一是时间戳不均匀,二是噪声大。尤其是GPS,在城市峡谷或隧道里,信号跳变几米是常事。

3.3.1 插值:填补时间缝隙

我常用的插值方法有三种:

方法 适用场景 优缺点
线性插值 匀速直线运动 简单快速,但弯道误差大
三次样条插值 弯道、变道场景 平滑性好,但可能过冲
阿克曼模型插值 车辆动力学约束 最符合实际,但计算量大

我个人习惯:高速直线段用线性插值,弯道用三次样条。如果计算资源允许,阿克曼模型插值效果最好。

3.3.2 去噪:剔除“野点”

去噪的方法很多,我推荐一个组合拳:

  1. 中值滤波——对位置序列做窗口滤波,窗口大小取5~11帧。能有效剔除孤立跳变点。
  2. 速度/加速度阈值——计算相邻点的速度和加速度,如果超过物理极限(比如加速度 > 5m/s²),就标记为异常点。
  3. RANSAC拟合——对局部轨迹做RANSAC直线或曲线拟合,剔除离群点。

我曾经在一条高速上遇到GPS信号被高架遮挡,轨迹出现了连续十几米的跳变。单纯用中值滤波根本拉不回来,后来我加了“道路约束”——把轨迹投影到高精地图的车道线上,才把问题解决。

避坑指南: 去噪别下手太狠。我见过有人把滤波窗口设到50帧,结果轨迹是平滑了,但真实的变道动作也被抹掉了。记住,我们的目标是“去噪保真”,不是“过度平滑”。

3.4 知识体系总览

下面这张图,是我自己总结的数据预处理流程。你可以把它当作一个检查清单:

数据预处理流程 原始数据 GPS / IMU / CAN 时间戳对齐 统一到GPST 坐标系转换 WGS84 → UTM 插值 去噪 各步骤关键点: • 时间戳对齐:主时钟选择(GPS)、偏移量计算、线性插值 • 坐标系转换:UTM带号一致性、跨带处理、局部坐标系 • 数据插值:线性/样条/阿克曼模型,按场景选择 • 数据去噪:中值滤波 + 速度阈值 + RANSAC 输出: 时间对齐、坐标统一、平滑干净的轨迹序列 注:每一步的输出都是下一步的输入,顺序不可颠倒。

嗯,数据预处理这部分,说难不难,说简单也不简单。关键是要理解每一步“为什么这么做”,而不是“怎么调API”。

我见过太多人拿着现成的库一顿调,结果轨迹回放出来全是问题。记住:预处理的质量,直接决定了回放测试的可信度。

一句话总结: 时间戳对齐是基础,坐标系转换是桥梁,插值与去噪是保障。三者缺一不可。

可可精品资料库