VIO第一章作业:
VIO文献阅读
提问1: 视觉与IMU融合之后有哪些优势
- IMU的优缺点:加速度计与陀螺仪都会收到零偏的影响,导致长时间积分后位姿结果必然有大的漂移。IMU短时间内得到的结果不受外界环境的困扰,比较可靠。
- 相机的优缺点:容易收到环境光照影响,比如平滑的墙面,干净的天空,动态的进入物体,都会对VO结果产生干扰。但是长期来看,回归结果得出的位姿变化较为可靠。
所以IMU和相机是互补的关系,融合后的优点有:
- 融合方案可以在VO的基础上恢复尺度不确定的问题。
- 融合方案可以提供一个较为准确的促使估计,防止局部最优解
- 融合方案可以解决MONO无法估计单纯旋转的问题
- 融合方案可以预防图像模糊的问题。
- 融合方案可以用视觉长期有效性对冲IMU的零偏与积分漂移
- 融合方案因为IMU具有高频特性,可以提高估计输出位姿的更新频率
提问2: 有哪些常用的视觉+IMU融合方案?有没有工业界应用的例子?
- 基于滤波的方案:
- MSCKF
- ROVIO
- OpenVINS
- 基于优化的方案
- OKVIS
- VINS
- VI-ORB
- ICE-BA
工业界应用的例子
- AR环境感知
- 自动驾驶建图与环境感知
- 机器人导航&无人机导航
提问3: 在学术界,VIO研究有哪些新进展?有没有将学习方法运用到VIO中的例子?
VIO目前有两个研究方向:
- 研究新的融合模式增强系统的鲁棒性和适用性。如:加入激光雷达,轮速计,GNSS等传感器,具有代表性的工作有LVI-SAM,GVINS,R3Live。
- 研究新的视觉约束和新的视觉特征提取来提高系统的精度。如:使用线,曲线,平面特征来构建残差。
将深度学习应用到VIO上有这些尝试:
- 使用深度学习替换传统SLAM中的不同模块
- SuperPoint替换特征提取模块
- SuperGlue替换回环检测模块
- 加入语义信息
- 基于深度学习的端到端位姿估计
举例来说
- Unsupervised Depth Completion from Visual Inertial Odometry(ICRA-2019)
采用了无监督的KITTI深度作为基准深度数据集,首次提出了视觉惯性+深度数据集的融合方式,进一步增强视觉和惯性传感器的互补优势。 - Selective Sensor Fusion for Neural Visual-Inertial Odometry(CVPR-2019)
针对目前视觉惯性里程计(VIO)的深度学习方法很少结合稳健的融合策略去处理不完美的输入数据。提出了一种新的单目端到端VIO传感器融合框架,该框架融合了单目图像和惯性测量数据,以估计轨迹,同时提高了对真实问题的鲁棒性,如数据丢失和损坏或传感器同步不良等问题。还提出了两种基于不同掩蔽策略的融合模式:确定软融合和随机硬融合,且实验结果证明在数据被破坏的情况下,该融合策略与直接融合相比,具有更好的性能。 - VINet: Visual-Inertial Odometry as a Sequence-to-Sequence Learning Problem(AAAI-2017)
VINet是首次使用端到端可训练的深度神经网络架构尝试解决机器人领域视觉惯性里程计的问题,目前所披露的实验表现出了一定的实用价值。与传统方法相比具有许多优势。它消除了对摄像机和IMU进行繁琐的手动同步的需要,也消除了对IMU和摄像机之间进行手动校准的需要。另一个优势是,模型可以自然合并特定领域的信息,大大减轻了漂移。
四元数和李代数更新
可以使用四元数或旋转矩阵存储旋转变量。当我们用计算出来的
ω
\omega
ω 对某旋转更新时,有两种不同的方式:
R
⟵
R
exp
(
ω
∧
)
或
q
⟵
q
⊗
[
1
,
1
2
ω
]
T
R\longleftarrow R\exp(\omega^\land) \\ 或 q\longleftarrow q\otimes[1,\frac{1}{2}\omega]^T
R⟵Rexp(ω∧)或q⟵q⊗[1,21ω]T
请编程验证
对于小量
ω
=
[
0.01
,
0.02
,
0.03
]
T
\omega=[0.01,0.02,0.03]^T
ω=[0.01,0.02,0.03]T,两种方法得到的结果非常接近,实践中可视为等同、因此在后文提到旋转时,我们并不可以区分旋转本身时
q
q
q还是
R
R
R,也区分其更新方式为哪一种
coding:
#include "sophus/so3.hpp"
#include "sophus/se3.hpp"
int main(int argc, char** argv)
{
Eigen::Vector3d w(0.01, 0.02, 0.03);
Eigen::Quaterniond q = Eigen::Quaterniond::UnitRandom();
Eigen::Matrix3d exp_w = Sophus::SO3d::exp(w).matrix();
Eigen::Matrix3d R1 = q.toRotationMatrix() * exp_w;
Eigen::Quaterniond q2;
q2.w() = 1;
q2.vec() = 0.5 * w;
q2.normalized();
Eigen::Matrix3d R2 = (q * q2).toRotationMatrix();
std::cout << "R1" << R1 << std::endl;
std::cout << "R2" << R2 << std::endl;
std::cout << R2*R1.transpose() < std::endl;
return 0;
}
result:
s o ( 3 ) so(3) so(3)导数:
使用右乘so(3)推导以下函数导数:
d
(
R
−
1
p
)
d
R
\frac{d(R^{-1}p)}{dR}
dRd(R−1p)
d
l
n
(
R
1
R
2
−
1
)
∨
d
R
2
\frac{d ln(R_1R_2^-1)^\lor}{dR_2}
dR2dln(R1R2−1)∨
推导过程(出于美观考虑,以下推导过程由mathpix转换手写过程生成)