GICI-LIB源码阅读(一)程序简介、编译调试、配置文件、车载数据集-程序员宅基地

技术标签: GICI源码阅读  导航定位  GNSS  Camera  INS  

  • 原始 Markdown文档、Visio流程图、XMind思维导图见:https://github.com/LiZhengXiao99/Navigation-Learning
  • 欢迎关注我的公众号:NaviCode小工匠

一、GICI-LIB 简介

作者的介绍:为了阐明 GNSS 的算法模型,加快在多源融合应用中针对 GNSS 的开发效率,我们开源了 GICI-LIB,并辅以详尽的文档和全面的数据集。GICI-LIB 以可扩展的设计理念,实现了GIC传感器之间多种形式的松紧组合。评估结果表明,GIC 系统能够在多种复杂环境下,提供分米到米级的高精度导航。

1、程序概述

GICI-LIB 全称 GNSS/INS/Camera Integrated Navigation Library,是上海交大最新开源的一套基于图优化的 GNSS+INS+Camera 集成导航定位库。基于 RTKLIB 处理 I/O 流、编解码;基于 OKVIS 因子图优化类型封装;基于 SVO 做特征提取。以 GNSS 为主,再加入 INS、Camera 做组合,支持相当多的数据格式、定位模式,包含很多 GNSS 因子、惯导因子、视觉因子及运动约束。以处理实时数据为主,后处理也采用模拟实时数据处理的方式进行。典型的应用方式如下图:

1689512108793

2、资源获取

3、功能简介

  • 支持非 ROS 模式和 ROS 模式,ROS 模式下可以使用 ROS 话题、RVIZ 显示轨迹。

  • 支持多种数据形式:serial 串口、TCP/IP server、TCP/IP client、Ntrip server、Ntrip client、V4L2、file 文件。

  • 支持多种数据编码:RTCM2、RTCM3、 Ublox raw、Septentrio raw、Tersus raw、NMEA、DCB file、ATX file、V4L2 image pack、GICI image pack、GICI IMU pack

  • 支持多种数据传输方式:I/O 端口、串口、ROS topics、TCP/IP、NTRIP、V4L2、文件

  • 支持多种定位模式:SPP、SDGNSS、DGNSS、RTK、PPP、SPP-based LC GINS、TC GINS、RTK-based LC GINS、SRR GVINS、RRR GVINS。

  • 支持多种因子

    • GNSS 松组合因子:Position Error Factor、Velocity Error Factor
    • GNSS 紧组合因子:Pseudorange Error Factors、Carrier Phase Error Factors、Doppler Error Factors
    • Camera 因子:Reprojection Error Factor
    • INS 因子:Pre-integration Factors、Zero Motion Update Factor、Heading Measurement Constraint Factor、Non-holonomic Constraint Factor
    • 公共因子:Parameter Error Factors、Relative Constant Error Factors、Relative Integral Error Factors
  • 支持三个层级的 SSR 服务:

    • 一级:提供精密星历、精密钟差、码偏差。
    • 二级:除一级改正信息外,还提供载波相位偏差。
    • 三级:除二级改正信息外,还提供大气延迟信息,能够支持 PPP-AR、PPP-RTK。
  • GICI 不支持时间系统偏差的估计,需要进行硬件层面的时间对准,且最好精度要达到 5ms。

4、代码分析

GICI-LIB 主要使用 C++ 编写,且大量使用 C++ 高级语法,CMake 文件里规定以 C++11 的标准编译,采用多线程、面向对象程序设计方法,写法"很C++",想看懂源码需要有一定的 C++ 基础。C++11 语法的内容可以看下图:

img

具体来说,还有以下特点:

  • 程序面向对象设计,大量使用继承、多态、友元、虚函数等面向对象特性。
  • 大量使用模板泛型技术,用了很多 STL 容器、迭代器,用了 std::functionstd::bind
  • 大量使用智能指针管理内存,还用 using 给智能指针起别名 xxxPtr。
  • 使用多线程技术,接受数据和解算由不同的线程来做。
  • 比较友好的地方是代码的注释还算完善,基本每个文件开头、每个函数、程序的关键代码段都有注释。
  • 代码质量很高,但还可以再整理整理,比如有的紧挨着的地方上面用了 auto 而下面没用、有些函数名太长、构造函数写太长、streamer 和 estimator 线程有好几种命名,看着有点乱。

用 cloc 统计 include、src、tools 文件夹代码量,结果如下:

