jjzjj

SLAM算法评测工具——开源工具EVO(以VINS为例)

Terrence Shen 2024-07-22 原文

EVO库是一个很方便的开源库(Python package for the evaluation of odometry and SLAM),
evo是一个很好的测评工具,它可以根据时间戳将轨迹进行对齐,同时可以将不同尺度的轨迹按照你指定的标准轨迹进行拉伸对齐,并可以算出均方差等评定参数,用于测评slam算法性能。

下载:

github链接:https://github.com/MichaelGrupp/evo

与其他公共基准测试工具相比,evo 有几个优势:

  1. 不同格式的通用工具 用于单目 SLAM 等的关联、对齐、比例调整的算法选项。
  2. 灵活的输出、绘图或导出选项(例如 LaTeX 绘图或 Excel 表格)
  3. 一个强大的、可配置的 CLI,可以涵盖许多用例
  4. 用于自定义扩展的模块化核心和工具库
  5. 比其他已建立的基于 Python 的工具更快(参见此处)

主要有如下几个常用命令:

从源码安装

git clone https://github.com/MichaelGrupp/evo.git
cd evo
pip install --editable . --upgrade --no-binary evo

案例:

cd test/data
evo_traj kitti KITTI_00_ORB.txt KITTI_00_SPTAM.txt --ref=KITTI_00_gt.txt -p --plot_mode=xz

自己的使用记录

运行了VINS-mono和PL-vins 对比了一组在开源数据集EuRoC下的结果,大概步骤是先 各自把程序运行结果利用 evo_traj tum 改为统一的 .tum格式,
再利用 evo_ape tum 把两组结果放在一个图里对比误差情况。




具体步骤如下:

数据格式(data formal):TUM/EuRoC/Kitti数据集
格式转换

1、 TUM数据集格式

2、 EuRoC数据集格式

3、 KITTI数据集格式

修改VINS-mono轨迹保存代码
由于VINS-Mono保存的轨迹格式与EVO所使用的格式不同,VISNmono输出的轨迹格式不符合tum数据集和euroc数据集的格式。因此需要对源代码就行修改,更改保存轨迹的格式。(如果只有一条轨迹也可以直接需要输出的csv文件,但是如果要反复评估一个算法的话,比如运行10次求平均值,这样还是修改源代码方便一点)

修改下列两个文件,共计3个地方

1.vins_estimator/src/utility/visualization.cpp
2.pose_graph/src/pose_graph.cpp

修改 visualization.cpp
找到以下代码段

 // write result to file
	 ofstream foutC(VINS_RESULT_PATH, ios::app);
	 foutC.setf(ios::fixed, ios::floatfield);
	 foutC.precision(0);
	 foutC << header.stamp.toSec() * 1e9 << ",";
	 foutC.precision(5);
	 foutC << estimator.Ps[WINDOW_SIZE].x() << ","
	       << estimator.Ps[WINDOW_SIZE].y() << ","
	       << estimator.Ps[WINDOW_SIZE].z() << ","
	       << tmp_Q.w() << ","
	       << tmp_Q.x() << ","
	       << tmp_Q.y() << ","
	       << tmp_Q.z() << ","
	       << estimator.Vs[WINDOW_SIZE].x() << ","
	       << estimator.Vs[WINDOW_SIZE].y() << ","
	       << estimator.Vs[WINDOW_SIZE].z() << "," << endl;

修改代码为:

// write result to file
	 ofstream foutC(VINS_RESULT_PATH, ios::app);
	 foutC.setf(ios::fixed, ios::floatfield);
	 foutC.precision(9);
	 foutC << header.stamp.toSec() << " ";
	 foutC.precision(5);
	 foutC << estimator.Ps[WINDOW_SIZE].x() << " "
	       << estimator.Ps[WINDOW_SIZE].y() << " "
	       << estimator.Ps[WINDOW_SIZE].z() << " "
	       << tmp_Q.x() << " "
	       << tmp_Q.y() << " "
	       << tmp_Q.z() << " "
	       << tmp_Q.w() << endl;
	       //<< estimator.Vs[WINDOW_SIZE].x() << ","
	       //<< estimator.Vs[WINDOW_SIZE].y() << ","
	       //<< estimator.Vs[WINDOW_SIZE].z() << "," << endl;
	 foutC.close();

修改 pose_graph.cpp
1) 在路径 /pose_graph/src/pose_graph.cpp 在函数 addKeyFrame() 中 找到以下代码段

if (SAVE_LOOP_PATH)
{
		    ofstream loop_path_file(VINS_RESULT_PATH, ios::app);
        loop_path_file.setf(ios::fixed, ios::floatfield);
        loop_path_file.precision(0);
        loop_path_file << cur_kf->time_stamp * 1e9 << ",";
        loop_path_file.precision(5);
        loop_path_file  << P.x() << ","
              << P.y() << ","
              << P.z() << ","
              << Q.w() << ","
              << Q.x() << ","
              << Q.y() << ","
              << Q.z() << ","
              << endl;
        loop_path_file.close();
 }

