卡尔曼滤波算法(C语言)

此处感谢华南虎和互联网的众多大佬的无偿分享。

入门常识

先简单了解以下概念:叠加性,齐次性。

用大白话讲,叠加性:多个输入对输出有影响。齐次性:输入放大多少倍,输出也跟着放大多少倍

卡尔曼滤波符合这两个特性。

卡尔曼滤波 :修正值 = 估计值 + 观测值。符合叠加性和齐次性。

协方差的基础知识

把Xt代入,然后将式子进行化简。

公式推导

基础公式理解

对于卡尔曼滤波,我们可以先从状态方程和观测方程开始理解,重点搞懂重点是状态方程和观测方程的实际含义。
 

状态方程公式的参数解析。Xk:当前状态值,Uk:输入值, Wk:过程噪声。A,B为系数。

观测方程公式的参数解析。Yk:观测值。Xk:当前状态值。Vk:观测噪声

简单理解:Vk是不可避免的仪器系统误差,Wk是由外界因素引起的误差。

Q:过程噪声的方差。R:观测噪声的方差。

最优估计值,先验估计值,(观测值)后验估计值。

卡尔曼滤波其实就是取估计值和测量值之间重合的部分。两个概率之间重合的部分。

卡尔曼的实现过程

使用上一次的最优结果预测当前值,同时使用观测值修正之前预测的当前值,得到最终结果(修正后的结果叫做最优估计)。

不需要严格推导,了解是什么意思,怎么用即可。

状态更新方程

卡尔曼增益化简后

过程噪声少,Q可以取小一点。反之,过程噪声大,Q取大一点。

传感器误差小,R可以取小一点。反之,传感器误差大,R取大一点。

执行流程

卡尔曼滤波算法介绍

基本思想:通过不精确的测量来估测真实值。测出来的是不精确的测量值,再利用数学模型和不精确的测量来估测真实值。

一句话概括:根据系统模型和现有状态预测下一刻的状态,然后根据实际的测量结果进行校正。

使用场景:卡尔曼主要用来多传感器的数据融合,单一传感器建议用其他滤波算法。

如何使用?

以下面的代码为例:先定义好卡尔曼滤波结构体,并为其赋值。之后把结构体参数传入,把要过滤的数据传入。卡尔曼滤波算法就会把过滤好的数据,放在其结构体的输出成员中存储好。我们再用变量把卡尔曼滤波结构体中的输出成员的值接收到就行了。

代码

kalman.c

/*** 一维卡尔曼滤波器实现* @param ekf 卡尔曼滤波器结构体指针,包含滤波所需参数* @param input 当前时刻的测量值* * 算法流程说明:* 1. 预测阶段:根据上一时刻的状态估计当前状态* 2. 计算卡尔曼增益:确定测量值和预测值的权重* 3. 更新估计:结合预测值和测量值得到最优估计* 4. 更新协方差:为下一时刻的预测做准备*/
void kalman_1(struct _1_ekf_filter *ekf, float input)
{// 1. 预测协方差矩阵(时间更新)// Now_P = LastP + Q// 预测误差 = 上一时刻误差 + 过程噪声// Q值越大,表明系统模型越不可靠,滤波器对新测量值更敏感ekf->Now_P = ekf->LastP + ekf->Q;// 2. 计算卡尔曼增益// Kg = Now_P / (Now_P + R)// 卡尔曼增益权衡预测值和测量值的权重// R值越大(测量噪声大),增益越小,更信任预测值ekf->Kg = ekf->Now_P / (ekf->Now_P + ekf->R);// 3. 状态更新方程(测量更新)// out = out + Kg * (input - out)// 本质是预测值与测量值的加权融合// 当Kg=1时完全信任测量值,当Kg=0时完全信任预测值ekf->out = ekf->out + ekf->Kg * (input - ekf->out);// 4. 更新误差协方差矩阵// LastP = (1-Kg) * Now_P// 更新当前估计误差,用于下一时刻的预测// 随着迭代进行,P值会收敛到稳态ekf->LastP = (1 - ekf->Kg) * ekf->Now_P;
}

kalman.h

#ifndef _KALMAN_H    // 防止头文件被重复包含
#define _KALMAN_H// 定义一维扩展卡尔曼滤波器结构体
struct _1_ekf_filter
{float LastP;    // 上一时刻的协方差(预测误差)float Now_P;    // 当前时刻的协方差(估计误差)float out;      // 滤波器输出值(最优估计值)float Kg;       // 卡尔曼增益,权衡预测值和测量值的权重float Q;        // 过程噪声协方差,反映系统模型的不确定性float R;        // 测量噪声协方差,反映测量设备的不确定性
};// 一维卡尔曼滤波器函数
// 参数:ekf-卡尔曼滤波器结构体指针,input-当前时刻的测量值
extern void kalman_1(struct _1_ekf_filter *ekf, float input);#endif // _KALMAN_H

