智能车四种常见滤波和 MATLAB 仿真:一阶 RC 低通滤波,二阶 IIR 低通滤波,五阶 FIR 低通滤波,卡尔曼滤波

简介: 智能车四种常见滤波和 MATLAB 仿真:一阶 RC 低通滤波,二阶 IIR 低通滤波,五阶 FIR 低通滤波,卡尔曼滤波

四种常见滤波和 MATLAB 仿真:一阶 RC 低通滤波,二阶 IIR 低通滤波,五阶 FIR 低通滤波,卡尔曼滤波

开源代码地址: https://github.com/ittuann/Enterprise_E

博客目录:
https://blog.csdn.net/sorcererr/article/details/124989905
https://ittuann.github.io/2021/08/30/Car.html

一阶 RC 低通滤波

FilterData = cof * RawData + (1.000f - cof) * FilterData;

一阶 RC 低通滤波又叫一阶惯性滤波,因为本质上也是积分滤波器。

不能滤除频率高于采样频率的二分之一的干扰。

cof是一阶RC低通滤波参数,代表新采样值在滤波结果中的权重。

滤波系数越小,滤波结果越平稳,灵敏度越低。

滤波系数可以理解为对采样值的相信程度。

float Cof =  = 1.0 / (1.0 + (1.0 / 2Pi * T(s) * fc));

上面是cof的计算公式。但一阶 RC 低通滤波在实际情况也可以不按照公式计算的结果,用上位机比较原始值和滤波后数值波形来试凑出来一版系数也是可行的。

二阶 IIR 低通滤波

IIR 滤波公式:

$$ y_n=\frac{1}{b_0}\left(\sum_{k=0}^{n}{b_kx\left(n-k\right)}-\sum_{k=1}^{n}{a_kx\left(n-k\right)}\right) $$

或是

$$ y_{\left(n\right)}=b_0x_{\left(n\right)}+b_1x_{\left(n-1\right)}+\ldots+b_Mx_{\left(n-M\right)}-a_1y_{\left(n-1\right)}-\ldots-a_Ny_{\left(n-N\right)} $$

IIR滤波就是这个个方程。yn为输出数据,xn为输入数据,a和b为滤波器的系数。

C语言实现:

#define ORDER 2

typedef struct {
    float A[ORDER + 1];
    float B[ORDER + 1];
    float OriginData[ORDER + 1];
    float FilterData[ORDER + 1];
} LpfIIR2nd_t;

/**
 * @brief            二阶IIR低通滤波器
 * @param[out]        lpf : 滤波结构数据指针
 * @param[in]        rawData : 原始数据
 */
void LowPassFilterIIR2nd(LpfIIR2nd_t* lpf, float rawData)
{
    uint8_t i = 0;
    // 递推旧值
    for (i = ORDER; i > 0; i--) {
        lpf->OriginData[i] = lpf->OriginData[i - 1];
        lpf->FilterData[i] = lpf->FilterData[i - 1];
    }
    // 计算滤波结果
    lpf->OriginData[0] = rawData;
    lpf->FilterData[0] = lpf->B[0] * lpf->OriginData[0];    // NUM 分子
    for (i = 1; i <= ORDER; i++) {
        lpf->FilterData[0] = lpf->FilterData[0] + lpf->B[i] * lpf->OriginData[i] - lpf->A[i] * lpf->FilterData[i];
    }
}

最后计算滤波结果也可以写成

lpf->FilterData[0] = (lpf->B[0] * lpf->OriginData[0] + lpf->B[1] * lpf->OriginData[1] + lpf->B[2] * lpf->OriginData[2] - lpf->A[1] * lpf->FilterData[1] - lpf->A[2] * lpf->FilterData[2]) / lpf->A[0];

注意在使用滤波前要先初始化结构体的滤波系数。只需要初始化一次即可。

其中分子系数是成对出现的,可以先合并来提高运算效率。

也可以优化成int型或是用移位器和加法器来代替乘法。

滤波系数的计算:

/**
 * @brief    二阶 IIR 低通滤波
 *            APM 和 PX4 内的计算系数方式
 */
