卡尔曼滤波分析

news/2024/11/21 20:56:29/

概述

在实际项目中,常常需要对数据进行滤波,这里分享卡尔曼滤波算法应用。

正文

卡尔曼滤波(KF)属于线性滤波器,使用均值和方差描述系统状态,将多个符合高斯分布的不确定信息源进行数据融合的一种最优状态估计算法。

使用前提:

  • 线性:系统状态方程为线性(比例性、齐次性)的系统,非线性则需要使用扩展卡尔曼滤波(EKF)。

  • KF和EKF最大的区别在于:EKF的 F k F_k Fk H k H_k Hk都是使用雅各比矩阵表示

  • 高斯分布:系统噪声服从高斯分布

    • 传感器噪声

    • ADC采样噪声

预测方程:

X ^ k = F k X ^ k − 1 + B k U ⃗ k \hat{X}_k=F_k\hat{X}_{k-1}+B_k\vec{U}_k X^k=FkX^k1+BkU k

P k = F k P k − 1 F k T + Q k P_k=F_kP_{k-1}F^T_k+Q_k Pk=FkPk1FkT+Qk

更新方程:

K ′ = P k H k T H k P k H k T + R k K'=\frac {P_kH^T_k}{H_kP_kH^T_k+R_k} K=HkPkHkT+RkPkHkT

