imu绘制轨迹

news2024/11/16 19:52:30

本文作者感谢武汉大学卫星导航定位技术研究中心多源智能导航实验室(i2Nav)牛小骥教授团队开源的KF-GINS软件平台。

首先声明,仅仅是实现,实际应用意义不大

这套算法利用EKF更新误差并且补偿到状态更新,如果没有gps信号时,利用imu信息运行捷联惯导算法进行短时间的状态更新,这个短时间由自己的imu质量高低决定

在这套算法中存在gps信号判断,为了实现单独imu轨迹绘制,将这个判断始终设置为Faule,也就是只运行捷联惯导算法,但这里存在一个问题,就是捷联惯导算法也会使用gps信息,主要用来计算重力和地球向心加速度,为了彻底避免使用gps信息,可以将重力设置为常量9.8,其余gps计算得出的相关量全部设置为零。

修改src/kf-gins/gi_engine.cpp,将

int res = isToUpdate(imupre_.time, imucur_.time, updatetime);

修改为

int res = 0;

下面是修改后的imesh.cpp文件

#include "common/earth.h"
#include "common/rotation.h"

#include "insmech.h"

void INSMech::insMech(const PVA &pvapre, PVA &pvacur, const IMU &imupre, const IMU &imucur) {

    // perform velocity update, position updata and attitude update in sequence, irreversible order
    // 依次进行速度更新、位置更新、姿态更新, 不可调换顺序
    std::cout<<imucur.time<<std::endl;
    std::cout<<imucur.dtheta<<std::endl;
    std::cout<<imucur.dvel<<std::endl;
    std::cout<<imucur.dt<<std::endl;
    velUpdate(pvapre, pvacur, imupre, imucur);
    posUpdate(pvapre, pvacur, imupre, imucur);
    attUpdate(pvapre, pvacur, imupre, imucur);
}

void INSMech::velUpdate(const PVA &pvapre, PVA &pvacur, const IMU &imupre, const IMU &imucur) {

    Eigen::Vector3d d_vfb, d_vfn, d_vgn, gl, midvel, midpos;
    Eigen::Vector3d temp1, temp2, temp3;
    Eigen::Matrix3d cnn, I33 = Eigen::Matrix3d::Identity();
    Eigen::Quaterniond qne, qee, qnn, qbb, q1, q2;

    Eigen::Vector2d rmrn = Earth::meridianPrimeVerticalRadius(pvapre.pos(0));
    Eigen::Vector3d wie_n, wen_n;
    wie_n << 0, 0, 0;
    wen_n << 0, 0, 0;
    double gravity = 9.8;
    temp1 = imucur.dtheta.cross(imucur.dvel) / 2;
    temp2 = imupre.dtheta.cross(imucur.dvel) / 12;
    temp3 = imupre.dvel.cross(imucur.dtheta) / 12;
    d_vfb = imucur.dvel + temp1 + temp2 + temp3;
    temp1 = (wie_n + wen_n) * imucur.dt / 2;
    cnn   = I33 - Rotation::skewSymmetric(temp1);
    d_vfn = cnn * pvapre.att.cbn * d_vfb;
    gl << 0, 0, gravity;
    d_vgn = (gl - (2 * wie_n + wen_n).cross(pvapre.vel)) * imucur.dt;
    midvel = pvapre.vel + (d_vfn + d_vgn) / 2;
    temp3 = (wie_n + wen_n) * imucur.dt / 2;
    cnn   = I33 - Rotation::skewSymmetric(temp3);
    d_vfn = cnn * pvapre.att.cbn * d_vfb;
    gl << 0, 0, gravity;
    d_vgn = (gl - (2 * wie_n + wen_n).cross(midvel)) * imucur.dt;
    pvacur.vel = pvapre.vel + d_vfn + d_vgn;
}

