第一章:课程导论与坐标系基础
为什么需要运动补偿?
各位同学,我们先聊一个最根本的问题——为什么非要做运动补偿?
我刚开始做感知的时候,也想过这个问题。传感器每秒采集10帧、20帧数据,看起来挺快的。但车辆本身在运动,你想想看,当车以80km/h行驶时,每秒前进22米。两帧之间,车已经跑了2米多。如果直接把这两帧的点云或图像拼在一起,目标位置会严重错位。
说白了,运动补偿就是消除自车运动带来的观测偏差。你看到的障碍物位置,其实是「过去时刻」的位置。如果不补偿,你估计的目标速度、航向都会失真。
核心结论:运动补偿是动态目标状态估计的前提。不做补偿,后续的跟踪、预测都是空中楼阁。
我在项目中遇到过这样一个案例:有一次测试,毫米波雷达检测到前方车辆突然「跳变」了0.5米。排查了半天,发现是自车急加速时,运动补偿参数没更新。嗯,从那以后我养成了一个习惯——每次检查感知结果,先看补偿是否生效。
坐标系基础:三个核心坐标系
做运动补偿,绕不开坐标系。我个人习惯把坐标系分成三层:世界坐标系、车辆坐标系、传感器坐标系。这三者之间的转换,是感知算法的基本功。
1. 世界坐标系
世界坐标系是全局参考系。通常用经纬度(WGS84)或UTM坐标表示。它的原点在地球表面某处,X轴指向东,Y轴指向北,Z轴指向上。
为什么需要世界坐标系?因为多车协同、高精地图定位都依赖它。但注意,世界坐标系是静态的,而车辆是动态的。所以我们需要一个中间层——车辆坐标系。
2. 车辆坐标系
车辆坐标系的原点通常在后轴中心或车辆质心。按照ISO 8855标准:
- X轴:指向车辆前进方向
- Y轴:指向车辆左侧(注意,有些标准指向右侧)
- Z轴:指向上方
这个坐标系会随着车辆运动而移动和旋转。说白了,它是「跟着车走的」。做运动补偿时,我们通常先把传感器数据转换到车辆坐标系下,再补偿自车运动。
小技巧:我建议在代码里统一使用ISO标准。曾经有个项目,团队里有人用右手系、有人用左手系,结果坐标转换时出了bug,排查了两天。统一标准能省很多麻烦。
3. 传感器坐标系
每个传感器都有自己的坐标系。比如:
| 传感器类型 | 原点位置 | X轴方向 | Y轴方向 | Z轴方向 |
|---|---|---|---|---|
| 激光雷达 | 激光雷达中心 | 传感器前方 | 传感器左侧 | 传感器上方 |
| 摄像头 | 光心 | 光轴方向 | 图像水平方向 | 图像垂直方向 |
| 毫米波雷达 | 天线中心 | 雷达法线方向 | 水平方向 | 垂直方向 |
传感器坐标系是「局部中的局部」。每个传感器的安装位置、朝向都不同。所以第一步,就是把所有传感器数据统一到车辆坐标系下。
坐标系转换:从传感器到世界
坐标系转换说白了就是旋转+平移。用数学表达就是:
P_vehicle = R_sensor_to_vehicle * P_sensor + T_sensor_to_vehicle
其中:
P_sensor:传感器坐标系下的点R_sensor_to_vehicle:旋转矩阵(3x3)T_sensor_to_vehicle:平移向量(3x1)
从车辆坐标系到世界坐标系,还需要考虑车辆当前的位姿(位置+朝向):
P_world = R_vehicle_to_world * P_vehicle + T_vehicle_to_world
这里的 R_vehicle_to_world 和 T_vehicle_to_world 来自车辆的定位模块(GPS+IMU或SLAM)。
注意:旋转矩阵的乘法顺序很重要。先旋转再平移,还是先平移再旋转?答案是先旋转再平移。我曾经见过一个同事把顺序搞反了,结果点云全部飞到了天上。嗯,调试的时候画面很壮观。
运动补偿的数学本质
现在我们来点干货。运动补偿的数学本质是什么?
假设在时刻 t0,传感器观测到一个目标,位置为 P_sensor(t0)。但我们要估计的是当前时刻 t1 的目标位置。自车在这段时间内运动了 ΔT 和 ΔR。
补偿公式如下:
P_compensated = ΔR * (R_sensor_to_vehicle * P_sensor(t0) + T_sensor_to_vehicle) + ΔT
其中:
ΔR:自车从t0到t1的旋转变化ΔT:自车从t0到t1的平移变化
说白了,就是把过去时刻的观测「搬」到当前时刻的车辆坐标系下。
关键点:运动补偿的精度取决于自车运动估计的精度。如果IMU有漂移,或者GPS更新频率低,补偿结果就会打折扣。我建议在工程中引入轮速计作为辅助,能有效抑制漂移。
避坑指南
最后,分享几个我踩过的坑:
- 时间戳对齐:不同传感器的时间戳可能不同步。我曾经遇到过激光雷达和摄像头时间差50ms,补偿后目标位置偏差了1米。解决方案是用硬件同步或插值对齐。
- 坐标系方向:确认每个坐标系的轴方向。有些传感器用右手系,有些用左手系。转换时别忘了取反。
- 单位统一:角度用弧度还是度?距离用米还是厘米?我建议在代码入口处统一转换,避免后续混乱。
好了,第一章的内容就到这里。下一章我们会深入运动补偿的具体实现,包括如何利用IMU和轮速计进行状态估计。到时候我会带大家手写一个补偿模块,敬请期待。