做啥用的
我们想知道一个系统在某个时刻的真实状态,手段往往有多种,比如最常见的两种:
- 用合适的传感器测量出来;
- 根据上一时刻的状态用数学模型推算出来;
那么,应该相信哪一种办法得到的值呢?
怎么做的
先把上述概念实例化一下,对于一个小车,我们想知道它在当前时刻$t$距离障碍物的真实距离$x_t$。我们用两种办法:
- 测距雷达测得的测量值$m_t$
- 根据上一时刻的车速$v_{t-1}$和上一时刻的最终估计值$p_{t-1}$得到的预测值$n_t$,即有
然后,想办法平衡$m_t$和$n_t$,得到本时刻的最终估计值$p_t$。卡尔曼的做法是,将所有变量都视作一个正态的概率分布,而不是一个简单的标量值。即有
- 自变量$v_{t-1}$ -> $v_{t-1}(\mu _v,\sigma _v)$,数据来自于传感器,可以认为均值和方差已知。
- 自变量$m_{t}$ -> $m_{t}(\mu _m,\sigma _m)$,数据来自于传感器,可以认为均值和方差已知。
- 中间变量$n_{t}$ -> $n_{t}(\mu _n,\sigma _n)$
- 结果变量$p$ -> $p(\mu _p,\sigma _p)$
然后,按照经典方式,分两步计算来得到$p_t$
Step1 预测
首先因为
所以,可以得到$n_t$的均值和方差分别为
Step2 融合/更新/校正
平衡$m_t$和$n_t$这两个概率分布的方式是概率的乘法,即有
由于正态分布在变量取均值是概率最大,所以$\mu_t^p$即为$t$时刻的最终估计值$p_t$。而$\sigma_t^p$则用于计算下时刻的最终估计值。
代码实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| import numpy as np import matplotlib.pyplot as plt
t = np.linspace(1, 100, 100) a = 0.5 position = (a * t ** 2) / 2
position_noise = position + np.random.normal(0, 120, size=(t.shape[0]))
plt.plot(t, position, label='truth position') plt.plot(t, position_noise, label='only use measured position')
predicts = [position_noise[0]] position_predict = predicts[0]
predict_var = 0 odo_var = 120 ** 2 v_std = 50 for i in range(1, t.shape[0]): dv = (position[i] - position[i - 1]) + np.random.normal(0, 50) position_predict = position_predict + dv predict_var += v_std ** 2 position_predict = position_predict * odo_var / (predict_var + odo_var) + position_noise[i] * predict_var / ( predict_var + odo_var) predict_var = (predict_var * odo_var) / (predict_var + odo_var) ** 2 predicts.append(position_predict)
plt.plot(t, predicts, label='kalman filtered position')
plt.legend() plt.show()
|
参考链接
- https://zhuanlan.zhihu.com/p/77327349