调用示例

最后我们要使用的数据在结构体的.out中

for (i = 0; i < 6; i++) // 处理读取的数据{pMpu[i] = (((int16_t)buffer[i << 1] << 8) | buffer[(i << 1) + 1]) - MpuOffset[i]; // 整合为16bit,并减去水平静止校准值if (i < 3)																		  // 以下对加速度做卡尔曼滤波{{static struct _1_ekf_filter ekf[3] = {{0.02, 0, 0, 0, 0.001, 0.543}, {0.02, 0, 0, 0, 0.001, 0.543}, {0.02, 0, 0, 0, 0.001, 0.543}};kalman_1(&ekf[i], (float)pMpu[i]); // 一维卡尔曼pMpu[i] = (int16_t)ekf[i].out;}}// 如果是陀螺仪数据,进行低通滤波if (i > 2) // 以下对角速度做一阶低通滤波{uint8_t k = i - 3;const float factor = 0.15f; // 滤波系数static float tBuff[3];		// 滤波缓冲区pMpu[i] = tBuff[k] = tBuff[k] * (1 - factor) + pMpu[i] * factor;}}

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

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

相关文章

SolidWork-2023 鼠標工程

地址 https://github.com/MartinxMax/SW2023-Project/tree/main/mouse 鼠標

vue 组件函数式调用实战:以身份验证弹窗为例

通常我们在 Vue 中使用组件&#xff0c;是像这样在模板中写标签&#xff1a; <MyComponent :prop"value" event"handleEvent" />而函数式调用&#xff0c;则是让我们像调用一个普通 JavaScript 函数一样来使用这个组件&#xff0c;例如&#xff1a;…

Vite Proxy配置详解:从入门到实战应用

Vite Proxy配置详解&#xff1a;从入门到实战应用 一、什么是Proxy代理&#xff1f; Proxy&#xff08;代理&#xff09;是开发中常用的解决跨域问题的方案。Vite内置了基于http-proxy的代理功能&#xff0c;可以轻松配置API请求转发。 二、基础配置 在vite.config.js中配置…

图像画质算法记录(前言)

一、背景介绍 本篇主要是对图像画质增强相关&#xff0c;进行简单整理和记录。 二、整体流程 整体效果主要受到两部分影响&#xff1a; 1、前端isp处理。 2、后端画质增强。 三、isp常规流程 可以参考&#xff1a;刘斯宁&#xff1a;Understanding ISP Pipeline 四、后端画质…

Qt 中信号与槽(signal-slot)机制支持 多种连接方式(ConnectionType)

Qt 中信号与槽&#xff08;signal-slot&#xff09;机制支持 多种连接方式&#xff08;ConnectionType&#xff09; Qt 中信号与槽&#xff08;signal-slot&#xff09;机制支持 多种连接方式&#xff08;ConnectionType&#xff09;&#xff0c;用于控制信号发出后如何调用槽…

卷积神经网络实战(4)代码详解

目录 一、导包 二、数据准备 1.数据集 2. 标准化转换(Normalize) 3.设置dataloader 三、定义模型 四、可视化计算图&#xff08;不重要&#xff09; 五、评估函数 六、Tensorboard 一、导包 import matplotlib as mpl import matplotlib.pyplot as plt %matplotlib i…

深入解析进程地址空间:从虚拟到物理的奇妙之旅

深入解析进程地址空间&#xff1a;从虚拟到物理的奇妙之旅 前言 各位小伙伴&#xff0c;还记得我们之前探讨的 fork 函数吗&#xff1f;当它返回两次时&#xff0c;父子进程中同名变量却拥有不同值的现象&#xff0c;曾让我们惊叹于进程独立性与写时拷贝的精妙设计。但你是否…

opencv处理图像(二)

接下来进入到程序线程设计部分 我们主线程负责图形渲染等操作&#xff0c;OpenGL的限制&#xff0c;opencv技术对传入图像加以处理&#xff0c;输出预期图像给主线程 QThread 我之前也是在想给opencv开一个专门的线程&#xff0c;但经过了解有几个弊端&#xff0c;第一资源浪…

学习threejs,使用Physijs物理引擎

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️Physijs 物理引擎1.1.1 ☘️…

