14

Lidar与IMU标定代码实战:lidar_align

 3 years ago
source link: https://mp.weixin.qq.com/s/wHnc6ZmbnGVwtlX3YVyY1Q
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

点击上方“3D视觉工坊”,选择“星标”

干货第一时间送达Image本文转载自「计算机视觉工坊」,该公众号重点在于介绍深度学习、智能驾驶等领域,一个小众的公众号。

0. 前言

对于Lidar+IMU系统,往往需要标定Lidar与IMU的外参[4],即从Lidar到IMU的6个位姿参数。ETH开源的lidar_align代码[0],用于标定Lidar和里程计Odom之间的位姿参数。本文将对代码进行初步介绍,并总结一些使用中可能会遇到的问题。

1. 代码整体一览

1.1 代码结构

代码主要包括:头文件、cpp、以及ROS的launch启动文件等。其中头文件包括:aligner.h:Lidar和Odom对齐(外参计算)时用到的类loader.h:从ROS的Bag或CSV格式载入数据的相关函数sensors.h:主要包括:里程计Odom,以及雷达Lidar相关接口transform.h:一些SO3变化的计算以及转换,在插值、优化时使用

1.2 方法基本思想

方法本质解决的是一个优化问题,即在外参参数(6DoF)如何选择时,使Lidar采集到的数据转化到Odom系下后,前后两次scan的数据点能够尽可能的重合。详细一点儿来说,方法将Lidar数据根据当前假设的状态变量(6DoF参数)变换到Odom系下,构成点云PointCloud,之后对每一次scan时的数据,在下一次scan中通过kdtree的方式寻找最近邻的数据点并计算距离,当总距离最小时可以认为完全匹配,即计算的外参参数正确。

1.3 主要流程

代码主要有两部分:载入数据优化计算。载入数据部分从Bag数据载入雷达的数据(sensor_msgs/PointCloud2),并从CSV或Bag数据中载入Odom获得的6DoF位置信息。具体的位置信息如何获得将在后面进行介绍。优化计算部分将在第2.2小节详细展开。

2. 详细介绍

2.1 主要数据类型

Odom数据:主要包括两个数据:时间戳timestamp_us_与从当前时刻到初始时刻的变换T_o0_ot_。Lidar数据:主要包括两个参数:从Lidar到Odom的外参T_o_l_与每次扫描的数据scans_,而每次的扫描scan数据类型主要包括:扫描起始时间timestamp_us_,本次扫描的点云raw_points_,某个点在Odom的变换(用于去畸变)T_o0_ot_,以及相关配置参数等。Aligner数据:Aligner首先包含了需要优化的数据OptData(其中包括Lidar、Odom等数据),以及相应的配置参数(数据载入路径、初值、优化参数、KNN相关参数等),以及优化计算的相关参数。

2.2 优化过程详细介绍

在载入了Odom和Lidar数据之后,进行优化求解6个位姿参数。主要求解函数为:lidarOdomTransformAligner::lidarOdomTransform()首先进行相关的优化配置。默认优化参数是6个,但可以考虑两个传感器传输造成的时间差,如果考虑这个因素,参数数量将变为7。优化时,采用NLOPT优化库[3],默认首先全局优化这三个参数。如果提供的初值与真值相差较大,或完全没有设置初值(默认为全0),则需要进行全局优化获得旋转参数。在局部优化这6个参数,局部优化开始时的初值就是3个为0的平移参数,以及全局优化计算出来的旋转参数。全局优化、局部优化,都是调用的optimize函数。Aligner::optimize()在这个函数设置了NLOPT优化的相关参数,包括:是全局优化还是局部优化、优化问题的上下界、最大迭代次数、求解精度以及目标函数等。最重要的是目标函数LidarOdomMinimizerLidarOdomMinimizer()这个函数在优化中会不断调用,迭代计算。首先会通过上一时刻的状态,计算新的从Lidar到Odom的变换(这里用到了Transform.h中定义的一些变换),误差是由lidarOdomKNNError函数获得。lidarOdomKNNError()这个是一个重载函数,具有两种重载类型。首先调用的是lidarOdomKNNError(const Lidar),处理的是Lidar的数据,首先根据估计的Lidar到Odom的变化,对完整的scans_数据计算出每次scan时每个点在Odom下的坐标(getTimeAlignedPointcloud函数,相当于点云去畸变),得到一个结合的点云(CombinedPointcloud),之后从这个点云中寻找每个点的最近邻,在利用另一个重载类型的lidarOdomKNNError(const Pointcloud, const Pointcloud)函数进行计算最近邻误差。计算最近邻误差时,构建了一个KD-Tree,并行计算kNNError函数,利用pcl库的nearestKSearch函数搜索一定范围(全局优化时是1m,局部优化时是0.1m)的最近邻,计算最近2个点的误差。小结优化的目标函数是每次scan的每个点在完整点云中的最近邻的距离,首先通过粗的全局优化估计一部分参数,再局部优化求解精细的6DoF参数。

3. 配置与运行

3.1 安装

首先在安装时需要安装NLOPT:sudo apt-get install libnlopt-dev。之后把代码拷贝到ros的工作空间,使用 catkin_make进行编译。

3.2 编译可能遇到的问题