语言 文件数 空行 注释行 代码行
C++ 110 3704 4547 26189
C/C++ Header 104 2746 4841 8452
MATLAB 16 111 232 666
C 10 98 93 394
CMake 9 71 36 262
YAML 4 8 17 185
Gencat NLS 13 0 0 94
XML 2 8 0 56
总计 268 6746 9766 36298

src 和 tools 文件夹内各子文件夹功能信息如下表所示:

文件名 功能 代码行数
estimate 因子图优化相关类型、函数 2451
fusion 多源融合导航相关:估计器、初始化器类型定义 2872
gnss GNSS相关:误差改正、模糊度固定、SPP、PPP、RTK 9347
imu IMU相关:数值更新、误差改正 1725
stream 数据流相关、Node处理相关类型定义 2829
utility 全局变量、配置选项、信号处理函数、 Spin线程定义 1159
vision 视觉相关:初始化、特征提取、处理、跟踪、相对位置计算 1900
conversions 时间转换、坐标转换 175
edit_binary 二进制数据处理、处理采样间隔 1137
evaluation NMEA相关 1672
ros ros 相关、话题消息发布、msg定义 2149
matlab_plot MATLAB 画图脚本 666

5、第三方库

  • RTKLIB:开源 GNSS 软件包,由一个程序库和多个应用程序工具库组成。
  • fast:Features from Accelerated Segment Test,特征检测算法。
  • svo:半直接发法稀疏直接法视觉里程计(Visual Odometry)算法,用到其中函数做视觉前端
  • OKVIS:Open Keyframe-based Visual-Inertial SLAM,用到了其中的因子图函数
  • Eigen:线性代数库,用于处理矩阵和向量的计算,它提供了许多线性代数运算的功能,包括矩阵运算、向量运算、特征值分解、奇异值分解、矩阵求逆等。
  • Ceres:Google 的非线性最小二乘库,用于实现因子图优化解算。
  • glog:Google 的日志库。
  • OpenCV:Open Source Computer Vision Library,跨平台计算机视觉库。
  • yaml-cpp:GICI 采用 YAML 配置文件格式,YAML-CPP 是一个 C++ 的 YAML 库,用于 yaml 格式的解析和生成。

6、manual

GICI-LIB 的 manual 足足有 117 面,挺详细的,内容如下:

  • 1~2:对软件简单介绍。
  • 3~5:软件编译,下文会对每个步骤详细展开介绍。
  • 5~39:介绍配置文件格式,下文会做总结,具体设置看文档。
  • 40~45:介绍常见使用场景及配置,内容主要就是本文开头的图。
  • 47~58:硬件设置:输入数据方式和格式、ROS 系统、硬件时间同步。
  • 60~64:介绍因子图优化基本模型,下文会详细展开描写。
  • 62~98:介绍各种因子
  • 98~110:介绍各种定位模式,下文会简单概括,详细的公式还是要看文档和代码。
  • 111~113:坐标系框架定义和转换,多源融合涉及很多的坐标系,各种坐标系的统一至关重要。值得注意的是:导航坐标系(n 系)用ENU(东北天)、载体坐标系(b 系)用RFU(右前上)。
  • 114~115:GNSS 线性组合和差分模型。
  • 116:参考文献,上文已经给出下载链接。

7、程序执行流程图

image-20230807135432767

8、定位模式

1. GNSS

1689675695644

  • Single Point Positioning(SPP):用单历元的伪距、多普勒测量值,解算接收机的位置、速度、钟差。只实现了单频非差伪距的 SPP,没做消电离层,因为多频组合要额外估计 IFB,模型复杂的同时也提高不了多少 SPP 的精度。
  • Real-Time Differential(RTD):用单历元的双差伪距、非差多普勒测量值,解算接收机位置、速度。RTD 中可以很方便的使用多频观测值,因为 IFB 在双差中被大大消除,可以通过更改配置文件中 estimator 节点的输入项来设置。
  • Real-Time Kinematic(RTK):用多历元的双差伪距,双差载波,非差多普勒观测值,计算接收机位置、速度。估计了单差模糊度,如果有 m 颗共视卫星、n 个共同频率,需要估计 m × n m \times n m×n 个单差模糊度。除了图优化估计,RTK 还有模糊度固定的步骤,GICI-LIB 支持部分模糊度固定。
  • Precise Point Positioning(PPP):使用非差的伪距、载波、多普勒观测值,估计接收机速度、位置、钟差、大气延迟、IFB。GICI-LIB 支持 PPP-AR,但没有完全测试,由于 PPP 比 RTK 浮点解的噪声更大,想固定必须要有偏差产品,并进行改正。
  • Global Frame Initialization:纯 GNSS 解算在 ECEF 框架进行,而进行组合需要在 ENU 框架进行,因此需要进行转换。全局框架初始化定义一个基准点,用于将 ECEF 框架中的状态转换为 ENU 框架中的状态。基准点也可用于计算重力加速度,用于惯导惯导。设置基准点有两种方法:
    • 我们运行 SPP 估计,将基准点设置为该估计的第一个有效解。
    • 如果将 force initial global position 选项设置为 true,我们通过 initial global position 选项从配置文件中加载点坐标。
