做非线性状态估计的同行,应该都被EKF(扩展卡尔曼滤波器)折磨过。算雅可比矩阵的时候,链式法则一层套一层,微分方程复杂一点,整个人就麻了。即使勉强把导数算出来了,遇到强非线性系统,一阶线性化的近似误差又会把滤波精度拖垮,调试的时候完全不知道是模型问题还是代码问题。后来我转到无迹卡尔曼滤波器算法(UKF),才算是把这个死结解开了——它不需要求导,精度却能达到二阶以上,在MATLAB里实现起来也比EKF直觉得多。这篇就把我从原理理解到代码实现,再到实际调参踩坑的完整过程整理出来,适合正在用Matlab做非线性状态评估、目标跟踪或导航解算的工程师参考。
1. 为什么EKF不够用了:无迹卡尔曼滤波器要解决的问题
1.1 非线性状态评估的现实场景
先说清楚什么叫非线性状态评估。你去跟踪一个转弯的无人机,观测量是雷达的方位角和距离,但状态量是直角坐标系下的位置和速度,从极坐标到直角坐标的转换方程是非线性的。你去估计电池的剩余电量(SOC),开路电压和SOC之间是个带滞回特性的曲线,同样是非线性的。再比如航天器再入大气层时的状态估计,气动加热导致的减速模型,非线性程度更是夸张。
在这些场景里,卡尔曼滤波的标准形式没法直接用,因为它整个推导过程都是建立在线性高斯模型基础上的。工程上最常用的补救办法就是EKF:把非线性函数在当前估计点做一阶泰勒展开,用雅可比矩阵替代线性卡尔曼滤波里的状态转移矩阵和观测矩阵。思路没错,但实际用起来的体验非常差。
1.2 EKF线性化方案的三个硬伤
第一个问题是雅可比矩阵动不动就算不出来。很多系统的状态方程是由查表、数值求解微分方程、甚至分段函数构成的,压根没有解析导数。就算你能手推导数,一个10维状态的雅可比矩阵,里面几十个偏导项,任何一个符号错了,滤波结果都能偏到姥姥家。我在MATLAB里用符号工具箱求过几次雅可比,符号表达式长得让人头皮发麻,最后还要转成数值函数,调试成本极高。
第二个问题是精度不够。一阶泰勒展开本质上是用切线代替曲线,只在展开点附近误差小。如果系统的非线性强度高,比如观测方程里有三角函数、平方项,或者状态更新间隔长,线性化之后的均值和真实均值之间会有明显偏差。更麻烦的是,线性化会系统性地低估协方差,因为所有高阶项都被截断了。协方差一旦被低估,卡尔曼增益就会算错,滤波器要么收敛得很慢,要么干脆发散。
第三个问题是EKF对不连续或不光滑的函数无能为力。现实中很多系统模型带有符号判断或者饱和限幅,导数在这些点不存在。硬要用EKF,就得人为修光滑,修出来的模型和真实系统之间的距离又变成新误差源。
1.3 UKF换了一个角度:分布传不动就传点
UKF能绕开EKF的这些问题,核心思想其实特别朴素:既然状态是随机变量,关心的本质上是它的概率分布,而不是状态函数本身长什么样。那我们就别去近似那个非线性函数了,直接近似状态的分布。怎么近似一个高斯分布呢?用一组精心挑选的点,也就是sigma点,去代表这个分布。把每个sigma点丢进非线性函数里跑一遍,跑出来的点群自然就携带了非线性变换后的信息,再对这些输出点做加权统计,就能得到变换后的均值和协方差。
这批做法的妙处在于,它完全绕开了雅可比矩阵,对系统模型没有光滑性的要求。而且sigma点的选取是二维精确的,什么意思呢?只要非线性函数在展开点附近有连续的二阶导数,UT变换得到的均值和协方差精度就能达到二阶,比EKF的一阶精度高一整个量级。如果非线性函数本身就是二次型的,UT变换甚至能精确复现真实结果。这个性质我在后面会用一个例子验证。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. UT变换的数学内功:sigma点怎么选、权重怎么定
2.1 sigma点构造公式的直觉解读
无迹变换(Unscented Transform,UT)的构造方法看起来是个公式,但背后逻辑其实很像你在一个团队里挑代表去参加调研:不能只让一个人去,因为他只代表自己的观点;得挑几个人,覆盖主流意见和不同极端情况,回来后综合大家的见闻估计整体情况。
公式层面上,给定n维状态向量x,均值是x̄,协方差矩阵是P。构造2n+1个sigma点:
- 第一个点是均值本身:X₀ = x̄
- 剩下的点沿P矩阵的各主轴方向对称散布:Xᵢ = x̄ + (√((n+λ)P))ᵢ,Xᵢ₊ₙ = x̄ - (√((n+λ)P))ᵢ,其中(√((n+λ)P))ᵢ表示矩阵(n+λ)P的Cholesky分解第i列
请注意,这里需要的是矩阵平方根。MATLAB里用chol((n+lambda)*P, 'lower')得到下三角矩阵,它的各列就是sigma点的散布方向。实际写代码的时候这也是个关键细节:用sqrtm做矩阵平方根在数值上远不如chol稳定,尤其是当P接近半正定或者维度较高时,sqrtm返回的结果可能出现微小负特征值,后面算协方差就容易崩。
2.2 三个参数 alpha、beta、kappa 到底在管什么
公式里的 λ = α²(n + κ) - n 是一个缩放参数,它决定了sigma点离均值有多远。三个参数各管一摊:
| 参数 | 典
