VIO第2讲:IMU标定实验

VIO第2讲:IMU标定实验

文章目录

  • VIO第2讲:IMU标定实验
  • 5 IMU标定实验
    • 5.1 仿真数据产生
      • 5.1.1 c++代码分析
      • 5.1.2 生成ros包数据
    • 5.2 Allan方差实验(港科大imu_utils)
      • 5.2.1 安装
      • 5.2.2 运行
    • 5.3 Allan方差实验(matlab代码kalibr_allan)
      • 5.3.1 安装
      • 5.3.2 bag转mat
      • 5.3.3 运行标定

5 IMU标定实验

5.1 仿真数据产生

参考代码

5.1.1 c++代码分析

在这里插入图片描述

下面代码确实是高斯噪声连续到离散除以sqr(δt),偏差随机游走则是乘以sqr(δt)

void IMU::addIMUnoise(MotionData& data)
{
    std::random_device rd;
    std::default_random_engine generator_(rd());
    std::normal_distribution<double> noise(0.0, 1.0);   // 均值为0,标准差为1的正态分布

    // 将噪声添加到原始的陀螺仪数据
    Eigen::Vector3d noise_gyro(noise(generator_),noise(generator_),noise(generator_));
    Eigen::Matrix3d gyro_sqrt_cov = param_.gyro_noise_sigma * Eigen::Matrix3d::Identity();
    // w = w + cov(3*3)*noise_gyro(3*1)/sqrt(t) + bg
    data.imu_gyro = data.imu_gyro + gyro_sqrt_cov * noise_gyro / sqrt( param_.imu_timestep ) + gyro_bias_;

    Eigen::Vector3d noise_acc(noise(generator_),noise(generator_),noise(generator_));
    Eigen::Matrix3d acc_sqrt_cov = param_.acc_noise_sigma * Eigen::Matrix3d::Identity();
    data.imu_acc = data.imu_acc + acc_sqrt_cov * noise_acc / sqrt( param_.imu_timestep ) + acc_bias_;

    // gyro_bias update
    Eigen::Vector3d noise_gyro_bias(noise(generator_),noise(generator_),noise(generator_));
    gyro_bias_ += param_.gyro_bias_sigma * sqrt(param_.imu_timestep ) * noise_gyro_bias;
    data.imu_gyro_bias = gyro_bias_;

    // acc_bias update
    Eigen::Vector3d noise_acc_bias(noise(generator_),noise(generator_),noise(generator_));
    acc_bias_ += param_.acc_bias_sigma * sqrt(param_.imu_timestep ) * noise_acc_bias;
    data.imu_acc_bias = acc_bias_;

}

运动模型:利用p求出v,a;通过欧拉角的导数求出角速度w,根据时间变量t来产生数据。