void INSMech::posUpdate(const PVA &pvapre, PVA &pvacur, const IMU &imupre, const IMU &imucur) {

    Eigen::Vector3d temp1, temp2, midvel, midpos;
    Eigen::Quaterniond qne, qee, qnn;

    // 重新计算中间时刻的速度和位置
    // recompute velocity and position at k-1/2
    midvel = (pvacur.vel + pvapre.vel) / 2;
    midpos = pvapre.pos + Earth::DRi(pvapre.pos) * midvel * imucur.dt / 2;

    // 重新计算中间时刻地理参数
    // recompute rmrn, wie_n, wen_n at k-1/2
    Eigen::Vector2d rmrn;
    Eigen::Vector3d wie_n, wen_n;
    rmrn = Earth::meridianPrimeVerticalRadius(midpos[0]);
    wie_n << WGS84_WIE * cos(midpos[0]), 0, -WGS84_WIE * sin(midpos[0]);
    wen_n << midvel[1] / (rmrn[1] + midpos[2]), -midvel[0] / (rmrn[0] + midpos[2]),
        -midvel[1] * tan(midpos[0]) / (rmrn[1] + midpos[2]);

    // 重新计算 k时刻到k-1时刻 n系旋转矢量
    // recompute n-frame rotation vector (n(k) with respect to n(k-1)-frame)
    temp1 = (wie_n + wen_n) * imucur.dt;
    qnn   = Rotation::rotvec2quaternion(temp1);
    // e系转动等效旋转矢量 (k-1时刻k时刻,所以取负号)
    // e-frame rotation vector (e(k-1) with respect to e(k)-frame)
    temp2 << 0, 0, -WGS84_WIE * imucur.dt;
    qee = Rotation::rotvec2quaternion(temp2);

    // 位置更新完成
    // position update finish
    qne           = Earth::qne(pvapre.pos);
    qne           = qee * qne * qnn;
    pvacur.pos[2] = pvapre.pos[2] - midvel[2] * imucur.dt;
    pvacur.pos    = Earth::blh(qne, pvacur.pos[2]);
}

void INSMech::attUpdate(const PVA &pvapre, PVA &pvacur, const IMU &imupre, const IMU &imucur) {

    Eigen::Quaterniond qne_pre, qne_cur, qne_mid, qnn, qbb;
    Eigen::Vector3d temp1, midpos, midvel;
    Eigen::Vector3d wie_n, wen_n;
    wie_n << 0.000, 0.000, 0.000;
    wen_n << 0.000, 0.000, 0.000;
    temp1 = -(wie_n + wen_n) * imucur.dt;
    qnn   = Rotation::rotvec2quaternion(temp1);
    temp1 = imucur.dtheta + imupre.dtheta.cross(imucur.dtheta) / 12;
    qbb   = Rotation::rotvec2quaternion(temp1);
    pvacur.att.qbn   = qnn * pvapre.att.qbn * qbb;
    pvacur.att.cbn   = Rotation::quaternion2matrix(pvacur.att.qbn);
    pvacur.att.euler = Rotation::matrix2euler(pvacur.att.cbn);
}

Kf-gins更新的状态为三轴速度,位置(经纬度高程),姿态(欧拉角),仅依赖三轴速度就可以绘制轨迹,下面是代码

import numpy as np
import matplotlib.pyplot as plt



#打开结果文件
with open("/home/workspace/KF-GINS/dataset/KF_GINS_Navresult.nav","r") as f:
    datas = f.readlines()

 #先把速度提出来
dv = []
for data in datas:
    data_split = data.split(" ")
    data = [float(i) for i in data_split if i != "" and i != "\n"]
    dv.append([data[1],data[5],data[6],data[7]])
dv = np.array(dv)

x = np.zeros(3,)
sx = []
sy = []
sz = []
for i in range(len(dv)-1):
    pre_data = dv[i]
    cur_data = dv[i+1]
    v0 = pre_data[1:]
    dt = cur_data[0] - pre_data[0]
    if dt == 0:
        a = 0
    else:
        a = (cur_data[1:]-v0)/dt
    dx = v0 * dt + 0.5 * a *dt **2
    x += dx
    sx.append(x[0])
    sy.append(x[1])
    sz.append(x[2])

fig = plt.figure()
ax = fig.add_subplot(projection="3d")
ax.scatter(sx,sy,sz)
ax.set_xlabel("X Label")
ax.set_ylabel("Y Label")
ax.set_zlabel("Z Label")
ax.set_title("3D scatter plot")
plt.show()



先用KF-gins自带数据进行测试,第一幅图为groundtruth,第二幅图为经过修改的算法绘制的轨迹,时长为100s,也就是不到100s就开始漂,而且z轴方向漂的很厉害(单位m)
在这里插入图片描述


使用自己数据绘制轨迹,俯视图,z轴方向偏的很大。三个轴运动超过三秒轨迹直接起飞
在这里插入图片描述
在这里插入图片描述
另外,输入数据需要注意的是方向对齐,Kf-gins的数据格式为

