通俗易懂“卡尔曼滤波”

前言

相信所有学习卡尔曼滤波的同学首先接触的都是状态方程和观测方程,学过控制系统的同学可能不陌生,否则,先被那两个看起来好深奥的公式给吓跑了,关键是还不知道他们究竟是干什么的,什么是状态,什么是观测。。。。。。如果再看到后面的一大串递归推导增益,实在很晕很晕,更糟糕的是还没整明白的时候就已经知道卡尔曼滤波其实已经不够使了,需要extended kalmanfilter 和particle filter了。。。

其实我们完全不用理会这些公式。先来看看究竟卡尔曼滤波是做什么的,理解了卡尔曼滤波,下面的就顺其自然了。

用一句最简单的话来说,卡尔曼滤波是来帮助我们做测量的,大家一定不明白测量干嘛搞那么复杂?测量长度拿个尺子比一下,测量温度拿温度表测一下不就完了嘛。的确如此,如果你要测量的东西很容易测准确,没有什么随机干扰,那真的不需要劳驾卡尔曼先生。但在有的时候,我们的测量因为随机干扰,无法准确得到卡尔曼先生就给我们想了个办法,让我们在干扰为高斯分布的情况下,得到的测量均方误差最小,也就是测量值扰动最小,看起来最平滑

还是举例子最容易明白。我最近养了只小兔子,忍不住拿小兔子做个例子嘻嘻。

每天给兔子拔草,看她香甜地吃啊吃地,就忍不住关心一下她的体重增长情况。那么我们就以小兔子的体重作为研究对象吧。假定我每周做一次观察,我有两个办法可以知道兔子的体重:

  • 拿体重计来称:

或许你有办法一下子就称准兔子的体重(兽医通常都有这办法),但现在为了体现卡尔曼先生理论的魅力,我们假定你的称实在很糟糕,误差很大,或者兔子太调皮,不能老实呆着,弹簧秤因为小兔子的晃动会产生很大误差。尽管有误差,那也是一个不可失去的渠道来得到兔子的体重。我们把用称称出来的叫观察量

  • 根据相关的资料和兔子的年龄来估计

用资料估计出来的叫估计值,无论是观察值还是估计值显然都是有误差的,假定误差是高斯分布。

卡尔曼的思想

现在问题就来了,按照书本上说我的兔子该3公斤重,称出来却只有2.5公斤,我究竟该信哪个呢?如果称足够准,兔子足够乖,卡尔曼先生就没有用武之地了呵呵,再强调一下是我们的现状是兔兔不够乖,称还很烂呵呵。在这样恶劣的情景下,卡尔曼先生告诉我们一个办法,仍然可以估计出八九不离十的兔兔体重,这个办法其实也很直白,就是加权平均称称出来的结果也就是观测值和按照书本经验估算出来的结果也就是估计值分别加一个权值,再做平均

当然这两个权值加起来是等于一的。也就是说如果你有0.7分相信称出来的体重,那么就只有0.3分相信书上的估计。说到这里大家一定更着急了,究竟该有几分相信书上的,有几分相信我自己称的呢?都怪我的称不争气,没法让我百分一百信赖它,还要根据书上的数据来做调整。

权重分配的思想

好在卡尔曼先生也体会到了我们的苦恼,告诉我们一个办法来决定这个权值,这个办法其实也很直白,就是根据以往的表现来做决定,这其实听起来挺公平的,你以前表现好,我就相信你多一点,权值也就给的高一点,以前表现不好,我就相信你少一点,权值自然给的低一点。那么什么是表现好表现不好呢,表现好意思就是测量结果稳定,方差很小,表现不好就是估计值或观测值不稳定,方差很大。想象你用称称你的哦兔子,第一次1公斤第二次10公斤,第三次5公斤,你会相信你的称吗,但是如果第一次3公斤第二次3.2公斤,第三次2.8公斤,自然我就相信它多一点,给它一个大的权值了。

权重调整的过程

有了这个权值,下面的事情就很好办了。很显然卡尔曼先生是利用多次观察和估计来达到目的的,我们也只能一步一步地调整我们的观察和估计值,来渐渐达到准确的测量,所以整个算法是递归的,需要多次重复调整的。调整的过程也很简单,就是把实测值(称出来的体重)和估计值(书上得来的体重)比较一下,如果估计值比测量值小,那就把估计值加上他们之间的偏差作为新的估计值,当然前面要加个系数,就是我们前面说的加权系数,这个地方我要写个公式,因为很简单就能说明白。

比如我们的观查值是Z,估计值是X, 那么新的估计值就应该是:

Xnew  =  X  + K ( Z-X)

从这个公式可以看到,如果X估计小了,那么新的估计值会加上一个量K ( Z-X), 如果估计值大了,大过Z了,那么新的估计值就会减去一个量K ( Z-X),这就保证新的估计值一定比现在的准确,一次一次递归下去就会越来越准却了,当然这里面很有作用的也是这个K,也就是我们前面说的权值,书上都把他叫卡尔曼增益。。。

