4. 刚体变换与位姿表示

在激光SLAM前端配准中,我们反复要做的一件事,是把同一束激光在不同时刻、不同位姿下测到的点,统一到同一个坐标系里比较。这个“统一”的数学本质就是刚体变换。若位姿表示选得不合适,配准会变慢、插值会失真、优化会震荡;若表示得当,整个前端会稳定得多。本节把旋转矩阵、欧拉角、四元数、李群李代数、位姿插值与坐标系变换串成一条工程可用的知识链。

一、刚体变换的数学结构

三维刚体变换由旋转与平移组成,通常写成齐次形式:

T = [ R  t ]      R ∈ SO(3), t ∈ R³
    [ 0  1 ]      T ∈ SE(3)

p_world = R * p_body + t
p_world_h = T * p_body_h

其中 R 是 3×3 正交矩阵,满足 RᵀR=I 且 det(R)=1;t 是三维平移向量。SO(3) 表示三维旋转群,SE(3) 表示三维刚体变换群。激光SLAM中,雷达外参、帧间位姿、地图到基座的变换,都是 SE(3) 中的元素。

工程要点:旋转矩阵没有冗余但约束强,优化时不能直接对 9 个元素做无约束更新;四元数只有 4 个参数但存在双覆盖;李代数则把约束流形局部参数化为无约束向量,是优化的首选。

二、四种旋转表示的对比

表示参数个数优点缺点典型用途
旋转矩阵 R9(约束6)复合直接、无奇异冗余、需正交化坐标变换、外参存储
欧拉角3直观、易读万向锁、依赖顺序人机界面、标定初值
四元数 q4(约束1)紧凑、插值平滑双覆盖、需归一化位姿插值、IMU融合
李代数 ξ6无约束、适合优化需指数/对数映射位姿图优化、BA

欧拉角必须说明旋转顺序,例如 ZYX 表示先绕 Z 转 yaw,再绕 Y 转 pitch,最后绕 X 转 roll。当 pitch 接近 ±90° 时,yaw 与 roll 轴重合,出现万向锁,此时欧拉角不再适合做连续插值。

三、李群与李代数:优化的语言

SO(3) 和 SE(3) 是光滑流形,不能像普通向量一样直接相加。李代数 so(3)、se(3) 是流形在单位元处的切空间,可以看作普通向量空间。通过指数映射 exp 和对数映射 log,可以在李代数与李群之间往返:

so(3):  φ = θ * n        R = exp(φ^) = I + sinθ n^ + (1-cosθ) n^²
se(3):  ξ = [ρ, φ]       T = exp(ξ^)
更新:   T_new = T_old * exp(δξ^)

在激光SLAM前端,我们通常把待优化的位姿写成 T = exp(ξ^),然后对 ξ 求导。这样每次迭代只需在 6 维向量上做加法,再通过 exp 映射回 SE(3),既保持约束又便于使用高斯牛顿或 LM 算法。ICP、NDT、GICP 的雅可比推导,几乎都建立在这套语言上。

刚体变换与位姿表示:从流形到工程实现 SO(3) / SE(3) 旋转群 / 刚体变换群 RᵀR=I, det(R)=1 李代数 so(3)/se(3) φ ∈ R³, ξ ∈ R⁶ 无约束向量空间 优化更新 T ← T · exp(δξ^) 高斯牛顿 / LM log exp 扰动 δξ 旋转矩阵 R 9参数 / 6约束 坐标变换首选 欧拉角 3参数 / 顺序相关 直观但存在万向锁 四元数 q 4参数 / 单位约束 插值平滑、双覆盖 位姿插值 slerp / lerp 去畸变关键 坐标系变换链:T_map_lidar = T_map_odom · T_odom_base · T_base_lidar 外参标定 → 帧间配准 → 位姿插值去畸变 → 地图拼接

四、位姿插值与坐标系变换

激光雷达一帧不是瞬时曝光,而是持续约 100 ms 的扫描过程。若机器人在这段时间内运动,每个激光点对应的雷达位姿都不同。前端必须用位姿插值把每个点还原到统一时刻,否则墙壁会弯曲、地面会倾斜。常用做法是:

  1. 从里程计或 IMU 获取帧起始与结束时刻的位姿 T_start、T_end;
  2. 对每个点的时间戳 t 计算比例 s = (t - t_start) / (t_end - t_start);
  3. 平移用线性插值,旋转用四元数 slerp 或李代数插值;
  4. 得到 T(t),将点变换到帧起始坐标系或世界坐标系。
// 四元数 slerp 插值示例
Eigen::Quaterniond q0, q1, qt;
double s = (t - t0) / (t1 - t0);
qt = q0.slerp(s, q1);

// 李代数插值
Sophus::SE3d T0, T1, Tt;
Sophus::SE3d delta = T0.inverse() * T1;
Tt = T0 * Sophus::SE3d::exp(s * delta.log());

坐标系变换则要严格区分“点变换”和“坐标系变换”。若 T_ab 表示把 a 坐标系下的点变换到 b 坐标系,则 p_b = T_ab · p_a。链式法则为 T_ac = T_bc · T_ab。工程中最常见的错误是把外参方向写反,导致建图整体旋转 180° 或点云飞到地图外。

常见误区:
1. 欧拉角顺序不统一:标定用 ZYX,代码里按 XYZ 解析,结果姿态完全错误。
2. 四元数未归一化:长时间递推后模长漂移,旋转矩阵不再正交。
3. 插值用线性插值旋转矩阵:中间结果不满足正交约束,点云被拉伸。
4. 外参方向混淆:T_base_lidar 与 T_lidar_base 互为逆,写反后配准永远不收敛。

五、工程复盘与选型建议

在激光SLAM前端,推荐遵循以下实践:存储和传输外参用旋转矩阵加平移向量,避免歧义;优化内部状态用李代数,保证无约束更新;位姿插值和 IMU 融合用四元数,保证平滑;只在人机界面和标定初值处使用欧拉角。每次修改外参或位姿表示后,务必用一个小场景做闭环验证:让机器人原地旋转 360°,观察地图是否闭合、地面是否水平、墙角是否笔直。若出现弯曲或错层,优先检查插值时刻、外参方向和四元数归一化,而不是急于调 ICP 参数。

把刚体变换的表示选对、把坐标系链写清、把插值做准,前端配准的很多“玄学问题”都会变成可定位、可复现的工程问题。