C++实现卡尔曼滤波(完整代码)

悄悄话:

        找了半天,发现都没有人发布C++实现的卡尔曼滤波的文章,故我琢磨了一会,自己写一遍,提供给大家参考。

        话不多说,相信大家都是了解过卡尔曼滤波,这里就不多介绍了,直接上公式!

实现:

1.1 前提

        以小车做匀加速直线运动为例,那么便可以写出预测模型和测量模型,便可以知道F、B、H的对应的值。

1.2 代码

#include "matplotlibcpp.h"
#include <Eigen/Core>
#include <Eigen/Dense>
#include <vector>
#include <time.h> 
using namespace std;

namespace plt = matplotlibcpp;

int main()
{
    // 造数据,平面小车以匀速加速度行驶,向前行驶
    double initX = 100;            // 初始位置
    double initAcc = 1.0;          // 初始加速度
    double initVel = 0;            // 初始速度
    vector<double> real_pos, sys_time; // 真实的小车路径(P—t)
    for (double t = 1; t < 40; t += 1)
    {
        real_pos.push_back(initX + initVel * t + 0.5 * initAcc * t * t);
        sys_time.push_back(t);
    }

    // 模拟噪声
    srand((unsigned)time(NULL)); 
    vector<double> detect_pos;
    for (double data : real_pos) {
        detect_pos.push_back((data + (rand() % (101)) - 50));
    }

    // 卡尔曼滤波
    double cutPos = 95, // 观测到当前位置
            cutAcc = 1, // 观察到当前加速度, 高斯分部
            cutVel = 0; // 观测到当前速度
    
    Eigen::Matrix2d F; // 预测模型的F
    Eigen::Vector2d B; // 预测模型的B
    Eigen::Matrix2d H; // 测量模型的H
    Eigen::Matrix2d Q,R; // Q与R
    Eigen::Matrix2d covP; // 协方差
    Eigen::Vector2d initState;
    vector<double> optimi_pos;
    double VarTime = sys_time[1] - sys_time[0];
    H << 1,0,0,1; // 转移方程
    Q << 1e-5,0,0,1e-5; 
    R << 0.001,0,0,0;
    covP << 1,0,0,1; //协方差一开始为1,后续会迭代收敛
    initState << detect_pos[0], 0; // 初始状态值, 第一个为位移、第二个为速度
    F << 1,VarTime,0,1;
    B << 0.5 * VarTime * VarTime, VarTime;
    for (int i=0;i<detect_pos.size() ;i++) {// 迭代
        Eigen::Vector2d z; // 设置观测状态向量,位移、速度
        z << detect_pos[i], i*cutAcc;
        Eigen::Matrix2d I;
        I.setIdentity(); // 矩阵单位化

        // 预测
        initState = F * initState + B * cutAcc; // 估计位移
        covP = F * covP * F.transpose() + Q; // 协方差
        
        // 更新
        Eigen::Matrix2d K = covP * H.transpose() * ( H * covP * H.transpose() + R).inverse(); // 卡尔曼增益
        initState = initState + K*(z - H.transpose() * initState); // 优化后的数据
        covP = (I - K) * covP; // 更新协方差
        optimi_pos.push_back(initState(0,0));
    }


    // 可视化
    plt::xlabel("time");
    plt::ylabel("Position");
    plt::named_plot("real_pos", sys_time, real_pos);
    plt::named_plot("detect_pos", sys_time, detect_pos);
    plt::named_plot("opti_pos", sys_time, optimi_pos);
    plt::title("KalmanFilter");
    plt::legend();
    plt::show();

    return 0;
}

 注:matplotlib的使用,请看文章最后的参考3

1.3 结果

real_pos 为真实位置 、detect_pos为观测位置、opti_pos为优化后的位置。效果很明显呀!

1.4 思考

K权重

        对于卡尔曼滤波来讲,它就是在估计、观测直接进行权重衡量(也就是K值),当K值非常小的时候,优化后的值就基本等于估计值,当K值非常大的时候,那么优化后的值就趋近于观测值!K值非常重要,那么K值又由R、Q来决定大小。R、Q的超参数的设置, 大伙可以看参考1