X k ′ ^ = X ^ k + K ′ ( Z ⃗ k − H k X ^ k ) \hat{X_k'}=\hat{X}_k+K'(\vec{Z}_k-H_k\hat{X}_k) Xk^=X^k+K(Z kHkX^k)

P k ′ = P k − K ′ H k P k {P_k}'=P_k-K'H_kP_k Pk=PkKHkPk

  • X ^ k \hat{X}_k X^k k k k时刻系统最优的状态向量

  • F k F_k Fk为状态转移矩阵,表示用 k − 1 k-1 k1时刻的状态向量估算 k k k时刻的状态向量

  • B k B_k Bk为输入控制矩阵,代表着控制向量 U ⃗ k \vec{U}_k U k和状态向量 X ^ k \hat{X}_k X^k的关系

  • U ⃗ k \vec{U}_k U k代表着控制向量,如加速度、角加速度等

  • P k P_k Pk为状态向量的协方差矩阵,代表着状态向量每个元素之间的关系

  • Q k Q_k Qk为预测状态的高斯噪声协方差矩阵,它用来衡量模型的准确度,模型越准确其值越小

  • Z ⃗ k \vec{Z}_k Z k k k k时刻测量值的状态向量

  • H k H_k Hk为转换矩阵,它将状态向量 X ^ k \hat{X}_k X^k映射到测量值所在的向量空间 Z ⃗ k \vec{Z}_k Z k

  • R k R_k Rk为测量值的高斯噪声协方差矩阵,代表着传感器的测量误差

一阶卡尔曼滤波
(1)预测状态方程:

在一阶系统下, F k F_k Fk的值为1,无外部控制向量 U ⃗ k \vec{U}_k U k的作用。所以,代入公式 X ^ k = F k X ^ k − 1 + B k U ⃗ k \hat{X}_k=F_k\hat{X}_{k-1}+B_k\vec{U}_k X^k=FkX^k1+BkU k得出:

X ^ k = X ^ k − 1 \hat{X}_k=\hat{X}_{k-1} X^k=X^k1

(2)预测状态协方差方程:

在一阶系统下, F k F_k Fk的值为1,所以转置矩阵 F k T F^T_k FkT的值也为1。所以,代入公式 P k = F k P k − 1 F k T + Q k P_k=F_kP_{k-1}F^T_k+Q_k Pk=FkPk1FkT+Qk得出:

P k = P k − 1 + Q k P_k=P_{k-1}+Q_k Pk=Pk1+Qk

(3)卡尔曼增益方程:

在一阶系统下, H k H_k Hk的值为1。所以,代入公式 K ′ = P k H k T H k P k H k T + R k K'=\frac {P_kH^T_k}{H_kP_kH^T_k+R_k} K=HkPkHkT+RkPkHkT得出:

K ′ = P k P k + R k K'=\frac {P_k}{P_k+R_k} K=Pk+RkPk

(4)更新最优状态方程:

在一阶系统下, H k H_k Hk的值为1。所以,代入公式 X k ′ ^ = X ^ k + K ′ ( Z ⃗ k − H k X ^ k ) \hat{X_k'}=\hat{X}_k+K'(\vec{Z}_k-H_k\hat{X}_k) Xk^=X^k+K(Z kHkX^k)得出:

X k ′ ^ = X ^ k + K ′ ( Z ⃗ k − X ^ k ) \hat{X_k'}=\hat{X}_k+K'(\vec{Z}_k-\hat{X}_k) Xk^=X^k+K(Z kX^k)

(5)更新状态协方差方程:

在一阶系统下, H k H_k Hk的值为1。所以,代入公式 P k ′ = P k − K ′ H k P k {P_k}'=P_k-K'H_kP_k Pk=PkKHkPk得出:

P k ′ = P k − K ′ P k {P_k}'=P_k-K'P_k Pk=PkKPk

C代码实现
typedef struct{float last_P;    float Q;         float R;         float out;float now_P;float Kg;
}kalman_t;kalman_t my_kalman;
float kalman_filter_init(void)
{my_kalman.last_P = 1.0;my_kalman.Q = 0;my_kalman.R = 0.01;my_kalman.out = 0;my_kalman.now_P = 0;my_kalman.Kg = 0;
}float kalman_filter_calc(kalman_t *kfp, float input)
{kfp->now_P = kfp->last_P + kfp->Q;kfp->Kg = kfp->now_P / (kfp->now_P + kfp->R);kfp->out += kfp->Kg * (input - kfp->out);kfp->last_P = (1 - kfp->Kg) * kfp->now_P;return kfp->out;
}
实验效果

在这里插入图片描述

二阶卡尔曼滤波

以经典卡尔曼滤波模型:加速度计、陀螺仪进行角度数据融合为例。

(1)预测状态方程:

首先,根据系统建立系统方程:

a n g l e k = a n g l e k − 1 − Q _ b i a s k − 1 ∗ Δ t + G y r o k ∗ Δ t + 1 2 ∗ ( G y r o k − G y r o k − 1 ) ∗ Δ t 2 angle_k = angle_{k-1} - Q\_bias_{k-1}*\Delta{t}+Gyro_k*\Delta{t}+\frac{1}{2}*(Gyro_k-Gyro_{k-1})*{\Delta _{t}}^{2} anglek=anglek1Q_biask1Δt+GyrokΔt+21(GyrokGyrok1)Δt2

Q _ b i a s k = Q _ b i a s k − 1 Q\_bias_{k} = Q\_bias_{k-1} Q_biask=Q_biask1

用矩阵的方式表示为:

∣ a n g l e k Q _ b i a s k ∣ = ∣ 1 − Δ t 0 1 ∣ ∣ a n g l e k − 1 Q _ b i a s k − 1 ∣ + ∣ Δ t 0 ∣ G y r o k + ∣ 1 2 ∗ Δ t 2 0 ∣ ( G y r o k − G y r o k − 1 ) \begin{vmatrix}angle_k\\Q\_bias_k\end{vmatrix}=\begin{vmatrix}1&-\Delta{t}\\0&1\end{vmatrix}\begin{vmatrix}angle_{k-1}\\Q\_bias_{k-1}\end{vmatrix}+\begin{vmatrix}\Delta{t}\\0\end{vmatrix}Gyro_k+\begin{vmatrix}\frac{1}{2}*{\Delta _{t}}^{2}\\0\end{vmatrix}(Gyro_k-Gyro_{k-1}) anglekQ_biask = 10Δt1 anglek1Q_biask1 + Δt0 Gyrok+ 21Δt20 (GyrokGyrok1)

  • a n g l e angle angle为角度,如pitch、roll、yaw

  • Q _ b i a s Q\_bias Q_bias为陀螺仪零漂,固定值

  • 由于 Δ t 2 {\Delta_{t}}^{2} Δt2非常小,所以忽略不计,所以 B k B_k Bk为0

  • F k = ∣ 1 − Δ t 0 1 ∣ F_k=\begin{vmatrix}1&-\Delta{t}\\0&1\end{vmatrix} Fk= 10Δt1

所以,预测状态方程的C代码如下:

angle += (gyro - Q_bias) * dt;//预测角度等于上次最优角度加上//角速度减去零漂后的积分角度
(2)预测状态协方差方程:

由于高斯分布中的每个数据点的协方差可以用 C o v ( x ) = Σ Cov(x)=\Sigma Cov(x)=Σ表示,所以高斯噪声协方差矩阵 Q k = ∣ C o v ( a n g l e , a n g l e ) C o v ( Q _ b i a s , a n g l e ) C o v ( a n g l e , Q _ b i a s ) C o v ( Q _ b i a s , Q _ b i a s ) ∣ Q_k=\begin{vmatrix}Cov(angle,angle)&Cov(Q\_bias,angle)\\Cov(angle,Q\_bias)&Cov(Q\_bias,Q\_bias)\end{vmatrix} Qk= Cov(angle,angle)Cov(angle,Q_bias)Cov(Q_bias,angle)Cov(Q_bias,Q_bias)

因为加速度计和陀螺仪噪声相互独立,所以:

Q k = ∣ C o v ( a n g l e , a n g l e ) 0 0 C o v ( Q b i a s , Q b i a s ) ∣ Q_k=\begin{vmatrix}Cov(angle,angle)&0\\0&Cov(Q_bias,Q_bias)\end{vmatrix} Qk= Cov(angle,angle)00Cov(Qbias,Qbias)

假设预测状态协方差矩阵 P k = ∣ a k b k c k d k ∣ P_k=\begin{vmatrix}a_k&b_k\\c_k&d_k\end{vmatrix} Pk= akckbkdk

代入预测状态协方差方程得出:

P k = ∣ a k − 1 − ( c k − 1 + b k − 1 ) ∗ Δ t + Δ t 2 b k − 1 − d k − 1 ∗ Δ t c k − 1 − d k − 1 ∗ Δ t d k − 1 ∣ + ∣ C o v ( a n g l e , a n g l e ) 0 0 C o v ( Q _ b i a s , Q _ b i a s ) ∣ P_k=\begin{vmatrix}a_{k-1}-(c_{k-1}+b_{k-1})*\Delta{t}+{\Delta{t}}^2&b_{k-1}-d_{k-1}*\Delta{t}\\c_{k-1}-d_{k-1}*\Delta{t}&d_{k-1}\end{vmatrix}+\begin{vmatrix}Cov(angle,angle)&0\\0&Cov(Q\_bias,Q\_bias)\end{vmatrix} Pk= ak1(ck1+bk1)Δt+Δt2ck1dk1Δtbk1dk1Δtdk1 + Cov(angle,angle)00Cov(Q_bias,Q_bias)

  • 由于 Δ t 2 {\Delta_{t}}^{2} Δt2非常小,所以忽略不计

所以,预测状态协方差方程的C代码如下:

PP[0][0] = PP[0][0] + Q_angle - (PP[0][1] - PP[1][0])*dt;
PP[0][1] = PP[0][1] - PP[1][1]*dt;
PP[1][0] = PP[1][0] - PP[1][1]*dt;
PP[1][1] = PP[1][0] + Q_gyro;
(3)卡尔曼增益方程:

首先建立测量方程 Z k = H k X k + V k Z_k=H_kX_k+V_k Zk=HkXk+Vk

  • Z k Z_k Zk k k k时刻实际观测量

  • X k X_k Xk k k k时刻状态量

  • V k V_k Vk k k k时刻的噪声

由于传感器数据自带噪声,所以 V k = 0 V_k=0 Vk=0

所以测量方程可以用矩阵表示为:

Z k = ∣ 1 0 ∣ ∣ X k 0 ∣ Z_k=\begin{vmatrix}1&0\end{vmatrix}\begin{vmatrix}X_k\\0\end{vmatrix} Zk= 10 Xk0

所以转换矩阵 H k = ∣ 1 0 ∣ H_k=\begin{vmatrix}1&0\end{vmatrix} Hk= 10

代入卡尔曼增益方程得出:

K ′ = ∣ a b c d ∣ ∣ 1 0 ∣ ∣ 1 0 ∣ ∣ a b c d ∣ ∣ 1 0 ∣ + R _ a n g l e = a + c a + R _ a n g l e K'=\frac{\begin{vmatrix}a&b\\c&d\end{vmatrix}\begin{vmatrix}1\\0\end{vmatrix}}{\begin{vmatrix}1&0\end{vmatrix}\begin{vmatrix}a&b\\c&d\end{vmatrix}\begin{vmatrix}1\\0\end{vmatrix}+R\_angle}=\frac{a+c}{a+R\_angle} K=10 acbd 10 +R_angle acbd 10 =a+R_anglea+c

所以卡尔曼增益方程的C代码如下:

K_0 = PP[0][0] / (PP[0][0] + R_angle);    //angle增益
K_1 = PP[1][0] / (PP[0][0] + R_angle);    //Q_bias增益
(4)更新最优状态方程:

代入更新最优状态方程得出:

∣ a n g l e Q _ b i a s ∣ = ∣ a n g l e Q _ b i a s ∣ + ∣ K 0 K 1 ∣ ( a n g l e z − ∣ 1 0 ∣ ∣ a n g l e Q _ b i a s ∣ ) \begin{vmatrix}angle\\Q\_bias\end{vmatrix}=\begin{vmatrix}angle\\Q\_bias\end{vmatrix}+\begin{vmatrix}K_0\\K_1\end{vmatrix}(angle_z-\begin{vmatrix}1&0\end{vmatrix}\begin{vmatrix}angle\\Q\_bias\end{vmatrix}) angleQ_bias = angleQ_bias + K0K1 (anglez 10 angleQ_bias )

所以更新最优状态方程的C代码如下:

Q_bias += K_1 * (angle_now - angle);
angle += K_0 * (angle_now - angle);
(5)更新状态协方差方程

代入更新状态协方差方程得出:

∣ a k ′ b k ′ c k ′ d k ′ ∣ = ( ∣ 1 0 0 1 ∣ − ∣ K 0 K 1 ∣ ∣ 1 0 ∣ ) ∗ ∣ a k b k c k d k ∣ \begin{vmatrix}{a_k}'&{b_k}'\\{c_k}'&{d_k}'\end{vmatrix}=(\begin{vmatrix}1&0\\0&1\end{vmatrix}-\begin{vmatrix}K_0\\K_1\end{vmatrix}\begin{vmatrix}1&0\end{vmatrix})*\begin{vmatrix}a_k&b_k\\c_k&d_k\end{vmatrix} akckbkdk =( 1001 K0K1 10 ) akckbkdk

所以更新状态协方差的C代码如下:

PP[0][0] = PP[0][0] - K_0 * PP[0][0];
PP[0][1] = PP[0][1] - K_0 * PP[0][1];
PP[1][0] = PP[1][0] - K_1 * PP[0][0];
PP[1][1] = PP[1][1] - K_1 * PP[0][1];
整理完整代码
static float Q_angle = 0.001;		//角度噪声的协方差
static float Q_gyro  = 0.003;		//角速度噪声的协方差  
static float R_angle = 0.5;		    //加速度计测量噪声的协方差
static float dt      = 0.01;		//采样周期即计算任务周期10msfloat kalman_acc_gyro(float angle_now, float gyro)
{static float Q_bias;static float K_0,K_1;   static float PP[2][2] = {{1, 0}, {0, 1}};static float angle;angle += (gyro - Q_bias) * dt;      PP[0][0] += Q_angle - (PP[0][1] - PP[1][0])*dt;PP[0][1] -= PP[1][1]*dt;PP[1][0] -= PP[1][1]*dt;PP[1][1] += Q_gyro;K_0 = PP[0][0] / (PP[0][0] + R_angle);    K_1 = PP[1][0] / (PP[0][0] + R_angle);Q_bias += K_1 * (angle_now - angle);angle += K_0 * (angle_now - angle);PP[0][0] -= K_0 * PP[0][0];PP[0][1] -= K_0 * PP[0][1];PP[1][0] -= K_1 * PP[0][0];PP[1][1] -= K_1 * PP[0][1];return angle;
}void test(float acc_x, float acc_y, float acc_z,float gyro_x, float gyro_y, float gyro_z)
{float roll = (atan(acc_x/acc_z))*180/3.14159;kalman_acc_gyro(roll, gyro_y);
}
实验效果

在这里插入图片描述

总结

这样就完成了卡尔曼滤波的简单分析和基础应用,实际项目中不同系统的传递函数不同,所以需要进行调整设计,但是5大核心公式都不会变。扩展卡尔曼其实也是利用线性去模拟非线性,具体的应用大家有兴趣可以自行查文献实验,这里不做分析介绍。水平有限,这里只做自己的理解分析,有错误的地方,请大佬们不吝赐教!


http://www.ppmy.cn/news/283267.html

相关文章

WeKa 数据集

今天找weka官方数据集差点被自己蠢哭,写个博客纪念一下。最近在学习weka的基本操作,来训练自己的数据进行分类等操作,网上找了一个视频Weka讲解视频 YouTobe视频 “https://www.youtube.com/watch?vLcHw2ph6bss&listPLm4W7_iX_v4NqPUjc…

[学习笔记] [机器学习] 7. 集成学习(Bagging、随机森林、Boosting、GBDT)

视频链接数据集下载地址:无需下载 1. 集成学习算法简介 学习目标: 了解什么是集成学习知道机器学习中的两个核心任务了解集成学习中的 Boosting 和 Bagging 1.1 什么是集成学习 集成学习通过建立几个模型来解决单一预测问题。它的工作原理是生成多个分…

一文详解!JMeter该如何并发测试和持续性压测?

目录 前言: 概念 并发测试 持续性压测 查看报告 总结 试试其他 API 工具 知识扩展: 前言: JMeter 是一个 Java 编写的开源负载测试工具,基于模拟用户、线程和请求,结合测试计划和策略,可以模拟真实…

软件测试与打螺丝

单元测试中的FIRST代表下面五组英文单词对应的原则: FastIsolated / IndependentRepeatableSelf-validatingTimely / Thorough 软件开发中,往往会因为我们没有注意到的逻辑或难以理解的代码,而引进Bug来。 怎么尽早地发现Bug,…

总结vue3 的一些知识点:MySQL NULL 值处理

MySQL NULL 值处理 我们已经知道 MySQL 使用 SQL SELECT 命令及 WHERE 子句来读取数据表中的数据,但是当提供的查询条件字段为 NULL 时,该命令可能就无法正常工作。 为了处理这种情况,MySQL提供了三大运算符: IS NULL: 当列的值是 NULL,此运算符返回 …

中国七七红客网

中国七七红客网 链接:http://www.zg77hk.com 来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/3704/viewspace-488804/,如需转载,请注明出处,否则将追究法律责任。 转载于:http://blog.itpub.net/3704/viewspace-4…

宝月红

宝月红啊宝月红

抖音网红大蓝称视频号永远都做不起来

最近杰哥从微商大佬龚文祥爆料了解到,抖音头部知识付费网红大蓝最近跟视频号杠上了,大蓝发视频表示,视频号永远都做不起来,视频号给抖音提鞋都不配,因为字节跳动短视频技术一直高于腾讯,视频号永远无法超越…