激光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

相关文章

Linux系统中查询JDK安装目录的几种常用方法

《Linux系统中查询JDK安装目录的几种常用方法》:本文主要介绍Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目... 目录方法 1:通过update-alternatives查询(推荐)方法 2:检查所有已安装的 JDK方

Linux系统之lvcreate命令使用解读

《Linux系统之lvcreate命令使用解读》lvcreate是LVM中创建逻辑卷的核心命令,支持线性、条带化、RAID、镜像、快照、瘦池和缓存池等多种类型,实现灵活存储资源管理,需注意空间分配、R... 目录lvcreate命令详解一、命令概述二、语法格式三、核心功能四、选项详解五、使用示例1. 创建逻

Java获取当前时间String类型和Date类型方式

《Java获取当前时间String类型和Date类型方式》:本文主要介绍Java获取当前时间String类型和Date类型方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录Java获取当前时间String和Date类型String类型和Date类型输出结果总结Java获取

Python实现批量提取BLF文件时间戳

《Python实现批量提取BLF文件时间戳》BLF(BinaryLoggingFormat)作为Vector公司推出的CAN总线数据记录格式,被广泛用于存储车辆通信数据,本文将使用Python轻松提取... 目录一、为什么需要批量处理 BLF 文件二、核心代码解析:从文件遍历到数据导出1. 环境准备与依赖库

Spring Boot配置和使用两个数据源的实现步骤

《SpringBoot配置和使用两个数据源的实现步骤》本文详解SpringBoot配置双数据源方法,包含配置文件设置、Bean创建、事务管理器配置及@Qualifier注解使用,强调主数据源标记、代... 目录Spring Boot配置和使用两个数据源技术背景实现步骤1. 配置数据源信息2. 创建数据源Be

使用Python构建一个高效的日志处理系统

《使用Python构建一个高效的日志处理系统》这篇文章主要为大家详细讲解了如何使用Python开发一个专业的日志分析工具,能够自动化处理、分析和可视化各类日志文件,大幅提升运维效率,需要的可以了解下... 目录环境准备工具功能概述完整代码实现代码深度解析1. 类设计与初始化2. 日志解析核心逻辑3. 文件处

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

Javaee多线程之进程和线程之间的区别和联系(最新整理)

《Javaee多线程之进程和线程之间的区别和联系(最新整理)》进程是资源分配单位,线程是调度执行单位,共享资源更高效,创建线程五种方式:继承Thread、Runnable接口、匿名类、lambda,r... 目录进程和线程进程线程进程和线程的区别创建线程的五种写法继承Thread,重写run实现Runnab

go中的时间处理过程

《go中的时间处理过程》:本文主要介绍go中的时间处理过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1 获取当前时间2 获取当前时间戳3 获取当前时间的字符串格式4 相互转化4.1 时间戳转时间字符串 (int64 > string)4.2 时间字符串转时间