总结

        卡尔曼滤波是基于叶贝斯公式理论,也就是说当前时刻的状态只与上一个时刻有关,而卡尔曼滤波的前提是基于线性、高斯系统,在线性系统上有很好的优化,但在非线性的系统却表现欠佳,因此人们提出扩展卡尔曼滤波等来解决非线性问题。

参考:

1. 讲述QR的协方差问题:

雷达:卡尔曼滤波器中P,Q,R矩阵的设置(匀速直线运动模型)_卡尔曼滤波状态转移矩阵怎么设_我部的博客-CSDN博客

2. 讲述卡尔曼滤波:

从放弃到精通!卡尔曼滤波从理论到实践~_哔哩哔哩_bilibili

3. 使用matplotlib

GitHub - lava/matplotlib-cpp: Extremely simple yet powerful header-only C++ plotting library built on the popular matplotlib

注:本人实力有限,难免有错误。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.项目代码功能经验证ok,确保稳定可靠运行。欢迎下载使用! 2.主要针对各个计算机相关专业,包括计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师或企业员工使用。 3.项目具有丰富的拓展空间,不仅可作为入门进阶,也可直接作为毕设、课程设计、大作业、初期项目立项演示等用途。 4.当然也鼓励大家基于此进行二次开发。在使用过程中,如有问题或建议,请及时私信沟通。 5.期待你能在项目中找到乐趣和灵感,也欢迎你的分享和反馈! 【资源说明】 基于ROS平台和C++实现卡尔曼滤波算法对IMU的加速度xyz进行滤波处理源码.zip基于ROS平台和C++实现卡尔曼滤波算法对IMU的加速度xyz进行滤波处理源码.zip基于ROS平台和C++实现卡尔曼滤波算法对IMU的加速度xyz进行滤波处理源码.zip基于ROS平台和C++实现卡尔曼滤波算法对IMU的加速度xyz进行滤波处理源码.zip基于ROS平台和C++实现卡尔曼滤波算法对IMU的加速度xyz进行滤波处理源码.zip基于ROS平台和C++实现卡尔曼滤波算法对IMU的加速度xyz进行滤波处理源码.zip基于ROS平台和C++实现卡尔曼滤波算法对IMU的加速度xyz进行滤波处理源码.zip基于ROS平台和C++实现卡尔曼滤波算法对IMU的加速度xyz进行滤波处理源码.zip基于ROS平台和C++实现卡尔曼滤波算法对IMU的加速度xyz进行滤波处理源码.zip基于ROS平台和C++实现卡尔曼滤波算法对IMU的加速度xyz进行滤波处理源码.zip基于ROS平台和C++实现卡尔曼滤波算法对IMU的加速度xyz进行滤波处理源码.zip
卡尔曼滤波是一种用于状态估计的优秀方法,其可以用于跟踪目标的位置、速度和加速度等。在C语言实现卡尔曼滤波跟踪,可以按照以下步骤来进行: 1. 定义状态向量和观测向量:根据具体的问题,定义状态向量和观测向量的维度。状态向量包括目标的位置、速度等状态变量,观测向量包括可以直接观测到的目标信息。 2. 初始化卡尔曼滤波器:定义初始状态向量、初始协方差矩阵和过程噪声协方差矩阵等参数。 3. 进行预测步骤:利用系统模型和状态转移矩阵进行状态预测,同时更新协方差矩阵。 4. 进行观测步骤:利用观测模型和观测矩阵将预测值映射到观测空间,同时计算残差和卡尔曼增益。 5. 进行修正步骤:根据计算得到的卡尔曼增益,对预测值进行修正,并更新状态向量和协方差矩阵。 6. 重复预测、观测和修正步骤:根据实际情况,不断重复进行预测、观测和修正步骤,以实现目标的跟踪。 在C语言中,可以利用矩阵运算库或者自行实现矩阵相关的操作,如矩阵相乘、矩阵加减等。同时,需要定义相关的函数来实现卡尔曼滤波算法中的各个步骤。在实际应用中,还需要根据具体问题进行参数调整和优化,以达到更好的跟踪效果。 综上所述,通过定义状态向量、观测向量,初始化卡尔曼滤波器,并按照预测、观测和修正的步骤进行迭代更新,就可以在C语言实现卡尔曼滤波跟踪。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值