修改为:

if (SAVE_LOOP_PATH)
{
		    ofstream loop_path_file(VINS_RESULT_PATH, ios::app);
        loop_path_file.setf(ios::fixed, ios::floatfield);
        loop_path_file.precision(9);
        loop_path_file << cur_kf->time_stamp  << " ";
        loop_path_file.precision(5);
        loop_path_file  << P.x() << " "
              << P.y() << " "
              << P.z() << " "
              << Q.x() << " "
              << Q.y() << " "
              << Q.z() << " "
              << Q.w() << endl;
        loop_path_file.close();
 }

2) 在路径 /pose_graph/src/pose_graph.cpp 在函数 updatePath() 中 找到以下代码段

if (SAVE_LOOP_PATH)
        {
            ofstream loop_path_file(VINS_RESULT_PATH, ios::app);
            loop_path_file.setf(ios::fixed, ios::floatfield);
            loop_path_file.precision(0);
            loop_path_file << (*it)->time_stamp * 1e9 << ",";
            loop_path_file.precision(5);
            loop_path_file  << P.x() << ","
                  << P.y() << ","
                  << P.z() << ","
                  << Q.w() << ","
                  << Q.x() << ","
                  << Q.y() << ","
                  << Q.z() << ","
                  << endl;
            loop_path_file.close();
        }

修改为:

if (SAVE_LOOP_PATH)
        {
            ofstream loop_path_file(VINS_RESULT_PATH, ios::app);
            loop_path_file.setf(ios::fixed, ios::floatfield);
            loop_path_file.precision(9);
            loop_path_file << (*it)->time_stamp << " ";
            loop_path_file.precision(5);
            loop_path_file  << P.x() << " "
                  << P.y() << " "
                  << P.z() << " "
                  << Q.x() << " "
                  << Q.y() << " "
                  << Q.z() << " "
                  << Q.w() << endl;
            loop_path_file.close();
        }

修改VINS-mono运行参数
在路径 VINS-Mono/config/euroc 下有配置文件 euroc_config.yaml

output_path: 设置轨迹保存位置
pose_graph_save_path 设置位姿图保存位置
loop_closure: 0 表示不使用回环 1表示使用回环
estimate_td: 0表示不估计传感器之间的延时 1表示启动

运行代码获得轨迹信息

roscore
roslaunch vins_estimator euroc.launch 
roslaunch vins_estimator vins_rviz.launch
rosbag play MH_01_easy.bag

本文以VINS为例子介绍如何使用evo评估其在Euroc数据集上的效果。数据集网站:The EuRoC MAV Dataset。数据集采用MH_01_easy.bag。

euroc的评估支持 .csv的groudtruth 和 tum 格式的轨迹文件. 虽然我们使用的是euroc数据集,但evo只支持tum格式的绘制,它提供了euroc格式转tum格式的工具。 首先我们打开数据集的state_groundtruth_estimate0/文件夹,会发现有一个文件: data.csv。这是一个euroc格式的文件,我们首先要把他转成tum格式。输入以下命令:

evo_traj euroc data.csv --save_as_tum

生成data.tum

evo评测
单条轨迹

首先设置回环(loop_closure: 1),重载地图(load_previous_pose_graph: 0),快速定位(fast_relocalization: 0)。

经过我们上面的修改,该文件是符合tum格式的轨迹输出以及数据集提供的真值state_groundtruth_estimate0/data.csv(由下载的zip格式的数据解压得到)。

使用evo_traj 显示轨迹
首先我们可以使用 evo_traj将轨迹画出来。
~/vins-mono/output_pose_graph$ evo_traj tum vins_result_no_loop.csv -p --plot_mode=xyz




使用evo_ape(地图用颜色深浅表示)确定轨迹绝对位姿误差

evo_ape euroc data.csv vins_result_no_loop.csv -va --plot --plot_mode xyz --save_results a.zip

终端输出:

Synchronizing trajectories...
Found 1817 of max. 1828 possible matching timestamps between...
	data.csv
and:	vins_result_no_loop.csv
..with max. time diff.: 0.01 (s) and time offset: 0.0 (s).
--------------------------------------------------------------------------------
Aligning using Umeyama's method...
Rotation of alignment:
[[-0.88919506 -0.45728639  0.01487636]
 [ 0.45736642 -0.88927532  0.00231603]
 [ 0.01217009  0.00886335  0.99988666]]
