对IMU数据进行卡尔曼滤波

2023-05-16

 我们要使用IMU数据,必须对数据进行预处理,卡尔曼滤波就是很好的方式。

1.卡尔曼滤波

卡尔曼滤波(Kalman filtering)是一种利用线性系统状态方程,通过系统输入输出观测数据,对系统状态进行最优估计的算法。由于观测数据中包括系统中的噪声和干扰的影响,所以最优估计也可看作是滤波过程。

其原理可以参考b站的视频:

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

2.代码实现

#include <ros/ros.h>
#include <fstream>
#include "sensor_msgs/Imu.h"
#include "Eigen/Dense"

double a_x; //x方向的加速度
double a_y; //y方向的加速度
double a_z; //z方向的加速度

Eigen::MatrixXd X = Eigen::MatrixXd(3,1); //创建一个3*1矩阵

using namespace std;

class kalman_filter
{
private:
    Eigen::MatrixXd A; //系统状态矩阵
    Eigen::MatrixXd P; //协方差
    Eigen::MatrixXd Q; //测量过程噪音(预测)
    Eigen::MatrixXd R; //真实传感器噪音
    Eigen::MatrixXd H; //测量矩阵

    bool isinitized = false; //判断是否进行了初始化

public:
    kalman_filter();
    Eigen::MatrixXd predictAndupdate( Eigen::MatrixXd x,Eigen::MatrixXd z);
    ~kalman_filter();
};

Eigen::MatrixXd kalman_filter::predictAndupdate(Eigen::MatrixXd x,Eigen::MatrixXd z)
{
    if(!isinitized)
    {
        P = Eigen::MatrixXd(3,3); //协方差 3*3矩阵
        P<< 1,0,0,
            0,1,0,
            0,0,1; //协方差的初始化
        isinitized=true;
    }
    x = A*x; // 状态一步预测方程
    P = A*P*(A.transpose())+Q; //一步预测协方差阵
    Eigen::MatrixXd  K = P*(H.transpose())*((H*P*(H.transpose())+R).inverse()); //kalman增益
    x = x+K*(z-H*x); //状态更新:
    int x_size = x.size();
    Eigen::MatrixXd I = Eigen::MatrixXd::Identity(x_size, x_size);
    P = (I-K*H)*P; // 协方差阵更新:
    return x;
}

kalman_filter::kalman_filter()
{
//参数初始化设置
    A=Eigen::MatrixXd(3,3); //系统状态矩阵
    A<< 1,0,0,
        0,1,0,
        0,0,1;
    H=Eigen::MatrixXd(3,3); //测量矩阵
    H<< 1,0,0,
        0,1,0,
        0,0,1;
    Q=Eigen::MatrixXd(3,3); //(预测)过程噪音
    Q<< 0.03,0,0,
        0,0.03,0,
        0,0,0.03;
    R=Eigen::MatrixXd(3,3); //真实传感器噪音
    R<<3.65,0,0,            //R太大,卡尔曼滤波响应会变慢
       0,3.65,0,
       0,0,3.65;     
}