2. GNSS+ INS

1689675885876

  • Loosely Integration(LC):GNSS/INS 松组合用 GNSS 解算结果(位置、速度),和 INS 的原始数据(比力、角增量)进行组合解算。
  • Tightly Integration(TC):GNSS/INS 紧组合用 GNSS 的原始数据(伪距、载波、多普勒),和 INS 的原始数据(比力、角增量)进行组合解算。
  • Initialization:GNSS/INS 初始化会估计速度、位置和偏差;为了提高效率,无论松紧组合都使用松组合的方程。先用加速度计比力量测值计算俯仰角和横滚角,当有足够比力量测值之后再对航向角进行估计,因子图结构与松组合一致,不同的是,我们使用多普勒来计算初始位置的增量,因为初始位置噪声过大,而多普勒噪声较低。
3. GNSS + INS + Camera

1689675982558

摄像机状态之间没有相互联系,因为相应的参数是时变的。我们在图中保留了连接,以表示由于跟踪地标的切换,各次的估计参数会发生变化。

  • Solution/Raw/Raw Integration(SRR):SRR 采用 GNSS 的解算结果(速度、位置),和 INS 的原始数据(比力、角增量),以及 Camera 数据(特征点),进行组合解算。
  • Raw/Raw/Raw Integration(RRR):RRR 采用 GNSS 的原始数据(伪距、载波、多普勒),和 INS 的原始数据(比力、角增量),以及 Camera 数据(特征点),进行组合解算。
  • Initialization:GNSS/INS/Camera 初始化位置、速度、偏差、特征点位置。分两步进行,先进行 GNSS/INS 初始化,再通过空间交汇对特征点追踪。
4. Estimator 类型封装

GICI-LIB 提供的多种传感器在不同定位模式下的很多因子,并封装了一个基类,为所有传感器提供基础的函数去操作变量因子和量测因子,具体可以看各种 xxx_estimator_base.h,看算法的时候肯定重点要看这些文件

1690024555067

二、GICI-LIB 编译

  • git clone 下载不了,可以去 git clone 后面的网站上手动下载。

  • 本文只介绍非 ROS 版。

  • 我使用的环境是 VSCode + WSl,很多导航定位的开源软件都基于 Linux,比起虚拟机,VSCode + WSl 要流畅一些,不熟悉的推荐看这篇文章

  • 确保之前已经配置好 C++ 环境(g++、Cmake、VScode 插件)。

  • 看别人的博客,都提到了曾经安装过 glog/gflag 会出问题:GICI-OPEN多源融合导航框架编译及问题说明

  • 构建、编译的时候找不到库,可能是因为库装到/usr/local/lib 里了,试试创建软链接到 /usr/lib

    ln -s /usr/local/lib/库名.a /usr/lib/库名.a
    

1、安装需要的库

1. 安装 Eigen
sudo apt-get install libeigen3-dev
2. 安装 OpenCV
  • 文件下载

  • 环境配置

    sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
    sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev
    
  • 进入 opencv 目录编译安装

    cd opencv
    mkdir build
    cd build
    
    sudo cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..
    
    sudo make -j8
    sudo make install
    
  • 将 OpenCV 的库添加到路径,从而可以让系统找到

    sudo vim /etc/ld.so.conf.d/opencv.conf
    
    在文件中加上并保存退出 /usr/local/lib
    
    sudo ldconfig
    
  • 配置 bash

    sudo vim /etc/bash.bashrc
    
    # 在打开的文件最末尾添加以下代码并保存退出
    PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig  
    export PKG_CONFIG_PATH 
    
    source /etc/bash.bashrc
    
  • 执行 pkg-config --cflags opencv 如果报错,可以看博客

3. 安装 glfg、glog

参考:Ubantu下glog编译安装与使用简介

  • 下载 glfg

    git clone https://github.com/gflags/gflags
    
  • 进入 glfg 目录编译安装

    cd glfg
    mkdir build
    cd build/
    
    cmake -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=ON -DINSTALL_HEADERS=ON -DINSTALL_SHARED_LIBS=ON -DINSTALL_STATIC_LIBS=ON -DCMAKE_INSTALL_PREFIX=/usr/ ..
    
    make
    sudo make install
    
  • 下载 glog

    git clone https://github.com/google/glog
    
  • 进入 glog 目录编译安装

    cd glog
    mkdir build
    cd build 
    
    cmake -DGFLAGS_NAMESPACE=google -DCMAKE_CXX_FLAGS=-fPIC -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=/opt/glog ..
    
    make
    sudo make install
    
  • 为使 glog 库生效,需要在 /etc/ld.so.conf.d 下新建配置文件并使其生效

    cd /etc/ld.so.conf.d
    sudo vim glog.conf
    输入 /opt/glog/lib
    
    sudo ldconfig
    
4. 安装 Yaml-cpp
  • 下载

    git clone https://github.com/jbeder/yaml-cpp.git
    
  • 进入 Yaml-cpp 目录编译安装

    cd yaml-cpp
    mkdir build 
    cd build
    
    cmake -D BUILD_SHARED_LIBS=ON ..
    
    make -j16
    sudo make install
    
5. 安装 ceres-solver
  • 下载

    git clone https://ceres-solver.googlesource.com/ceres-solver
    
  • 进入 ceres-solver 目录编译安装

    mkdir ceres-bin
    cd ceres-bin
    cmake ../ceres-solver-2.1.0
    make -j3
    make test
    make install
    

2、GICI-LIB 编译

  • 下载

    git clone https://github.com/chichengcn/gici-open
    
  • 编译

    在工程目录下打开终端,输入以下命令:

    mkdir build
    cd build
    cmake ..
    make -j4 	# 编译需要一段时间
    

四、glog 日志系统

glog 即 Google Log ,是一个 Google 开源的日志库,它提供了一个轻量级的、可扩展的、跨平台的日志系统。 glog 的用法包括:

  • 引入头文件:需要包含 glog 的头文件:

    include <glog/logging.h>
    
  • 初始化库:在开始使用 glog 之前, 初始化库,例如:

    google::InitGoogleLogging(argv[0])
    
  • 配置日志:可以通过配置文件或代码来配置 glog 的参数,例如:

    google::SetLogDestination(LOG_TO_FILE, "/path/to/logfile.log")
    
  • 输出日志:使用 LOG(level) 宏函数来输出日志。level 表示日志的严重程度,可以是以下几个级别之一:INFO:一般信息、WARNING:警告信息、ERROR:错误信息、FATAL:致命错误信息,输出后会终止程序。例如输出一般信息:

    LOG(INFO) << "This is an informational message."
    
  • 条件输出日志:使用 LOG_IF()LOG_EVERY_N()LOG_FIRST_N() 宏函数来条件输出日志。例如:

    LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"
    
  • 关闭日志:在程序结束之前,关闭 glog:

    google::ShutdownGoogleLogging()
    

五、YMAL 配置文件

在手册的 9~39 面,详细的介绍了配置文件的具体内容。GICI-LIB 采用 YAML 配置文件格式,下面先对 YMAL 做个简单介绍。

1、YAML 简介

链接时找不到 yaml-cpp,可以参考博客:error while loading shared libraries的解决方案,在 /etc/ld.so.conf 文件中加上 /usr/local/lib

YAML(YAML Ain’t Markup Language)是一种轻量级的数据序列化格式,可以用于配置文件、数据交换、API请求等多种场景。它是一种简单易用的数据序列化格式,使得数据可以以人类可读的方式进行存储和传输。YAML的语法非常简单,它使用缩进和符号来表示数据结构。以下是一些YAML的基本语法:

  1. 字符串:用引号括起来的文本,例如:“hello world”。

  2. 数字:没有引号的数字,例如:42。

  3. 布尔值:用 true 或 false 表示的真或假。

  4. 缩进:YAML使用缩进来表示嵌套关系,每个缩进级别用空格数表示。例如,下面的代码段表示一个包含两个列表的字典:

  5. 字典/对象/键值对:用短横线 - 或中括号[]表示的键值对的集合。例如:{name: John, age: 30}- name: John age: 30。多层对象可表示为:

    key: {
          key1: value1, key2: value2}
    

    或者

    key:
      key1: value1
      key2: value2
    
  6. 数组/列表:用短横线 - 或中括号 [] 表示的值的列表。例如:[apple, banana, orange]- apple - banana - orange。复杂一点的如:

    streamers:
        - streamer:
            tag: str_gnss_rov
            output_tags: [fmt_gnss_rov]
            type: file
            path: <data-directory>/gnss_rover.bin
        - streamer:
            tag: str_gnss_ref
            output_tags: [fmt_gnss_ref]
            type: file
            path: <data-directory>/gnss_reference.bin
    
  7. 引用& 用来建立锚点,<< 表示合并到当前数据,* 用来引用锚点。

  8. 注释:在YAML中,使用 # 表示注释。

