|
简介受限于MCU自身的ADC外设缺陷,精度和稳定性通常较差,很多场景下需要用滤波算法进行补偿。滤波的主要目的是减少噪声与干扰对数据的影响,让数据更加接近真实值。一阶低通滤波一阶低通滤波是一种信号处理技术,用于去除信号中高频部分,保留低频部分。在滤波过程中,一阶低通滤波器会使得高于某个截止频率的信号被衰减,而低于截止频率的信号则会被保留。这有助于减少噪音或者不需要的信号成分,从而提高信号的质量。典型案例:蓝牙耳机、音响Python实现importnumpyasnpimportmatplotlib.pyplotasplt#生成示例数据sensor_data=np.random.randn(200)#正态分布随机数据#定义低通滤波函数deflow_pass_filter(data,cutoff_freq):filtered_data=np.copy(data)foriinrange(1,len(data)):filtered_data[i]=(1-cutoff_freq)*filtered_data[i-1]+cutoff_freq*data[i]returnfiltered_data#设置截止频率cutoff_freq=0.2#应用低通滤波filter_sensor_data=low_pass_filter(sensor_data,cutoff_freq)#绘制原始数据和滤波后数据plt.figure(figsize=(10,6))plt.plot(sensor_data)plt.plot(filter_sensor_data)plt.show()'运行运行均值滤波说明:连续取N个采样值进行算术平均运算达到降噪目的;N值较大时:信号平滑度较高,但灵敏度较低N值较小时:信号平滑度较低,但灵敏度较高优点:试用于对一般具有随机干扰的信号进行滤波。这种信号的特点是有一个平均值,信号在某一数值范围附近上下波动。缺点:测量速度较慢或要求数据计算较快的实时控制不适用。典型案例:电子秤...Python实现importnumpyasnpimportmatplotlib.pyplotasplt#生成模拟示例数据sensor_data=np.random.randn(200)#正态分布随机数据m=0#起始角标n=11#在多少个数中取中间值,必须为奇数defaverage_filter(data):globalm,ndata=sensor_data[m:m+n]m+=nvalue=np.average(data)returnvaluefilter_sensor_data=np.zeros_like(sensor_data)foriinrange(0,len(sensor_data),n):filter_sensor_data[i]=average_filter(sensor_data)#绘制原始数据和滤波后数据plt.figure(figsize=(10,6))plt.plot(sensor_data,c="green")plt.plot(filter_sensor_data,c="red")plt.show()'运行运行滑动平均滤波说明:把连续取N个采样值看成一个队列,队列的长度固定为N。每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据(先进先出原则)。把队列中的N个数据进行算术平均运算,就可获得新的滤波结果。N值的选取:流量,N=12;压力:N=4;液面,N=4~12;温度,N=1~4优点:对周期性干扰有良好的抑制作用,平滑度高;试用于高频振荡的系统缺点:灵敏度低;对偶然出现的脉冲性干扰的抑制作用较差,不适于脉冲干扰较严重的场合比较浪费RAM(改进方法,减去的不是队首的值,而是上一次得到的平均值)典型应用:汽车上剩余可行驶里程预估Python实现importnumpyasnpimportmatplotlib.pyplotaspltsensor_data=np.random.randn(200)n=11filter_sensor_data=np.zeros_like(sensor_data)foriinrange(1,len(sensor_data)):ifiNone:self.q=q#过程噪声协方差self.r=r#测量噪声协方差self.p=5#估计误差协方差self.k_gain=0#卡尔曼增益self.prev_data=0#先前数据值defupdata(self,measurement):#预测self.p+=self.q#计算卡尔曼增益self.k_gain=self.p/(self.p+self.r)#更新估计值estimation=self.prev_data+self.k_gain*(measurement-self.prev_data)#更新估计误差协方差self.p=(1-self.k_gain)*self.p#更新先前数据值self.prev_data=estimationreturnestimation#测试kf=KalmanFilter()input_data=5filter_data=kf.updata(input_data)print(f"滤波后:filter_data")importnumpyasnpimportmatplotlib.pyplotaspltsensor_data=np.random.randn(200)n=11filter_sensor_data=np.zeros_like(sensor_data)foriinrange(1,len(sensor_data)):src_data=sensor_data[i]filter_sensor_data[i]=kf.updata(src_data)plt.figure(figsize=(10,6))plt.plot(sensor_data,c="green")plt.plot(filter_sensor_data,c="red")plt.show()'运行运行
|
|