MotionData IMU::MotionModel(double t)
{

    MotionData data;
    // param
    float ellipse_x = 15;
    float ellipse_y = 20;
    float z = 1;           // z轴做sin运动
    float K1 = 10;          // z轴的正弦频率是x,y的k1倍
    float K = M_PI/ 10;    // 20 * K = 2pi   由于我们采取的是时间是20s, 系数K控制yaw正好旋转一圈,运动一周

    // translation 
    // twb:  body frame in world frame
    // p v a
    Eigen::Vector3d position( ellipse_x * cos( K * t) + 5, ellipse_y * sin( K * t) + 5,  z * sin( K1 * K * t ) + 5);
    Eigen::Vector3d dp(- K * ellipse_x * sin(K*t),  K * ellipse_y * cos(K*t), z*K1*K * cos(K1 * K * t));              // position导数 in world frame
    double K2 = K*K;
    Eigen::Vector3d ddp( -K2 * ellipse_x * cos(K*t),  -K2 * ellipse_y * sin(K*t), -z*K1*K1*K2 * sin(K1 * K * t));     // position二阶导数

    // Rotation
    double k_roll = 0.1;
    double k_pitch = 0.2;
    Eigen::Vector3d eulerAngles(k_roll * cos(t) , k_pitch * sin(t) , K*t );   // roll ~ [-0.2, 0.2], pitch ~ [-0.3, 0.3], yaw ~ [0,2pi]
    Eigen::Vector3d eulerAnglesRates(-k_roll * sin(t) , k_pitch * cos(t) , K);      // euler angles 的导数

//    Eigen::Vector3d eulerAngles(0.0,0.0, K*t );   // roll ~ 0, pitch ~ 0, yaw ~ [0,2pi]
//    Eigen::Vector3d eulerAnglesRates(0.,0. , K);      // euler angles 的导数
    // 角速度是通过欧拉角求导来得到的?
    Eigen::Matrix3d Rwb = euler2Rotation(eulerAngles);         // body frame to world frame
    Eigen::Vector3d imu_gyro = eulerRates2bodyRates(eulerAngles) * eulerAnglesRates;   //  euler rates trans to body gyro

    Eigen::Vector3d gn (0,0,-9.81);                                   //  gravity in navigation frame(ENU)   ENU (0,0,-9.81)  NED(0,0,9,81)
    Eigen::Vector3d imu_acc = Rwb.transpose() * ( ddp -  gn );  //  Rbw * Rwn * gn = gs

    data.imu_gyro = imu_gyro;
    data.imu_acc = imu_acc;
    data.Rwb = Rwb;
    data.twb = position;
    data.imu_velocity = dp;
    data.timestamp = t;
    return data;

}

5.1.2 生成ros包数据

  GitHub同时提供了ros代码,我们直接用这套代码生成相应的imu.bag

// ros还是cpp代码种原始设置的标准差都是下面数据

	// noise----离散时间噪声标准差
    double gyro_bias_sigma = 1.0e-5;    // δbg rad/s
    double acc_bias_sigma = 0.0001;     // δba m/(s^2)

    double gyro_noise_sigma = 0.015;    // rad/s     δg
    double acc_noise_sigma = 0.019;      // m/(s^2)  δa

  这里先直接给出利用imu_utils进行的一个标定结果,对于高斯噪声,数量级一致,但对于偏置随机游走,数量级差了10~100!总而言之,这种标定方法对于高斯白噪声即角度/速度随机游走的标定结果是可信的,但是对于偏置还是没有那么可信!

%YAML:1.0
---
type: IMU
name: vio_test
Gyr:
   unit: " rad/s"
   avg-axis:
      gyr_n: 2.1017740504505478e-01	
      gyr_w: 1.1046695141140115e-03
   x-axis:
      gyr_n: 2.0373831670509726e-01
      gyr_w: 8.5917637284818333e-04
   y-axis:
      gyr_n: 2.0848823537157685e-01
      gyr_w: 1.1543541527689969e-03
   z-axis:
      gyr_n: 2.1830566305849022e-01
      gyr_w: 1.3004780167248545e-03
Acc:
   unit: " m/s^2"
   avg-axis:
      acc_n: 2.6608701268913315e-01
      acc_w: 5.0312842533421255e-03
   x-axis:
      acc_n: 2.6703857869563274e-01
      acc_w: 5.4894453768553463e-03
   y-axis:
      acc_n: 2.6561748859645246e-01
      acc_w: 5.1153714824778724e-03
   z-axis:
      acc_n: 2.6560497077531420e-01
      acc_w: 4.4890359006931569e-03

5.2 Allan方差实验(港科大imu_utils)

Github

5.2.1 安装

sudo apt-get install libdw-dev

报错1

  创建一个ROS空间,把两个ROS包放进去,然后catkin_make.如果这样做的话,大概率会报下面的错误。本质就是imu_utils依赖于code_utils这个包,但实际上我们之前没有按照那个包,就会报下面的错,其实可以在catkin_make之前显示的告诉它路径,或者就是先编译成功code_utils,再编译imu_utils

-- +++ processing catkin package: 'imu_utils'
-- ==> add_subdirectory(imu_utils)
-- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy
-- Could NOT find code_utils (missing: code_utils_DIR)
-- Could not find the required component 'code_utils'. The following CMake error indicates that you either need to install the package with the same name or change your environment so that it can be found.
CMake Error at /opt/ros/noetic/share/catkin/cmake/catkinConfig.cmake:83 (find_package):
  Could not find a package configuration file provided by "code_utils" with
  any of the following names:

    code_utilsConfig.cmake
    code_utils-config.cmake

  Add the installation prefix of "code_utils" to CMAKE_PREFIX_PATH or set
  "code_utils_DIR" to a directory containing one of the above files.  If
  "code_utils" provides a separate development package or SDK, be sure it has
  been installed.
Call Stack (most recent call first):
  imu_utils/CMakeLists.txt:13 (find_package)


-- Configuring incomplete, errors occurred!
See also "/home/pj/pj/vio_with_only_eigen/imu_allan/build/CMakeFiles/CMakeOutput.log".
See also "/home/pj/pj/vio_with_only_eigen/imu_allan/build/CMakeFiles/CMakeError.log".
Invoking "cmake" failed

  编译出现的报错code_utils

报错2

  报错显示没有那个头文件,查看之后发现是有的,说名再CMakeLists.txt中没有显示的引入头文件,我们只需要添加即可。或者把#include "backward.hpp"改成#include "code_utils/backward.hpp"