YAML 需要特别注意的几个点:

  • 大小写敏感。
  • 缩进不允许使用 tab,只允许空格。
  • 缩进的空格数不重要,只要相同层级的元素左对齐即可。

2、读取 YAML 的语法

  1. YMAL 在 C++ 中以 Node 类表示。

  2. LoadFile():从文件中加载 YAMl 到 C++ 中 Node 对象:

    yaml_node = YAML::LoadFile(文件名); 
    
  3. []:Node 对象可以理解为是树形的,用中括号可以取出里面的子数,创建一个新的 Node 对象:

    YAML::Node logging_node = yaml_node["logging"];
    
  4. safeGet():第一个参数为 Node,第二个参数为关键字,判断配置文件的 Node 里有没有你要的那个关键字,有的话再把对应的值作为第三个参数返回。

    option_tools::safeGet(logging_node, "log_to_stderr", &FLAGS_logtostderr);
    
  5. checkSubOption():第一个参数为 Node、第二个参数为子配置选项,检查参一中是否存在参二子配置选项,如果不存在有两种处理:

    • 当参三为 true 时,LOG(FATAL) 退出程序。
    • 当参三为 false 时,LOG(INFO) 输出错误到日志文件。

下面三个函数都是写了函数模板,然后重载写了很多的 :

  1. convert():参一传入 YAML 配置种类字符串,转换成 StreamerType、FormatorType 等枚举值作为参二返回。
  2. sensorType():传入 formator_role 字符串,转换成传感器种类枚举值 SensorType 返回。
  3. loadOptions():参一传入文档 18~39 对应 estimate 的选项 Node,转换成对应的 ImuParameters、AmbiguityResolutionOptions 等选项结构体作为参二返回。

3、GICI-LIB 配置文件结构

配置文件以 数组 + 键值对 的方式组织,每一个键值对都是一个配置项,用多级数组来分模块组织配置项键值对。有三大模块:stream、estimate、logging,其中 stream 模块内还分为三个子模块 steamers、formators、replay。如下图:

1689518262550

4、示例配置文件

option 文件夹里有一些配置文件,以伪实时定位解算为主,对应于下面的应用方式,图上每个模块都对应着咱们要配置的内容。

1689512108793

使用方式

  • 建立 data、output 文件夹,存放数据和输出。
  • 将 yaml 配置文件中的 <data-directory><gici-root-directory><output-directory> 分别换成你的数据文件夹路径gici-open 文件夹的路径、和 输出文件夹路径
  • 改配置中的 start_time,起始时间。
  • streamer 写了两套,非 ROS 模式和 ROS 模式,想用哪套就把另一套注释掉。
  • 注意看 streamers 里一项项 streamer 的路径项 path,确保数据文件夹中都有对应的数据。
  • 有些 streamer 中路径设置在 option 文件夹中,程序会从 gici-open 文件夹的路径 找 option 文件夹,确保 option 文件夹和里面数据在对应位置,最好不要动 option 文件夹。
  • 程序运行前,把 yaml 配置文件的路径加到命令行参数中。
  • 结果在 output 文件夹下,xxx_solution.txt 文件可以直接用 rtkplot 打开查看结果。用matlab_plot 里的脚本应该也行。

一定注意,配置文件中有好几处 <data-directory><gici-root-directory><output-directory>start_time 要改,不能漏,我在这卡了很久。

没运行成功,仔细看看报错信息,INFO不用看,关注ERROR,看对应配置是否正确。

六、数据集

对 GitHub 上的介绍简单做个翻译

1、数据集介绍

  • Github地址:https://github.com/chichengcn/gici-open-dataset
  • 百度网盘下载:https://pan.baidu.com/share/init?surl=xZS-C_42LrGtUB0x6Bw_0A&pwd=6ncd,提取码:6ncd

作者专为开发 GICI-LIB 而搭建的数据采集的平台如下图所示:

image-20230902170048417