void AccLowpassIIR2Filter_E(void)
{
    const float sample_freq = 500;
    const float _cutoff_freq = 200;
    
    const float fr = sample_freq / _cutoff_freq;
    const float ohm = tanf(M_PI_F / fr);
    const float c = 1.0f + 2.0f * cosf(M_PI_F / 4.0f) * ohm + ohm * ohm;
    
    const float _b0 = ohm * ohm / c;
    const float _b1 = 2.0f * _b0;
    const float _b2 = _b0;
    const float _a1 = 2.0f * (ohm * ohm - 1.0f) / c;
    const float _a2 = (1.0f - 2.0f * cosf(M_PI_F / 4.0f) * ohm +ohm * ohm) / c;
    
//    lFilter[0] = Origin[0] * _b0 + Origin[1] * _b1 + Origin[2] * _b2 - Filter[1] * _a1 - Filter[2] * _a2;
}

滤波系数的计算也可以使用MATLAB仿真的方式计算:

打开 Matlab 在APP中选择 Filter Designer(fdatool)

img

  • 设计方法(Design Method)用于选择IIR滤波器还是FIR滤波器。这里我们选择IIR滤波器,类型选择Butterworth。当然也可以选择其他类型,不同类型的频率响应不同,选择后默认的滤波器结构是直接II型。
  • 响应类型(Response Type)用于选择低通、高通、带通、带阻等类型。这里选择选择低通(Lowpass)。
  • 频率设定(Frequency Specifications)用于设置采样频率以及截止频率,这里填入500以及50,即采样率为500Hz,50Hz以上的频率将被滤除掉。
  • 滤波器阶数(Fiter Order )选择指定滤波器阶数为二阶。
  • 参数设置好后点击设计滤波器(Design filter)按钮,将按要求设计滤波器。
  • 默认生成的IIR滤波器类型是直接Ⅱ型,每个Section是一个二阶滤波器(Direct-Form II, Second-Order Sections)。
  • 在工具栏上点击右数第五个滤波器系数(Filter Coefficients)图标,或菜单栏上选择分析(Analysis)→滤波器系数(Filter Coefficients),即可查看生成的滤波器系数。
  • 最后在菜单栏点击编辑(edit)→转换为二节点(Convert to Single Section),即是我们最终用的滤波器系数。在MATLAB里,IIR公式中的ab又分别叫做分子(Numerator)和分母(Denominator)。
  • 左边实现模型(Realize Model)还可以生成Simulink模型进行仿真。

五阶 FIR 低通滤波

FIR 滤波公式:

$$ y_{(n)}=\sum_{k=0}^{N-1}{k_{(k)}x_{(n-k)}} $$

FIR滤波就是这个个方程。x(n)为输入信号,k(n)为FIR滤波系数,y(n)为经过滤波后的信号;N表示FIR滤波器的抽头数,滤波器阶数为N-1。

C语言实现:

#define ORDER 5

void FIR5Filter(void)
{
    const float H[ORDER + 1] = {...};
    
    Filter[0] = 0;
    for (uint16_t j = 0; j < ORDER + 1; j++) {
         Filter[0] += H[j] * Origin[j];
    }
}

滤波系数的计算:

  • FIR滤波器设计方法有多种,如图4所示,最常用的是窗函数设计法(Window)、等波纹设计法(Equiripple)和最小二乘法 (Least-Squares)等。
  • 设置频率响应的参数,包括采样频率Fs、通带频率Fpass和阻带频率Fstop
  • 可以使用ARM官方DSP库实现FIR和IIR滤波,提高运行速度和效率。

卡尔曼滤波

算法的思想是,根据当前的仪器"测量值" 和上一刻的 "预测量" 和 "误差",计算得到当前的最优量,再预测下一刻的量。卡尔曼滤波器就是一个带有预测功能的低通滤波器。

一维卡尔曼滤波C语言实现:

