卡尔曼滤波器 - 导出状态转换函数

信息处理 matlab 卡尔曼滤波器 无味卡尔曼滤波器
2022-02-20 12:41:07

我对使用卡尔曼滤波比较陌生。目前我正在尝试理解它以及如何在 Matlab 中实现它。我找到了一个网站,里面有一些很好的例子,我想在 Matlab 中使用 unscentedKalmanFilter() 函数重写。该网站是卡尔曼滤波器示例,我正在尝试重建第一个示例,其中根据一些带有噪声的测量来估计金条的重量。

我想出了一些代码,但我怀疑我的状态转换功能f是正确的。据我了解,需要测量功能y=h(x)计算状态x从测量y和状态转换函数xn+1=f(xn,u)在哪里xn+1是来自输入的下一个状态的预测u和当前状态xn.

由于金条重量是直接测量的,因此测量函数应为h(x)=x+vkvk是加性噪声项。对于状态转换功能,我不知道。在他们写的例子中x^n=x^n1+αn(ynx^n1)在哪里yn是最后一次测量和αn一个因素。但是我不认为状态转换功能f应包括测量。

所以也许有人可以启发我。这是我到目前为止的Matlab代码:

initialStateGuess = [1030];
n=length(initialStateGuess);

h=@(x)[x(1)];% Measurement function
f=@(x)[x(1)];% State transition function

ukf = unscentedKalmanFilter(...
    f,... % State transition function
    h,... % Measurement function
    initialStateGuess,...
    'HasAdditiveMeasurementNoise',true,...
    'HasAdditiveProcessNoise',true);

yMeas = [1030 989 1017 1009 1013 979 1008 1042 1012 1011];% Measurement Values
R = var(yMeas);%0.2; % Variance of the measurement noise v[k]
ukf.MeasurementNoise = R;
ukf.ProcessNoise = 60;

Nsteps = length(yMeas); % Number of time steps
xCorrectedUKF = zeros(Nsteps,n); % Corrected state estimates
PCorrected = zeros(Nsteps,n,n); % Corrected state estimation error covariances
e = zeros(Nsteps,1); % Residuals (or innovations)

for k=1:Nsteps
    % Let k denote the current time.
    %
    % Residuals (or innovations): Measured output - Predicted output
    e(k) = yMeas(k) - vdpMeasurementFcn(ukf.State); % ukf.State is x[k|k-1] at this point
    [xCorrectedUKF(k,:), PCorrected(k,:,:)] = correct(ukf,yMeas(k));
    predict(ukf);
end

plot(xCorrectedUKF')
hold on
plot(yMeas)
plot(1010*ones(1,Nsteps))
legend('Kalman FIlter state','Measurement Values','True Value')

在我的 Matlab 代码中实现的卡尔曼滤波器状态的 10 个步骤

编辑:

从上图中可以看出,我编写的 Matlab 代码确实有效。随着越来越多的测量进入该状态,该状态越来越接近真实值。然而,过程噪声的方差值似乎与实现快速收敛非常相关。即使在玩了一会儿之后,我也无法像示例中那样实现快速收敛:

来自示例源的卡尔曼滤波器的 10 个步骤

所以我想知道为什么我的代码收敛得这么慢?

编辑2:

正如建议的那样,我尝试将过程噪声设置为 0,将测量噪声设置为测量值的方差。然而,这会导致建立时间非常缓慢。这可能与我使用无味卡尔曼滤波器有关吗?我认为这将是一个不错的选择,因为我也可以将它用于其他非线性问题。 ProcessNoise0 MeasurementNoise320

1个回答

嗨 Matthias La:我不想批评,但您提供的链接中的第一个示例实际上很差,因为它们最终使用了指数平滑(他们对x^可以重写为指数平滑更新)用于状态的更新,xt, 无需推导。导出状态的指数平滑更新的方法(他们还提出了指数平滑因子的启发式公式,αn, 的1n这不是最优的。它实际上最终成为 SNR 的函数)是以下列方式编写整个系统:

yt=xt+ϵt # 测量方程

xt=xt1+γt # 状态方程

在哪里ϵtγt是独立的正态误差项。

使用上述框架,如果您导出卡尔曼滤波器的更新方程,您将获得状态的指数平滑更新(和yt=xt^作为测量的更新)。在统计计量经济学文献中,上述 KF 设置称为“随机游走 + 噪声”模型。我并不是说这个链接完全没用,但就 KF 的介绍而言,这不是一个好的第一个例子,因为他们把东西从天上拉出来,也没有解释它们来自哪里。在浏览后面的示例时,这可能会令人困惑。

我希望上面的设置有助于展示如何获取 ES 更新。哦,我建议在下面详细了解 KF。哈维有一种简洁的风格,一开始可能很难(对我来说),但最后(经过几次阅读:)),你会发现他实际上提供了一个非常好的解释。我已经多次阅读它的各个部分。

https://www.amazon.com/Forecasting-Structural-Time-Harvey/dp/0521405734/ref=sr_1_1?dchild=1&keywords=Andrew+Harvey+Kalman+Filter&qid=1615252088&sr=8-1

编辑:我没有在上面提到它,但我后来记得如果你想运行更新方程,你需要一种方法来估计测量方差和状态方差。Harvey 使用预测误差分解,但我的印象是 dsp 人有不同的估计方式。预测误差 decomp 是我熟悉的唯一方法,但您可能知道更好的方法。如果您这样做并且可以向我解释,我们将不胜感激。