第一章:课程导论与坐标系基础

为什么需要运动补偿?

各位同学,我们先聊一个最根本的问题——为什么非要做运动补偿?

我刚开始做感知的时候,也想过这个问题。传感器每秒采集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_worldT_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:自车从 t0t1 的旋转变化
  • ΔT:自车从 t0t1 的平移变化

说白了,就是把过去时刻的观测「搬」到当前时刻的车辆坐标系下。

关键点:运动补偿的精度取决于自车运动估计的精度。如果IMU有漂移,或者GPS更新频率低,补偿结果就会打折扣。我建议在工程中引入轮速计作为辅助,能有效抑制漂移。

避坑指南

最后,分享几个我踩过的坑:

  • 时间戳对齐:不同传感器的时间戳可能不同步。我曾经遇到过激光雷达和摄像头时间差50ms,补偿后目标位置偏差了1米。解决方案是用硬件同步或插值对齐。
  • 坐标系方向:确认每个坐标系的轴方向。有些传感器用右手系,有些用左手系。转换时别忘了取反。
  • 单位统一:角度用弧度还是度?距离用米还是厘米?我建议在代码入口处统一转换,避免后续混乱。

好了,第一章的内容就到这里。下一章我们会深入运动补偿的具体实现,包括如何利用IMU和轮速计进行状态估计。到时候我会带大家手写一个补偿模块,敬请期待。