- 初见Kalman
假设我养了一只猪:
![](https://i-blog.csdnimg.cn/blog_migrate/76366b7888b9c89ca312b843a9052dd6.png)
一周前,这只猪的体重是46±0.5kg。注意,在这里我用了±0.5,表示其实我对这只猪一周前的体重并不是那么确定的,也就是说,46kg这个体重有0.5kg的误差。现在,我又养了这只猪一个星期。那么我想要知道它一个星期之后多重,又大概有多少的误差?
为了得到一周后的体重,我有两种方法:一是根据我多年的养猪经验得到的猪体重公式推求出一个大概的值,另一个就是直接去称它的体重。当然,两种方法都有一定的误差。假设经验公式得到的体重是48kg,误差2kg;直接称体重得到的是49kg,误差1kg:为了得到一周后的体重,我有两种方法:一是根据我多年的养猪经验得到的猪体重公式推求出一个大概的值,另一个就是直接去称它的体重。当然,两种方法都有一定的误差。假设经验公式得到的体重是48kg,误差2kg;直接称体重得到的是49kg,误差1kg:
可是,我是一个处女座的人,不管是经验公式得到的值,还是直接称量得到的值,我都觉得不够准。我希望有一种方法,可以同时结合这只猪一周前的体重、用经验公式估计的值以及直接称量得到的值,综合考虑,得出一个最接近猪真实体重的,误差最小的值。这就是卡尔曼滤波要完成的任务。现在我们来把养猪的模型抽象成数学公式:
上图的左边,上一周的猪的体重,可以抽象为也k-1时刻的状态值,用k-1时刻的最优估计值加上一个误差项来表示,右边同理。其中,
这一项表示的是估计值的协方差。这里要说明两点:
- 上图中所有的变量都是用粗体,表示这是一个向量或者一个矩阵;
- 之所以用(列)向量而非一个数来表示状态值,是因为,虽然一只猪的体重可以用一个值来表示,但是在实际的应用中很多状态并不是一个数就能表示的(比如导弹在空间中的位置,同时有x、y、z三个坐标)。
图中右边表示k时刻的状态值,这个值可以通过预测模块(也就是根据经验公式估计猪的体重)和纠错模块(也就是直接去称量猪的体重值)来估计。同样,预测模块和纠错模块都有着对应的误差和误差协方差矩阵。卡尔曼滤波要做的,就是根据贝叶斯估计的相关理论,同时考虑预测模块和纠错模块的协方差,对误差小的项赋予较大的权重,对误差大的项赋予较小的权重,并使预测的误差最小。
具体的实现过程如下:
参考:
https://www.zhihu.com/question/23971601/answer/137325095
- Kalman的数学原理
假设我们要研究的对象是一个房间的温度。根据你的经验判断,这个房间的温度是恒定的。(这里的假设相当于状态方程的系数A为1)假设你对你的经验不是100%的相信,可能会有上下偏差几度,我们把这些偏差看成是高斯白噪声(这里就是W(k))。另外,我们在房间里放一个温度计,但是这个温度计也不准确的,测量值会比实际值偏差。我们也把这些偏差看成是高斯白噪声。(温度计的测量值就是Z(k),而由于温度测到的温度就是温度,不用再换算,所以系数H就是1,偏差就是V(k))。好了,现在对于某一分钟我们有两个有关于该房间的温度值:你根据经验的预测值(系统的预测值X(k|k-1))和温度计的值(测量值Z(k))。下面我们要用这两个值结合他们各自的噪声来估算出房间的实际温度值。
假如我们要估算k时刻的是实际温度值。首先你要根据k-1时刻的温度值,来预测k时刻的温度。因为你相信温度是恒定的,所以你会得到k时刻的温度预测值是跟k-1时刻一样的,假设是23度,同时该值的高斯噪声的偏差是5度(5是这样得到的:如果k-1时刻估算出的最优温度值的偏差(p(k-1|k-1)就是上一时刻的p(k|k))是3,你对自己预测的不确定度是4度,他们平方相加再开方,就是5(算出来的就是P(k|k-1)))。然后,你从温度计那里得到了k时刻的温度值(测量值Z(k)),假设是25度,同时该值的偏差是4度(这个就是R了)。由于我们用于估算k时刻的实际温度有两个温度值,分别是23 度和25度。究竟实际温度是多少呢?相信自己还是相信温度计呢?究竟相信谁多一点,我们可以用他们的covariance(协方差)来判断。因为 Kg2=52/(52+42)(该式的计算相当于上面的(4)式子),所以Kg=0.78,我们可以估算出k时刻的实际温度值是:23+0.78*(25-23)=24.56度(该式对应(3)式,就是算出最优估算值)。可以看出,因为温度计的covariance比较小(比较相信温度计),所以估算出的最优温度值偏向温度计的值。
现在我们已经得到k时刻的最优温度值了,下一步就是要进入 k+1时刻,进行新的最优估算。到现在为止,好像还没看到什么自回归的东西出现。对了,在进入k+1时刻之前,我们还要算出k时刻那个最优值(24.56 度)的偏差。算法如下:((1-Kg)*52)0.5=2.35(该式对应(5)式)。这里的5就是上面的k时刻你预测的那个23度温度值的偏差,得出的2.35就是进入 k+1时刻以后k时刻估算出的最优温度值的偏差(对应于上面的3)。就是这样,卡尔曼滤波器就不断的把 covariance递归,从而估算出最优的温度值。他运行的很快,而且它只保留了上一时刻的covariance。上面的Kg,就是卡尔曼增益(Kalman Gain)。他可以随不同的时刻而改变他自己的值,是不是很神奇!