kalman_filter::~kalman_filter(){}
//订阅发布者主要订阅imu信息并调用前面的卡尔曼滤波处理后再发布信息
class SubscribeAndPublish
{
public:
    SubscribeAndPublish()
    {
        imu_info_sub = n.subscribe("/imu/data_raw", 10, &SubscribeAndPublish::imuInfoCallback,this);
        IMU_kalman_pub = n.advertise<sensor_msgs::Imu>("/imu_kalman", 10);
    }
    void imuInfoCallback(const sensor_msgs::Imu::ConstPtr& msg)
    {
        // 第一次将接收到的消息打印出来
        if(first)
        {
            // 三个方向的线性加速度
            double a_x_m = msg->linear_acceleration.x;
            double a_y_m = msg->linear_acceleration.y;
            double a_z_m = msg->linear_acceleration.z;
            // 用X存第一帧三个方向的线性加速度
            X<<a_x_m,a_y_m,a_z_m;
            // 第一次不用卡尔曼滤波,直接发布出去,
            sensor_msgs::Imu M;
            M.linear_acceleration.x = a_x_m;
            M.linear_acceleration.y = a_y_m;
            M.linear_acceleration.z = a_z_m;
            M.header = msg->header;
            IMU_kalman_pub.publish(M);
            first=false;
            cout<< "first farm"<< endl;
        }
        else
        {
            double a_x_m = msg->linear_acceleration.x;
            double a_y_m = msg->linear_acceleration.y;
            double a_z_m = msg->linear_acceleration.z;
            Eigen::MatrixXd z;
            z = Eigen::MatrixXd(3,1);
            z<<a_x_m,a_y_m,a_z_m;
            kalman_filter kf;   //kalman_filter创建的对象kf,之后就进行卡尔曼滤波
            Eigen::MatrixXd x_new = kf.predictAndupdate(X,z);//z当前时刻的量测值,X
            X = z;

            // 整理成适合话题发布的形式
            a_x = x_new(0,0);
            a_y = x_new(1,0);
            a_z = x_new(2,0);
            sensor_msgs::Imu M;
            M.linear_acceleration.x = a_x;
            M.linear_acceleration.y = a_y;
            M.linear_acceleration.z = a_z;
            M.header = msg->header;
            cout<< "linear_acceleration.x = " << a_x <<"linear_acceleration.y = " << a_y <<"linear_acceleration.z = " << a_z << endl;
            IMU_kalman_pub.publish(M);
        }
    }
private:
    ros::NodeHandle n;
    ros::Publisher IMU_kalman_pub;
    ros::Subscriber imu_info_sub;
    bool first=true;
};
//接收IMU话题,通过卡尔曼滤波参数进行数据处理,然后发布处理后的数据作为一个话题。
int main(int argc, char **argv)
{
    ros::init(argc, argv, "subscribe_and_publish");

    SubscribeAndPublish SAPObject;

    ros::spin();
    return 0;
}

获得发布后的数据后,需要对于数据作图处理,ros中的作图工具不是很好,可以通过录制bag包的方式,再将.bag文件转为.csv的格式通过命令:rostopic echo -b <BAGFILE> -p <TOPIC> > <output>.csv

该代码用的最基础卡尔曼滤波算法,且没有进行调参。MATLAB/simulink中自带有封装好了的卡尔曼滤波代码,通过ros/tool工具可以直接接收IMU的信息,用MATLAB内置滤波器实现滤波。

3.matlab内置滤波器

将主机和车载ros系统连接在同一个局域网下,用ip地址对二者进行连接。可以通过MATLAB自带的demo,选取需要发布的信息。

下载MATLAB-control库,找到建立好的卡尔曼滤波器的simulink模块,将输入端与imu接口连接,后面的可视化模块就能显示滤波后的效果。

