SLAM部署与imu标定
前言
笔者在上一条帖子时已经在尝试运行若干SLAM算法试图择优观察部署效果
(包括FAST_LIO,LIO-SAM,Point-LIO,rtabmap等笔者看过的建图,定位算法)笔者最终聚焦在LIO-SAM的建图(意即先导地图的获取),随后利用liorf_localization的LIO-SAM衍生纯定位算法实现机器人在已知地图的重定位
可能有的开发者想问SLAM已经自带了同时建图与定位功能,为什么还要将建图和定位隔开进行开发。笔者在单跑LIO-SAM时发现过其轨迹与实际录取数据包时的误差,有时甚至会平地起飞(漂移)
为了解决这一问题,笔者尝试了隔离建图定位,进行imu内参标定的尝试,将其记录下来(
其实就是臭掉包工程师)
基础知识扫盲
首先,我们要了解一下SLAM和传感器的有关术语
SLAM,定位与建图
1.建图:简而言之,就是收集正在运作的传感器数据(本文中提到的均为激光SLAM,所以传感器基本上是激光雷达+imu),利用建图算法将这段时间的传感器数据记录为一张地图
2.定位:实际上就是确定机器人从规定的地图原点(通常也是机器人的上电原点),到机器人任何一时刻运行时刻的位置改变,确定这个改变也就是给机器人定位了
或者,有了解过tf树的同学也可以通过几大坐标系更轻松的理解。map:地图原点;odom:机器人上电原点,里程计的初始点;base_link:机器人在运行过程中的任意一点,定位,就是时刻刷新odom到base_link的tf树变化
3.SLAM(同时建图与定位):能够依靠高计算量算法,做到机器人首次在新环境中同时完成前两项的工作
需要注意的是,前面的三个概念,在实际运行的时候所需的数据资源一模一样,除了定位需要多用到一个建图结束生成的先导地图,三者均只需要提供雷达和imu数据即可。
SLAM的分类
松、紧耦合传感器SLAM
1.紧,即传感器数据处理方式。将多个传感器的原始数据直接融合到同一个优化框架中,共同完成状态估计(如位姿、地图等)。
所有传感器的原始数据在同一个数学模型中被联合优化需注意,本帖中所提到的所有SLAM均为紧耦合SLAM,紧耦合最大的好处是充分发挥各传感器之间位姿带来的数据融合互补,配合算法纠偏
2.松,即多传感器分模块单独处理,各个传感器独立处理数据,生成局部估计结果(如相机的位姿、IMU的位姿),再通过后处理(如滤波或优化)进行融合
视觉与激光SLAM
1.激光SLAM即主要运用激光类传感器,如激光雷达。主要传感器数据为3D点云。目前被广泛运用,且有很多牛b的实验室算法
同样,本帖中所提到的所有SLAM均为激光SLAM,这也是大多数情况下使用的SLAM类型
2.视觉SLAM主要运用相机(如双目等)。主要传感器数据为2D图像。不如激光的发展迅速和好用,但在一些特定情况下能发挥其可以捕捉细节纹理的优势。
跑定位前,你需要做什么
传感器标定
缘由
传感器的标定,直接影响了传感器在运行时数据的质量
传感器在运行时存在噪声,但是可以通过标定算法来平衡或者减小这一噪声带来的数据误差
噪声标定分类
内参标定:标定传感器自身运行时的数据,自我校准,解决自身数据噪声。
外参标定:多传感器处于机器人不同的方位,外参标定就是因为人为测量计算两传感器之间的旋转矩阵存在误差,用外参标定包来进行二次校准,可以让两传感器之间的相对位置表示更加准确,方便后续的数据对齐(算法里的数据需要再同一坐标系下)
标定的分类(若想更详细的了解可以点击这篇优质文章)
相机标定
消除畸变:
相机镜头存在光学畸变(如径向畸变、切向畸变),导致图像边缘的直线弯曲。标定可以量化并校正这些畸变获取相机内参:
内参包括焦距(fx、fy)、主点(u0、v0)和畸变系数(k1、k2、p1、p2),这些参数决定了相机如何将3D世界投影到2D图像平面确定相机外参:
外参包括旋转矩阵 R 和平移向量 T,描述相机坐标系与世界坐标系之间的相对位置关系使用的方法一般是棋盘格法标定,或采用OpenCV库函数正畸来进行标定
IMU标定
知晓IMU在运行时加速度仪和陀螺仪的白噪声和随机噪声,用得到的平均噪声去优化算法对于IMU数据的处理
一般采取IMU内参标定包如imu_utils,在IMU静态或极缓状态下移动,并记录较长时间段(1h到3h不等),采集数据包后运行该包进行噪声计算
联合标定:标定传感器之间位置关系的外参
相机与IMU,IMU与Lidar,相机与Lidar之间如果可以,建议都进行标定。原理这里不多赘述,理论上而言外参如果相信自己的测量且精度要求没有那么高的情况下,标定与不标定的区别对最终结果的影响没有那么大。
附若干外参标定工程项目:LiDAR与IMU联合标定浙大开源的lidar_IMU_calib,相机雷达联合标定calibration_camera_lidar 等
跑通SLAM与定位的流程(以LIO-SAM建图和liorf_localization定位为例)
概述:仅仅只是单论跑起来的步骤很简单
首先写好各个硬件的驱动模块,让所有传感器开始工作,并发布要求的话题,并在话题中发布传感器数据(IMU和Lidar传感器驱动,对于Mid360用户而言,这个激光雷达中自带了一个精度还行的IMU所以只需要一个硬件)
然后再运用上述提到的标定包标定对应传感器的内参,得到内参标定结果,写入SLAM算法的config文件的对应传感器配置项。
随后只需要调整SLAM原始包的参数文件,修改订阅的传感器话题和前述自己传感器发布的话题一致,并启动SLAM的launch文件,理论上而言就可以跑起来了
但仅仅跑起来远远不够,在没有调整其他参数,如地图降采样率,传感器数据置信度,数据单位等(官方包数据和你的传感器数据单位不一定一样)。你会发现你的建图虽然正常打开了,但是机器人一开起来就去外太空旅游了,根本不是实际你采集数据时候的轨迹
重点记录1:参数文件的修改
这也是困扰了笔者很久很久的调参环节,想要看懂yaml文件里的参数,要去回查源码和了解SLAM的部分运行原理是最好,包括算法的模块设计思路
参数详解
- 笔者整理了大部分的lio-sam的yaml中的参数含义并添加了大段注释,知道了参数含义,才能做出正确尝试性的改参,详细看下文注释
lio_sam: |
重点记录2:imu_utils的imu标定包的使用
注意
笔者很想喷人的是,github上开源的imu_utils包的内容不能过编译,其中的源码有需要修改的部分,笔者自己在原包的基础上进行了二次开发,并封装了docker容器
包的使用
- 首先拉取项目
git clone https://github.com/njustup70/nagisa_little_kit.git |
- 配置好docker-compose环境,注意也要提前下载好docker(对docker下载和docker-compose容器管理不太清楚的话可以看看我之前的帖子,这里默认用户已下载好了docker
sudo apt install docker-compose |
- 编译并打开容器
nagisa_little_kit/IMU_init/.devcontainer$ docker-compose up --b && docker-compose up --d |
- 进入容器(再开一个终端)
nagisa_little_kit/IMU_init/.devcontainer$ docker exec -it littlekit-comtainer bash |
- 进入容器后,先source(这里牵扯到ROS1的source工作空间覆盖问题,但是笔者已经解决,按照步骤来,不要做多余步骤,就可以解决这个问题,ROS开发中的一些小坑会在之后的博客中更新,这里暂时先不说原理了)
cd ~/packages/ros_manager && source devel/setup.bash # 这步就可以解决source问题 |
- 启动标定launch文件
cd ../nagisa_ws && roslaunch my_imu_init A3.launch |
- 随后启动IMU数据包即可,但是注意,IMU数据包中的IMU话题需要与A3.launch中定义的一样,如果不一样请先在拉取工程后修改为一样(ROS1中的launch和yaml文件修改后不用catkin_make和source)
文末
- 附LIO-SAM的官方论文