卡尔曼滤波与扩展卡尔曼滤波:从核心原理到工程实践详解
1. 项目概述从直觉理解KF与EKF如果你在机器人、自动驾驶、无人机或者任何涉及传感器数据融合的领域摸爬滚打过一阵子那么“卡尔曼滤波”这个名字你一定如雷贯耳。它就像一个藏在系统背后的“老法师”总能在嘈杂的传感器读数中为我们推算出那个最可能接近真实的状态。但当你翻开教科书或者学术论文满篇的矩阵和概率论符号又常常让人望而却步。今天我们不搞那些云山雾罩的理论推导就从一个一线工程师的视角来拆解卡尔曼滤波和它的升级版——扩展卡尔曼滤波的核心思路、工作流程以及那些你真正写代码时需要用到的计算公式。简单来说卡尔曼滤波要解决的核心问题是我们有一个动态系统比如一辆移动的车我们既有描述它运动规律的模型比如根据速度和时间的位移公式也有来自传感器的、带噪声的观测数据比如GPS位置。这两者都不完全可靠模型是简化的有误差传感器读数有噪声也不准。卡尔曼滤波的魔法就在于它提供了一套严谨的数学框架能够最优地在最小均方误差意义下将不可靠的模型预测和不可靠的传感器观测融合起来得到一个比两者单独使用都更可靠的状态估计。而扩展卡尔曼滤波则是当这个动态系统或者观测模型不是简单的线性关系时比如涉及角度、三角函数对标准卡尔曼滤波的“打补丁”方案。它通过局部线性化的方式让卡尔曼滤波这套强大的工具能应用到更广泛的非线性系统中去。理解了两者的核心思路和流程你就能在项目里游刃有余地应用它们而不是仅仅从开源库里复制粘贴一段看不懂的代码。2. 卡尔曼滤波的核心思路与两阶段流程卡尔曼滤波的整个过程可以清晰地分为两个交替进行的阶段预测和更新。你可以把它想象成一个“预测-实测-修正”的循环。这个循环在每一个时间步长比如传感器每10毫秒传来一次数据都会执行一次。2.1 预测阶段基于模型向前看在预测阶段我们利用系统自身的运动模型从上一时刻的最优估计去预测当前时刻系统状态应该是什么样子。这里涉及两个关键信息状态预测系统现在大概在哪儿、速度是多少不确定性预测这个预测有多大的把握不确定性这个过程必然会引入误差因为模型是对现实的简化。我们用过程噪声来描述这个模型的不完美程度。比如我们用一个匀速模型来预测小车位置但实际中小车可能受到未知的风阻或地面摩擦这些未建模的因素就是过程噪声。2.2 更新阶段用观测数据来修正在更新阶段我们拿到了传感器的实际观测值。同样这个观测值也不完美带有观测噪声。卡尔曼滤波最精妙的部分就在这里它不会简单地用观测值替换预测值也不会对两者取个平均了事。它会计算一个叫做“卡尔曼增益”的权重。这个增益本质上是一个“信任系数”。它的计算基于我们之前预测的不确定性和传感器观测的不确定性如果模型预测非常准预测不确定性小而传感器很烂观测不确定性大那么卡尔曼增益会很小更新结果会更信任预测值。反之如果传感器精度极高观测不确定性小而模型预测很粗糙预测不确定性大那么卡尔曼增益会很大更新结果会更信任观测值。最后算法用这个动态计算出的权重将预测值和观测值融合得到当前时刻的最优估计并同步更新对这个最优估计的不确定性。这个更新后的不确定性一定会比预测阶段的不确定性要小因为新的观测信息减少了我们的认知模糊。至此一个循环结束这个“最优估计”将作为下一个时间步预测的起点如此往复。注意这里说的“不确定性”在卡尔曼滤波中是用协方差矩阵来数学表达的。它描述的不仅仅是某个状态值如位置的误差范围还描述了不同状态值之间如位置和速度误差的关联关系。理解这一点对后续看懂公式至关重要。3. 卡尔曼滤波的五大核心公式拆解下面我们直接给出标准线性卡尔曼滤波的五个核心公式并逐一进行“说人话”解读。假设我们的系统可以用线性状态空间方程描述预测方程时间更新状态预测x̂ₖ⁻ Fₖ x̂ₖ₋₁ Bₖ uₖ解读x̂ₖ⁻是我们在得到k时刻观测值之前的先验状态预测。Fₖ是状态转移矩阵它描述了系统如何从k-1时刻的状态自然演化到k时刻例如用速度乘以时间得到位移增量。x̂ₖ₋₁是k-1时刻的后验最优估计。Bₖ是控制输入矩阵uₖ是控制量如油门、舵机指令这部分描述了外部控制对状态的影响。误差协方差预测Pₖ⁻ Fₖ Pₖ₋₁ Fₖᵀ Qₖ解读Pₖ⁻是先验状态预测对应的先验误差协方差矩阵代表我们对于预测值x̂ₖ⁻的不确定程度。Fₖ Pₖ₋₁ Fₖᵀ这一项意味着上一时刻的不确定性Pₖ₋₁会通过系统模型Fₖ传递并放大到当前时刻。Qₖ是过程噪声协方差矩阵它代表了系统模型本身的不精确度。两者相加使得预测的不确定性总是比上一时刻更新后的不确定性要大。更新方程测量更新 3. 卡尔曼增益计算Kₖ Pₖ⁻ Hₖᵀ (Hₖ Pₖ⁻ Hₖᵀ Rₖ)⁻¹*解读这是整个算法的“大脑”。Kₖ就是卡尔曼增益矩阵。Hₖ是观测矩阵它将系统状态空间映射到观测空间比如状态包含位置和速度但GPS只观测位置H矩阵就是[1, 0]。Rₖ是观测噪声协方差矩阵代表传感器的精度。公式分母(Hₖ Pₖ⁻ Hₖᵀ Rₖ)是预测观测值的不确定性。这个公式的本质是用预测的不确定性Pₖ⁻除以预测的不确定性 观测的不确定性来决定该相信谁更多。分子Pₖ⁻ Hₖᵀ可以理解为将状态空间的预测不确定性转换到观测空间。 4. 状态更新x̂ₖ x̂ₖ⁻ Kₖ (zₖ - Hₖ x̂ₖ⁻)*解读这是融合发生的地方。x̂ₖ是我们最终得到的k时刻后验最优估计。zₖ是k时刻传感器的实际观测值。(zₖ - Hₖ x̂ₖ⁻)被称为新息或残差是实际观测值与预测观测值之间的差值。卡尔曼增益Kₖ作为权重决定了这个残差中有多少信息被用来修正我们的预测。如果增益大修正幅度就大增益小就主要相信预测。 5. 误差协方差更新Pₖ (I - Kₖ Hₖ) Pₖ⁻*解读在融合了观测信息后我们对系统状态的不确定性降低了。这个公式计算的是更新后的后验误差协方差矩阵Pₖ。I是单位矩阵。可以看到由于Kₖ Hₖ是一个正定项Pₖ总是小于等于Pₖ⁻。这直观地反映了“获取新信息后不确定性下降”这一事实。实操心得在具体实现时Q过程噪声和R观测噪声矩阵的取值往往是调参的关键它们没有绝对正确的值需要根据你对模型可信度和传感器精度的理解来设定。通常Q和R会被设置为对角矩阵对角线上的值分别代表各个状态变量和观测量的噪声方差。一个常用的技巧是将R设置为传感器厂商提供的精度指标如GPS的CEP而Q则通过实验调试观察滤波器的跟踪性能和平滑度来权衡。4. 扩展卡尔曼滤波应对非线性世界的利器标准的卡尔曼滤波要求系统模型F和观测模型H都是线性的。但现实世界中大量系统是非线性的。例如车辆的运动模型涉及航向角状态转移包含sin和cos。雷达观测目标时测量的是距离和方位角这与目标的直角坐标位置之间存在非线性关系。强行在这些场景下使用线性模型会导致滤波结果发散完全偏离真实值。扩展卡尔曼滤波的解决思路非常“工程师化”局部线性化。4.1 EKF的核心思想雅可比矩阵与泰勒展开EKF不再假设F和H是固定的矩阵而是将它们视为由非线性函数f和h在当前最优估计点处进行一阶泰勒展开后得到的雅可比矩阵。状态转移函数xₖ f(xₖ₋₁, uₖ, wₖ)其中w是过程噪声。观测函数zₖ h(xₖ, vₖ)其中v是观测噪声。EKF的做法是在每一个滤波循环中在预测阶段使用非线性函数f本身来进行状态预测x̂ₖ⁻ f(x̂ₖ₋₁, uₖ, 0)。注意这里的过程噪声均值设为0。但是在预测不确定性Pₖ⁻时我们需要一个线性的近似来描述状态误差是如何传播的。这个近似就是函数f在点x̂ₖ₋₁处的雅可比矩阵Fₖ。Fₖ的每个元素F[i,j]是f的第i个输出对第j个输入的偏导数在当前估计点的值。同理在更新阶段计算卡尔曼增益和更新协方差时我们需要观测模型h在预测点x̂ₖ⁻处的雅可比矩阵Hₖ。4.2 EKF的公式修正基于以上思想EKF的公式在KF基础上做了如下调整预测阶段状态预测x̂ₖ⁻ f(x̂ₖ₋₁, uₖ, 0)使用非线性函数误差协方差预测Pₖ⁻ Fₖ Pₖ₋₁ Fₖᵀ Qₖ其中Fₖ是f在x̂ₖ₋₁处的雅可比矩阵更新阶段 3. 卡尔曼增益Kₖ Pₖ⁻ Hₖᵀ (Hₖ Pₖ⁻ Hₖᵀ Rₖ)⁻¹其中Hₖ是h在x̂ₖ⁻处的雅可比矩阵 4. 状态更新x̂ₖ x̂ₖ⁻ Kₖ (zₖ - h(x̂ₖ⁻, 0))计算残差时使用非线性函数h 5. 误差协方差更新Pₖ (I - Kₖ Hₖ) Pₖ⁻可以看到EKF的框架和KF完全一致只是将固定的F和H矩阵替换成了随着当前估计值变化而动态计算的雅可比矩阵Fₖ和Hₖ。注意事项EKF的线性化只是一种一阶近似当系统非线性程度很强或者初始误差很大时这种近似会失效导致滤波性能下降甚至发散。因此确保状态估计始终在真实值附近是EKF能有效工作的前提。对于高度非线性的系统可能需要考虑无迹卡尔曼滤波或粒子滤波。5. 从理论到实践一个EKF的简易实例为了让大家更有体感我们考虑一个经典例子基于轮式编码器测距和陀螺仪测角速度的移动机器人二维定位同时用GPS进行位置校正。这是一个典型的传感器融合问题且涉及角度是非线性的。状态定义x [px, py, v, theta]ᵀ即x坐标、y坐标、线速度、航向角。控制输入u [a, omega]ᵀ即线加速度、角速度可由编码器差分和陀螺仪得到。1. 非线性状态转移函数f 假设在短时间Δt内近似为匀速圆周运动。px_k px_{k-1} v_{k-1} * cos(theta_{k-1}) * Δt py_k py_{k-1} v_{k-1} * sin(theta_{k-1}) * Δt v_k v_{k-1} a * Δt theta_k theta_{k-1} omega * Δt这就是我们的f函数。可以看到px和py的更新依赖于cos(theta)和sin(theta)是非线性的。2. 计算雅可比矩阵Fₖ 我们需要计算Fₖ ∂f/∂x在x̂ₖ₋₁处的值。这是一个4x4的矩阵。Fₖ [ 1, 0, cos(θ)*Δt, -v*sin(θ)*Δt ] [ 0, 1, sin(θ)*Δt, v*cos(θ)*Δt ] [ 0, 0, 1, 0 ] [ 0, 0, 0, 1 ]注意第三行第四列为0因为我们假设线速度v的变化与航向角theta无关模型简化。这个矩阵在每一步预测时都需要用最新的v和theta估计值重新计算。3. 观测模型 假设GPS直接提供位置观测z [px_gps, py_gps]ᵀ。那么观测函数h很简单h(x) [px, py]ᵀ。其雅可比矩阵Hₖ是一个常数矩阵Hₖ [ 1, 0, 0, 0 ] [ 0, 1, 0, 0 ]因为它只选取了状态向量的前两个元素。4. 实操流程初始化设定初始状态x̂₀例如从第一个GPS点获得和初始协方差P₀通常设为一个较大的对角阵表示初始不确定性很大。循环开始每当收到新的编码器/陀螺仪数据预测用f函数和当前控制输入u计算x̂ₖ⁻。用当前x̂ₖ₋₁计算雅可比矩阵Fₖ再代入公式Pₖ⁻ Fₖ Pₖ₋₁ Fₖᵀ Q计算预测协方差。等待观测如果当前时刻没有GPS数据则跳过更新步骤直接将预测值作为最优估计x̂ₖ x̂ₖ⁻,Pₖ Pₖ⁻。更新当收到GPS数据zₖ时计算卡尔曼增益Kₖ。计算残差zₖ - h(x̂ₖ⁻)。更新状态x̂ₖ和协方差Pₖ。将x̂ₖ和Pₖ作为下一时刻的输入继续循环。通过这个流程机器人在没有GPS信号时可以依靠自身模型里程计进行航位推算虽然误差会累积P会增大。一旦收到GPS信号便立即用高精度的位置信息修正整个状态包括速度、航向并将不确定性P缩小。这样我们就得到了一个比单纯用GPS或单纯用里程计都更平滑、更连续、更可靠的位置姿态估计。6. 实现中的常见陷阱与调参心得在实际编码和调试KF/EKF时有几个坑几乎每个人都会遇到。1. 协方差矩阵的初始化与维护初始化P₀不能设为全零矩阵全零意味着你100%确定初始状态滤波器将无法接受后续的观测修正。通常设为对角阵对角线上的值根据你对初始状态的置信程度来设定例如位置初始方差100 m²速度方差10 (m/s)²。对称正定性理论上协方差矩阵P必须是对称半正定的。但在数值计算中由于浮点数精度和公式Pₖ (I - Kₖ Hₖ) Pₖ⁻的计算可能导致P失去对称性或出现负特征值从而使滤波器发散。一个实用的技巧是在每次更新后强制令P (P Pᵀ) / 2以确保对称性。更稳健的方法是使用约瑟夫形式更新Pₖ (I - Kₖ Hₖ) Pₖ⁻ (I - Kₖ Hₖ)ᵀ Kₖ Rₖ Kₖᵀ虽然计算量大些但能保证正定性。2. Q和R矩阵的调参艺术Q过程噪声反映了你对模型的信任程度。Q设得越大表示你认为模型越不可靠滤波器会更信任观测值响应变快但估计结果可能因观测噪声而抖动。Q设得越小则更信任模型结果更平滑但可能对真实变化的响应迟缓。R观测噪声反映了你对传感器的信任程度。R设得越大认为传感器噪声越大滤波器会更信任模型预测增益K变小。R设得越小则认为传感器越精确会更信任观测值增益K变大。调试方法通常先根据传感器手册设定R。然后调整Q。在离线数据上回放时可以观察新息序列(zₖ - Hₖ x̂ₖ⁻)。理想情况下新息应该是一个零均值的白噪声序列。如果新息显示出明显的趋势或自相关说明Q或R设置不当或者模型有误。3. 离散时间与连续时间 系统模型通常是在连续时间下描述的微分方程。而卡尔曼滤波在数字计算机中运行是离散的。需要将连续时间的系统方程和过程噪声协方差Q_c离散化得到离散时间的状态转移矩阵F和过程噪声协方差Q。如果采样时间Δt很小有时可以近似F ≈ I A*ΔtQ ≈ Q_c * Δt其中A是连续时间系统的状态矩阵。忽略这一步或处理不当会导致滤波器性能严重下降。4. EKF线性化误差与发散 EKF最大的敌人就是线性化误差。当系统非线性剧烈或预测误差较大时一阶泰勒展开的近似效果很差。表现为估计值明显偏离真实值。协方差矩阵P异常地变小过度自信但实际误差很大。应对策略增加过程噪声Q给模型更大的不确定性容忍度。限制增益K设置增益的上限防止单次更新修正过度。使用更高级的滤波器如无迹卡尔曼滤波它通过采样点来近似非线性分布精度通常优于EKF。保证观测更新频率对于快速变化的系统确保有足够频繁的观测来及时修正预测防止预测误差积累过大。7. 卡尔曼滤波的数学基础与学习路径看到这里你可能对矩阵运算和概率论感到头疼。确实要彻底弄懂卡尔曼滤波的推导需要一些数学基础线性代数矩阵乘法、转置、求逆虽然实际中避免直接求逆、矩阵的对称正定性。这是理解状态空间表达和协方差传播的基础。概率论与数理统计均值、方差、协方差、高斯正态分布。卡尔曼滤波的核心假设就是所有噪声都是高斯的。最优估计理论最小均方误差估计。卡尔曼滤波本质上是在寻找给定所有历史观测条件下当前状态的最小均方误差估计。对于初学者我建议的学习路径是第一步直觉像本文一样先理解“预测-更新”的两阶段循环和“信任权重”的核心思想。可以找一些一维的例子比如估计一个恒定电压值手动算一遍。第二步应用在具体项目如用MPU6050做姿态解算中尝试使用现成的库如C的Eigen库配合Kalman Filter库Python的FilterPy或PyKalman重点关注调参和结果分析。第三步深入当你对效果和问题有切身感受后再回头去学习贝叶斯滤波框架从条件概率密度传播的角度理解KF/EKF的推导。这时再看那些复杂的公式会更有感觉。记住工具的价值在于使用。你可以不必成为推导公式的数学家但一定要成为理解其思想、能驾驭其参数的工程师。当你成功地将一个飘忽不定的传感器信号通过卡尔曼滤波变成一条平滑可靠的曲线时那种成就感就是对你投入学习的最好回报。