SLAM相关
2020-3-19更新(个人总结,如有错误,欢迎指出)
=======================================
=======================================
一、最优化相关
1、解释一下卡尔曼滤波?
- 假设你有两个传感器,测的是同一个信号。可是它们每次的读数都不太一样,怎么办?取平均。
- 再假设你知道其中贵的那个传感器应该准一些,便宜的那个应该差一些。那有比取平均更好的办法吗?加权平均。怎么加权?
- 假设两个传感器的误差都符合正态分布,假设你知道这两个正态分布的方差,用这两个方差值,(此处省略若干数学公式),你可以得到一个“最优”的权重。
- 接下来,重点来了:假设你只有一个传感器,但是你还有一个数学模型。模型可以帮你算出一个值,但也不是那么准。怎么办?把模型算出来的值,和传感器测出的值,(就像两个传感器那样),取加权平均。OK,
- 最后一点说明:你的模型其实只是一个步长的,也就是说,知道x(k),我可以求x(k+1)。问题是x(k)是多少呢?答案:x(k)就是你上一步卡尔曼滤波得到的、所谓加权平均之后的那个、对x在k时刻的最佳估计值。于是迭代也有了。这就是卡尔曼滤波。
作者:Kent Zeng
链接:https://www.zhihu.com/question/23971601/answer/26254459
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
2、BA的流程?
- BA本质是一个优化模型,目的是最小化重投影/光度误差,用于优化相机位姿和世界点。
- 根据相机的投影模型构造代价函数,利用非线性优化(比如GN或者LM)来求解,利用雅克比矩阵的稀疏性求解增量方程,得到相机位姿和特征点3D位置的最优解
- BA是一个图优化模型,一般选择LM算法在此基础上利用BA模型的稀疏性进行计算,可以直接计算,也可以使用g2o或者Ceres等优化库计算
- Bundle Adjustment流程:
- 1、将世界坐标转换到相机坐标得 P / P^/ P/,用到相机外参Rt
- 2、 将 P / P^/ P/投影到归一化平面
- 3、得到去畸变前的原始坐标
- 4、根据内参模型,计算像素坐标
- 5、也就是得到一个观测方程,最小化这个重投影误差
3、RANSAC(随机抽样一致)的框架
- 1、随机假设一小组局内点为初始值,用此内点拟合模型,此模型适应于假设的局内点,所有未知参数从假设局内点计算得出
- 2、用1中模型测试所有其他数据,符合则认为内点,扩充
- 3、若足够多点被归为内点,则模型合理
- 4、用所有假设内点重新估计模型,若有扩充,重新更新
- 5、最后,通过估计内点与模型的错误率来评估模型
4、为什么SLAM中常用LM算法而不是高斯牛顿求解优化问题?
- G-N中的H矩阵可能为奇异矩阵或者病态矩阵,导致算法不收敛。而且当步长较大时,也无法保证收敛性,所以采用L-M求解增量方程,但是它的收敛速度可能较慢
- LM对高斯牛顿法引入了阻尼因子,
- 阻尼因子需大于零,保证迭代朝着下降方向进行
- 阻尼因子非常大,接近最速下降法
- 阻尼因子比较小,则接近高斯牛顿法
- LM好处:如果下降太快,使用较小的 λ \lambda λ ,如果下降太慢,使用较大的 λ \lambda λ
5、最小二乘中遇到outlier怎么处理?
- 鲁邦核函数。直接作用在残差f上
6、说一下DogLeg算法
- DL也是联合GN和最速下降法,但是Dl是利用信赖域半径来控制。
- DL策略是根据信赖域半径选择步长
7、Marginalization的时候,信息矩阵如何维护?
- 直接丢弃变量和应的测量值,会损失信息。正确的做法是使用边际概率,将丢弃变量所携带的信息传递给剩余变量。
二、标定相关
1、相机和陀螺仪之间的外参如何标定?(不完整)
输入:IMU位姿P R和图像帧
输出:相机和IMU外参 R T
- 预先知道相机位姿(纯视觉初始化),利用相机和IMU旋转转换关系式得到R初值
- 求出尺度S后。根据平移公式得到T的初值
- 非线性优化,同时优化R T 和空间点深度
三、视觉相关(直接法和特征法)
1、ORB用什么方法提取角点和描述子?ORB中改进的FAST角点提取策略?
提取角点
- FAST:核心就是找卓尔不群的点,即拿一个点和它领域的点比较,如果它和其中大部分不一样就认为是一个特征点
描述子
- BRIEF二进制描述子:核心就是在关键点P周围以一定模式选取N个点对,把这个N个点对的比较结果组合起来作为描述子
【注意:ORB主要解决了BRIEF描述子不具备旋转不变性的问题。通过在计算BRIEF描述子时建立的坐标系是以关键点为圆心,以关键点和取点区域的质心的连线为X轴建立2维坐标系,质心随着旋转不会变化】
- 利用灰度质心法计算每个特征点的主方向。从中心位置到质心位置的向量,定义为该特征点的主方向。
2、ORB提取不到特征点的地方怎么办?
- 增加光流法或者直接法进行补充,不至于使系统中断。
- 若环境中线特征明显,可加入边缘检测或者结构线特征
3、提取特征点的方法有几种?分别说说
4、直接法与特征点法的优缺点对比
- 特征点法,根据提取、匹配 特征点来估计相机运动,优化的是重投影误差,对光照变化不敏感 ,是比较成熟的方案。常见的开源方案 比如ORBSLAM
优点:
(1)特征点本身对光照、运动、旋转比较不敏感,所以比较稳定
(2)相机运动较快(相对直接法来说)也能跟踪成功,鲁棒性好一些
(3)研究时间较久,方案比较成熟
缺点:
(1)关键点提取、描述子、匹配耗时长
(2)特征点丢失场景无法使用
(3)只能构建稀疏地图 - 直接法,根据相机的亮度信息估计相机的运动,可以不需要计算关键点和描述子,优化的是光度误差,根据使用像素数量可分为稀疏、半稠密、稠密三种。常见开源方案有SVO, LSD-SLAM
优点:
(1)速度快,可以省去计算特征点、描述子时间
(2)可以用在特征缺失的场合(比如白墙),特征点法在该情况下会急速变差
(3)可以构建半稠密乃至稠密地图
缺点:
(1)因为假设了灰度不变,所以易受光照变化影响
(2)要求相机运动较慢或采样频率较高(可以用图像金字塔改善)
(3)单个像素或像素块区分度不强,采用的是数量代替质量的策略
四、VINS相关
1、解释一下VINS-Mono的初始化部分以及大致框架
初始化
提取图像的Features和做完IMU的预积分之后,进入系统初始化:恢复尺度、重力、速度、以及IMU的bias
- 主要目的:1、系统使用单目,若没有良好的尺度估计,无法对传感器进一步融合。恢复绝对尺度。2、对IMU进行初始化,IMU会受到bias的影响。要得到IMU的bias
- 主要环节:求相机与IMU之间相对旋转、相机初始化(局部SFM,无尺度的BA)、IMU与视觉对齐(IMU预积分中的
α
\alpha
α和相机的平移)
- 1 相机与IMU之间相对旋转:
- 相机利用对极几何得到旋转矩阵,IMU预积分得到旋转矩阵,对于任何一帧满足 R b k + 1 b k R c b = R c b R c k + 1 c k R^{b_k}_{b_{k+1}}R^b_c=R^b_cR^{c_k}_{c_{k+1}} Rbk+1bkRcb=RcbRck+1ck
- 将旋转矩阵写成四元数,写成左乘右乘形式
- 得到IMU预积分和相机的findFundmentalMat所得旋转矩阵残差
- 得到旋转残差之后进一步得到权重(剔除外点的权重)
- 在足够多的旋转运动中,轨迹外参旋转R, Q N Q_N QN对应一个准确解,其零空间秩为1。但是可能存在退化运行,这时 Q N Q_N QN零空间秩大于1,判断条件为第二小的奇异值是否大于某个阈值,若大于则其零空间秩为1,反之秩大于1,校准不成功。
- 2 相机初始化(单目初始化):
- 先求本质矩阵求解位姿,进而三角化特征点,pnp求解位姿,然后不断pnp重复
- 3 视觉和IMU对齐:
- 解决三个问题:修正陀螺仪的bias、初始化速度重力向量 g g g和尺度因子、优化的重力向量 g g g的量值
- 3.1 陀螺仪bias修正:利用旋转约束修正陀螺仪bias
- 3.2 初始化速度、重力向量和尺度因子: 由前面的IMU预积分推导,构建状态量最小二乘,求解得到状态量(速度,重力和尺度)
- 3.3 纠正重力向量:不断迭代更新重力向量的过程,优化重力模长
- 1 相机与IMU之间相对旋转:
https://www.zybuluo.com/Xiaobuyi/note/866099
框架
- 1、数据预处理:图像提特征,IMU做预积分,输出两帧图像IMU积分结果
- 2、视觉惯导初始化:先视觉SFM,然后联合初始化得到尺度,重力,速度和bias
- 3、局部BA:后端融合优化,状态量包括:IMU状态+相机外参+逆深度:残差包括:先验+IMU+视觉 ,优化后得到各时刻位姿,实现VIO
- 4、闭环检测+全局位姿优化:只优化四个自由度,因为尺度,roll和pitch可观
2、你对滑动窗口的理解?---------
- 目的:为了保持优化变量的个数在一定范围内,使用滑窗动态增加或移除变量
- 流程:
- 1、增加新的变量进入最小二乘系统优化
- 2、如果变量数目达到一定维度,则移除老的变量
- 3、SLAM系统不断循环前两步
3、滑动窗口中的FEJ算法
- 滑窗算法优化过程中,信息矩阵变成两部分,且这两部分计算雅克比时线性化点不同,这可能会导致信息矩阵的零空间发生变化,从而求解时引入错误信息。
- FEJ算法:不同残差对同一个状态求雅克比时,线性化点必须一致,这样能避免零空间退化而使得不可观变量变的可观。
4、IMU预积分----------------
- 为什么:原本PVQ对IMU测量值积分,每次 q w b t q_{wb_{t}} qwbt优化更新都需要重新积分,运算量大
- 步骤:
- 通过 q w b t = q w b i × q b i b t q_{wb_{t}} = q_{wb_i} × q_{b_ib_t} qwbt=qwbi×qbibt (将t时刻相对于世界的姿态转为相对于第i时刻IMU的姿态),将积分模型转为预积分模型
- PVQ积分公式中的积分项变成相对于第i时刻状态,而不是相对于世界坐标系的姿态
- 预积分量仅仅与IMU测量值有关,它将一段时间内IMU数据直接积分起来就是预积分量
- 预计分误差:一段时间内IMU构建的预积分量作为测量值,对两时刻之间状态量进行约束
五、多视图几何相关
1、什么是PnP算法?请用你的语言描述一下原理,它一般用在什么场景,解决什么问题?
- 3D-2D的位姿求解方式,已知n个3D空间点及其投影位置时,如何估计相机的位姿
- 原理:
- 场景1:输入物体在世界坐标系下的3D点,以及这些点在图像上投影的2D点,因此求得的是相机坐标系相对于世界坐标系的(Twc)的位姿
- 场景2:输入上一帧中的3D点(在上一帧相机坐标系下表示的点),和这些3D点在当前中投影的2D点,所以它求得的是当前帧相对于上一帧的位姿变换
2、按照你的理解讲解一下什么是极线约束?这个约束能带来什么好处?
- 假设相机在不同位置拍摄两幅图像,若一个空间点p在两幅图像上分别有两个成像点p1,p2,则有图成像点p2一定在相对于p1的极线上。
- 好处:
- 1、在做特征点匹配时,左图成像点p1的待匹配点p2一定在相对于p1的极线上,在搜索时可以在极线附近搜索,相对暴力匹配极大减少待匹配的点
- 2、极线约束可以简洁的给出匹配点的空间位置关系,使得相机位姿估计问题变得简单
六、数学相关
1、为什么要引入李群李代数?
- 旋转矩阵自身是带有约束的,正交且行列式为1,它们作为优化变量时,会引入额外的约束(什么约束),使优化边的困难,通过李群李代数的转换关系,把位姿变成无约束的优化问题。
2、齐次坐标
- 原本是n维向量,用一个n+1维向量表示,是指一个用于投影几何里的坐标系统
- 能够用来明确区分向量和点
- 如果(x,y,z)是个点,则变为(x,y,z,1);如果是个向量,则变为(x,y,z,0)
- 更易于进行仿射(几何)变换
七、系统及策略问题
1、关键帧在SLAM里应用非常多,很多知名的开源算法都使用了关键帧。请你用自己的语言描述一下关键帧是什么?有什么用?如何选择关键帧?
-
理解:关键帧可以减少优化的帧数,并且可以代表其附近的帧。可以理解为论文中写的关键词
-
选取指标:
- 时间:距离上一次时间足够长。简单,但是容易冗余
- 空间:距离最近的关键帧是否足够远。效果好,但是可能会出现大量相对关键帧
- 跟踪质量/共视特征点:利用共视关系,视差足够大时添加关键帧。复杂
-
VINS中选取关键帧:
- 新的关键帧需要和上一关键帧有足够视差
- 若Track的Feature数低于某阈值
-
ORBSLAM选取关键帧:
- 很久没新的关键帧,则插入新的关键帧
- LocalMapping空闲
- 当前追踪效果差
- 当前帧的MapPoint和ref keyframe重复率低
2、 SLAM中的绑架问题
- 绑架问题就是重定位,指机器人在缺少之前位置信息的情况下,如果和确定当前位姿。例如当机器人被安置在一个已经构建好地图的环境中,但是并不知道它在地图中的相对位置,或者在移动过程中,由于传感器的暂时性功能故障或相机的快速移动,都导致机器人先前的位置信息的丢失,在这种情况下如何重新确定自己的位置。
- VINS-Kidnap
C++相关
1、 什么是C++纯虚函数和抽象类
- 纯虚函数就是没有函数体,同时在定义的时候,其函数名后面要加上”=0“
- 纯虚函数也一定是某个类的成员函数,那么,包含纯虚函数的类也叫抽象类
2、C++虚函数与纯虚函数用法与区别
- 虚函数为了重载和多态的需要
- 两者在它们子类都可以被重写
- 区别是:
- 纯虚函数只有定义,没有实现;而虚函数既有定义,也有实现
- 纯虚函数一般没有代码实现部分, 其函数名后面要加上”=0“;而一般虚函数必须要有代码实现部分,否则出现函数未定义的错误。
- 包含纯虚函数的类不能定义其他对象,而包含虚函数的可以
- 纯虚函数只是一个接口,是个函数的声明而已,它要留到子类里去实现 - 虚方法就是每个子类都可以有的相同属性,并且可以在父类实例化。
纯虚方法就是每个子类都需要该方法,但是没有相同点,就先在父类声明(防止自己后来忘记),然后再在子类分别实例化
3、C++三大特性
封装,继承,多态
-
封装可以隐藏实现细节,使得代码模块化,继承可以扩展已存在的模块,它们目的都是为了:代码重用。而多态是为了实现另一个目的:接口重用
-
什么是多态?
eg:开门,开窗户,开电脑,这里“开”就是多态。
多态性可以简单概括为“一个接口,多种实现”,是通过虚函数实现的。基类提供一个虚接口,其派生类重写这个接口,这样就构成了多态。
商汤自动驾驶见习研究员
- 解释一下EKF怎么融合多传感器?
- 解释一下LM算法流程?
- vins因子图模型一般有多少个顶点?如果多了的话怎么处理?
- C++静态成员变量可以访问非静态成员变量吗?
- 寻找二叉树最大深度
普渡科技
- robot_pose_ekf有哪些状态量和观测量?如果是你设计你会设计哪些状态量和观测量?
- 去畸变模型,
- 轮速计模型
- ros的CMakeLists分为哪几部分?
- 怎么进行传感器数据预处理?
- 怎么进行C++内存管理
- 激光雷达的选型,及怎么评测激光雷达的优劣
- 怎么进行IMU标定
- git的操作
- Lambda表达式
- 正则表达式
普瑞思查
- 解释下预积分
- 多传感器融合思路
https://blog.csdn.net/doo66/article/details/52208922