图解卡尔曼滤波(Kalman Filter)

news2024/11/24 8:39:26

背景

关于滤波

首先援引来自知乎大神的解释。

一位专业课的教授给我们上课的时候,曾谈到:filtering is weighting(滤波即加权)。滤波的作用就是给不同的信号分量不同的权重。最简单的loss pass filter, 就是直接把低频的信号给1权重,而给高频部分0权重。对于更复杂的滤波,比如维纳滤波, 则要根据信号的统计知识来设计权重。

从统计信号处理的角度,降噪可以看成滤波的一种。降噪的目的在于突出信号本身而抑制噪声影响。从这个角度,降噪就是给信号一个高的权重而给噪声一个低的权重。维纳滤波就是一个典型的降噪滤波器。

关于卡尔曼滤波

Kalman Filter 算法,是一种递推预测滤波算法,算法中涉及到滤波,也涉及到对下一时刻数据的预测。Kalman Filter 由一系列递归数学公式描述。它提供了一种高效可计算的方法来估计过程的状态,并使估计均方误差最小。卡尔曼滤波器应用广泛且功能强大:它可以估计信号的过去和当前状态,甚至能估计将来的状态,即使并不知道模型的确切性质。

Kalman Filter 也可以被认为是一种数据融合算法(Data fusion algorithm),已有50多年的历史,是当今使用最重要和最常见的数据融合算法之一。Kalman Filter 的巨大成功归功于其小的计算需求,优雅的递归属性以及作为具有高斯误差统计的一维线性系统的最优估计器的状态。

Kalman Filter 只能减小均值为0的测量噪声带来的影响。只要噪声期望为0,那么不管方差多大,只要迭代次数足够多,那效果都很好。反之,噪声期望不为0,那么估计值就还是与实际值有偏差[3]。

问题描述

上面的描述可能把大家绕晕了,下面来点轻松的。

我们会有一个疑问:卡尔曼滤波到底是如何解决实际问题的呢?

我们以机器人为例介绍卡尔曼滤波的原理,我们的任务是要预测机器人的状态,包括位置与速度,即可表示为:

某个时刻,我们不知道真实的位置与速度到底是多少,二者存在一个所有可能性的组合,大致如下图所示。

卡尔曼滤波假设状态所有的变量都是随机的且都服从高斯分布,每个变量都有其对应的均值以及方差(它代表了不确定性)。

在上图中,位置和速度是不相关(uncorrelated)的,这意味着某个变量的状态不会告诉你其他变量的状态是怎样的。即,我们虽然知道现在的速度,但无法从现在的速度推测出现在的位置。但实际上并非如此,我们知道速度和位置是有关系的(correlated),这样一来二者之间的组合关系变成了如下图所示的情况。

这种情况是很容易发生的,例如,如果速度很快,我们可能会走得更远,所以我们的位置会更大。如果我们走得很慢,我们就不会走得太远。

这种状态变量之间的关系很重要,因为它可以为我们提供更多信息:One measurement tells us something about what the others could be。这就是卡尔曼滤波器的目标,我们希望从不确定的测量中尽可能多地获取信息!

这种状态量的相关性可以由协方差矩阵表示。简而言之,矩阵的每个元素是第i个状态变量和第j个状态变量之间的相关度。(显然地可以知道协方差矩阵是对称的,这意味着交换i和j都没关系)。协方差矩阵通常标记为“ ”,因此我们将它们的元素称为“”。

状态预测

问题的矩阵形式表示

我们把状态建模成高斯分布(Gaussian blob,由于二维高斯分布长得像一个个小泡泡,之所以长这个样子,可参考链接[2])。我们需要求解/估计在时间时刻的两个信息:1. 最优估计以及它的协方差矩阵,我们可以写成下面矩阵形式:

(当然,这里我们仅使用位置和速度,但是请记住状态可以包含任意数量的变量,并且可以表示所需的任何变量)

接下来,我们需要某种方式来查看当前状态(时刻)并预测在时刻处的状态。请记住,我们不知道哪个状态是“真实”状态,但是这里提到的预测(prediction)并不在乎这些。

我们可以用一个矩阵来表示这个预测过程:

这个矩阵将原始估计中的每个点移动到新的预测位置。

那么问题来了,应该如何使用上述矩阵来预测下一时刻的位置和速度呢?为了阐述这个过程,我们使用了一个非常基础的运动学公式(初中物理中就学过)进行描述:

写成矩阵形式:

现在我们有了一个预测矩阵或者叫做状态转移矩阵,该矩阵可以帮助我们计算下一个时刻的状态。但我们仍然不知道如何更新状态的协方差矩阵,其实过程也是很简单,如果我们将分布中的每个点乘以矩阵,那么其协方差矩阵会发生什么?

将公式(3)代入公式(4)我们可以得到:

External influence

不过我们并没有考虑到所有的影响因素。可能有一些与状态本身无关的变化——如外界因素可能正在影响系统。

例如,我们用状态对列车的运动进行建模,如果列车长加大油门,火车就加速。同样,在我们的机器人示例中,导航系统软件可能会发出使车轮转动或停止的命令。如果我们很明确地知道这些因素,我们可以将其放在一起构成一个向量,我们可以对这个量进行某些“处理”,然后将其添加到我们的预测中对状态进行更正。

假设我们知道由于油门设置或控制命令而产生的预期加速度。根据基本运动学原理,我们可以得到下式:

将其写成矩阵形式:

其中被称为控制矩阵,被称为控制向量。(注意:对于没有外部影响的简单系统,可以忽略这个控制项)。

如果我们的预测并不是100%准确模型,这会发生什么呢?

External uncertainty

如果状态仅仅依赖其自身的属性进行演进,那一切都会很好。如果状态受到外部因素进行演进,我们只要知道这些外部因素是什么,那么一切仍然很好。

但在实际使用中,我们有时不知道的这些外部因素到底是如何被建模的。例如,我们要跟踪四轴飞行器,它可能会随风摇晃;如果我们跟踪的是轮式机器人,则车轮可能会打滑,或者因地面颠簸导致其减速。我们无法跟踪这些外部因素,如果发生任何这些情况,我们的预测可能会出错,因为我们并没有考虑这些因素。

通过在每个预测步骤之后添加一些新的不确定性,我们可以对与“世界”相关的不确定性进行建模(如我们无法跟踪的事物):

这样一来,由于新增的不确定性原始估计中的每个状态都可能迁移到多个状态。因为我们非常喜欢用高斯分布进行建模,此处也不例外。我们可以说的每个点都移动到具有协方差的高斯分布内的某个位置,如下图所示:

这将产生一个新的高斯分布,其协方差不同(但均值相同):

所以呢,我们在状态量的协方差中增加额外的协方差,所以预测阶段完整的状态转移方程为:

换句话说:新的最佳估计是根据先前的最佳估计做出的预测,再加上对已知外部影响的校正。

新的不确定度是根据先前的不确定度做出的预测,再加上来自环境额外的不确定度

上述过程描绘了状态预测过程,那么当我们从传感器中获取一些测量数据时会发生什么呢?

状态更新

利用测量进一步修正状态

假设我们有几个传感器,这些传感器可以向我们提供有关系统状态的信息。就目前而言,测量什么量都无关紧要,也许一个读取位置,另一个读取速度。每个传感器都告诉我们有关状态的一些间接信息(换句话说,传感器在状态下运作并产生一组测量读数)。

请注意,测量的单位可能与状态量的单位不同。我们使用矩阵对传感器的测量进行建模。

所以我们期望传感器的度数可以被建模成如下形式:

卡尔曼滤波器的伟大之处就在于它能够处理传感器噪声。换句话说,传感器本身的测量是不准确的,且原始估计中的每个状态都可能导致一定范围的传感器读数,而卡尔曼滤波能够在这些不确定性存在的情况下找到最优的状态。

根据传感器的读数,我们会猜测系统正处于某个特定状态。但是由于不确定性的存在,某些状态比其他状态更可能产生我们看到的读数

我们将这种不确定性(如传感器噪声)的协方差表示为,读数的分布均值等于我们观察到传感器的读数,我们将其表示为

这样一来,我们有了两个高斯分布:一个围绕通过状态转移预测的平均值,另一个围绕实际传感器读数

因此,我们需要将基于预测状态(粉红色)的推测读数与基于实际观察到的传感器读数(绿色)进行融合。

那么融合后最有可能的新状态是什么?对于任何可能的读数,我们都有两个相关的概率:(1)我们的传感器读数是的测量值的概率,以及(2)先前估计值的概率认为是我们应该看到的读数。

如果我们有两个概率,并且想知道两个概率都为真的机会,则将它们相乘。因此,我们对两个高斯分布进行了相乘处理:

两个概率分布相乘得到的就是上图中的重叠部分。而且重叠部分的概率分布会比我们之前的任何一个估计值/读数都精确得多,这个分布的均值就是两种估计最有可能配置(得到的状态)。

事实证明,两个独立的高斯分布相乘之后会得到一个新的具有其均值和协方差矩阵的高斯分布!下面开始推公式。

合并两个高斯分布

首先考虑一维高斯情况:一个均值为,方差为的高斯分布的形式为:

我们想知道将两个高斯曲线相乘会发生什么。下图中的蓝色曲线表示两个高斯总体的(未归一化)交集:

将公式(9)代入公式(10),我们可以得到新的高斯分布的均值和方差如下所示:

我们将其中的一小部分重写为:

这样一来,公式的形式就简单多了!我们顺势将公式(12)和(13)的矩阵形式写在下面:

其中表示新高斯分布的协方差矩阵,是每个维度的均值,就是大名鼎鼎的“卡尔曼增益”(Kalman gain)。

公式汇总

我们有两个高斯分布,一个是我们预测的观测,我们将这两个高斯分布带入公式(15)中就可以得到二者的重叠区域:

从公式(14)我们可以知道,卡尔曼增益是:

然后我们将公式(16)与公式(17)中的去除,同时将后面的去除,我们可以得到最终的化简形式的更新方程:

图说

大功告成,就是更新后的最优状态!接下来我们可以继续进行预测,然后更新,重复上述过程!下图给出卡尔曼滤波信息流。

总结

在上述所有数学公式中,你需要实现的只是公式(7)(18)和(19)。(或者,如果你忘记了这些,可以从等式(4)和(15)重新推导所有内容。)

这将使你能够准确地对任何线性系统建模。对于非线性系统,我们使用扩展卡尔曼滤波器,该滤波器通过简单地线性化预测和测量值的均值进行工作。

参考资料

[1]: How a Kalman filter works, in pictures, 图解卡尔曼滤波是如何工作的:

http://www.bzarg.com/p/how-a-kalman-filter-works-in-pictures/#mathybits

[2]: A geometric interpretation of the covariance matrix, 协方差矩阵的几何解释:

https://www.visiondummy.com/2014/04/geometric-interpretation-covariance-matrix

[3]: Kalman Filter 卡尔曼滤波:

https://sikasjc.github.io/2018/05/08/kalman_filter

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/157595.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux操作系统】1. Linux操作系统简介、安装

前言 本系列是Linux操作系统的一些知识以及实践内容,Linux操作系统作为开发最常使用的操作系统,是必备的一门求职、提升技术。本文先介绍Linux操作系统,并安装一个Linux操作系统。 Linux操作系统简介 Linux,全称GNU/Linux&#…

Javadoc

Javadoc 在学习JavaSE时,我们知道Java支持三种注释方式: 单行注释多行注释文档注释 Javadoc是文档注释,用来对类或方法进行标准的注释,在开发中写好JavaDoc非常重要。 在调用方法时,你可能会看到这样的情景 这种注…

Unity - 搬砖日志 - 如何设置AssetDatabase.Create(“xxx.asset“, mesh) 的Read/Write=false

最近很忙,想写的 BLOG 都遗漏编写了 踩坑的时间比较多,充电的时间少了很多 为了减少以后自己填坑时间,随便简单的记录一下 搬砖日志 环境 unity : 2020.3.37f1 pipeline : brp 问题 因为之前搜索、购买、使用了各式各样的 LOD 插件、工具…

机器学习100天(三十一):031 K近邻回归算法

机器学习100天,今天讲的是:K 近邻回归算法! 《机器学习100天》完整目录:目录 一、理论介绍 我们之前讲了 K 近邻分类算法,用来处理分类问题。其实 K 近邻也可以用来处理回归问题。 如左图所示,K 近邻分类算法的思路是选取与测试样本距离最近的前 k 个训练样本。然后对…

回收租赁商城系统功能拆解07讲-订单列表

回收租赁系统适用于物品回收、物品租赁、二手买卖交易等三大场景。 可以快速帮助企业搭建类似闲鱼回收/爱回收/爱租机/人人租等回收租赁商城。 回收租赁系统支持智能评估回收价格,后台调整最终回收价,用户同意回收后系统即刻放款,用户微信零…

寒假题练——day(3)

题目1: 给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 进阶:尝试设计时间复杂度为 O(n)、空间复杂度为…

58、正则表达式

目录 一、快速入门 二、正则表达式基本语法 1、基本介绍: 2、正则表达式底层实现 3、元字符(Metacharacter)- 转义号\\ (1)限定符 (2)选择匹配符 (5)字符匹配符…

FX5U DRVMUL指令多个轴的表格运行

1.简述该指令可以用GX Works3预先在表格数据中设定的控制方式的动作,执行多个轴的表格。 2.指令解释同时执行多个轴的表格。指令执行开始后,各轴独立进行动作,也可连续运行。但是,只可在同一模块内同时执行2.1 操作数n1在(n1)中指…

.NETCore 多线程学习笔记(多线程、线程结束顺序掌控、线程相对平均分配)

参考资料&#xff1a;多线程MutiThread最佳实践专题-1-1_哔哩哔哩_bilibili 跟着视频学习的&#xff0c;下面是自己的注释笔记和实验结果 写了个窗体来学习线程的 多线程、线程掌控、线程分配 下面会用到这个方法 /// <summary> /// 仅仅只是一个耗时方法 …

STM32RTC外设详解

目录一.RTC 实时时钟简介1.RTC时钟来源2.RTC主要特性二.RTC 外设功能框图1.RTC功能框图剖析2.使能对后备寄存器和RTC的访问3.复位过程4.读RTC寄存器5.配置RTC寄存器三.实现一个简易时钟1.实验目的2.实验原理3.实验源码4.效果演示一.RTC 实时时钟简介 实时时钟是一个独立的定时…

链表题目总结 -- 双指针技巧

文章目录一. 合并两个有序链表1. 思路简述2. 代码3. 总结二. 分隔链表1. 思路简述2. 代码3. 总结三. 合并K个升序链表1. 思路简述2. 代码3. 总结四. 单链表的倒数第 k 个节点1. 思路简述2. 代码3. 总结五. 链表的中间结点1. 思路简述2. 代码3. 总结六. 环形链表&#xff08;链表…

docker一个容器内部署多个服务

原因是&#xff0c;我有一个springBoot服务需要写入httpd的目录&#xff0c;然后httpd提供链接给别人下载。之前的方法是&#xff0c;httpd和springBoot各一个容器&#xff0c;但是我们将镜像是部署在腾讯云上的&#xff0c;腾讯云会自动对每个容器分离不同的虚拟机&#xff0c…

pytorch简单自定义Datasets

前言 本文记录一下如何简单自定义pytorch中Datasets&#xff0c;官方教程文件层级目录如下&#xff1a; images 1.jpg2.jpg…9.jpg annotations_file.csv 数据说明 image文件夹中有需要训练的图片&#xff0c;annotations_file.csv中有2列&#xff0c;分别为image_id和labe…

Python的23种设计模式(完整版带源码实例)

作者&#xff1a;虚坏叔叔 博客&#xff1a;https://xuhss.com 早餐店不会开到晚上&#xff0c;想吃的人早就来了&#xff01;&#x1f604; Python的23种设计模式 一 什么是设计模式 设计模式是面对各种问题进行提炼和抽象而形成的解决方案。这些设计方案是前人不断试验&…

【入门篇】1 # 复杂度分析(上):如何分析、统计算法的执行效率和资源消耗?

说明 【数据结构与算法之美】专栏学习笔记。 什么是复杂度&#xff1f; 复杂度也叫渐进复杂度&#xff0c;包括时间复杂度和空间复杂度&#xff0c;用来分析算法执行效率与数据规模之间的增长关系&#xff0c;可以粗略地表示&#xff0c;越高阶复杂度的算法&#xff0c;执行…

时域脉冲通信采用高斯脉冲且使用PAM调制的Matlab简易演示仿真

时域脉冲通信采用高斯脉冲且使用PAM调制的Matlab简易演示仿真 环境 matlab 2016a 指标 1 将声音信号转为二进制码 2 PAM调制 3 采用高斯脉冲 流程 代码 [OriginVoice,fs]audioread(voice.m4a) ; OriginVoiceOriginVoice(:,2); Nlength(OriginVoice); % 计算信号x的长度 …

算法训练营 day15 二叉树 层序遍历 翻转二叉树 对称二叉树

算法训练营 day15 二叉树 层序遍历 翻转二叉树 对称二叉树 层序遍历 102. 二叉树的层序遍历 - 力扣&#xff08;LeetCode&#xff09; 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。…

标签设计打印软件:LabelJoy 6.23.0 Crack

LabelJoy 专业条码软件 生成25种条形码 从数据源导入条码 计算自动校验 商业条形码标签软件 兼容 Excel、Access、MySQL、Oracle 11.000 个预装的纸张布局 支持任何打印机 通过 3 个步骤创建和打印标签&#xff1a; 选择布局 创建您的标签 开始打印 最好的标签打印软件&#xf…

kafka-1

文章目录1.启动2.创建主题3.发送消息4.消费消息5.使用kafka connect将现有的数据导入到kafka中6.使用kafka streams处理kafka中的events6.终止服务集群配置要点创建主题要点主题分区变更主题副本可变更吗&#xff1f;创建生产者要点> tar -xzf kafka_2.12-3.3.1.tgz1.启动 …

Mac生成和查看ssh key

从 git 上拉取或者提交代码每次都需要输入账号密码&#xff0c;这样很麻烦。我们可以在电脑上生成一个 ssh key&#xff0c;然后把ssh key添加到 git 中&#xff0c;就可以不用每次去输账号密码了。下面就介绍一下怎么在自己的 Mac 中生成和查看 ssh key。一、Mac生成SSH Key打…