[ 30%] Building CXX object code_utils/CMakeFiles/sumpixel_test.dir/src/sumpixel_test.cpp.o
/home/pj/pj/vio_with_only_eigen/imu_allan/src/code_utils/src/sumpixel_test.cpp:2:10: fatal error: backward.hpp: No such file or directory
    2 | #include "backward.hpp"
      |          ^~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [code_utils/CMakeFiles/sumpixel_test.dir/build.make:63: code_utils/CMakeFiles/sumpixel_test.dir/src/sumpixel_test.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:480: code_utils/CMakeFiles/sumpixel_test.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....

include_directories(
    ${catkin_INCLUDE_DIRS}
    ${CMAKE_SOURCE_DIR}/code_utils/include/code_utils	# 添加这个,这样就能找到了
    ${EIGEN3_INCLUDE_DIR}
     )

报错3

  报错显示没找到glog.so动态库文件,但是这个环境前两天刚装的,所以必然不是这个问题

make[2]: *** No rule to make target '/usr/lib/x86_64-linux-gnu/libglog.so', needed by '/home/pj/pj/vio_with_only_eigen/imu_allan/devel/lib/libpnp.so'.  Stop.
make[2]: *** Waiting for unfinished jobs....
[ 92%] Building CXX object code_utils/CMakeFiles/pnp.dir/src/cv_utils/pnp/nonlinearpnp.cpp.o
make[1]: *** [CMakeFiles/Makefile2:804: code_utils/CMakeFiles/pnp.dir/all] Error 2
make: *** [Makefile:141: all] Error 2
Invoking "make -j2 -l2" failed

  locate下发现,库文件存在,但上面找的不是这个

pj@pj:~$ locate glog | grep so
...
/usr/lib/x86_64-linux-gnu/libglog.so.0
/usr/lib/x86_64-linux-gnu/libglog.so.0.0.0

  libglog.solibglog.so.0,所以我们把这两个软链接起来就能解决问题

sudo ln -s /usr/lib/x86_64-linux-gnu/libglog.so.0 /usr/lib/x86_64-linux-gnu/libglog.so

  然后编译imu_utils就没有报错了

5.2.2 运行

要么就是自己录个数据,至少2个小时以上

  • 播放rosbag数据
 rosbag play -r 200 imu_A3.bag
  • 启动对应得launch文件,注意修改!
roslaunch imu_utils A3.launch	# 换成自己的launch文件
<launch>
    <node pkg="imu_utils" type="imu_an" name="imu_an" output="screen">
    
    <!--改成自己IMU的话题-->
    <param name="imu_topic" type="string" value= "/djiros/imu"/>
    
    <!--这个和最后保存的文件名有关,最后的文件名为A3_imu_param.yaml-->
    <param name="imu_name" type="string" value= "A3"/>
    
    <!--标定结果存放的文件目录-->
    <param name="data_save_path" type="string" value= "$(find imu_utils)/data_my/"/>
    
    <!--修改标定时间,单位是分钟,需要根据数据包的时长来调整-->
    <param name="max_time_min" type="int" value= "120"/>
    <param name="max_cluster" type="int" value= "100"/>
    </node>
</launch>
  • 结果

  会生成很多文件,最终计算结果再yaml文件中,可以利用脚本文件下的matlab函数去画出角速度和加速度的Allan曲线。

在这里插入图片描述

type: IMU
name: A3
Gyr:
   unit: " rad/s"
   avg-axis:		
      gyr_n: 1.0351286977809465e-04		# δg
      gyr_w: 2.9438676109223402e-05		# δbg
   x-axis:
      gyr_n: 1.0312669892959053e-04
      gyr_w: 3.3765827874234673e-05
   y-axis:
      gyr_n: 1.0787155789128671e-04
      gyr_w: 3.1970693666470835e-05
   z-axis:
      gyr_n: 9.9540352513406743e-05
      gyr_w: 2.2579506786964707e-05
Acc:
   unit: " m/s^2"
   avg-axis:
      acc_n: 1.3985049290745563e-03
      acc_w: 6.3249251509920116e-04
   x-axis:
      acc_n: 1.1687799474421937e-03
      acc_w: 5.3044554054317266e-04
   y-axis:
      acc_n: 1.2050535351630543e-03
      acc_w: 6.0281218607825414e-04
   z-axis:
      acc_n: 1.8216813046184213e-03
      acc_w: 7.6421981867617645e-04

github给出的—标定是离散参数
在这里插入图片描述

  • 绘图结果—script—这下面的图像不是A3,是生成的那个仿真数据图像!

角速度allan曲线

在这里插入图片描述

加速度allan曲线

在这里插入图片描述

​ 其实也能看出来,关于角速度偏置随机游走肯定是误差最大的!

5.3 Allan方差实验(matlab代码kalibr_allan)

5.3.1 安装

  GitHub,主要是装那个ros转换包,matlab直接打开就行

mkdir -p datacen/src
catkin_make

5.3.2 bag转mat

  使用命令 rosrun bagconvert bagconvert xx.bag/imu0,该命令的解释是rosrun bagconvert bagconvert [bag名字] [topic名字],这里如果topic输入不正确,可能会得到一个177kb的错误mat文件

在这里插入图片描述

在这里插入图片描述

5.3.3 运行标定

  • 修改SCRIPT_allan_matparallel.m
% Our bag information
%mat_path = '../data/imu_mtig700.mat';
%mat_path = '../data/imu_tango.mat';
% 改成上面bag转mat文件的路径,可以在matlab命令行pwd,像Ubuntu一样
mat_path = 'I:\kalibr_allan-master\data\imu.mat';

  然后运行这个文件,根据电脑的性能,运行时间长短不一,最终会在你的mat文件下生成一个resultmat文件

  • 修改SCRIPT_process_results.m
titlestr = 'ADIS16448 VI-Sensor';
% 修改路径
mat_path = 'I:\kalibr_allan-master\data\results_20240106T181017.mat';

结果展示

加速度allan曲线

在这里插入图片描述

角速度allan曲线:目前不知道哪里有问题,导致对应偏置随机游走无法计算!

在这里插入图片描述

上面生成的数据对应方差!

	// noise----离散时间噪声标准差
    double gyro_bias_sigma = 1.0e-5;    // δbg rad/s
    double acc_bias_sigma = 0.0001;     // δba m/(s^2)

    double gyro_noise_sigma = 0.015;    // rad/s     δg
    double acc_noise_sigma = 0.019;      // m/(s^2)  δa

其实可以看出,这种方差实验结果要比imu_utils要准确一点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/399470.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度学习基础——GAN生成对抗网络

生成对抗网络(GAN)的简介 生成对抗网络GAN(Generative adversarial networks)是Goodfellow等在2014年提出的一种生成式模型。GAN在结构上受博弈论中的二元零和博弈(即二元的利益之和为零&#xff0c;一方的所得正是另一方的所失)的启发&#xff0c;系统由一个生成器和一个判别器…

pc微信逆向最新3.9.8.25版本

朋友让我开发一个关于微信的计数、统计、自动回复功能的机器人&#xff0c;主要是用在win10上面。 先看看结果&#xff01; 之前写过手机端的逆向&#xff0c;PC端逆向很长时间没写了&#xff0c;所以就在网上找了找。基本都是基于3.6&#xff0c;3.7&#xff0c;3.8版本的&a…

python读取txt文档数据并断言value值的大小

本文主要介绍&#xff1a;将接口返回的字典值{"x1":1,"x2":2....}手动存到txt&#xff0c;然后写代码断言每个value值是否都满足某个区间。运用到&#xff1a; 1、读取txt文件中的数据 2、pytest写用例格式 3、pytest.assume断言方式&#xff08;出现报错A…

C++力扣题目139--单词拆分 198--打家劫舍 213--打家劫舍II 337打家劫舍III

139.单词拆分 力扣题目链接(opens new window) 给定一个非空字符串 s 和一个包含非空单词的列表 wordDict&#xff0c;判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。 说明&#xff1a; 拆分时可以重复使用字典中的单词。 你可以假设字典中没有重复的单词。 …

【IEEE出版会议征稿】第七届计算机信息科学与应用技术国际学术会议(CISAT 2024)

【IEEE出版】第七届计算机信息科学与应用技术国际学术会议&#xff08;CISAT 2024&#xff09; 2024 7th International Conference on Computer Information Science and Application Technology 第七届计算机信息科学与应用技术国际学术会议&#xff08;CISAT 2024&#x…

低代码:更高效、简单的方式开发出专业级的项目

你是否为编程世界的各种挑战感到头痛&#xff1f;想要以更高效、简单的方式开发出专业级的项目&#xff1f; JNPF低代码工具正是你苦心寻找的产品&#xff01;它是一款专为稍微懂一点点编程思想的入门级人员设计的神奇工具&#xff0c;集成了丰富的功能和组件&#xff0c;让你轻…

[NOIP2016 普及组] 魔法阵(枚举的典型例题,值得一看)

在透视这道题之前&#xff0c;先用一道小题来练练手 密码锁&#xff08;这道题是我根据魔法阵改的&#xff09; Description 叮当在探索迷宫时被一扇大门挡住了去路&#xff0c;门上刻画了很多乱七八糟的数字&#xff0c;门被锁上了&#xff0c;无法打开&#xff0c;但是门上…

WebGIS开发常用的JS库:VUE/React/Angular对比

Angular: 作用&#xff1a; Angular是一个完整的基于TypeScript的Web应用开发框架&#xff0c;主要用于构建单页Web应用&#xff08;SPA&#xff09;。它适用于大型和复杂的项目&#xff0c;具有强大的组件集合和丰富的文档。 架构&#xff1a; Angular采用组件化的方式&am…

【DC-DC】世微AP5192 LED恒流IC 摩托电动车货车 12-80V 1.5A 有极输入 电源驱动芯片

产品描述 AP5192是一款PWM工作模式,效率高、简单、内置功率MOS管&#xff0c;适用于4.5-100V输入的高精度降压LED恒流驱动芯片。电流1.5A。AP5192可实现线性调光和PWM调光&#xff0c;线性调光脚有效电压范围0.55-2.6V.AP5192 工作频率可以通过RT 外部电阻编程来设定&#xff0…

[经验] 动车盒饭价格2022 #其他#职场发展

动车盒饭价格2022 1、动车盒饭 近年来&#xff0c;随着中国高速铁路的发展&#xff0c;动车盒饭也成为了不可忽视的一份美食。它不仅解决了旅途中的饮食需求&#xff0c;还体现了中国美食文化的多样性和可口。 动车盒饭是一种便捷且美味的餐食&#xff0c;在火车上也不失为一…

胶原蛋白市场研究:预计2029年将达到27亿美元

胶原蛋白是一种白色、无支链的纤维状蛋白&#xff0c;是细胞外间质蛋白质的主要成分&#xff0c;占人体总蛋白质的25%到30%。 按胶原蛋白来源划分&#xff0c;可分为天然胶原蛋白和人工合成的胶原蛋白&#xff0c;后者以重组类人胶原蛋白为主&#xff0c;而重组类人胶原蛋白又可…

失败了,又继续失败了

这是一个普通的老人在小县城坚持写作的故事。与很多人的老年生活不同&#xff0c;78岁的舒绍平每天过着规律的写作生活&#xff0c;不做家务的时候&#xff0c;他便坐在书房&#xff0c;打开笔记本电脑&#xff0c;时断时续地敲字写作。 年轻时&#xff0c;他当过老师&#xf…

五种多目标优化算法(MOJS、MOGWO、NSWOA、MOPSO、NSGA2)性能对比,包含6种评价指标,9个测试函数(提供MATLAB代码)

一、5种多目标优化算法简介 1.1MOJS 1.2MOGWO 1.3NSWOA 1.4MOPSO 1.5NSGA2 二、5种多目标优化算法性能对比 为了测试5种算法的性能将其求解9个多目标测试函数&#xff08;zdt1、zdt2 、zdt3、 zdt4、 zdt6 、Schaffer、 Kursawe 、Viennet2、 Viennet3&#xff09;&#xff0…

C++学习Day08之函数模板

目录 前言一、程序及输出1.1 不使用函数模板1.2 使用函数模板1.2.1 自动类型推导1.2.2 显示指定类型 二、分析与总结 前言 C 函数模板是一种通用编程技术&#xff0c;允许您编写通用的函数代码&#xff0c;以适用于不同类型的数据。 一、程序及输出 1.1 不使用函数模板 每一…

【riscv】使用qemu运行riscv裸机freestanding程序

文章目录 1. 运行显示2. 工具准备3. 裸机代码和编译3.1 源码3.2 编译 4. 使用qemu仿真运行riscv裸机程序 1. 运行显示 详见左下角&#xff0c; 运行时串口输出的字符 A ; 2. 工具准备 # for riscv64-linux-gnu-gcc sudo apt-get install gcc-riscv64-linux-gnu# for qemu-s…

【RT-DETR有效改进】大核注意力 | LSKAttention助力极限涨点

一、本文介绍 在这篇文章中,我们将讲解如何将LSKAttention大核注意力机制应用于RT-DETR,以实现显著的性能提升。首先,我们介绍LSKAttention机制的基本原理,它主要通过将深度卷积层的2D卷积核分解为水平和垂直1D卷积核,减少了计算复杂性和内存占用。接着,我们介绍将这一…

记录留下的脚印

记录走过的脚印&#xff01;

【爬虫JS逆向-工具篇】浏览器内存漫游加密参数Hook实战教程

文章目录 1. 写在前面2. 环境搭建2. 加密定位实战 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【作者推荐】&#xff1a;对JS逆向感兴趣的朋友可以关…

数据库的备份模式(完全备份,增量备份,差异备份)

数据库的备份 备份原因 数据的丢失 数据的删除 备份目标 数据的一致性 数据的可用性 备份技术 物理备份/冷备份 直接复制数据库文件&#xff0c;适用于大型数据库环境&#xff0c;不受存储引擎的限制&#xff0c;但不能恢复到不同的MySQL版本。 常用的冷备份工具 ta…

利用iSCSI服务部署IP SAN网络存储服务

一、配置环境&#xff08;Vmware WorkStation虚拟环境&#xff09; 服务端与客户端OS&#xff1a;openEuler 22.03-LTS CPU&#xff1a;1U1C 内存&#xff1a;2G 硬盘&#xff1a;5个SCSI磁盘&#xff0c;其中一个作为系统盘&#xff0c;另外四个配置为RAID5阵列 服务器IP…