模块和效果图如下:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对IMU数据进行卡尔曼滤波 的相关文章

  • 自制Pixracer自定义IMU传感器飞控

    自制Pixracer自定义IMU传感器四层通孔板飞控 xff0c 板载DC降压 xff1a 飞行演示视频如下链接 xff1a https v youku com v show id XNDgxMjUzODc2MA 61 61 html
  • ROS消息sensor_msgs::Imu数据格式

    ubuntu下打开终端输入 rosmsg show sensor msgs Imu 查看sensor msgs Imu的数据格式 std msgs Header header uint32 seq time stamp 时间戳 string
  • VIO标定工具kalibr和imu_utils的使用

    0 参考资料 Kalibr进行IMU 43 相机的标定 xff1a 这个步骤写的非常好 xff0c 应该是目前看到的最符合的步骤了 使用ROS功能包标定相机内参 Kalibr标定camera IMU详细步骤 xff1a 这篇博客里给出了它的
  • 自动驾驶传感器评估 ——IMU惯性测量单元

    自动驾驶传感器评估 IMU惯性测量单元 前言 对于自动驾驶来说 xff0c 高精度定位必不可少 为了让自动驾驶系统更高频率的获取定位信息 xff0c 就必须引入更高频率的传感器 xff0c 这时就体现出了惯性测量单元 xff08 Inert
  • IMU的轨迹解算和航迹显示

    基于ros操作系统 xff0c 调用IMU数据包 xff0c 利用数据解算小车运动的轨迹 xff0c 并在rviz中实现轨迹的可视化 其中IMU四元数对于位移速度和加速度的转换 轨迹解算和换机显示的代码 xff1a IMU航迹推算 incl
  • VINS slam , imu fusion

    VINS 基本介绍 VINS Mono 和 VINS Mobile 是香港科技大学沈劭劼老师开源的单目视觉惯导 SLAM 方案 2017年发表于 IEEE Transactions on Robotics 另外 xff0c VINS 的最新
  • Kalibr 之 Camera-IMU 标定 (总结)

    Overview 欢迎访问 持续更新 xff1a https cgabc xyz posts db22c2e6 ethz asl kalibr is a toolbox that solves the following calibrati
  • ORB-SLAM3测试:数据集(单目/双目/imu)& ROS (D435 T265)

    ORB SLAM3环境配置 安装各种依赖库 orb slam3非常友好 xff0c 不用自己下载各种依赖库 xff0c 因为他们全部在thirdParty文件夹中 xff0c 编译orb slam3的同时会自动编译各种依赖库 Eigen3
  • 使用IMU进行状态估计及进阶

    文章目录 前言基本思想一 姿态估计1 1 通过6轴IMU来进行姿态估计的入门级方法1 1 1 通过加速度计计算姿态1 1 2 引入陀螺仪来得到更好的姿态估计 1 2 四元数解算姿态角解析 二 姿态估算与滤波的关系2 1 状态方程和观测方程2
  • 传统定位方法简介--------里程计、IMU惯性传感器以及光电编码器等

    移动机器人最初是通过自身携带的内部传感器基于航迹推算的方法进行定位 xff0c 后来进一步发展到通过各种外部传感器对环境特征进行观测从而计算出移动机器人相对于整个环境的位姿 目前为止 xff0c 形成了基于多传感器信息融合的定位方法 现有移
  • 在ROS下Intel RealSense D435i 驱动的安装,避免踩坑,避免缺少imu话题等各种问题(适用于D400系列、SR300和T265跟踪模块等)

    版权声明 本文为博主原创文章 未经博主允许不得转载 https blog csdn net AnChenliang 1002 article details 109454465 目录 背景 方法1 使用apt安装 不建议使用此方法 了解一下
  • 飞控IMU数据进阶处理(FFT,滤波器)

    前面的文章 xff08 知乎专栏 https zhuanlan zhihu com c 60591778 xff09 曾简单讲过IMU数据 xff08 陀螺仪 加速度数据 xff09 的校准以及一阶低通滤波 本文在此基础上更进一步讲一下数据
  • 再谈IMU数据处理(滤波器)

    本文开始前 xff0c 先回答一个问题 上一篇文章最后提到了卡尔曼滤波器用来做一维数据的数字滤波处理 xff0c 最终的实验结果说 xff1a 该模型下的卡尔曼滤波处理与二阶IIR低通滤波处理效果几乎一致 有网友指出是错误的 xff0c 卡
  • 49、OAK测试官方的IMU模块和SpatialLocationCalculator节点

    基本思想 xff1a 不太懂IMU是干嘛的 xff0c 不像图像那么容易可视化 xff0c 参考官方demo的 xff0c 记录一下 xff0c 后续这篇需要补充 xff0c 参考的IMU的介绍 xff0c 原理不懂 xff0c 先占个坑
  • vins中imu融合_VINS代码解读

    VINS estimator 摘抄 我们初始化的原因是单目惯性紧耦合系统是一个非线性程度很高的系统 xff0c 首先单目是无法获得空间中的绝对尺度 xff0c 而IMU又必然存在偏置 xff0c 在后面进行求解的时候还需要用到重力加速度 包
  • 惯导(IMU)的使用

    提示 xff1a 和上一篇关于利用imu计算位移的文章相比 xff0c 这篇我对imu的理解应该是更加深刻了 目录 前言 一 imu调试 二 利用IMU计算旋转 1 引入库 2 读入数据 总结 前言 这次使用的imu和上一篇文章中所提到的i
  • Ardupilot IMU恒温控制代码学习

    目录 文章目录 目录 摘要 第一章原理图学习 第二章恒温代码学习 1 目标温度怎么设置 摘要 本节主要学习ardupilot的IMU恒温控制代码 采用的飞控是pixhawk v5 欢迎一起交流学习 第一章原理图学习
  • 【深蓝学院】手写VIO第2章--IMU传感器--笔记

    0 内容 1 旋转运动学 角速度的推导 xff1a 左 61 omega wedge xff0c 而
  • IMU背包对动物行为影响测试

    动物行为是一种可观察和可测量的指标 轻量化和低成本的传感器技术的先进发展为研究人员提供了以最小干预来跨越空间和时间跟踪动物的机会 特别是对于家禽业来说 已经从传统的笼养系统转变为无笼养系统 许多技术可用于检测大群鸡的行为 活动和位置 为了有
  • 四元素与旋转矩阵

    如何描述三维空间中刚体的旋转 是个有趣的问题 具体地说 就是刚体上的任意一个点P x y z 围绕过原点的轴 i j k 旋转 求旋转后的点P x y z 旋转矩阵 旋转矩阵乘以点P的齐次坐标 得到旋转后的点P 因此旋转矩阵可以描述旋转 x

