激光slam坐标系和视觉slam坐标系对齐,两个slam系统之间坐标对齐,轨迹对齐,时间戳对齐

本文主要是介绍激光slam坐标系和视觉slam坐标系对齐,两个slam系统之间坐标对齐,轨迹对齐,时间戳对齐,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 面临的问题

两个独立的SLAM系统中,常常面临一个问题,那就是一个系统上的某一个pose,对应到另一个系统中是在哪里?

紧耦合的SLAM系统,不存在这个问题,比如激光雷达和相机融合的SLAM系统,它们不存在上述问题!

造成这种关系不确定的最主要原因是:两个系统各自有自己的一个参考系。如果它俩在一个统一的世界参考系下,那么就不存在上述的问题。

我们立马想到的一个办法是,我让两个SLAM系统同时开机运行,那么开机运行那一刻的原点不就是它们的坐标原点了嘛!但是你能保证两个SLAM系统都是一开机运行就能初始化成功吗?对于单目视觉slam,它的世界坐标系是在初始化成功的第一帧。也就是说可能开机运行了一段时间之后,它才出现自己的世界坐标系。而激光SLAM、RGBD SLAM、立体相机SLAM情况又不一样。

所以我们需要一种更通用的方法,来解决两个坐标系的对应问题。

以下分析方法,对于多于两个的SLAM系统也适用!

2. 问题分析

如果用几何来描述这个问题,可以通过下图来表示:

在这里插入图片描述

图 1

坐标系 O − x y z O-xyz Oxyz和坐标系 O ′ − x ′ y ′ z ′ O'-x'y'z' Oxyz分别表示两个SLAM系统的坐标原点,只要能找到这两个坐标系之间的变换关系,那么两个坐标系下的位姿就可以通过这个变换关系相互变换。

假设我们已经求出来了 O → O ′ O \rightarrow O' OO的变换矩阵为 T O ′ O T_{O'O} TOO

那么, O − x y z O-xyz Oxyz坐标系下的某一个位姿 P O P_{O} PO转换到 O ′ − x ′ y ′ z ′ O'-x'y'z' Oxyz坐标系下可以通过如下公式:
P O ′ = T O ′ O P O (0) P_{O}' = T_{O'O} P_{O} \tag{0} PO=TOOPO(0)