开发了一块 GICI 板,用于收集 IMU 和摄像头数据,并在整个平台中应用了与其他传感器同步的硬件。板载 IMU 和摄像头分别为博世 BMI088 和 Onsemi MT9V034。GNSS 接收器为 Tersus David30 多频接收器。我们还从千寻 SI 数据流中收集了参考站数据,用于 RTD 和 RTK ,并从国际 GNSS 服务(IGS)数据流中收集了状态空间表示(SSR)数据,用于 PPP。光纤 IMU 通过对其数据和 GNSS 原始数据进行后处理来提供参考值。

收集了两种数据集:不同场景的短期(几分钟)实验(1.1 ~ 4.3)和涵盖多个场景的长期(几十分钟)实验(5.1 ~ 5.2)。在短期实验中,我们将场景分为 4 类: 开阔天空、绿树成荫、典型城市和密集城市。对于每个场景,我们提供 2 ~ 3 条轨迹。在长期实验中,我们提供了在上海市中心收集到的涵盖这些场景的两个轨迹。

ID Scene Size Date Scene View
1.1 Open-sky 0.7 GB 2023.03.20 Images
1.2 Open-sky 0.5 GB 2023.03.27 Images
2.1 Tree-lined 1.4 GB 2023.03.20 Images
2.2 Tree-lined 0.6 GB 2023.03.27 Images
3.1 Typical urban 1.7 GB 2023.03.27 Images
3.2 Typical urban 1.4 GB 2023.03.27 Images
3.3 Typical urban 1.9 GB 2023.03.27 Images
4.1 Dense urban 1.4 GB 2023.05.21 Images
4.2 Dense urban 0.8 GB 2023.03.27 Images
4.3 Dense urban 1.6 GB 2023.03.27 Images
5.1 Long-term 8.2 GB 2023.05.21 Images
5.2 Long-term 5.8 GB 2023.05.21 Images

用对应数据的时候记得改时间

2、非 ROS 方式使用数据集

提供了各种 YAML 配置文件示例,在 <gici-root-directory>/option。请记住替换所有 <path> "start_time"。通过命令来运行软件处理数据集:

./gici_main <gici-config-file>

要将实时输出流连接到 RTKLIB,应执行以下步骤:

  1. 指定 NMEA 格式的 TCP 服务器输出。配置示例见pseudo_real_time_estimation_RTK_RRR.yaml
  2. 在 Windows 计算机中打开 RTKPLOT。想要访问 Linux 计算机的 IP 地址,Windows 计算机必须位于同一网段。
  3. 单击文件->连接设置。启用 TCP 客户端。单击选项配置 TCP 客户端选项。填写服务器地址(Linux 计算机的 IP)和端口(在 GICI YAML 文件中配置)。
  4. 点击文件->连接,形成连接。然后就可以看到实时绘制的结果图了。

3、把原始数据转为 rosbag

我们提供了一个将 bin 文件转换为 rosbags 的工具,请参见 <gichi-root-directory>/tools/ros/gici_tools/src/gici_files_to_rosbag.cpp。其配置文件位于 <gici-root-directory>/tools/ros/gici_tools/option/convert_rosbags.yaml 中。请记住替换所有 <path> "start_time"

可以通过以下方式编译转换器:

cd \<gici-root-directory\>/tools/ros
catkin_make -DCMAKE_BUILD_TYPE=Release

然后可以通过以下方式运行转换器:

./devel/lib/gici_tools/gici_files_to_rosbag <config-file>

4、ROS 方式

YAML 配置文件示例,请参见 <gichi-root-directory>/ros_wrapper/src/gici/option。使用前要替换所有<path>"start_time"。在运行 ROS 可执行文件之前,请记得运行一个 roscore。然后,可以通过以下方式运行可执行文件:

rosrun gici_ros gici_ros_main <gici-config-file>

或者:

cd \<gici-root-directory\>/ros_wrapper
./devel/lib/gici_ros/gici_ros_main <gici-config-file>

之后,您可以通过以下方式播放从我们的 bin 文件转换而来的 rosbags

rosbag play <data1.bag> <data2.bag> <data3.bag> ...

为了实现可视化,您可以通过以下方式运行我们的 RVIZ 配置:

rviz -d \<gici-root-directory\>/ros_wrapper/src/gici/rviz/gici_gic.rviz

5、结果评估

我们为每个数据集提供 ground_truth.txt。参考数据采用光纤 IMU 的框架。在比较结果之前,您应该进行坐标转换。对于包含 IMU 的估计器,GICI 以 IMU 框架输出解决方案。我们提供将参考值转换为 IMU 框架的工具。首先要编译这个工具:

