1. 项目概述
这个项目实现了一个基于平面运动假设的误差状态卡尔曼滤波器(ESKF),用于融合多传感器数据。我在机器人定位导航项目中多次使用这种方案,它特别适合地面移动机器人的位姿估计场景。相比传统卡尔曼滤波,ESKF通过误差状态参数化有效解决了非线性系统的滤波问题,而平面运动约束则大幅降低了计算复杂度。
典型应用场景包括:
- 仓储AGV的实时定位
- 服务机器人的导航避障
- 自动驾驶车辆的局部定位
- 无人机在二维平面的运动跟踪
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心算法解析
2.1 误差状态卡尔曼滤波原理
ESKF的核心思想是将状态量分解为名义状态(nominal state)和误差状态(error state)。名义状态采用常规积分更新,而误差状态保持在小量范围内,可以使用线性化处理。这种分离处理带来了三个显著优势:
- 旋转参数化不会出现奇异点(使用三维误差角而非四元数)
- 误差状态始终接近零值,线性化近似更准确
- 重置操作简单直接(将误差状态归零)
在平面运动场景中,我们定义名义状态为:
code复制x = [p_x, p_y, v_x, v_y, θ]^T
其中(p_x,p_y)为位置,(v_x,v_y)为速度,θ为航向角。
误差状态则定义为:
code复制δx = [δp_x, δp_y, δv_x, δv_y, δθ]^T
2.2 平面运动约束实现
平面运动假设意味着:
- 无垂直方向运动(z轴位置、速度为零)
- 无横滚和俯仰角变化
- 角速度仅存在于z轴方向
这使我们可以将6自由度问题简化为3自由度(x,y,θ),状态转移矩阵维度从18×18降至15×15。在实际代码中,我通过以下方式实现约束:
cpp复制// 状态转移矩阵简化
Eigen::MatrixXd F = Eigen::MatrixXd::Zero(15, 15);
F.block<2,2>(0,3) = Eigen::Matrix2d::Identity(); // 位置与速度关系
F.block<2,2>(3,6) = Eigen::Matrix2d::Identity(); // 速度与加速度关系
F(2,5) = 1.0; // 航向角与角速度关系