随机推荐

  • 深拷贝与浅拷贝

    深拷贝和浅拷贝是指在计算机编程中 xff0c 当需要复制一个对象时 xff0c 复制出来的副本与原对象之间的关系的不同 浅拷贝是指在复制对象时 xff0c 只复制了对象本身的值 xff0c 而没有复制对象包含的子对象 也就是说 xff0c
  • C++三种继承方式的区别

    访问方式分为两种 xff0c 一种是类内访问 xff0c 还有一种是类外访问 xff1b 所谓类内访问 xff0c 就是类内的函数中是使用了属性 xff1b 类外访问 xff0c 就是新建一个实例对象 xff0c 并访问这个对象的属性 xf
  • python爬虫之数据解析(BeautifulSoup)

    BeautifulSoup也是python爬虫常用的一种数据解析方法 xff0c 主要就两步 1 实例化一个Beautifulsoup对象 xff0c 平且将页面源码数据加载到该对象中 2 通过调用Beautifulsoup对象中相关的属性
  • 蓝桥杯嵌入式第十四届省赛题目解析

    前几天刚刚参加完第十四届的省赛 xff0c 这届题目比我想象中的要难 xff0c 其实想一想这也是应该的 xff0c 以前的知识点都被摸透了 xff0c 也是需要加入新的知识点了 xff0c 但是我还是想说能不能别在我参加的时候加大题目难度
  • dockerfile构建

    2 简答题 编写Dockerfile制作镜像 xff0c 生成镜像名为my build Nginx2 首先创建目录dockerfile nginx2 xff0c 保存Dockerfile文件 具体要求如下 xff1a 1 基于镜像cento
  • 安装虚拟机之后怎么配置虚拟环境、深度学习、深度强化学习环境安装

    安装步骤目录 一 配置虚拟机VMware安装包 amp Ubuntu的光盘映像文件 xff1a VMware安装Ubuntu安装 二 进入虚拟机配置环境深度 xff08 强化 xff09 学习环境的配置1 得知系统所自带python版本 x
  • 力扣-刷题方法总结(测试文章)

    知乎方面收集到的资料 xff08 非原创 xff0c 题主只是对其进行统一的整理 xff0c 方便后续查看 xff09 算法训练讲究循序渐进 xff1a 1 先从简单开始 xff0c 然后过度到中等 xff0c 再过渡到困难的进程 2 如何
  • 文件分隔符 ‘/‘(斜杠) 和 ‘\‘(反斜杠) 的使用

    前言 在学习时 xff0c 总会用到 Windows 和 Linux xff0c 输入路径时 xff0c 文件路径分隔符有时用 xff08 斜杠 xff09 xff0c 有时用 xff08 反斜杠 xff09 xff0c 属实不好区分 xf
  • VMware虚拟机安装Win11教程(解决常见报错)

    前言 今天闲来无事 xff0c 就想着装一下最新版的win11玩一下 xff0c 然后来来去去还是折腾了一些时间 xff0c 有遇到一些错误不过最好都找到了解决办法 xff0c 下面我就分享一下VMware虚拟机安装win11的详细步骤 V
  • vue打包后neditor不显示了

    原因是vue和vue template compiler 1 两者的版本不一致 xff1b 2 两者的版本低了 xff1b 例如 xff1a 我出问题的版本是 34 vue 34 34 2 5 10 34 34 vue template c
  • 【Docker常用命令】

    Docker常用命令 xff08 学习笔记 xff09 一 Docker基础命令二 Docker镜像命令三 Docker容器命令3 1 运行容器3 2 退出容器3 3 查看容器进程 xff0c 日志3 4 再次进入容器3 5 容器启停3 6
  • OpenCV学习——ArUco模块

    前提介绍 xff1a ArUco模块是OpenCV的contrib拓展库中一个模块 xff0c 需要安装OpenCV的 contrib拓展库 才能正常使用 ArUco标记 xff1a ArUco 标记是由 宽黑色边框 和 确定其标识符 xf
  • 【Vue】报错:Avoid mutating a prop directly since the value will be overwritten whenever the parent

    当我们直接改变父组件的 props 值是会报以下警告 xff1a Vue warn Avoid mutating a prop directly since the value will be overwritten whenever th
  • 深蓝学院-机器人运动规划学习笔记-第一章

    第一课 移动机器人运动规划 Motion planning for mobile robots IntroductionCourse outlineTypical planning methods overviewMap represent
  • opencv+python实战日记 入门篇(八)色块识别

    色块识别 import cv2 import numpy as np frameWidth 61 640 frameHeight 61 480 cap 61 cv2 VideoCapture 0 获取摄像头 cap set 3 640 ca
  • highway_env中自定义环境

    前言 highway env中集成了很多强化学习或者控制算法测试的驾驶环境 xff0c 但很多时候我们需要依据需求对环境进行自定义 xff0c 这里给出了自定义环境的一些步骤 xff0c 主要是基于gym 61 61 0 26版本 创建步骤
  • 深度相机和激光雷达的融合标定(Autoware)

    深度相机和激光雷达是智能汽车上常用的传感器 但深度相机具有特征难以提取 xff0c 容易受到视角影响 激光雷达存在数据不够直观且容易被吸收 xff0c 从而丢失信息 因此在自动驾驶领域 xff0c 需要对于不同传感器做数据的融合和传感器的标
  • 基于OpenCv和ROS的图像灰度化处理

    直接调用opencv灰度化函数 xff0c 对于本地图像进行处理 实现C 43 43 代码如下 xff1a 图像灰度化 include lt iostream gt cv cvtColor头文件 include lt opencv2 img
  • IMU的轨迹解算和航迹显示

    基于ros操作系统 xff0c 调用IMU数据包 xff0c 利用数据解算小车运动的轨迹 xff0c 并在rviz中实现轨迹的可视化 其中IMU四元数对于位移速度和加速度的转换 轨迹解算和换机显示的代码 xff1a IMU航迹推算 incl
  • 对IMU数据进行卡尔曼滤波

    我们要使用IMU数据 xff0c 必须对数据进行预处理 xff0c 卡尔曼滤波就是很好的方式 1 卡尔曼滤波 卡尔曼滤波 xff08 Kalman filtering xff09 是一种利用线性系统状态方程 xff0c 通过系统输入输出观测