cd \<gici-root-directory\>tools/evaluation/alignment
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j8

cd \<gici-root-directory\>tools/evaluation/format_converters
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j8

然后,您可以通过以下方法转换参考值:

\<gici-root-directory\>tools/evaluation/format_converters/build/ie_to_nmea ground_truth.txt
\<gici-root-directory\>tools/evaluation/alignment/build/nmea_pose_to_pose ground_truth.txt.nmea

nmea_pose_to_pose.cpp 中的默认设置是将姿势从光纤 IMU 帧转换为数据集的 IMU 帧。如果您有其他要求,应修改 nmea_pose_to_pose.cpp 中的参数。现在,您将获得以 NMEA 格式转换的参考值文件 ground_truth.txt.nmea.transformed。为了便于可视化,您可以通过以下方法将该文件转换为 TUM 格式

\<gici-root-directory\>tools/evaluation/format_converters/build/nmea_to_tum ground_truth.txt.nmea.transformed

还可以将 GICI NMEA 输出转换为 TUM 格式,然后用任何软件进行比较。

对于纯 GNSS 估计器,GICI 以 GNSS 天线框架输出解决方案。您应进一步将参考值转换为 GNSS 天线,方法是

\<gici-root-directory\>tools/evaluation/alignment/build/nmea_pose_to_position ground_truth.txt.nmea.transformed

现在您会得到一个参考值文件 ground_truth.txt.nmea.transformed.translated。然后就可以继续上面的操作了。
nd_truth.txt.nmea


nmea_pose_to_pose.cpp 中的默认设置是将姿势从光纤 IMU 帧转换为数据集的 IMU 帧。如果您有其他要求,应修改 nmea_pose_to_pose.cpp 中的参数。现在,您将获得以 NMEA 格式转换的参考值文件 ground_truth.txt.nmea.transformed。为了便于可视化,您可以通过以下方法将该文件转换为 TUM 格式