ARCGIS PRO DSK 选择坐标系控件(CoordinateSystemsControl )的调用

在WPF窗体上使用 xml&#xff1a;加入空间命名引用 xmlns:mapping"clr-namespace:ArcGIS.Desktop.Mapping.Controls;assemblyArcGIS.Desktop.Mapping" 在控件区域加入&#xff1a; <mapping:CoordinateSystemsControl x:Name"CoordinateSystemsControl&q…

LangGraph(三)——添加记忆

目录 1. 创建MemorySaver检查指针2. 构建并编译Graph3. 与聊天机器人互动4. 问一个后续问题5. 检查State参考 1. 创建MemorySaver检查指针 创建MemorySaver检查指针&#xff1a; from langgraph.checkpoint.memory import MemorySavermemory MemorySaver()这是位于内存中的检…

深入理解Mysql

BufferPool和Changebuffer是如何加快读写速度的? BufferPool 在Mysql启动的时候 Mysql会申请连续的空间来存储BufferPool 每个页16kb 当控制块不足以存储信息的时候就会向后申请一个新的页 每个控制块都对应了一个缓存页 控制块占chunk的百分之5左右 LRU链表 Changebuffer …

Python核心编程深度解析:作用域、递归与匿名函数的工程实践

引言 Python作为现代编程语言的代表&#xff0c;其作用域管理、递归算法和匿名函数机制是构建高质量代码的核心要素。本文基于Python 3.11环境&#xff0c;结合工业级开发实践&#xff0c;深入探讨变量作用域的内在逻辑、递归算法的优化策略以及匿名函数的高效应用&#xff0c…

《用MATLAB玩转游戏开发》贪吃蛇的百变玩法:从命令行到AI对战

《用MATLAB玩转游戏开发&#xff1a;从零开始打造你的数字乐园》基础篇&#xff08;2D图形交互&#xff09;-&#x1f40d; 贪吃蛇的百变玩法&#xff1a;从命令行到AI对战 &#x1f3ae; 欢迎来到这篇MATLAB贪吃蛇编程全攻略&#xff01;本文将带你从零开始&#xff0c;一步步…

Android平台FFmpeg音视频开发深度指南

一、FFmpeg在Android开发中的核心价值 FFmpeg作为业界领先的多媒体处理框架&#xff0c;在Android音视频开发中扮演着至关重要的角色。它提供了&#xff1a; 跨平台支持&#xff1a;统一的API处理各种音视频格式完整功能链&#xff1a;从解码、编码到滤镜处理的全套解决方案灵…

AI大模型驱动的智能座舱研发体系重构

随着AI大模型&#xff08;如LLM、多模态模型&#xff09;的快速发展&#xff0c;传统智能座舱研发流程面临巨大挑战。传统座舱研发以需求驱动、功能固定、架构封闭为特点&#xff0c;而AI大模型的引入使得座舱系统向自主决策、动态适应、持续进化的方向发展。 因此思考并提出一…

Day20 常见降维算法分析

一、常见的降维算法 LDA线性判别PCA主成分分析t-sne降维 二、降维算法原理 2.1 LDA 线性判别 原理 &#xff1a;LDA&#xff08;Linear Discriminant Analysis&#xff09;线性判别分析是一种有监督的降维方法。它的目标是找到一个投影方向&#xff0c;使得不同类别的数据在…

Python----机器学习(模型评估:准确率、损失函数值、精确度、召回率、F1分数、混淆矩阵、ROC曲线和AUC值、Top-k精度)

一、模型评估 1. 准确率&#xff08;Accuracy&#xff09;&#xff1a;这是最基本的评估指标之一&#xff0c;表示模型在测试集上正确 分类样本的比例。对于分类任务而言&#xff0c;准确率是衡量模型性能的直观标准。 2. 损失函数值&#xff08;Loss&#xff09;&#xff1…

cdn 是什么?

内容分发网络&#xff0c;Content Delivery Network 介绍 CDN&#xff08;Content Delivery Network&#xff09;是一种将内容分发到靠近用户的边缘服务器&#xff0c;以加速访问速度、减少延迟、降低源站压力的网络系统。 CDN 把网站的静态资源&#xff08;如 HTML、JS、CSS、…

BUCK基本原理学习总结-20250509

一、电感伏秒平衡特性 处于稳定状态的电感,开关导通时间(电流上升段)的伏秒数须与开关关断(电流下降段)时的伏秒数在数值上相等,尽管两者符号相反。这也表示,绘出电感电压对时间的曲线,导通时段曲线的面积必须等于关断时段曲线的面积。 二、BUCK的基本概念和原理 基…