Unscented Kalman Filter in Matlab无迹卡尔曼滤波
无迹卡尔曼滤波(Unscented Kalman Filter, UKF)
无迹卡尔曼滤波(Unscented Kalman Filter, UKF)是一种基于卡尔曼滤波的非线性状态估计方法,它通过一种称为无迹变换(Unscented Transformation)的方法,将非线性系统的状态估计问题转化为线性系统的状态估计问题,然后使用卡尔曼滤波器进行状态估计。
这是一种在线方法,也就是说,它会连续地对系统状态进行估计,而不是像批处理方法那样,一次性处理所有的数据。
要定义一个UKF,我们需要定义如下两个函数:
- 状态转移函数 $f(x, u, t)$
- 观测函数 $h(x)$
其中,$x$ 是状态向量,$u$ 是控制向量,$t$ 是时间,$f$ 是状态转移函数,$h$ 是观测函数。
提供这两个函数外加噪声的信息,既可以创建一个UKF对象。其后,就可以通过predict
来预测下个时间步长的状态;在拿到实时数据后,通过correct
函数来校正状态。
系统的框图如上所示。非线性系统的输入为 $u$,系统噪声为 $w$,系统状态为 $x$,观测值为 $y$, 观测噪声为 $v$。UKF 通过输入 $u$ 和观测值 $y$ 来估计系统状态 $\hat{x}$。
van der Pol Oscillator
这里我们以 van der Pol Oscillator 为例,来演示如何使用 UKF 进行状态估计。
首先,我们给出 van der Pol Oscillator 的一般形式:
$$ \ddot{x} - \mu (1 - x^2) \dot{x} + x = 0 $$其中,$\mu$ 是 van der Pol Oscillator 的参数。
这个方程可以被转化为两个一阶微分方程:
\begin{cases} \dot{x_1} &= x_2 \\ \dot{x_2} &= \mu (1 - x_1^2) x_2 - x_1 \\ \end{cases}
采用ODE45求解这个方程,我们可以得到 van der Pol Oscillator 的状态变化。
1T = 0.05; % [s] Filter sample time
2timeVector = 0:T:5;
3[t, xTrue] = ode45(@vdp1, timeVector, [2; 0]);
4
5figure;
6plot(t, xTrue, 'LineWidth', 2);
7xlabel('Time [s]');
8ylabel('States');
9legend('x_1', 'x_2', 'Location', 'Best');
10title('Van der Pol Oscillator');
11grid on;
12
13exportgraphics(gcf, '../matlab-img/vdp1Ode.png', 'Resolution', 100);
观测
假设我们对 van der Pol Oscillator 的状态进行观测,但是观测值是带有噪声的。
\begin{cases} R = 0.2 \\ y_1 = x_1 * (1 + \mathcal{N}(0, R)) \\ \end{cases}
1R = 0.2;
2
3rng(1); % For reproducibility
4yTrue = xTrue(:, 1);
5yMeas = yTrue .* (1 + sqrt(R) * randn(size(yTrue)));
6
7figure;
8plot(t, yTrue, 'LineWidth', 2);
9hold on;
10plot(t, yMeas, 'LineWidth', 2);
11xlabel('Time [s]');
12ylabel('State: x_1');
13legend('True', 'Measured', 'Location', 'Best');
14title('Van der Pol Oscillator Observations of x_1');
15
16exportgraphics(gcf, '../matlab-img/vdp1Observ.png', 'Resolution', 100);
UKF
接下来,我们使用 UKF 对 van der Pol Oscillator 的状态进行估计。
1% 猜测初始状态
2initialStateGuess = [2; 0]; % xhat[k|k-1]
3% 构造 UKF
4ukf = unscentedKalmanFilter( ...
5 @vdpStateFcn, ... % State transition function
6 @vdpMeasurementNonAdditiveNoiseFcn, ... % Measurement function
7 initialStateGuess, ...
8 'HasAdditiveMeasurementNoise', false);
9
10% 设置 UKF 参数
11ukf.MeasurementNoise = R;
12ukf.ProcessNoise = diag([0.02 0.1]);
13
14% 初始化数组存储
15Nsteps = numel(yMeas); % Number of time steps
16xCorrectedUKF = zeros(Nsteps, 2); % Corrected state estimates
17PCorrected = zeros(Nsteps, 2, 2); % Corrected state estimation error covariances
18e = zeros(Nsteps, 1); % Residuals (or innovations)
19
20for k = 1:Nsteps % k时刻
21 % 新息更新
22 e(k) = yMeas(k) - vdpMeasurementFcn(ukf.State); % ukf.State <- x[k|k-1]
23 % 新的输入测量更新状态估计
24 [xCorrectedUKF(k, :), PCorrected(k, :, :)] = correct(ukf, yMeas(k)); % ukf.State <- x[k|k]
25 % 预测下一个状态
26 predict(ukf);
27end
28
29% 绘制结果
30figure();
31h = plot(timeVector, xTrue(:, 1), timeVector, xCorrectedUKF(:, 1), timeVector, yMeas(:), 'LineWidth', 0.5);
32set(h(2), 'LineWidth', 2);
33set(h(1), 'LineWidth', 2);
34
35legend('True', 'UKF estimate', 'Measured', 'Location', 'Best');
36xlabel('Time [s]');
37ylabel('State: x_1');
38title('Van der Pol Oscillator State Estimation with UKF');
39
40exportgraphics(gcf, '../matlab-img/vdp1Ukf.png', 'Resolution', 100);
41
42function x = vdpStateFcn(x)
43 dt = 0.05; % [s] Sample time
44 x = x + vdpStateFcnContinuous(x) * dt;
45end
46
47function dxdt = vdpStateFcnContinuous(x)
48 %取 mu = 1的 van der Pol ODE
49 dxdt = [x(2); (1 - x(1) ^ 2) * x(2) - x(1)];
50end
51
52function yk = vdpMeasurementNonAdditiveNoiseFcn(xk, vk)
53 yk = xk(1) * (1 + vk);
54end
经过 UKF 估计后,我们可以得到 van der Pol Oscillator 的状态估计值。
进一步分析
当然,我们还可以对新息、协方差等进行分析。这里仅仅展示对一个连续的状态进行UKF估计的过程。
参考:Van der Pol Equation: Overview, Derivation, and Examination of Solutions
文章标签
|-->matlab |-->state estimation |-->ukf |-->system identification
- 本站总访问量:次
- 本站总访客数:人
- 可通过邮件联系作者:Email大福
- 也可以访问技术博客:大福是小强
- 也可以在知乎搞抽象:知乎-大福
- Comments, requests, and/or opinions go to: Github Repository