打印
[开发资料]

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

[复制链接]
282|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mikewalpole|  楼主 | 2024-11-13 21:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1 ADC采样模型
(本文为笔者早期所写,当时对卡尔曼滤波器理解尚未透彻,如今回顾,该模型还有所缺陷,
假设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{δ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,k−1​=Pk−1,k−1​+QGk​=Pk,k−1​/(Pk,k−1​+R)Pk,k​=(1−Gk​)Pk,k−1​x0∣0​=0xk∣k−1​=xk−1∣k−1​xk∣k​=xk∣k−1​+Gk​(Zk​−xk∣k−1​)​
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),采用一阶滞后滤波算法,反之采用卡尔曼滤波算法。  





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);}



使用特权

评论回复
沙发
星辰大海不退缩| | 2024-11-22 18:03 | 只看该作者
滤波都有哪些测试算法

使用特权

评论回复
板凳
中国龙芯CDX| | 2024-11-24 14:52 | 只看该作者
卡尔曼滤波算法都有哪些注意事项?

使用特权

评论回复
地板
tpgf| | 2024-12-3 09:03 | 只看该作者
import numpy as np

# 定义系统参数
F = 1  # 状态转移矩阵
B = 0  # 控制输入矩阵
H = 1  # 观测矩阵
Q = 1e-5  # 过程噪声协方差
R = 1e-4  # 观测噪声协方差
P0 = 1.0  # 初始协方差
x0 = 0.0  # 初始状态估计

# 初始化卡尔曼滤波器参数
x_est = x0
P = P0

# 模拟ADC采样数据(带噪声的真实信号)
true_signal = np.linspace(0, 10, 50)  # 真实信号
measurements = true_signal + np.random.normal(scale=0.1, size=true_signal.shape)  # 带噪声的测量值

# 卡尔曼滤波
for z in measurements:
    # 预测
    x_pred = F * x_est
    P_pred = F * P * F + Q
   
    # 计算卡尔曼增益
    K = P_pred * H / (H * P_pred * H + R)
   
    # 更新估计值
    x_est = x_pred + K * (z - H * x_pred)
    P = (1 - K * H) * P_pred

print("滤波后的信号估计值:", x_est)

使用特权

评论回复
5
xiaoqizi| | 2024-12-4 18:34 | 只看该作者
卡尔曼滤波算法是一种递归算法,能够实时处理和优化动态系统中观测数据

使用特权

评论回复
6
木木guainv| | 2024-12-4 20:23 | 只看该作者
卡尔曼滤波器基于线性系统的状态空间表示,通过预测和更新步骤来估计系统状态

使用特权

评论回复
7
磨砂| | 2024-12-4 22:05 | 只看该作者
在ADC采样中,可以将采样值作为观测值,用卡尔曼滤波器来估计真实信号

使用特权

评论回复
8
晓伍| | 2024-12-5 08:40 | 只看该作者
在ADC采样中,卡尔曼滤波可以用来减少噪声,提高信号的估计精度。

使用特权

评论回复
9
八层楼| | 2024-12-5 12:45 | 只看该作者
卡尔曼滤波算法在ADC采样中的应用可以有效减少噪声,提高信号的估计精度。通过合理设置模型参数和噪声协方差,可以在各种应用场景中实现高效的信号处理

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

36

主题

1458

帖子

0

粉丝