针对于单片机的AD数据滤波算法有很多,众多算法中我唯独钟爱滑动平均值和卡尔曼滤波,因为一个够简单,一个够霸道
卡尔曼滤波算法已经有半个多世纪的历史了,时至今日仍然在很多领域有不可撼动的地位,我等只能振臂高呼 卡尔曼滤波yyds 数学yyds
接下来分享的小工具,是把收集到的单片机ad数据,在电脑端显示,并调节卡尔曼的Q和R参数观察效果,当然你需要把ad数据提前保存到一个txt文件中,数据格式很简单就是用逗号
分割的字符:
234,245,265.7,458,.........
先看一下软件效果
软件功能大概介绍一下
-
红色曲线是原始数据
-
绿色和蓝色是对原始数据用两种不同深度的滑动平局值滤波后的结果,两种深度可以在输入框中指定,范围是1-31
-
水红色是对原始数据进行标准的卡尔曼滤波后的结果
-
黑色是利用改良卡尔曼算法滤波后的结果,改良原理就是
当数据的突变超过10%
,怎把滑动平均值的结果传递给给卡尔曼的输出,使卡尔曼快速响应 -
还有一个
数据跳变使能
,意思就是在一个范围内给原始数据乘上一个系数
,模拟原始数据产生突变,这样就可以观察滤波算法的响应数据(使用跳变功能后,在相同参数参数下,改良后的卡尔曼响应更快)
-
软件中内置的卡尔曼算法代码如下
//1. 结构体类型定义
typedef struct
{
float LastP;//上次估算协方差 初始化值为0.0
float Now_P;//当前估算协方差 初始化值为0
float out;//卡尔曼滤波器输出 初始化值为0
float Kg;//卡尔曼增益 初始化值为0
float Q;//过程噪声协方差 初始化值为0.000
float R;//观测噪声协方差 初始化值为0.0
}KFP;//Kalman Filter parameter
/ **
*卡尔曼滤波器
*@param KFP *kfp 卡尔曼结构体参数
* float input 需要滤波的参数的测量值(即传感器的采集值)
*@return 滤波后的参数(最优值)
*/
float kalmanFilter(KFP *kfp,float input)
{
//预测协方差方程:k时刻系统估算协方差 = k-1时刻的系统协方差 + 过程噪声协方差
kfp->Now_P = kfp->LastP + kfp->Q;
//卡尔曼增益方程:卡尔曼增益 = k时刻系统估算协方差 / (k时刻系统估算协方差 + 观测噪声协方差)
kfp->Kg = kfp->Now_P / (kfp->Now_P + kfp->R);
//更新最优值方程:k时刻状态变量的最优值 = 状态变量的预测值 + 卡尔曼增益 * (测量值 - 状态变量的预测值)
kfp->out = kfp->out + kfp->Kg * (input -kfp->out);//因为这一次的预测值就是上一次的输出值
//更新协方差方程: 本次的系统协方差付给 kfp->LastP 威下一次运算准备。
kfp->LastP = (1-kfp->Kg) * kfp->Now_P;
return kfp->out;
}
- 改良算法的部分代码,这种改良方法不一定适合你哈
后记
- 这个工具使用QT做的,后期要开源的,只是代码整理需要一段时间,要不然乱糟糟的代码怕小伙伴看不懂呀
- 有不在乎代码质量的小伙伴可以私信我