typedef struct {
    float x;        // state
    float A;        // x(n)=A*x(n-1)+u(n),u(n)~N(0,q)
    float H;        // z(n)=H*x(n)+w(n),w(n)~N(0,r)
    float q;        // process(predict) noise convariance
    float r;        // measure noise(error) convariance
    float p;        // estimated error convariance
    float gain;        // kalman gain
} kalman1_filter_t;


/**
 * @brief            一阶卡尔曼滤波初始化
 * @param[out]        state : 滤波结构数据指针
 * @param[in]        q & r
 */
void kalman1_init(kalman1_filter_t *state, float q, float r)
{
    state->x = 0.0f;
    state->p = 0.0f;
    state->A = 1.0f;
    state->H = 1.0f;
    state->q = q;
    state->r = r;
}

/**
 * @brief            一阶卡尔曼滤波
 * @param[out]        state : 滤波结构数据指针
 * @param[in]        z_measure : 原始数据
 */
float kalman1_filter(kalman1_filter_t *state, float z_measure)
{
    /* Predict */
    // 时间更新(预测): X(k|k-1) = A(k,k-1)*X(k-1|k-1) + B(k)*u(k)
    state->x = state->A * state->x;
    // 更新先验协方差: P(k|k-1) = A(k,k-1)*A(k,k-1)^T*P(k-1|k-1)+Q(k)
    state->p = state->A * state->A * state->p + state->q;

    /* Measurement */
    // 计算卡尔曼增益: K(k) = P(k|k-1)*H(k)^T/(P(k|k-1)*H(k)*H(k)^T + R(k))
    state->gain = state->p * state->H / (state->p * state->H * state->H + state->r);
    // 测量更新(校正): X(k|k) = X(k|k-1)+K(k)*(Z(k)-H(k)*X(k|k-1))
    state->x = state->x + state->gain * (z_measure - state->H * state->x);
    // 更新后验协方差: P(k|k) =(I-K(k)*H(k))*P(k|k-1)
    state->p = (1 - state->gain * state->H) * state->p;

    return state->x;
}
  • 一维卡尔曼滤波全部是标量计算
  • R固定,Q越大,代表越信任侧量值,Q无穷代表只用测量值(Q/R取0无意义)Q/R决定了滤波器的稳态频率响

    应。Q增大和R减小都会导致卡尔曼增益K变大

  • 测量噪声大 R需要设置的较大
  • 模型不准确 Q需要增大
  • 卡尔曼增益的值越大,意味着越相信测量值的输出,从而使得估计值倾向于测量值,收敛速度越快,最优估计值震荡越明显
  • A B H 根据模型来确定
  • P变大也会导致卡尔曼增益变大,但是很快会迭代至稳定值,因此P的初始值只会对前几个周期的估计值有影响。
  • 二维及以上的卡尔曼滤波运算过程涉及到大量的矩阵运算,如果将矩阵运算拆开成基本的四则运算扩展性很差,并且在遇到例如求逆运算的时候比较麻烦。可以使用ARM的DSP库里面的矩阵运算功能
