1. 前言
之前看过崔华坤的《VINS论文推导及代码解析》还有深蓝学院的VIO课程,对VINS的后端非线性优化有了较为清晰的认识,但是一直没有时间整理写成笔记,最近看到Manni的博客VINS-Mono理论学习——后端非线性优化 概括得很不错,针对这三份资料还有自己的一些理解重新整理下,感谢优秀的大佬们提供的参考资料。
2. 非线性最小二乘
尽管非线性最小二乘是很常见的问题,可参考《SLAM14讲》第六章节,《多视图几何》附录6,乔治梅森大学Timothy Sauer的《数值分析》都有提及,在我之前的博客非线性最小二乘也进行了总结,这里简单回顾一下,由于VINS-Mono中在视觉重投影误差添加了鲁棒核函数,因此也整理下对残差添加鲁棒核函数对需要优化的状态量增量方程的影响。
对于最常见的最小二乘问题有:
xminF(x)=xmin21∥f(x)∥22 将残差写成组合向量的形式:
f(x)=⎣⎡f1(x)⋯fm(x)⎦⎤, 则
F(x)=∥f(x)∥22=fT(x)f(x)=i=1∑m(fi(x))2 同理,如果记
Ji(x)=∂x∂fi(x), 则有:
∂x∂f(x)=Jm×n=⎣⎡J1(x)⋯Jm(x)⎦⎤ , Ji(x)1×n=[∂x1∂fi(x) ∂x2∂fi(x) ⋯ ∂xn∂fi(x)]
对残差函数
f(x)进行一阶泰勒展开:
f(x+Δx)=f(x)+JΔx, 其中
J是残差函数
f的雅可比矩阵,代入损失函数(以下推导用
f代替
f(x)):
F(x+Δx)=21(f+JΔx)T(f+JΔx)=21fTf+ΔxTJTf+21ΔxTJTJΔx=F(x)+ΔxTJTf+21ΔxTJTJΔx(1) 这样损失函数就近似成了一个二次函数,如果雅可比矩阵是满秩的(并不一定满秩),则
JTJ正定,损失函数有最小值,且易得
F′(x)=(JTf)T, F′′(x)=JTJ
Gauss-Newton Method:
令公式(1)的一阶导数等于0,得到
(JTJ)Δxgn=−JTf 由于
H=JTJ可能出现H矩阵奇异或者病态,此时高斯牛顿法增量的稳定性较差,导致算法不收敛。同时对于步长问题,若求出来的
Δxgn太长,则可能出现局部近似不够准确,无法保证迭代收敛。
Levenberg-Marquardt Method (LM):
在高斯牛顿法的基础上引入阻尼因子:
(JTJ+μI)Δxlm=−JTf,with μ≥0 其中
μ称为阻尼因子。
阻尼因子的作用:
μ>0保证
(JTJ+μI)正定,迭代朝着下降方向进行。
阻尼因子
μ的更新策略:
- 如果
Δx→F(x)↑,则
μ↑→Δx↓,增大阻尼减小步长,拒绝本次迭代。
- 如果
Δx→F(x)↓,则
μ↓→Δx↑,减小阻尼增加步长,减少迭代次数。
3. 局部Bundle Adjustment代价函数的构建
对于需要优化的状态向量,包括滑动窗口内的所有IMU状态
xk(位姿
P、速度
V、旋转
Q、加速度偏置
ba,陀螺仪偏置
bw)、相机到IMU的外参
xcb、所有3D点的逆深度
λm:【论文公式(21)】
X=[x0,x1,⋯,xn,xcb,λ0,λ1,⋯,λm]
xk=[pbkw,vbkw,qbkw,ba,bg],k∈[0,n]
xcb=[pcb,qcb] 其中
xk代表相机获取图片时对应时刻
k的IMU状态,
n为滑动窗口内的关键帧的数量,
m为滑动窗口内3D视觉特征(空间点)的数量,
λm为第
m个3D视觉特征的逆深度(第一次被观察时计算得到的值)。
目标函数为 【论文公式(22)(23)】:
Xmin{∥rp−HpX∥2+k∈B∑∥∥∥rB(z^bk+1bk,X)∥∥∥Pbk+1bk2+(l,j)∈C∑ρ(∥∥rC(z^lcj,X)∥∥Plcj2)}
ρ(s)={1,s≥12s
−1,s<1 其中这三项分别为边缘化的先验信息 (由滑动窗口产生的关键帧边缘化)、IMU的测量误差、视觉的重投影误差,三种残差都是用马氏距离表示。
Pbk+1bk代表IMU残差的协方差,
Plcj代表视觉重投影误差的协方差,通过协方差的逆 (即信息矩阵) 对各个变量计算残差时进行加权。
ρ(s)为Huber核函数。
由于在IMU测量误差和视觉的重投影误差通过协方差的逆进行了加权,因此实际优化的是
min(d)=min(rkTP−1Rk), 这里
rk代表
k时刻时候的残差,
P代表协方差。而Ceres只接受诸如
min(rkTrk)的优化,因此在代码里,需要将信息矩阵
P−1做
LLT分解,即
LLT=P−1 ,代码中对应为sqrt_info
,这样就可以将优化进行转换:
min(d)=min(rkTP−1Rk)=min((LTrk)T(LTrk))=min(rk′Trk)