Translation of alignment:
[ 4.58596346 -1.65593626  0.77392133]
Scale correction: 1.0
--------------------------------------------------------------------------------
Compared 1817 absolute pose pairs.
Calculating APE for translation part pose relation...
--------------------------------------------------------------------------------
APE w.r.t. translation part (m)
(with SE(3) Umeyama alignment)

       max	0.349640
      mean	0.144082
    median	0.140714
       min	0.034372
      rmse	0.154602
       sse	43.429475
       std	0.056053


多条轨迹
同时显示回环轨迹和真值轨迹:

evo_traj tum vins_result_loop.txt --ref=data.tum -p --plot_mode=xyz --align --correct_scale

evo还可以将两个结果放在一个图中,进行对比。参数中的两个zip文件就是刚刚前面生成的。

evo_res a.zip b.zip -p --save_table table.csv


这就是上面举例子里面放的那一类图,可以用来评测各个不同的SLAM算法的好坏。

有关SLAM算法评测工具——开源工具EVO(以VINS为例)的更多相关文章

  1. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  2. 区块链之加解密算法&数字证书 - 2

    目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非

  3. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  4. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  5. ruby-on-rails - 有没有一种工具可以在编码时自动保存对文件的增量更改? - 2

    我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功

  6. ruby - 使用 Ruby 开发工具包将文件上传到 Amazon S3 - 2

    我正在尝试上传文件。一个简单的hello.txt。我正在关注文档,但无法将其上传到我的存储桶。#STARTAWSCLIENTs3=Aws::S3::Resource.newbucket=s3.bucket(BUCKET_NAME)begins3.buckets[BUCKET_NAME].objects[KEY].write(:file=>FILE_NAME)puts"Uploadingfile#{FILE_NAME}tobucket#{BUCKET_NAME}."bucket.objects.eachdo|obj|puts"#{obj.key}=>#{obj.etag}"endresc

  7. ruby - 在 StockChart (highchart) 中以编程方式显示柱形图的工具提示 - 2

    我有一个Highstock图表(带有标记和阴影的线条),并且想以编程方式显示一个highstock工具提示,例如,当我选择某个表上的一行(包含图表数据)我想显示相应的highstock工具提示。这可能吗? 最佳答案 股票图表thissolution不起作用:在thisexample你必须更换这个:chart.tooltip.refresh(chart.series[0].data[i]);为此:chart.tooltip.refresh([chart.series[0].points[i]]);解决方案可用here.

  8. u盘安装系统(win10为例) - 2

    下载微PE工具箱进入官网下载微PE工具箱-下载 安装好后,打开微PE工具箱客户端,选择安装PE到U盘 PE壁纸可选择自己喜欢的壁纸,勾选上包含DOS工具箱,个性化盘符图标 下载原版系统进入网站下载镜像NEXT,ITELLYOU如果没有账号,注册一下就好进入选择开始使用选择win10 这里我们选择消费者版,用迅雷把BT种子下载下来 下面的两个盘符,是PE工具箱安装进U盘后,分成的盘符,注意EFI的盘符,这里面不能删东西,也不能添东西,另一个盘符可以当做正常的U盘空间使用,我们现在需要把下载下来的景象文件复制到正常的U盘空间中去 这个时候我们的系统U盘就只做好了 安装系统我们将U盘插入电脑,开机,

  9. 100个python算法超详细讲解:画直线 - 2

    1.问题描述使用Python的turtle(海龟绘图)模块提供的函数绘制直线。2.问题分析一幅复杂的图形通常都可以由点、直线、三角形、矩形、平行四边形、圆、椭圆和圆弧等基本图形组成。其中的三角形、矩形、平行四边形又可以由直线组成,而直线又是由两个点确定的。我们使用Python的turtle模块所提供的函数来绘制直线。在使用之前我们先介绍一下turtle模块的相关知识点。turtle模块提供面向对象和面向过程两种形式的海龟绘图基本组件。面向对象的接口类如下:1)TurtleScreen类:定义图形窗口作为绘图海龟的运动场。它的构造器需要一个tkinter.Canvas或ScrolledCanva

  10. ABB-IRB-1200运动学分析MATLAB RVC工具分析+Simulink-Adams联合仿真 - 2

    一、机器人介绍        此处是基于MATLABRVC工具箱,对ABB-IRB-1200型号的微型机械臂进行正逆向运动学分析,并利Simulink工具实现对机械臂进行具有动力学参数的末端轨迹规划仿真,最后根据机械模型设计Simulink-Adams联合仿真。 图1.ABBIRB 1200尺寸参数示意图ABBIRB 1200提供的两种型号广泛适用于各作业,且两者间零部件通用,两种型号的工作范围分别为700 mm 和 900 mm,大有效负载分别为 7 kg 和5 kg。 IRB 1200 能够在狭小空间内能发挥其工作范围与性能优势,具有全新的设计、小型化的体积、高效的性能、易于集成、便捷的接

随机推荐