Xnew  =  X  + K ( Z-X) = X ×(1-K) + KZ

也就是说估计值X的权值是1-k,而观察值Z的权值是k,究竟k 取多大,全看估计值和观察值以前的表现,也就是他们的方差情况了)

发现把一个问题讲明白还真不是件容易的事情,谁听明白了我佩服谁,因为我已经把自己讲糊涂了哈

顺便就把extended kalman filter和particle filter提一下,因为高斯模型有时不适用,于是有了extended kalman filter,而particle filter是用于多个对象的,比如除了兔子我还有只猫,他们的体重有一个联合概率模型,每一个对象就是一个particle。无论是卡尔曼滤波还是particle滤波,都是概率分布传递的过程,卡尔曼传递的是高斯分布,particle filter 传递的是高斯混合分布,每一个峰代表一个动物在我们的例子。


原文:https://blog.csdn.net/karen99/article/details/7771743 
 

### 卡尔曼滤波简易解析 卡尔曼滤波是一种高效的递归滤波方法,旨在处理含有不确定性的动态系统状态估计问题。该技术特别适用于那些受到随机干扰影响的线性系统,在这些场景中,系统的实际行为可能偏离预期轨迹[^4]。 #### 预测阶段 在每次循环开始时,卡尔曼滤波器利用先前的时间步长所获得的信息对未来做出初步猜测。具体来说,就是基于上一步的状态向量\( \hat{x}_{k|k-1} \),以及已知的过程模型矩阵 \( F_k \) 和输入控制变量 \( u_k \),预测下一个时间点上的新状态: \[ \hat{x}_{k|k-1}=F_{k}\hat{x}_{k-1|k-1}+B_{k}u_{k} \] 同时,考虑到现实世界中的不确定性因素,还需要评估此次预估带来的潜在误差范围——即先验误差协方差矩阵 P 的更新: \[ P_{k|k-1}=FP_{k-1|k-1}F^{T}+Q \] 这里 Q 表达的是过程噪声所带来的额外波动程度。 #### 更新/校正阶段 当获取到了新的观测数据 z 后,则进入修正环节。此时引入了一个重要的参数 K —— 即所谓的“卡尔曼增益”,用于衡量我们应该相信多少来自传感器的数据而非之前的预测结果。其计算方式取决于当前状态下预测精度与测量精度之间的相对关系: \[ K_k=\frac{P_{k|k-1}H^{T}}{(HP_{k|k-1}H^{T})+R} \] 随后便能融合两者信息得出更精确的位置描述: \[ \hat{x}_k=\hat{x}_{k|k-1}+K(z-H\hat{x}_{k|k-1}) \] 与此同时还要调整相应的误差界限: \[ P_k=(I-KH)P_{k|k-1}(I-KH)^{T}+KRK^{T} \] 上述过程中 H 是将真实物理坐标映射至观察空间所需的转换函数;而 R 则反映了测量设备本身的局限性和外界干扰造成的偏差水平。 为了帮助更好地理解这一概念,不妨设想这样一个例子:假设有一个小男孩在家里面玩耍,但是他的眼睛被蒙住了看不见任何东西。尽管如此,他还是可以根据记忆尝试移动自己的身体位置。然而由于缺乏视觉反馈,这样的行动难免会出现偏差。这时如果有另一个人(比如父亲)在一旁观看并提供指导,那么即使孩子无法自行准确定位自己所在之处,借助外部提示也可以逐渐接近正确答案。这便是卡尔曼滤波工作原理的一种形象化比喻[^5]。 ```python import numpy as np def kalman_filter(x, P, measurement): """ 实现简单的卡尔曼滤波算法 参数: x (numpy.ndarray): 当前状态估计值 P (numpy.ndarray): 估计误差协方差矩阵 measurement (float or int): 新的测量值 返回: tuple: 包含两个元素的新状态估计和对应的误差协方差矩阵 """ # 测量更新(校正) z = np.array([measurement]) H = np.eye(len(x)) R = np.diag([1]) ** 2 y = z - np.dot(H,x) S = np.dot(np.dot(H,P),H.T)+R K = np.dot(P,np.dot(H.T,np.linalg.inv(S))) x = x + np.dot(K,y) I = np.eye(len(x)) P = np.dot((I-np.dot(K,H)),P) return x, P if __name__ == "__main__": measurements=[7.,6.,5.,4.,3.,2.,1.] initial_guess=0. error_variance=1e8 state_estimate=np.array([[initial_guess]]) covariance_matrix=np.array([[error_variance]]) for m in measurements: state_estimate,covariance_matrix=kalman_filter(state_estimate, covariance_matrix,m) print(f'最终状态估计:{state_estimate}') ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值