这个代码是个人编写使用,没有在大多数的ubuntu和ros版本进行测试,所以可能会遇到各种各样的问题。以Ubuntu18与ROS-melodic为例,首先会遇到一个定义冲突的报错:1. 定义冲突问题error: conflicting declaration ‘typedef struct LZ4_stream_t LZ4_stream_t’ typedef struct { long long table[LZ4_STREAMSIZE_U64]; } LZ4_stream_t;这个原因是ROS版本下有两个头文件定义发生冲突,github的issue中给出了两种解决办法,之一是重命名头文件避免冲突:sudo mv /usr/include/flann/ext/lz4.h /usr/include/flann/ext/lz4.h.baksudo mv /usr/include/flann/ext/lz4hc.h /usr/include/flann/ext/lz4.h.baksudo ln -s /usr/include/lz4.h /usr/include/flann/ext/lz4.hsudo ln -s /usr/include/lz4hc.h /usr/include/flann/ext/lz4hc.h(详见:https://github.com/ethz-asl/lidar_align/issues/16)2. 找不到"FindNLOPT.cmake"By not providing "FindNLOPT.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "NLOPT", but CMake did not find one. Solutions: Move "NLOPTConfig.cmake" file to src directory.解决方法:将"\lidar_align\FindNLOPT.cmake"文件移动到工作路径下中的"\src"文件夹下,再次编译即可。

3.3 测试运行

在github的issue中,由于存在准备数据(尤其是Odom数据)有错误的问题,造成运行失败。作者上传了测试数据https://drive.google.com/open?id=11fUwbVnvej4NZ_0Mntk7XJ2YrZ5Dk3Ub 可以运行测试。

3.4 数据准备

Lidar的数据直接是ros中的sensor_msgs/PointCloud2即可,但位置数据需要提供CSV格式或者ROS下的geometry_msgs/TransformStamped消息类型。后者如何获得?如果是IMU直接进行积分就好,但这样积分势必会不准确,作者也在issue中提到没有考虑noise的问题(https://github.com/ethz-asl/lidar_align/issues/5#issuecomment-432232087 ),所以目前看来对IMU进行积分,凑合使用就好。[1]给出了一种IMU计算Odom的实现。

3.5 数据采集要求

作者在issue和readme中指出,该方法存在的局限性是,必须要求采集数据时系统进行非平面运动,对平移要求不高但要求旋转必须充分。但对数据量、运动范围没有经过严格的测试。这个局限性也限制了不能用于给无人车这种系统标定。

参考资料

[0]. 原版代码github:https://github.com/ethz-asl/lidar_align[1]. IMU数据计算Odom的实现:https://www.cnblogs.com/gangyin/p/13366683.html[2]. lidarr_align原理简要介绍:https://blog.csdn.net/miracle629/article/details/87854450[3]. NLOPT优化库介绍:https://nlopt.readthedocs.io/en/latest[4]. Lidar和IMU标定需要标什么?https://blog.csdn.net/tfb760/article/details/108532974本文仅做学术分享,如有侵权,请联系删文。下载1在「3D视觉工坊」公众号后台回复:3D视觉即可下载 3D视觉相关资料干货,涉及相机标定、三维重建、立体视觉、SLAM、深度学习、点云后处理、多视图几何等方向。下载2在「3D视觉工坊」公众号后台回复:3D视觉github资源汇总即可下载包括结构光、标定源码、缺陷检测源码、深度估计与深度补全源码、点云处理相关源码、立体匹配源码、单目、双目3D检测、基于点云的3D检测、6D姿态估计汇总等。下载3在「3D视觉工坊」公众号后台回复:相机标定即可下载独家相机标定学习课件与视频网址;后台回复:立体匹配即可下载独家立体匹配学习课件与视频网址。

重磅!3DCVer-学术论文写作投稿 交流群已成立

扫码添加小助手微信,可申请加入3D视觉工坊-学术论文写作与投稿 微信交流群,旨在交流顶会、顶刊、SCI、EI等写作与投稿事宜。

同时也可申请加入我们的细分方向交流群,目前主要有3D视觉CV&深度学习SLAM三维重建点云后处理自动驾驶、CV入门、三维测量、VR/AR、3D人脸识别、医疗影像、缺陷检测、行人重识别、目标跟踪、视觉产品落地、视觉竞赛、车牌识别、硬件选型、学术交流、求职交流等微信群。

一定要备注:研究方向+学校/公司+昵称,例如:”3D视觉 + 上海交大 + 静静“。请按照格式备注,可快速被通过且邀请进群。原创投稿也请联系。

640?wx_fmt=jpeg▲长按加微信群或投稿

640?wx_fmt=jpeg

▲长按关注公众号

3D视觉从入门到精通知识星球:针对3D视觉领域的知识点汇总、入门进阶学习路线、最新paper分享、疑问解答四个方面进行深耕,更有各类大厂的算法工程人员进行技术指导。与此同时,星球将联合知名企业发布3D视觉相关算法开发岗位以及项目对接信息,打造成集技术与就业为一体的铁杆粉丝聚集区,近2000星球成员为创造更好的AI世界共同进步,知识星球入口:

学习3D视觉核心技术,扫描查看介绍,3天内无条件退款640?wx_fmt=jpeg 圈里有高质量教程资料、可答疑解惑、助你高效解决问题觉得有用,麻烦给个赞和在看~640?wx_fmt=gif


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK