卡尔曼滤波器使用一维与二维以及代码编写

news2024/9/17 8:21:37

注:要视频学习可以去B站搜索“DR_CAN”讲解的卡尔曼滤波器,深有体会!

链接:

1、【学习心得|基于卡尔曼滤波的MPU6050姿态解算】https://www.bilibili.com/video/BV1sL411F7fu?p=2&vd_source=3d0b47bb7325b7b3a156ba92207bbd63

2、【【卡尔曼滤波器】1_递归算法_Recursive Processing】https://www.bilibili.com/video/BV1ez4y1X7eR?vd_source=3d0b47bb7325b7b3a156ba92207bbd63

一、为啥需要卡尔曼滤波器

卡尔曼滤波器在生活中应用广泛,因为在我们生活中存在着不确定性,当我去描述一个系统,这个不确定性就包涵一下三点:

 所以要解决正样的问题,卡尔曼就诞生了。

1、下面我们进入公式推导,我们测量一个物品时,会存在测量读取误差以及测量工具误差,这时候我们正常采用多次测量取平均值来得出最终结果,那么下面我们就进行公式表达

 经过上述公式转换推导,是不是就出来了一个我们卡尔曼滤波器结果公式,其表达意思如下:

(1)既当前最优结果 = 上一次最优结果 + 卡尔曼增益*(此次测量值 - 上一次最优结果)

(2)随着测量次数的增加,当前次的测量结果就不那么重要了,反之测量次数比较少,那么当前次的结果作用就比较大。

(3)从公式也可以看出来,新的这一次X^k与上一次的估计值X^k-1有关,然后上一次的估计值X^k-1与上上次的有关,这就是一种递归思想。

(4)这也就是卡尔曼滤波器的优势,它不需要追溯很久以前的数据,只需要上一次的即可。

2、卡尔曼增益k

k在这里先做简单的解释,首先引入两个参数:

估计误差与测量误差,就是它们两个与真实值得差值

那么Kk的表达式:这里不做推导,这个公式是卡尔曼滤波器的核心公式

 

那么到这里,增益已经知道,我们把第一步的公式拿下来,合并起来

 是不是就可以转换成如下:

 3、估计误差与测量误差怎么确定参数?

估计上一次的误差同时初始化是为  kfp.Last_P = 1;切记不可为0

测量误差:这个取决于传感器的精度,如果你的传感很贵精度很厉害那这个测量误差你可以取0.1等,可以实际调试看看最终结果。

4、根据上面理解与公式,我们来做一维的滤波处理

eg:

 如果用程序表达

typedef struct

{

    float Last_P;//上次估算协方差 不可以为0 ! ! ! ! !

    float estout ;//卡尔曼滤波器输出

    float Kg;//卡尔曼增益

    float R;//(测量)观测噪声协方差

}Kalman;

Kalman kfp;

void Kalman_Init(void)

{

kfp.Last_P = 5;

kfp.estout = 40;

kfp.Kg = 0;

kfp.R = 3;//这个取决于传感器的精度

}

Void KalmanPro(float kfpMeak)

{

kfp.Kg = kfp.Last_P / (kfp.Last_P + kfp.R );

kfp.estout = kfp.estout + kfp.Kg(kfpMeak - kfp.estout);

kfp.Last_P = (1- kfp.Kg)*kfp.Last_P;

}

二、知道了一维卡尔曼处理,那么二维卡尔曼如何编写呢?

其实二维跟一维的思路与方式是一样,只不过二维是计算麻烦点变成矩阵参与运算,我相信很多同学在搜素卡尔曼滤波器陀螺仪应用时会看到大部分代码,但是不是很懂,它怎么计算这么复杂,所以在这里我们开始进行推导,一步一步,相信到最后你会发现二维跟一维其实都是一样。

在这里先上卡尔曼的五个经典公式

 按着这五个公式即可完成,具体推导代价可以看文章首页的链接在B站观看。

eg:

在这里我们以求取四轴飞行器的roll和角度为例,四轴飞行棋状元MPU6050。

(1)列状态方程

N_roll_k  =  N_roll_k-1 + Vroll * dt

N_pith_k = N_pith_k-1 + Vpith * dt

那我们将其转换成矩阵形式:

转换成矩阵形式后,我们可知 矩阵A 矩阵B,所以这就是为什么大家常说做卡尔曼要先列观测方程。

那么这一步代码编写:

N_roll_k  =  N_roll_k-1 + Vroll * dt;//求得先验值

N_pith_k = N_pith_k-1 + Vpith * dt;//求得先验值

//N_roll_k-1、 N_pith_k-1 初始值为0 

 (2)预测协方差矩阵(写方差可以看文章开头的链接B站搜索)

A的矩阵我们已经知道, 那么AT这个是A矩阵的转置,转置的意思就是将矩阵的行列位置进行对换位置,比如:

 所以AT我现在也知道了,那么还剩下Q这个矩阵,那么Q表达的意思是什么呢?

Q代表的是过程噪声协方差矩阵:

这里值0.0025是调试过程自己调试合理最佳的

左上角0.0025是指roll的方差,右下角是指pith的方差,而那两个 0 0是什么意思呢?这两个0 0是代表roll 和pith他们之间没有关系他们是相互独立的,所以就要写 0  0;

回过头假设你现在滤波的两个参数是身高跟体重,那么这个矩阵就不得写0 0,因为你想你的身高越高体重是不是也越重,所以他们两之间必会有联系。

那么 PK-1这是是指上一次的误差协方差

通常初始值我们初始化都为1,不为0,因为在后续更新迭代中P会陆续收敛,所以初始化为1即可。

现在参数都知道了,那么表达式为如下

 那么我们将矩阵看着二维数组,然后通过矩阵乘法运算可得:

 那么我们将其转换为程序:

    P[0][0] = P[0][0] +  Q[0][0];
    P[0][1] = P[0][1] +  Q[0][1];
    P[1][0] = P[1][0] +  Q[1][0];
    P[1][1] = P[1][1] +  Q[1][1];

 (3)更新卡尔曼增益

H是指单位矩阵: 1    0

                             0    1  至于为什么是这个值我也解释不来,单位矩阵就是这样

R矩阵:传感器测量噪声协方差,这个值也是自己调试的,如果你的你传感器很贵很精准这个值你就写小点,反之则写大点。这里我去0.3,

Q矩阵的 0  0跟R矩阵一样,这两个0 0是代表roll 和pith他们之间没有关系他们是相互独立的,所以就要写 0  0;

计算过程:

 

 那么矩阵的倒数怎么求呢?大家可以网上查下。

最终结果:

转换为程序: 

    K[0][0] = P[0][0] / (P[0][0] + R[0][0]);
    K[0][1] = P[0][1] / (P[0][1] + R[0][1]);  

    K[1][0] = P[1][0] / (P[1][0] + R[1][0]);
    K[1][1] = P[1][1] / (P[1][1] + R[1][1]);

(4)更新最优值

 程序编写:

roll  = N_roll_k + k[0][0]*(Z测roll  - N_roll_k )

pith = N_pith_k +k[1][1]*(Z测pith  - N_pith_k )

//因为k[0][1]  k[1][0]是等于0 的,所以上面式子就没表达了

 (5)更新协方差

    P[0][0] = (1 - k[0][0] )P[0][0] ;
    P[0][1] = 0;
    P[1][0] = 0;
    P[1][1] = (1 - k[1][1] )P[1][1] ;

  程序最终结果表达:     

  //初始化
   N_roll_k-1 = 0;
   N_pith_k-1 = 0;
   P[2][2] = {1,0,0,1};
   Q[2][2] = {0.0025,0,0,0.0025};
   R[2][2] = {0.3,0,0,0.3};
Void KalmanPro(float Z测roll,float Z测pith)
{
   N_roll_k = N_roll_k-1 + Vroll * dt;//求得先验值
   N_pith_k = N_pith_k-1 + Vpith * dt;//求得先验值
   P[0][0] = P[0][0] +  Q[0][0];
   P[0][1] = P[0][1] +  Q[0][1];//实际计算结果P[0][1] =  0;
   P[1][0] = P[1][0] +  Q[1][0];//实际计算结果P[0][1] =  0;
   P[1][1] = P[1][1] +  Q[1][1];
   K[0][0] = P[0][0] / (P[0][0] + R[0][0]);
   K[0][1] = P[0][1] / (P[0][1] + R[0][1]);//实际计算结果K[0][1] =  0; 
   K[1][0] = P[1][0] / (P[1][0] + R[1][0]);//实际计算结果K[0][1] =  0;
   K[1][1] = P[1][1] / (P[1][1] + R[1][1]);
   roll  = N_roll_k + k[0][0]*(Z测roll  - N_roll_k );
   pith = N_pith_k +k[1][1]*(Z测pith  - N_pith_k );
   N_roll_k-1 = roll;
   N_pith_k-1 = pith;
   P[0][0] = (1 - k[0][0] )P[0][0] ;
   P[0][1] = 0;
   P[1][0] = 0;
   P[1][1] = (1 - k[1][1] )P[1][1] ;
}

大家可以对比下,很直观可以发现,其实二维与一维在于两个参数有么有关系,如果没有关系相对独立,那么最终简化跟一维是一样的,所以最主要要确定好一开的观测方程。

到此卡尔曼结束。

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

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

相关文章

【人工智能】— 神经网络、M-P 神经元模型、激活函数、神经网络结构、学习网络参数、代价定义、总代价

【人工智能】— 神经网络 神经网络的历史Neural Network IntroM-P 神经元模型激活函数(Activation function)神经网络结构举例训练神经网络学习网络参数代价定义均方误差交叉熵(Cross Entropy) 总代价 神经网络的历史 第一阶段 ⚫ 1943年, McCulloch和Pi…

AES入门 万字详解(附推荐论文和研究领域)

目录 前言 加密过程 SubBytes(字节替换) ShiftRows(行移位) MixColumns(列混淆) AddRoundKey(轮密钥加) 轮密钥生成过程 概述 具体步骤 代码实现方式 Java Java Cryptog…

Build your own unconditional confidence

不要活在既定的社会价值体系中 人类的偏好大多数时候都是愚昧的 I play whatever gods give me 情绪价值稳定 解决问题的能力 Dont label yourself 真正的强者不会吝啬对他人的赞美 敬畏自然,敬畏未知事物 核心是你对这个事情是否感兴趣,觉得有价…

Java-三种基本控制结构及相关面试题

文章目录 前言一、 顺序控制结构1.1 概念1.2 代码1.3 NS图中体现 二、分支控制结构2.1 概念2.2 if语句2.3 switch语句2.4 NS图中的体现 三、循环控制结构3.1 概念3.2 for循环3.3 while循环3.4 do-while循环3.5 增强 for 循环NS图中的体现 四、相关面试题什么是控制流语句&#…

springboot解析@transaction注解原理

目录 第一步、全局搜索Transactional.class 第二步、查看哪里配置BeanFactoryTransactionAttributeSourceAdvisor 第四、SpringTransactionAnnotationParser是什么时候被注入的 第三、总结 先看一下transaction的官网文档 16. Transaction Management 第一步、全局搜索Tr…

Ansible-playbook-roles安装lnmp

使用roles安装lnmp 1、准备四台主机 192.168.142.10 192.168.142.20 192.168.142.30 192.168.142.40 2、10作为ansible管理端 首先ssh连接剩下三台主机 3、vim/etc/ansible/hosts 添加[nginxservers]配置nginx ip,[phpservers]php ip,[mysqlservers]mysql ip 4、cd /etc/ansibl…

ubuntu 20.04 qemu arm64 linux6.3.8 开发环境搭建

开发环境 ubuntu 20.04 VMware Workstation Pro 16 基于qemu(模拟器),ARM64 :virt cortex-a57 平台 搭建Linux 6.3.8 (当前最新版本) 准备 Linux 内核下载,下载最新稳定版本,当前为 linux-…

基于ipv6实现几乎零成本的内网穿透方案,小白的踩坑历程与经验分享

基于ipv6实现几乎零成本的内网穿透方案,小白的踩坑历程与经验分享 前言 最近想远程访问家里nas的想法老在脑海中浮现,原因大概是本人二开了一个管理系统,并在上面跑了些定时任务做自动化,就有了远程访问系统的需求。同时又想到&…

Python潮流周刊#7:我讨厌用 asyncio

△点击上方“Python猫”关注 ,回复“1”领取电子书 你好,我是猫哥。这里记录每周值得分享的 Python 及通用技术内容,部分为英文,已在小标题注明。(标题取自其中一则分享,不代表全部内容都是该主题&#xff…

MySQL 数据库初体验

文章目录 数据库的基本概念数据表数据库数据库管理系统数据库系统 数据库的发展史当今主流数据库介绍SQL Server (微软公司产品)Oracle (甲骨文公司产品)DB2 (IBM公司产品)MySQL (甲骨文公司收购…

S7-200 PLC通信方式有哪些

更多关于西门子S7-200PLC内容请查看:西门子200系列PLC学习课程大纲(课程筹备中) S7-200 PLC通信按通信对象方式分为三种情况:A.与计算机通信;B.与其他PLC通信;C.与其他设备和仪器通信; A.S7-200 PLC与计算机通信 如下图1-1 S7-…

长度延展攻击【密码学】(三)

一、什么是长度延展 假设有两段数据,S和M,以及一个单向散列函数h。 如果我们要将两段数据合并起来,并且还要计算合并后的散列值,这就叫做单向散列函数的长度延展。 二、长度延展攻击 如果S和M都是公开信息,那么S在前还…

网络层:网际控制报文协议ICMP

网络层:网际控制报文协议ICMP 笔记来源: 湖科大教书匠:网际控制报文协议ICMP 声明:该学习笔记来自湖科大教书匠,笔记仅做学习参考 主机或路由器使用ICMP来发送差错报告报文和询问报文 ICMP报文被封装在IP数据报中发送…

合宙Air724UG Cat.1模块硬件设计指南--I2C接口

I2C接口 简介 I2C总线(Inter-Integrated Circuit)是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。 特性 支持 Fast mode (400Kbps)和 Slow mode&…

探索人工智能在自动化测试中的应用

自动化测试技术从最初的模拟硬件方式,到基于数据驱动,基于关键字驱动,再到现在基于功能和指令驱动的自动化测试技术,在各类软件项目中的应用也越来越多,越来越成熟。自动 背景 自动化测试技术从最初的模拟硬件方式&a…

MATLAB | 如何使用MATLAB获取顶刊《Nature》全部绘图(附带近3年全部图像)

我出了如何使用MATLAB获取期刊《Cell》全部绘图,立马就有粉丝问《Nature》、《Sience》、《PNAS》啥的会不会安排,这期就给大家安排《Nature》全部绘图获取,之后其他期刊也会慢慢安排,但是不会一次性全出完(毕竟不能抓住一个主题就…

【第三次】21级计科计算机组成原理课外练习

【第三次】21级计科计算机组成原理课外练习 一、单选题二、填空题三、程序填空题 一、单选题 2-1假设变量x的位数为n(n>8),x的最低有效字节不变,其余各位全变为0,则对应C语言表达式为。 A.x | ~ 0xFF B.x ^ 0xFF C…

css基础四:说说设备像素、css像素、设备独立像素、dpr、ppi 之间的区别?

一、背景 在css中我们通常使用px作为单位,在PC浏览器中css的1个像素都是对应着电脑屏幕的1个物理像素 这会造成一种错觉,我们会认为css中的像素就是设备的物理像素 但实际情况却并非如此,css中的像素只是一个抽象的单位,在不同…

循环码生成矩阵与监督 (校验) 矩阵

本专栏包含信息论与编码的核心知识,按知识点组织,可作为教学或学习的参考。markdown版本已归档至【Github仓库:https://github.com/timerring/information-theory 】或者公众号【AIShareLab】回复 信息论 获取。 文章目录 循环码生成多项式与…

详解七层反向代理与四层反向代理【Nginx+Tomcat负载均衡、动静分离】

文章目录 1. 反向代理和正向代理概述2.七层反向代理实例2.1 实验环境描述2.2 部署Nginx负载均衡器2.3 部署2台Tomcat应用服务器2.3.1 部署CentOS 7-5 Tomcat服务器2.3.2 部署CentOS 7-6 Tomcat多实例服务器 3.四层反向代理实例3.1 实验环境描述3.2 部署Nginx负载均衡器&#xf…