SLAM
SLAM
第一讲:预备知识
Simultaneous Localization and Mapping(同时定位与地图构建) 解决: 定位和建图
常见的库: Eigen:线性代数,Opencv:视觉处理,PCL:点云处理,g2o:slam框架,Ceres:非线性关系求解
slam系统: 视觉里程计,后端优化,建图,回环检测
第二讲:初始SLAM
slam解决的问题
(早期的slam一种状态估计问题) – 空间状态不确定性的估计 本质: 对运动主体自身和周围环境空间不确定性的估计 定位: 我在什么地方? 建图: 周围环境是什么样?
常见传感器:激光传感器,相机,轮式编码器,惯性测量单元(IMU)等
照片的本质是拍摄某个场景在相机的成像平面上留下的一个投影:它以二维的形式记录 三维的世界.(丢失深度(距离)) -> 可能是很近很小,也可能是很远很大
相机:
分为双目相机和深度相机
双目相机: 1.双目相机由两个单目相机组成,但这两个相机之间的距离(基线)是已知的,我们通过这个极限来估计每个像素的空间位置—这和人眼很相似 2.双目相机测量到的深度范围与基线相关.极限距离越大,能够测量到的物体越远,双目相机的距离是比较左右眼的图像获得的,并不依赖其他传感器设备.
3.视差的计算非常消耗计算资源,需要GPU和FPGA设备加速
深度相机:(RGB-D相机): 通过红外结构光或Time-of-Fliagh原理,通过主动向物体发射光接收返回的光测出物体与相机之间的距离
视觉slam的目标:是通过这样的一些图像,进行定位和地图构建
视觉slam框架
image.png
1.传感器信息读取:主要为相机图像信息的读取和预处理,码盘,惯性传感器等信息的读取和同步
2.前端视觉里程计:视觉里程计的任务是估算相邻图像间相机的运动,以及局部地图的样子.VO又称为前端(Font End)
3.后端(非线性)优化:后端接受不停时刻视觉里程计测量的相机位姿,以及回环检测的信息,对它们进行优化,得到全局一致的轨迹和地图,由于接在VO之后,又称为后端(Back End)
4.回环检测:回环检测判断机器人是否到达过先前的位置.如果检测到回环,它会把信息提供给后端进行处理
5.建图:它更具估计的轨迹,建立与任务要求对应的地图
视觉里程计: — 前端
视觉里程计: 视觉里程计能够通过相邻帧间的图像估计相机运动,并恢复尝尽的空间结构.称它为里程计就像一种只有短时记忆的物种
(图像地特征提取与匹配)
图像在计算机里知识一个数值矩阵
一方面:只要把相邻时刻的运动串起来,就构成了机器人的运动轨迹 另一方面:我们根据每个时刻的相机位置,计算出各像素对应的空间点位置,就得到了地图
仅通过视觉里程计来估计轨迹,将不可避免地出现累积漂移
累积漂移:
每次估计都带有一定地误差,而由于里程计地工作方式,先前时刻地误差将会传递到下一时刻,导致经过一段时间之后,估计地轨迹将不再准确 -> 导致我i们无法建立一致地地图
后端优化:
主要处理SLAM过程中地噪声问题 — 如何让从这些带有噪声地数据中估计整个系统地状态,以及这个状态估计地不确定有多大 —- 最大后验概率估计
(滤波与非线性优化算法)
回环检测
又称闭环检测,主要解决位置估计随时间漂移的问题
解决方法: 使用某种手段m让机器人知道回到了原点这件事,或者把原点识别出来,我们再把位置估计值拉过去,就可以消除漂移了,这就是所谓的回环检测
(可以通过判断图像间的相似性来完成回环检测) — 回环检测成功,则可以显著地减小累积误差
建图:
构建地图的过程
地图: 是对环境的描述,但这个描述并不是固定的,需要视SLAM的应用而定
(相机有6个自由度) -> XYZ轴平移,绕XYZ轴旋转
度量地图:
拓扑地图:
调试:
单步跳过: 执行当前行代码.如果该行包含函数调用,不进入函数内部,直接得到结果并跳到下一行 F10 单步进入: 执行当前行代码,如果该行包含函数调用,会进入该函数内部,并暂停在函数的第一行 F11 单步跳出: 立即执行完当前函数体内剩余的所有代码,并跳出到该函数的下一行语句暂停处 Shift + F11
1.配置编译任务 按ctrl+shift+p,输入"Tasks: Configure Task" , 选择"Create tasks.json file from templates",选择"Others"或"C/C++ g++ buikd active file" ,这回生成一个tasks.json,然后问ai生成一个调试文件
2.配置调试设置(launch.json) 按F5,选择(GDB/LDB),然后选择"g++ build and debug activate file"
3.开始断点调试 1).设置断点: 在代码行号左侧单击,出现红点即为断点 2).启动调试: 按F5 3).调试操作 4).查看状态
4.高级调试技巧 条件断点 日志断点 函数断点
第三讲 三维空间刚体运动
主要目标: 1.理解三维空间的刚体运动描述方式: 旋转矩阵,变换矩阵,四元数和欧拉角 2.掌握Eigen库的矩阵,集合模块的使用方法
如何描述刚体在三维空间中的运动 -> 由一次旋转加一次平移组成
旋转矩阵
点,向量和坐标系
点: 空间中的基本元素,没有长度和体积,用于表示位置 向量: 连接两个点的有向线段,表示为箭头,具有方向和大小(模长).向量本身是空间中的实体,独立于坐标表示 坐标系: 为描述点和向量的位置而定义的框架,由一组基向量(e1,e2,e3)构成.向量在坐标系下的坐标表示为线性组合系数
右手系:常见于 OpenGL、3D Max 等库。坐标轴满足右手法则(x×y=z) 左手系:常见于 Unity、Direct3D 等库。坐标轴满足左手法则(x×y=−z)
向量的运算: 基本运算: 数乘,加法,减法,内积(描述投影关系,结果与坐标系无关),外积(结果向量垂直于原向量构成的平面,模长等于两向量张成的平行四边形面积)
坐标系间的欧式变换
例子: 惯性坐标系(世界坐标系) -> 可以认为它是固定不动的 相机或机器人是一个移动坐标系
刚体运动: 两个坐标系之间的运动由一个旋转加上一个平移组成,这种运动称为刚体运动 ,同一个向量在各个坐标系下的长度和夹角都不会发生变化
欧式变换: (刚体变换) -> 描述三维空间中刚体运动的一种数学工具.他能保持物体内部任意两点间的距离和角度不变,只改变物体的位置和姿态想象一下你拿起手机移动或旋转:手机本身的形状、大小、各个面的夹角都没变,只是它在空间中的“位置”和“朝向”变了。 我们说手机坐标系到世界坐标之间,相差了一个欧式变换(Euclidean Transform)
欧式变换由旋转和平移组成
齐次坐标: 我们在一个三维向量的末尾添加1,将其变成了四维向量,称为齐次坐标,对于这个四维向量,我们可以把旋转和平移写在一个矩阵里,使得整个关系变成线性关系 -> 该矩阵T(Transform Matrix)称为变换矩阵 -> 数学技巧(统一的线性方式来处理旋转和平移) :
Eigen库
简介: 是一个C++开源线性代数库.它提供了快速的有关矩阵的线性代数运算,还包括解方程等功能.许多上层的软件库也使用Eigen进行矩阵运算,包括g20,Sophus等
安装:
sudo apt-get install libeigen3-dev 查找头文件安装位置: 默认位置: /usr/include/eigen3/
终端输入:
sudo updatedb locate eigen3
Eigen库是一个纯头文件库,这意味它的全部实现都包含在头文件中,而不是预先编译好的二进制文件(如Windows下的.lib,.dll或Linux下的.a,.so) 好处: 1.不需要担心操作系统或编译器的差异 2.更佳的优化潜力 3.避免API问题: 传统库升级时,如果二进制接口(API)发生变化,可能需要编译整个项目, 而Eigen作为头文件库,不存在这个问题
为了达到更高的效率,在Eigen中需要指定矩阵的大小和类型 -> 完全可以在编译时确定它们的大小和数据类型 Eigen矩阵不支持自动类型提升 -> 在C++程序中,我们可以把一个float数据和double数据相加,相乘,编译器会自动把数据类型转换为最合适的那种,而在Eigen中,出于性能的考虑,必须显式地对矩阵类型进行转换否则 -> YOU MIXED DIFFERENT NUMERIC TYPES(混合了不同地数值类型)
同理,在计算过程中也需要保证矩阵位数的正确性,否则 -> YOU MIXED MATRICES OF DIFFERENT SIZES(混合了不同尺寸的矩阵)
6自由度的三维刚体运动
描述一个物体在三维空间中完整运动能力的基石 物体可以进行3个方向的平移 x,y,z 和3个方向的旋转 roll,pitch,yaw
旋转向量
第四讲: 李群与李代数
第五讲: 相机与图像
第六讲 非线性优化
使用ceres进行曲线拟合

点赞数据加载中
文档修订记录 8 次修订
- 197fd12 修复大小标题显示失败的bug
- 9a00af8 Fix: apply heading heuristic to 44 existing posts (26+18) - TOC now shows real sections
- edc8d79 博客界面更换 一些笑哦bug维修
- bce812d 6_28飞书文档同步更新
- 8c0c2ac 飞书同步test
- 7d34298 Add manual and sortable library
- 9402175 Improve blog layout and pinned posts
- 98d0f15 Create Hugo blog