反过来, O ′ − x ′ y ′ z ′ O'-x'y'z' Oxyz坐标系下的位姿 P O ′ P_O' PO的到 O − x y z O-xyz Oxyz变换:
P O = T O ′ O − 1 P O ′ (1) P_{O}= T_{O'O}^{-1} P_{O}' \tag{1} PO=TOO1PO(1)

上面介绍的变换是刚性变换,有时可能面临尺度不统一的问题,那么刚性变换就不能满足条件了,必须使用sim3变换。

3. 解法

要求解上述的变换矩阵,只需要找到几对对应点,比如 O − x y z O-xyz Oxyz坐标系下的某一个点,对应找到它在 O ′ − x ′ y ′ z ′ O'-x'y'z' Oxyz坐标系下位置,就这样就形成了一个对应点对,如果能找到多对这样的点对,那么势必是可以求解出这样的变化矩阵 T T T。这里我就不卖关子了,通过这种对应关系求解变换矩阵的方法很多,其中一种比较常用的方法是:umeyama algorithm,它实际上就是通过最小二乘的思路推导出来的,它不但可以求解刚性变换,还可以求解sim3变换。

该算法我自己实现了一个版本,如果需要可以参考:align_trajectory

4.工程中具体做法

4.1根据时间戳找匹配

我们的机器人上可能同时安装了激光雷达和相机,它们可以同时开始运行或者先后运行两个独立的SLAM系统,那么此时就需要统一两个坐标系,由于它们刚性连接,所以它们最终必然产生相似的轨迹形状。

暂时是假设两个SLAM系统精度都比较高,或者比较相近,因为只有这样轨迹形状才会很相似。

对于这种情形,可以采用的坐标系统一方法是:按时间戳对齐。

由于激光雷达和相机被固定连接在一起,所以某一个时刻它们必定处在同一个真实空间位置。那么只需要根据时间戳,取出该时刻下两个传感器对应获得的位姿。根据多个时间戳最终就可以获得多对这样的匹配,然后采用umeyama algorithm,就可以求出两个坐标系之间的变换矩阵。

由于时间戳的精度比较高,有可能激光雷达坐标系下的某一个位姿,在当前时间戳下,相机坐标系并没有与之对应的位姿,此就需要根据实际情况扩大时间戳的范围,比方说在当前时间戳前后0.01秒之内的,可以认为是对应的位姿。

4.2 根据空间位置找匹配

此种方式限制性更小一些。

多数情况下激光雷达建图是会比视觉建图更琐碎一些,可能要控制机器人在环境中来回的运动,对于更大的环境,甚至还需要一点儿点儿精细的对环境进行建图,如果此时相机与激光雷达同时运行势必会浪费很多计算资源和空间,可能还会给视觉带来更大的累计误差,所以最好的方式应该是激光雷达先进行建图,然后打开激光雷达的重定位功能,进行实时的重定位,然后相机进行视觉SLAM功能,视觉SLAM当前时刻跟踪出来的位姿,与当前激光雷达重定位获得的位姿就形成了一对对应点,同样的可以获得很多这样的对应点对。进一步还可以根据激光雷达的定位置信度选择定位更准的点。然后根据umeyama algorithm算法求解出来两个坐标系之间的变换矩阵。

如果你使用的是单线激光雷达,那么势必就少了一个维度(高度上)的信息,而相机恢复出来的是三维信息,不过这并不影响,在实际使用umeyama algorithm时,只需要将激光雷达的高度数据设置为0

这种方法不但适用激光雷达与相机,甚至里程计与相机,里程计与激光雷达,相机与相机,激光雷达与激光雷达,只要是能获得重新定位的能力,此种方法理论上就是适用的。

可能你会怀疑这种方法的精度,实际来说这种精度的误差主要还是来自于SLAM本身,或者测量误差,一旦你能很精准的获得匹配关系,这种误差实际上很小的。

我做过一个实验,1400多米长的轨迹,分别使用激光雷达和相机进行SLAM,最终通过时间戳进行轨迹对齐,它们的误差非常小,可能只是因为SLAM精度带来了这种影响。如果你好奇具体做法,可以参考我github上的代码:align_trajectory
在这里插入图片描述

这篇关于激光slam坐标系和视觉slam坐标系对齐,两个slam系统之间坐标对齐,轨迹对齐,时间戳对齐的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1033709

相关文章

python处理带有时区的日期和时间数据

《python处理带有时区的日期和时间数据》这篇文章主要为大家详细介绍了如何在Python中使用pytz库处理时区信息,包括获取当前UTC时间,转换为特定时区等,有需要的小伙伴可以参考一下... 目录时区基本信息python datetime使用timezonepandas处理时区数据知识延展时区基本信息

Python的time模块一些常用功能(各种与时间相关的函数)

《Python的time模块一些常用功能(各种与时间相关的函数)》Python的time模块提供了各种与时间相关的函数,包括获取当前时间、处理时间间隔、执行时间测量等,:本文主要介绍Python的... 目录1. 获取当前时间2. 时间格式化3. 延时执行4. 时间戳运算5. 计算代码执行时间6. 转换为指

Java中字符串转时间与时间转字符串的操作详解

《Java中字符串转时间与时间转字符串的操作详解》Java的java.time包提供了强大的日期和时间处理功能,通过DateTimeFormatter可以轻松地在日期时间对象和字符串之间进行转换,下面... 目录一、字符串转时间(一)使用预定义格式(二)自定义格式二、时间转字符串(一)使用预定义格式(二)自

使用Python从PPT文档中提取图片和图片信息(如坐标、宽度和高度等)

《使用Python从PPT文档中提取图片和图片信息(如坐标、宽度和高度等)》PPT是一种高效的信息展示工具,广泛应用于教育、商务和设计等多个领域,PPT文档中常常包含丰富的图片内容,这些图片不仅提升了... 目录一、引言二、环境与工具三、python 提取PPT背景图片3.1 提取幻灯片背景图片3.2 提取

Java中Date、LocalDate、LocalDateTime、LocalTime、时间戳之间的相互转换代码

《Java中Date、LocalDate、LocalDateTime、LocalTime、时间戳之间的相互转换代码》:本文主要介绍Java中日期时间转换的多种方法,包括将Date转换为LocalD... 目录一、Date转LocalDateTime二、Date转LocalDate三、LocalDateTim

利用Python快速搭建Markdown笔记发布系统

《利用Python快速搭建Markdown笔记发布系统》这篇文章主要为大家详细介绍了使用Python生态的成熟工具,在30分钟内搭建一个支持Markdown渲染、分类标签、全文搜索的私有化知识发布系统... 目录引言:为什么要自建知识博客一、技术选型:极简主义开发栈二、系统架构设计三、核心代码实现(分步解析

golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法

《golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法》:本文主要介绍golang获取当前时间、时间戳和时间字符串及它们之间的相互转换,本文通过实例代码给大家介绍的非常详细,感兴趣... 目录1、获取当前时间2、获取当前时间戳3、获取当前时间的字符串格式4、它们之间的相互转化上篇文章给大家介

Feign Client超时时间设置不生效的解决方法

《FeignClient超时时间设置不生效的解决方法》这篇文章主要为大家详细介绍了FeignClient超时时间设置不生效的原因与解决方法,具有一定的的参考价值,希望对大家有一定的帮助... 在使用Feign Client时,可以通过两种方式来设置超时时间:1.针对整个Feign Client设置超时时间

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整