```bash
\<gici-root-directory\>tools/evaluation/format_converters/build/nmea_to_tum ground_truth.txt.nmea.transformed

还可以将 GICI NMEA 输出转换为 TUM 格式,然后用任何软件进行比较。

对于纯 GNSS 估计器,GICI 以 GNSS 天线框架输出解决方案。您应进一步将参考值转换为 GNSS 天线,方法是

\<gici-root-directory\>tools/evaluation/alignment/build/nmea_pose_to_position ground_truth.txt.nmea.transformed

现在您会得到一个参考值文件 ground_truth.txt.nmea.transformed.translated。然后就可以继续上面的操作了。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/daoge2666/article/details/133343492

智能推荐

使用nginx解决浏览器跨域问题_nginx不停的xhr-程序员宅基地

文章浏览阅读1k次。通过使用ajax方法跨域请求是浏览器所不允许的,浏览器出于安全考虑是禁止的。警告信息如下:不过jQuery对跨域问题也有解决方案,使用jsonp的方式解决,方法如下:$.ajax({ async:false, url: 'http://www.mysite.com/demo.do', // 跨域URL ty..._nginx不停的xhr

在 Oracle 中配置 extproc 以访问 ST_Geometry-程序员宅基地

文章浏览阅读2k次。关于在 Oracle 中配置 extproc 以访问 ST_Geometry,也就是我们所说的 使用空间SQL 的方法,官方文档链接如下。http://desktop.arcgis.com/zh-cn/arcmap/latest/manage-data/gdbs-in-oracle/configure-oracle-extproc.htm其实简单总结一下,主要就分为以下几个步骤。..._extproc

Linux C++ gbk转为utf-8_linux c++ gbk->utf8-程序员宅基地

文章浏览阅读1.5w次。linux下没有上面的两个函数,需要使用函数 mbstowcs和wcstombsmbstowcs将多字节编码转换为宽字节编码wcstombs将宽字节编码转换为多字节编码这两个函数,转换过程中受到系统编码类型的影响,需要通过设置来设定转换前和转换后的编码类型。通过函数setlocale进行系统编码的设置。linux下输入命名locale -a查看系统支持的编码_linux c++ gbk->utf8

IMP-00009: 导出文件异常结束-程序员宅基地

文章浏览阅读750次。今天准备从生产库向测试库进行数据导入,结果在imp导入的时候遇到“ IMP-00009:导出文件异常结束” 错误,google一下,发现可能有如下原因导致imp的数据太大,没有写buffer和commit两个数据库字符集不同从低版本exp的dmp文件,向高版本imp导出的dmp文件出错传输dmp文件时,文件损坏解决办法:imp时指定..._imp-00009导出文件异常结束

python程序员需要深入掌握的技能_Python用数据说明程序员需要掌握的技能-程序员宅基地

文章浏览阅读143次。当下是一个大数据的时代,各个行业都离不开数据的支持。因此,网络爬虫就应运而生。网络爬虫当下最为火热的是Python,Python开发爬虫相对简单,而且功能库相当完善,力压众多开发语言。本次教程我们爬取前程无忧的招聘信息来分析Python程序员需要掌握那些编程技术。首先在谷歌浏览器打开前程无忧的首页,按F12打开浏览器的开发者工具。浏览器开发者工具是用于捕捉网站的请求信息,通过分析请求信息可以了解请..._初级python程序员能力要求

Spring @Service生成bean名称的规则(当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致)_@service beanname-程序员宅基地

文章浏览阅读7.6k次,点赞2次,收藏6次。@Service标注的bean,类名:ABDemoService查看源码后发现,原来是经过一个特殊处理:当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致public class AnnotationBeanNameGenerator implements BeanNameGenerator { private static final String C..._@service beanname

随便推点

二叉树的各种创建方法_二叉树的建立-程序员宅基地

文章浏览阅读6.9w次,点赞73次,收藏463次。1.前序创建#include&lt;stdio.h&gt;#include&lt;string.h&gt;#include&lt;stdlib.h&gt;#include&lt;malloc.h&gt;#include&lt;iostream&gt;#include&lt;stack&gt;#include&lt;queue&gt;using namespace std;typed_二叉树的建立

解决asp.net导出excel时中文文件名乱码_asp.net utf8 导出中文字符乱码-程序员宅基地

文章浏览阅读7.1k次。在Asp.net上使用Excel导出功能,如果文件名出现中文,便会以乱码视之。 解决方法: fileName = HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8);_asp.net utf8 导出中文字符乱码

笔记-编译原理-实验一-词法分析器设计_对pl/0作以下修改扩充。增加单词-程序员宅基地

文章浏览阅读2.1k次,点赞4次,收藏23次。第一次实验 词法分析实验报告设计思想词法分析的主要任务是根据文法的词汇表以及对应约定的编码进行一定的识别,找出文件中所有的合法的单词,并给出一定的信息作为最后的结果,用于后续语法分析程序的使用;本实验针对 PL/0 语言 的文法、词汇表编写一个词法分析程序,对于每个单词根据词汇表输出: (单词种类, 单词的值) 二元对。词汇表:种别编码单词符号助记符0beginb..._对pl/0作以下修改扩充。增加单词

android adb shell 权限,android adb shell权限被拒绝-程序员宅基地

文章浏览阅读773次。我在使用adb.exe时遇到了麻烦.我想使用与bash相同的adb.exe shell提示符,所以我决定更改默认的bash二进制文件(当然二进制文件是交叉编译的,一切都很完美)更改bash二进制文件遵循以下顺序> adb remount> adb push bash / system / bin /> adb shell> cd / system / bin> chm..._adb shell mv 权限

投影仪-相机标定_相机-投影仪标定-程序员宅基地

文章浏览阅读6.8k次,点赞12次,收藏125次。1. 单目相机标定引言相机标定已经研究多年,标定的算法可以分为基于摄影测量的标定和自标定。其中,应用最为广泛的还是张正友标定法。这是一种简单灵活、高鲁棒性、低成本的相机标定算法。仅需要一台相机和一块平面标定板构建相机标定系统,在标定过程中,相机拍摄多个角度下(至少两个角度,推荐10~20个角度)的标定板图像(相机和标定板都可以移动),即可对相机的内外参数进行标定。下面介绍张氏标定法(以下也这么称呼)的原理。原理相机模型和单应矩阵相机标定,就是对相机的内外参数进行计算的过程,从而得到物体到图像的投影_相机-投影仪标定

Wayland架构、渲染、硬件支持-程序员宅基地

文章浏览阅读2.2k次。文章目录Wayland 架构Wayland 渲染Wayland的 硬件支持简 述: 翻译一篇关于和 wayland 有关的技术文章, 其英文标题为Wayland Architecture .Wayland 架构若是想要更好的理解 Wayland 架构及其与 X (X11 or X Window System) 结构;一种很好的方法是将事件从输入设备就开始跟踪, 查看期间所有的屏幕上出现的变化。这就是我们现在对 X 的理解。 内核是从一个输入设备中获取一个事件,并通过 evdev 输入_wayland

推荐文章

热门文章

相关标签