IMU坐标系:原点为IMU测量位置,轴向为前-右-下方向
导航参考坐标系:原点和IMU坐标系一致,轴向为北-东-地方向

调整方式为

挪动imu,当三个角(rpy)输出为零的时候,x轴的方向为前,y轴的方向为右,z轴指向下,此时x-y-z轴应该分别指向北-东-地,下载一个指南针,就可以知道xy轴指向的是不是北和东,如果不是,就交换xyz顺序或者加正负号使其变成北东然后输入到Kf-gins算法中

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jetpack compose —— Card

jetpack compose Card 组件提供了一种简单而强大的方式来呈现卡片式的用户界面。 一、什么是 Card 组件 二、基本用法 三、属性和修饰符 四、嵌套使用和复杂布局 一、什么是 Card 组件 Card 是 Jetpack Compose 中的一个常用组件&#xff0c;用于呈现卡片式的用户界面。它…

量化投资 现代投资组合理论(MPT)

量化投资 现代投资组合理论&#xff08;MPT&#xff09; 问题&#xff1a;构建投资组合&#xff0c;达到目标收益率的同时拥有最小的 risk exposure. 有 J J J 个可交易证券&#xff0c;期望收益率为 R [ R 1 , ⋯ , R j ] T R[R_1,\,\cdots,\,R_j]^T R[R1​,⋯,Rj​]T&…

小红书数据洞察!父亲节将临,3大种草方式打动消费者

父亲节即将来临&#xff0c;各大社交平台陆陆续续开始讨论。品牌自然也不会错过此机&#xff0c;走心宣传。那么&#xff0c;今年的父亲节&#xff0c;有哪些热门内容呢&#xff1f;品牌如何点燃消费热情、提升形象&#xff1f;通过小红书数据和关键词分析&#xff0c;我们进一…

基于阿里云 Serverless 容器服务轻松部署企业级 AI 应用

作者&#xff1a;元毅、坤仑 数禾科技 AI 模型服务基于云原生架构&#xff0c;为不同业务环节提供智能决策支持。随着业务的快速发展&#xff0c;摆在数禾面前的难题是支撑模型计算的底层应用资源无法根据请求量来调整机器资源支持运算能力。同时&#xff0c;随着模型在线推理…

医疗行业的新选择:智能医疗管理模板

随着社会的发展&#xff0c;医疗行业也在不断地进步与发展&#xff0c;信息化已经成为医疗行业的重要一环。智能医疗管理应用作为新型医疗管理工具&#xff0c;已经成为中小型医院、门诊、美容机构等企业的必备软件之一。该应用包括患者管理、预约管理、诊断管理、住院管理、财…

Qt推荐的多线程的理解

目的 在Qt4.8之后&#xff0c;Qt多线程的写法最好还是通过QObject来实现&#xff0c;和线程的交互通过信号和槽(实际上其实是通过事件)联系。 用QObject来实现多线程有个非常好的优点&#xff0c;就是默认就支持事件循环&#xff08;Qt的许多非GUI类也需要事件循环支持&#x…

js执行顺序:

这篇笔记摘录来源&#xff1a; &#x1f449;我是javascript&#xff0c;2分钟彻底弄懂我的执行机制&#xff1f;【JavaScript教程】_哔哩哔哩_bilibili &#x1f449;js执行顺序_前端小白&#xff0c;请多指教的博客-CSDN博客 目录 面试题&#xff1a; 一、单线程 二、…

十年软件测试经验,我的成长之道

有很多小伙伴问&#xff0c;测试职业的天花板是不是很低&#xff1f; 在回答这个问题之前&#xff0c;我想请大家先想一下&#xff0c;当初自己为什么会选择测试这个职业&#xff1f;入门门槛低&#xff1f;不需要写代码&#xff1f;工作比开发轻松&#xff1f;还是其他。这个…

科技政策 | 工业和信息化部办公厅关于组织申报2023年跨行业跨领域工业互联网平台的通知

原创 | 文 BFT机器人 6月1日工业和信息化部办公厅发布关于组织申报2023年跨行业跨领域工业互联网平台的通知&#xff1b;旨在贯彻《国务院关于深化“互联网先进制造业”发展工业互联网的指导意见》&#xff0c;落实《工业互联网创新发展行动计划&#xff08;2021-2023年&#…

还有多少公司在使用H5?不怕被破解吗?

H5还有人在用吗 近几天&#xff0c;老板让我调查一下现在市面上H5的使用现状。粗略地调查了一下&#xff0c;发现现在使用H5的真不多了&#xff0c;但是还是有人在用H5的&#xff0c;原因无非一是成本低&#xff0c;相比户外广告&#xff0c;H5制作费用根本不值一提&#xff1…

Delta 一个新的 git diff 对比显示工具

目录 介绍git diff 介绍delta介绍 一、安装1.下载 Git2.下载 delta3.解压4.修改配置文件5. 修改主题6.其他配置和说明 二、对比命令1.在项目中 git diff 常用命令2.对比电脑上两个文件3.对比电脑上的两个文件夹 三、在Git 命令行中使用效果四、在idea 的Terminal命令行中使用效…

展览展会邀请媒体现场报道需要注意什么?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 真开心今天与大家分享展览展会邀请媒体的一些经验&#xff0c;行业复苏&#xff0c;各行各业都充满了活力&#xff0c;每天胡老师都会接到大大小小展会邀请媒体报道的需求&#xff0c;那…

终端数据防泄漏

场景描述 科技研发类公司在日常工作中&#xff0c;存在员工对源代码数据有意或者无意的传播。软件企业作为以源代码数据为核心资产的行业&#xff0c;如果数据安全管理不规范&#xff0c;会出现员工把核心数据一锅端&#xff0c;使企业失去竞争力&#xff0c;造成不可估计的损…

代码随想录算法训练营第五十六天|583. 两个字符串的删除操作|72. 编辑距离

LeetCode583. 两个字符串的删除操作 动态规划五部曲&#xff1a; 1&#xff0c;确定dp数组&#xff08;dp table&#xff09;以及下标的含义&#xff1a;dp[i][j]&#xff1a;以i-1为结尾的字符串word1&#xff0c;和以j-1位结尾的字符串word2&#xff0c;想要达到相等&#…

自己尝试在springboot2.0微服务中内嵌一个FTP Server

1.pom.xml添加依赖 <dependency><groupId>org.apache.ftpserver</groupId><artifactId>ftpserver-core</artifactId><version>1.2.0</version></dependency> 2.yml文件添加Ftp服务参数 3.增加apache.ftpserver专用配置文件 文…

OWASO 之认证崩溃基础技能

文章目录 一、burp爆破用法1.Attack type爆破方式设置2.payload处理3.请求引擎设置4.攻击结果设置5.grap匹配设置 二、常见端口与利用1、文件共享2、远程连接3、Web应用4、数据库 三、爆破案例经验1、暴力破解攻击产生的5个原因或漏洞2、猜测用户名方法3、猜测密码方法 四、实验…

第七十三天学习记录:计算机硬件技术基础:微型计算机基础

一、微型计算机的组成&#xff1a; 微型计算机由硬件和软件两大部分组成&#xff0c;硬件是指构成微型计算机的物理实体或物理装置&#xff0c;包括微型计算机的微处理器、储存器、总线接口电路和外部设备&#xff0c;以及电源和机械构件等。软件是指微型计算机所使用的各种程…

Python3数据分析与挖掘建模(11)多因子:复合分析-分组分析与实现示例

1. 分组分析 1.1 概述 分组与钻取是数据分析中常用的技术&#xff0c;用于对数据进行聚合和细分分析。它可以帮助我们从整体数据中获取特定维度的汇总信息&#xff0c;并进一步钻取到更详细的子集数据中进行深入分析。 分组&#xff08;Grouping&#xff09;是指根据某个或多…

SciencePub学术 | 国内高口碑重点SCIEI征稿中

SciencePub学术 刊源推荐: 国内高口碑重点SCI&EI征稿中&#xff01;期刊质量高&#xff0c;接收领域广。信息如下&#xff0c;录满为止&#xff1a; 一、期刊概况&#xff1a; 国内高口碑重点SCI&EI &#x1f4cc;【期刊简介】IF&#xff1a;7.5-8.0&#xff0c;JCR…

python高级-socket和web相关

目录 一、socket 1.客户端开发 2.tcp客户端 3.tcp服务端 4.连接的注意事项 5.多任务服务端 二、静态web 1.请求报文 2.响应头 3.静态web服务器 4.socket静态页面 5.多进程模拟404和200状态码 6.面向对象多任务 结语 一、socket 1.客户端开发 创建客户端套接字对…