ADC采样滤波算法利用卡尔曼滤波算法详解

ADC采样滤波算法利用卡尔曼滤波算法详解1ADC采样模型假设ADC采样的值已经为稳定状态,设k+1k+1k+1时刻ADC采样值为Xk+1Xk+1X_{k+1},则kkk时刻ADC采样值为XkXkX_k,假设k+1k+1k+1时刻的采样值为Zk+1Zk+1Z_{k+1},则有:{Xk+1=Xk,Zk+1=Xk+1+δ,δ为噪声{Xk+1=Xk,Zk+1=Xk+1+δ,δ为噪声\begin{cases}X_{k+1}=X…

大家好,又见面了,我是你们的朋友全栈君。

1 ADC采样模型

(本文为笔者早期所写,当时对卡尔曼滤波器理解尚未透彻,如今回顾,该模型还有所缺陷,推荐读者看卡尔曼的推导过程或者B站大佬Dr_CAN的空间

假设ADC采样的值已经为稳定状态,设 k + 1 k+1 k+1时刻ADC采样值为 X k + 1 X_{k+1} Xk+1,则 k k k时刻ADC实际值为 X k X_k Xk,假设 k + 1 k+1 k+1时刻的采样值为 Z k + 1 Z_{k+1} Zk+1,则有:
{ X k + 1 = X k + δ 1 , δ 1 为系统噪声 Z k + 1 = X k + 1 + δ 2 , δ 2 为测量噪声 \begin{cases} X_{k+1} = X_k+\delta_1, & \text{$\delta_1$为系统噪声}\\Z_{k+1}=X_{k+1} +\delta_2, & \text{$\delta_2$为测量噪声} \end{cases} {
Xk+1=Xk+δ1,Zk+1=Xk+1+δ2,δ1为系统噪声δ2为测量噪声

2 卡尔曼滤波算法

我们知道卡尔曼滤波算法的公式如下:
这里写图片描述

由于相关系数都为1,于是可以得出如下公式:
{ P 0 , 0 = 0 P k , k − 1 = P k − 1 , k − 1 + Q G k = P k , k − 1 / ( P k , k − 1 + R ) P k , k = ( 1 − G k ) P k , k − 1 x 0 ∣ 0 = 0 x k ∣ k − 1 = x k − 1 ∣ k − 1 x k ∣ k = x k ∣ k − 1 + G k ( Z k − x k ∣ k − 1 ) \begin{cases} P_{0,0} = 0 \\P_{k,k-1}=P_{k-1,k-1} +Q \\ G_k = P_{k,k-1}/(P_{k,k-1}+R) \\ P_{k,k}=(1-G_k)P_{k,k-1} \\ x_{0|0} = 0 \\ x_{k|k-1} = x_{k-1|k-1} \\ x_{k|k}=x_{k|k-1}+G_k(Z_k-x_{k|k-1}) \end{cases} P0,0=0Pk,k1=Pk1,k1+QGk=Pk,k1/(Pk,k1+R)Pk,k=(1Gk)Pk,k1x00=0xkk1=xk1k1xkk=xkk1+Gk(Zkxkk1)

3 C语言代码

用C实现的代码如下:

unsigned long kalman_filter(unsigned long ADC_Value)
{
    float x_k1_k1,x_k_k1;
    static float ADC_OLD_Value;
    float Z_k;
    static float P_k1_k1;

    static float Q = 0.0001;
    static float R = 0.005;
    static float Kg = 0;
    static float P_k_k1 = 1;

    float kalman_adc;
    static float kalman_adc_old=0;
    Z_k = ADC_Value;
    x_k1_k1 = kalman_adc_old;

    x_k_k1 = x_k1_k1;
    P_k_k1 = P_k1_k1 + Q;

    Kg = P_k_k1/(P_k_k1 + R);

    kalman_adc = x_k_k1 + Kg * (Z_k - kalman_adc_old);
    P_k1_k1 = (1 - Kg)*P_k_k1;
    P_k_k1 = P_k1_k1;

    ADC_OLD_Value = ADC_Value;
    kalman_adc_old = kalman_adc;

    return kalman_adc;
}

4 如何优化

用以上的代码实现的滤波算法,通常要么滞后严重,要么滤波效果不明显,在这里给出两种优化方案。
方案一:在采样值与优化值相差大于某值时采用一阶滞后滤波算法,小于该值时采用卡尔曼滤波算法;
方案二:比较一段时间内的ADC采样值与优化值差值,若一直处于某个范围如(6~30),采用一阶滞后滤波算法,反之采用卡尔曼滤波算法。
以下代码是方案一的优化代码,其优化效果可见我另一篇博文https://blog.csdn.net/moge19/article/details/80915432:

unsigned long kalman_filter(unsigned long ADC_Value)
{
float x_k1_k1,x_k_k1;
static float ADC_OLD_Value;
float Z_k;
static float P_k1_k1;

static float Q = 0.0001;
static float R = 5;
static float Kg = 0;
static float P_k_k1 = 1;

float kalman_adc;
static float kalman_adc_old=0;

Z_k = ADC_Value;

if (abs(kalman_adc_old-ADC_Value)>=10)
{ 
    x_k1_k1= ADC_Value*0.382 + kalman_adc_old*0.618;
}else
{
    x_k1_k1 = kalman_adc_old;
}
x_k_k1 = x_k1_k1;
P_k_k1 = P_k1_k1 + Q;

Kg = P_k_k1/(P_k_k1 + R);

kalman_adc = x_k_k1 + Kg * (Z_k - kalman_adc_old);
P_k1_k1 = (1 - Kg)*P_k_k1;
P_k_k1 = P_k1_k1;

ADC_OLD_Value = ADC_Value;
kalman_adc_old = kalman_adc;

return get_int_num(kalman_adc);
}

用python实现并对其进行仿真,详见博文
https://blog.csdn.net/moge19/article/details/82531119

利用FFT分析卡尔曼滤波与低通滤波详见博文:
https://blog.csdn.net/moge19/article/details/87389728
卡尔曼滤波算法的推导过程详见博文:
https://blog.csdn.net/moge19/article/details/89464151

若有错误望方家指正

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/131263.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 简述SOAP协议「建议收藏」

    简述SOAP协议「建议收藏」8个月过去了,依旧清楚的记得研究生复试时,老师问我SOAP协议是啥(当时还不知道这个协议的名字到底该怎么写),今天偶然之间看见了一篇博客提到了SOAP(见下图),于是就查了一下SOAP协议。SOAP是基于XML的简易协议,可使应用程序在HTTP之上进行信息交换。更简单地说:SOAP是用于访问网络服务的协议。什么是SOAP?SOAP指简易对象访问协议SOAP是一种…

    2022年7月27日
    3
  • 简聊 Session 与 Token 身份验证[通俗易懂]

    简聊 Session 与 Token 身份验证

    2022年2月14日
    39
  • 离心泵CAE_2_ICEM剖分网格_2_叶轮流道[通俗易懂]

    离心泵CAE_2_ICEM剖分网格_2_叶轮流道[通俗易懂]针对本科毕设中所涉及到的离心泵数值分析和性能计算,将用最简单粗暴的方法,讲解如何基于CFturbo、ICEM、FLUENT来开展离心泵水力设计和性能分析的计算机辅助(CAE)实现。离心泵的水力设计由CFturbo软件实现;网格剖分由ICEM软件实现;CFD数值计算由FLUENT软件实现;并验证设计值是否达到。这里是第二部分,ICEM软件实现离心泵过流通道的网格剖分,含叶轮流道、进口延伸段、蜗壳流道的网格剖分。由于三个流道分开来划分网格,所以分三部分来分别讲解,这里是第2篇,叶轮流道的网格剖分……

    2022年5月26日
    47
  • goland 2022 永久激活码_在线激活2022.03.13「建议收藏」

    (goland 2022 永久激活码)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html…

    2022年4月2日
    2.9K
  • 01 ORA系列:ORA-00904 标识符无效 invalid identifier

    01 ORA系列:ORA-00904 标识符无效 invalid identifier如果希望对常见的 Oracle 异常 ORA 报错解决方案有系统的了解 请看 ORACLE 系列异常总结 ORA nbsp 转载请说明出处 https blog csdn net baidu article details nbsp 1 字段名称与数据库中关键字冲突修改如下 nbsp 2 多层嵌套查询 内层字段别名使用了双引号错误原因 内层查

    2025年7月22日
    4
  • mysql5.7安装及配置超详细教程_mysql安装教程 linux

    mysql5.7安装及配置超详细教程_mysql安装教程 linuxMySQL5.7.35安装教程下载工具官网下载下载在下图中选择你自己需要的版本即可第二种下载方式如下图所示下载下载完成后对工具包进行解压,我解压的在D盘解压好过后在里面新建my.ini文件(如果你不知道怎么创建my.ini文件请看)右击新建文本文档创建文本文档过后进行重命名讲文本文档的后缀名改为ini如图操作再将新建的文本文档改名为my.ini编辑my.ini文件将下面的代码复制进去记得更改里面【basedir】【datadir】的路径为你自己的安装路径[mysqld]#

    2022年8月22日
    13

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号