目录
相关文章
|
6天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于生物地理算法的MLP多层感知机优化matlab仿真
本程序基于生物地理算法(BBO)优化MLP多层感知机,通过MATLAB2022A实现随机数据点的趋势预测,并输出优化收敛曲线。BBO模拟物种在地理空间上的迁移、竞争与适应过程,以优化MLP的权重和偏置参数,提升预测性能。完整程序无水印,适用于机器学习和数据预测任务。
|
6天前
|
机器学习/深度学习 数据采集 算法
基于MobileNet深度学习网络的MQAM调制类型识别matlab仿真
本项目基于Matlab2022a实现MQAM调制类型识别,使用MobileNet深度学习网络。完整程序运行效果无水印,核心代码含详细中文注释和操作视频。MQAM调制在无线通信中至关重要,MobileNet以其轻量化、高效性适合资源受限环境。通过数据预处理、网络训练与优化,确保高识别准确率并降低计算复杂度,为频谱监测、信号解调等提供支持。
|
4天前
|
算法 数据安全/隐私保护
泵浦光与斯托克斯光相遇耦合效应的matlab模拟与仿真
本程序使用MATLAB2022A模拟泵浦光与斯托克斯光在非线性光学材料中的耦合效应,基于拉曼散射原理。通过非线性薛定谔方程描述两者相互作用,实现能量转换与放大。核心代码展示了时间与距离上的光强变化,最终生成动态图像展示耦合过程。完整程序无水印,运行结果如附图所示。该仿真有助于理解非线性光学现象及其应用。
|
5天前
|
资源调度 算法 数据可视化
基于IEKF迭代扩展卡尔曼滤波算法的数据跟踪matlab仿真,对比EKF和UKF
本项目基于MATLAB2022A实现IEKF迭代扩展卡尔曼滤波算法的数据跟踪仿真,对比EKF和UKF的性能。通过仿真输出误差收敛曲线和误差协方差收敛曲线,展示三种滤波器的精度差异。核心程序包括数据处理、误差计算及可视化展示。IEKF通过多次迭代线性化过程,增强非线性处理能力;UKF避免线性化,使用sigma点直接处理非线性问题;EKF则通过一次线性化简化处理。
|
6天前
|
算法 数据安全/隐私保护
基于二次规划优化的OFDM系统PAPR抑制算法的matlab仿真
本程序基于二次规划优化的OFDM系统PAPR抑制算法,旨在降低OFDM信号的高峰均功率比(PAPR),以减少射频放大器的非线性失真并提高电源效率。通过MATLAB2022A仿真验证,核心算法通过对原始OFDM信号进行预编码,最小化最大瞬时功率,同时约束信号重构误差,确保数据完整性。完整程序运行后无水印,展示优化后的PAPR性能提升效果。
|
4天前
|
算法 数据安全/隐私保护 计算机视觉
基于sift变换的农田杂草匹配定位算法matlab仿真
本项目基于SIFT算法实现农田杂草精准识别与定位,运行环境为Matlab2022a。完整程序无水印,提供详细中文注释及操作视频。核心步骤包括尺度空间极值检测、关键点定位、方向分配和特征描述符生成。该算法通过特征匹配实现杂草定位,适用于现代农业中的自动化防控。
|
3天前
|
机器学习/深度学习 资源调度 算法
基于入侵野草算法的KNN分类优化matlab仿真
本程序基于入侵野草算法(IWO)优化KNN分类器,通过模拟自然界中野草的扩散与竞争过程,寻找最优特征组合和超参数。核心步骤包括初始化、繁殖、变异和选择,以提升KNN分类效果。程序在MATLAB2022A上运行,展示了优化后的分类性能。该方法适用于高维数据和复杂分类任务,显著提高了分类准确性。
|
7月前
|
安全
【2023高教社杯】D题 圈养湖羊的空间利用率 问题分析、数学模型及MATLAB代码
本文介绍了2023年高教社杯数学建模竞赛D题的圈养湖羊空间利用率问题,包括问题分析、数学模型建立和MATLAB代码实现,旨在优化养殖场的生产计划和空间利用效率。
286 6
【2023高教社杯】D题 圈养湖羊的空间利用率 问题分析、数学模型及MATLAB代码
|
7月前
|
存储 算法 搜索推荐
【2022年华为杯数学建模】B题 方形件组批优化问题 方案及MATLAB代码实现
本文提供了2022年华为杯数学建模竞赛B题的详细方案和MATLAB代码实现,包括方形件组批优化问题和排样优化问题,以及相关数学模型的建立和求解方法。
171 3
【2022年华为杯数学建模】B题 方形件组批优化问题 方案及MATLAB代码实现
|
7月前
|
数据采集 存储 移动开发
【2023五一杯数学建模】 B题 快递需求分析问题 建模方案及MATLAB实现代码
本文介绍了2023年五一杯数学建模竞赛B题的解题方法,详细阐述了如何通过数学建模和MATLAB编程来分析快递需求、预测运输数量、优化运输成本,并估计固定和非固定需求,提供了完整的建模方案和代码实现。
151 0
【2023五一杯数学建模】 B题 快递需求分析问题 建模方案及MATLAB实现代码