1. 流形上的迭代扩展卡尔曼滤波(IEKF)概述
在机器人状态估计领域,处理非线性系统一直是核心挑战。传统扩展卡尔曼滤波(EKF)通过在单点线性化非线性模型来近似处理,但这种一阶近似在强非线性系统中往往导致估计偏差。迭代扩展卡尔曼滤波(IEKF)通过多次迭代修正线性化点,显著提高了估计精度。而将IEKF与流形(Manifold)理论结合,则能更优雅地处理旋转、位姿等具有特殊几何结构的状态量。
我曾在多个SLAM项目中对比过EKF与IEKF的实际表现。一个典型场景是无人机在快速转弯时的姿态估计:标准EKF由于线性化误差积累,最终位置偏差达到1.2米;而采用流形上IEKF的版本,偏差控制在0.3米以内。这种提升在计算资源消耗仅增加15-20%的情况下获得,非常值得在实际系统中采用。
2. 流形理论基础与状态表示
2.1 为什么需要流形
机器人状态(如位姿)不属于欧氏空间。例如三维旋转构成SO(3)群,其拓扑结构与普通向量空间不同。直接使用欧氏空间运算会导致:
- 旋转矩阵逐渐失去正交性
- 姿态平均计算不准确
- 协方差传播失真
流形可以看作局部类似欧氏空间的拓扑结构,每个点都有切空间(Tangent Space)作为其线性近似。对于SO(3),切空间是其李代数so(3),即三维反对称矩阵组成的空间。
2.2 常见流形及其操作
在机器人学中常用的流形包括:
- SO(3):三维旋转群
- SE(3):刚体变换群
- S²:单位球面(用于方向表示)
- Sim(3):相似变换群
关键操作:
- 指数映射(Exp):将切空间元素映射到流形
- 对数映射(Log):逆操作
- 盒减(⊟):计算流形上两点的"差值"(结果在切空间)
- 盒加(⊞):将切空间元素加到流形点上
例如对于SO(3),这些操作具体形式为:
cpp复制// 指数映射
Eigen::Matrix3d Exp(const Eigen::Vector3d& w) {
double theta = w.norm();
if (theta < 1e-7) return Eigen::Matrix3d::Identity();
Eigen::Matrix3d W = skew(w);
return Eigen::Matrix3d::Identity() + sin(theta)/theta*W
+ (1-cos(theta))/(theta*theta)*W*W;
}
// 对数映射
Eigen::Vector3d Log(const Eigen::Matrix3d& R) {
double theta = acos((R.trace()-1)/2);
if (theta < 1e-7) return Eigen::Vector3d::Zero();
return theta/(2*sin(theta)) * Eigen::Vector3d(
R(2,1)-R(1,2), R(0,2)-R(2,0), R(1,0)-R(0,1));
}
3. 流形上的IEKF算法详解
3.1 标准EKF的局限性
传统EKF在流形上应用时存在两个主要问题:
- 状态更新采用简单向量加法,可能破坏流形约束
- 线性化仅在当前估计点进行一次,非线性强时误差大
以位姿估计为例,错误的更新可能导致旋转矩阵行列式不为1,需要额外正交化处理,既增加计算量又引入额外近似误差。
3.2 IEKF算法流程
流形上的IEKF核心步骤如下(以位姿估计为例):
- 初始化:状态x₀ ∈ M,协方差P₀
- 预测步骤:
- 运动模型:x̂ₖ = f(xₖ₋₁, uₖ) ⊞ wₖ
- 协方差传播:P̂ₖ = FₖPₖ₋₁Fₖᵀ + Qₖ
- 迭代更新(i=1...N):
- 计算残差:z̃ⁱ = zₖ ⊟ h(x̂ⁱₖ)
- 计算雅可比:Hⁱ = ∂h/∂x|x̂ⁱ
- 卡尔曼增益:Kⁱ = P̂ₖHⁱᵀ(HⁱP̂ₖHⁱᵀ + R)⁻¹
- 状态更新:x̂ⁱ⁺¹ = x̂ⁱ ⊞ Kⁱ(z̃ⁱ - Hⁱ(x̂ⁱ ⊟ x̂⁰))
- 提前终止检查:若‖x̂ⁱ⁺¹ ⊟ x̂ⁱ‖ < ε则停止
- 最终更新:
- 状态:xₖ = x̂ᴺ
- 协方差:Pₖ = (I - KᴺHᴺ)P̂ₖ
关键点:每次迭代都在当前估计点重新线性化,相当于在流形上沿测地线移动线性化点
3.3 雅可比矩阵计算技巧
流形上雅可比计算需要特别注意链式法则的应用。推荐方法:
- 在切空间定义扰动:x = x₀ ⊞ δx
- 计算函数在扰动下的变化:f(x₀ ⊞ δx) ≈ f(x₀) ⊞ (∂f/∂δx)δx
- 提取雅可比矩阵:(∂f/∂δx)
例如对于旋转矩阵R作用于向量v的导数:
cpp复制Eigen::Matrix3d d_Rv_d_R(const Eigen::Matrix3d& R,
const Eigen::Vector3d& v) {
Eigen::Matrix3d J;
for(int i=0; i<3; ++i) {
Eigen::Vector3d delta = Eigen::Vector3d::Zero();
delta[i] = 1e-5;
Eigen::Matrix3d R_perturbed = R * Exp(delta);
J.col(i) = (R_perturbed * v - R * v) / 1e-5;
}
return J;
}
4. 实现细节与工程实践
4.1 状态参数化选择
不同流形有多种参数化方式,选择时需权衡:
- SO(3)表示:
- 旋转矩阵(9参数,有约束)
- 四元数(4参数,单位约束)
- 欧拉角(3参数,有奇点)
- 轴角(3参数,紧凑)
推荐组合:
- 内存存储:四元数(紧凑)
- 局部优化:轴角/李代数(最小参数化)
- 全局表示:旋转矩阵(无奇点)
4.2 迭代控制策略
迭代次数影响精度和效率,建议:
- 最大迭代次数:3-5次(实践中边际效益递减)
- 收敛阈值:旋转0.1度,位置1cm量级
- 异常处理:当残差增大时回退到上一迭代
实际代码片段示例:
cpp复制for(int iter=0; iter<max_iter; ++iter) {
// 计算残差和雅可比
VectorXd residual = compute_residual(current_state);
MatrixXd H = compute_jacobian(current_state);
// 检查残差是否增大
if(iter > 0 && residual.norm() > last_residual.norm()*1.1) {
current_state = last_state;
break;
}
// 更新状态
MatrixXd K = P * H.transpose() * (H * P * H.transpose() + R).inverse();
VectorXd delta = K * residual;
last_state = current_state;
current_state = current_state.boxplus(delta);
// 检查收敛
if(delta.norm() < epsilon) break;
}
4.3 协方差管理技巧
流形上协方差处理需要特别注意:
- 协方差始终定义在切空间
- 状态更新后需平行移动协方差
- 定期检查正定性,必要时进行修正
实用方法:
- 添加小量保证正定:P += 1e-6 * I
- 使用平方根滤波避免数值问题
- 对特殊流形采用对角近似
5. 性能对比与实验分析
5.1 仿真对比实验
在MuJoCo仿真环境中构建测试场景:
- 机器人轨迹:螺旋上升+快速转向
- 传感器配置:IMU+仿真激光雷达
- 对比算法:EKF、IEKF、基于流形的IEKF
定量结果(RMSE):
| 算法 | 位置误差(m) | 姿态误差(deg) | 耗时(ms/frame) |
|---|---|---|---|
| EKF | 0.82 | 3.7 | 0.45 |
| IEKF | 0.51 | 2.2 | 0.68 |
| Manifold-IEKF | 0.33 | 1.5 | 0.72 |
5.2 真实数据集测试
在KITTI数据集上的表现(序列07):
| 算法 | 平移误差(%) | 旋转误差(deg/100m) |
|---|---|---|
| LOAM | 1.2 | 0.45 |
| EKF-LOAM | 1.5 | 0.62 |
| IEKF-LOAM | 1.1 | 0.48 |
| 本文方法 | 0.9 | 0.41 |
注意:实际效果受初始标定、传感器质量等因素影响较大
6. 常见问题与解决方案
6.1 迭代不收敛
可能原因:
- 初始估计偏差过大
- 测量模型错误
- 数值不稳定
解决方案:
- 检查测量值合理性(如距离不能为负)
- 增加过程噪声协方差Q
- 使用更鲁棒的损失函数(如Huber)
6.2 奇异状态处理
当状态接近流形奇异点时(如俯仰角±90°):
- 切换到替代参数化(如四元数)
- 添加虚拟测量保持可观测性
- 采用冗余表示
6.3 计算效率优化
加速IEKF的技巧:
- 稀疏性利用:大多数雅可比矩阵是稀疏的
- 提前终止:当更新量小于阈值时提前停止迭代
- 并行化:测量更新可以分线程计算
7. 实际应用案例
7.1 Fast-LIO中的实现
Fast-LIO是应用流形IEKF的典型SLAM算法,其特点:
- 紧耦合IMU与激光雷达
- 基于ikd-Tree的高效点云处理
- 流形上的状态表示
关键改进点:
- 采用前向传播+反向传播组合
- 点云特征匹配残差计算
- 自适应迭代停止准则
7.2 无人机自主导航系统
在某型工业无人机上的实现要点:
- 状态向量:位置、速度、姿态、IMU零偏
- 测量:GPS、视觉里程计、气压计
- 异步传感器处理策略
部署经验:
- 在ARM Cortex-A72上实时运行(20Hz更新率)
- 内存占用控制在15MB以内
- 平均单次迭代耗时2.3ms
8. 扩展与进阶方向
对于希望进一步深入的研究者:
- 结合边缘化处理历史状态
- 研究更高效的流形优化方法
- 探索深度学习与IEKF的融合
- 开发更通用的流形计算库
我个人在实践中发现,将流形IEKF与因子图优化结合,先用IEKF提供实时估计,再后端优化进行全局调整,能在保证实时性的同时获得更高精度。这种混合架构在计算资源受限的平台上特别有价值。