主要是看了范帝楷大佬在泡泡机器人SLAM中介绍。我把链接写到博客里便于自己以后查看。
【泡泡机器人原创专栏-OKVIS】OKVIS理论推导(上) https://mp.weixin.qq.com/s/FDMDleH8wszsD9HkBXwAnQ
【泡泡机器人原创专栏-OKVIS】OKVIS理论推导(下) https://mp.weixin.qq.com/s/UvRA_hOULokRgqJH1wk1iA
在OKVIS中的待估计的变量如下:
x
R
:
=
[
p
W
W
S
T
,
q
W
S
T
,
v
W
W
S
T
,
b
g
T
,
b
a
T
]
T
∈
R
3
×
S
3
×
R
9
\mathbf{x}_{\mathrm{R}}:=\left[\mathbf{p}_{W}^{W S^{T}}, \mathbf{q}_{W S}^{T}, \mathbf{v}_{W}^{W S^{T}}, \mathbf{b}_{\mathrm{g}}^{T}, \mathbf{b}_{\mathrm{a}}^{T}\right]^{T} \in \mathbb{R}^{3} \times S^{3} \times \mathbb{R}^{9}
xR:=[pWWST,qWST,vWWST,bgT,baT]T∈R3×S3×R9
其中并没包含特征点,即特征点不参与优化。路标用其次坐标表示为
x
L
:
=
l
W
W
L
=
[
l
x
,
l
y
,
l
z
,
l
w
]
T
∈
R
4
\mathbf{x}_{\mathrm{L}}:=l_{W}^{W L}=\left[l_{x}, l_{y}, l_{z}, l_{w}\right]^{T} \in \mathbb{R}^{4}
xL:=lWWL=[lx,ly,lz,lw]T∈R4
总的目标函数为
J
(
x
)
:
=
∑
i
=
1
I
∑
k
=
1
K
∑
j
∈
J
(
i
,
k
)
e
r
i
,
j
,
k
T
W
r
i
,
j
,
k
e
r
i
,
j
,
k
+
∑
k
=
1
K
−
1
e
s
k
T
W
s
k
e
s
k
J(\mathbf{x}):=\sum_{i=1}^{I} \sum_{k=1}^{K} \sum_{j \in \mathcal{J}(i, k)} \mathbf{e}_{\mathrm{r}}^{i, j, k^{T}} \mathbf{W}_{\mathrm{r}}^{i, j, k} \mathbf{e}_{\mathrm{r}}^{i, j, k}+\sum_{k=1}^{K-1} \mathbf{e}_{\mathrm{s}}^{k^{T}} \mathbf{W}_{\mathrm{s}}^{k} \mathbf{e}_{\mathrm{s}}^{k}
J(x):=i=1∑Ik=1∑Kj∈J(i,k)∑eri,j,kTWri,j,keri,j,k+k=1∑K−1eskTWskesk
分别对应重投影误差和IMU误差。
其中重投影误差不用讲了,IMU误差和VINS不同的是,这里是IMU积分预测的姿态和 “真实值” 之间的偏差(关于“真实值”的说明,对于滑窗内旧的关键帧,其实这个“真实值”就是之前优化后的姿态,而对于最新的那个关键帧,其实是根据IMU信息和上一帧位姿对最新关键帧预测得到的,这样的话按理说最后相邻两帧的IMU初始误差应该是0,但由于后续再和重投影误差联合优化的时候,为了使得整体的误差最小,最后两个关键帧的IMU误差可能会从0变成一个比较小的值。个人理解若有错误欢迎指正!)
关于IMU误差项协方差这一部分,VINS是直接用的IMU预积分的协方差,以为根据误差的定义的确是相等的。而okvis里的IMU误差项的协方差要在IMU积分的协方差上再用残差对IMU积分的雅克比进行一次更新,如下式所示
W
s
k
=
R
s
k
−
1
=
(
∂
e
s
k
∂
δ
χ
^
R
k
+
1
P
(
δ
χ
^
R
k
+
1
∣
x
R
k
,
z
s
k
)
∂
e
s
k
∂
δ
χ
^
R
k
+
1
)
−
1
\mathbf{W}_{\mathrm{s}}^{k}=\mathbf{R}_{\mathrm{s}}^{k^{-1}}=\left(\frac{\partial \mathbf{e}_{\mathrm{s}}^{k}}{\partial \delta \hat{\chi}_{\mathrm{R}}^{k+1}} \mathbf{P}\left(\delta \hat{\chi}_{\mathrm{R}}^{k+1} | \mathbf{x}_{\mathrm{R}}^{k}, \mathbf{z}_{\mathrm{s}}^{k}\right) \frac{\partial \mathbf{e}_{\mathrm{s}}^{k}}{\partial \delta \hat{\chi}_{\mathrm{R}}^{k+1}}\right)^{-1}
Wsk=Rsk−1=(∂δχ^Rk+1∂eskP(δχ^Rk+1∣xRk,zsk)∂δχ^Rk+1∂esk)−1
残差关于待优化状态量的雅克比矩阵,根据链式求导法则得
∂
e
s
k
∂
δ
χ
R
k
=
F
d
(
x
R
k
,
t
(
p
k
)
−
t
(
k
)
)
(
∏
p
=
p
k
p
k
+
1
−
1
F
d
(
x
^
R
p
,
Δ
t
)
)
F
d
(
x
^
R
p
k
+
1
−
1
,
t
(
k
+
1
)
−
t
(
p
k
+
1
−
1
)
)
∂
e
s
k
∂
δ
χ
^
R
k
+
1
\begin{aligned} \frac{\partial \mathbf{e}_{\mathrm{s}}^{k}}{\partial \delta \chi_{\mathrm{R}}^{k}}=& \mathbf{F}_{\mathrm{d}}\left(\mathbf{x}_{\mathrm{R}}^{k}, t\left(p^{k}\right)-t(k)\right)\left(\prod_{p=p^{k}}^{p^{k+1}-1} \mathbf{F}_{\mathrm{d}}\left(\hat{\mathbf{x}}_{\mathrm{R}}^{p}, \Delta t\right)\right) \\ & \mathbf{F}_{\mathrm{d}}\left(\hat{\mathbf{x}}_{\mathrm{R}}^{p^{k+1}-1}, t(k+1)-t\left(p^{k+1}-1\right)\right) \frac{\partial \mathbf{e}_{\mathrm{s}}^{k}}{\partial \delta \hat{\chi}_{\mathrm{R}}^{\mathrm{k}+1}} \end{aligned}
∂δχRk∂esk=Fd(xRk,t(pk)−t(k))⎝⎛p=pk∏pk+1−1Fd(x^Rp,Δt)⎠⎞Fd(x^Rpk+1−1,t(k+1)−t(pk+1−1))∂δχ^Rk+1∂esk
边缘化
okvis在边缘化的过程中和VINS的不太一样,分两个窗口。而且OKVIS在优化的过程中会考虑FEJ的问题。
文中定义边缘化的状态量为
x
λ
x_{\lambda}
xλ,剩余变量
x
μ
x_{\mu}
xμ
[
H
μ
μ
H
μ
λ
1
H
λ
1
μ
H
λ
1
λ
1
]
[
δ
χ
μ
δ
χ
λ
]
=
[
b
μ
b
λ
1
]
\left[\begin{array}{cc}{\mathbf{H}_{\mu \mu}} & {\mathbf{H}_{\mu \lambda_{1}}} \\ {\mathbf{H}_{\lambda_{1} \mu}} & {\mathbf{H}_{\lambda_{1} \lambda_{1}}}\end{array}\right]\left[\begin{array}{c}{\delta \chi_{\mu}} \\ {\delta \chi_{\lambda}}\end{array}\right]=\left[\begin{array}{c}{\mathbf{b}_{\mu}} \\ {\mathbf{b}_{\lambda_{1}}}\end{array}\right]
[HμμHλ1μHμλ1Hλ1λ1][δχμδχλ]=[bμbλ1]
对H矩阵进行舒尔补操作后得
H
λ
1
λ
1
∗
:
=
H
λ
1
λ
1
−
H
λ
1
μ
H
μ
μ
−
1
H
μ
λ
1
b
λ
1
∗
:
=
b
λ
1
−
H
λ
1
μ
H
μ
μ
−
1
b
μ
\begin{aligned} \mathbf{H}_{\lambda_{1} \lambda_{1}}^{*} &:=\mathbf{H}_{\lambda_{1} \lambda_{1}}-\mathbf{H}_{\lambda_{1} \mu} \mathbf{H}_{\mu \mu}^{-1} \mathbf{H}_{\mu \lambda_{1}} \\ \mathbf{b}_{\lambda_{1}}^{*} &:=\mathbf{b}_{\lambda_{1}}-\mathbf{H}_{\lambda_{1} \mu} \mathbf{H}_{\mu \mu}^{-1} \mathbf{b}_{\mu} \end{aligned}
Hλ1λ1∗bλ1∗:=Hλ1λ1−Hλ1μHμμ−1Hμλ1:=bλ1−Hλ1μHμμ−1bμ
然后可以求得
Δ
χ
λ
1
\Delta \chi_{\lambda_{1}}
Δχλ1
根据当前状态量的估计值和线性化点时对应的
x
0
x_0
x0可以得到状态量的增量表示为
Δ
χ
:
=
Φ
−
1
(
log
(
x
‾
□
x
0
−
1
)
)
)
\left.\Delta \chi:=\Phi^{-1}\left(\log \left(\overline{\mathbf{x}} \square \mathbf{x}_{0}^{-1}\right)\right)\right)
Δχ:=Φ−1(log(x□x0−1)))
而状态量的实际值可以表示为
x
=
exp
(
Φ
(
δ
χ
)
)
□
exp
(
Φ
(
Δ
χ
)
)
□
x
0
⏟
=
x
‾
\mathbf{x}=\exp (\Phi(\delta \boldsymbol{\chi})) \square \underbrace{\exp (\Phi(\Delta \boldsymbol{\chi})) \square \mathbf{x}_{0}}_{=\overline{\mathbf{x}}}
x=exp(Φ(δχ))□=x
exp(Φ(Δχ))□x0
因为后续剩余变量要不断的迭代更新进行优化,其中在边缘化后对那些与边缘化变量相连的剩余变量的H矩阵不再变化了,为了使得优化过程能正常进行下去,需要对b矩阵进行更新
对于状态增量
Δ
χ
\Delta \chi
Δχ,b的更新公式如下所示
b
+
∂
b
∂
Δ
χ
∣
x
0
Δ
χ
=
b
−
H
Δ
χ
\mathbf{b}+\left.\frac{\partial \mathbf{b}}{\partial \Delta \chi}\right|_{\mathbf{x}_{0}} \Delta \chi=\mathbf{b}-\mathbf{H} \Delta \chi
b+∂Δχ∂b∣∣∣∣x0Δχ=b−HΔχ
从而得在一次迭代之后,b矩阵更新如下
[
b
μ
b
λ
1
]
=
[
b
μ
,
0
b
λ
1
,
0
]
−
[
H
μ
μ
H
μ
λ
1
H
λ
1
μ
H
λ
1
λ
1
]
[
Δ
χ
μ
Δ
χ
λ
]
\left[\begin{array}{c}{\mathbf{b}_{\mu}} \\ {\mathbf{b}_{\lambda_{1}}}\end{array}\right]=\left[\begin{array}{l}{\mathbf{b}_{\mu, 0}} \\ {\mathbf{b}_{\lambda_{1}, 0}}\end{array}\right]-\left[\begin{array}{ll}{\mathbf{H}_{\mu \mu}} & {\mathbf{H}_{\mu \lambda_{1}}} \\ {\mathbf{H}_{\lambda_{1} \mu} \mathbf{H}_{\lambda_{1} \lambda_{1}}}\end{array}\right]\left[\begin{array}{l}{\Delta \chi_{\mu}} \\ {\Delta \chi_{\lambda}}\end{array}\right]
[bμbλ1]=[bμ,0bλ1,0]−[HμμHλ1μHλ1λ1Hμλ1][ΔχμΔχλ]
b
λ
1
∗
=
b
λ
1
,
0
−
H
λ
1
μ
T
H
μ
μ
−
1
b
μ
,
0
⏟
b
λ
1
,
0
∗
−
H
λ
1
λ
1
∗
Δ
χ
λ
1
\mathbf{b}_{\lambda_{1}}^{*}=\underbrace{\mathbf{b}_{\lambda_{1}, 0}-\mathbf{H}_{\lambda_{1} \mu}^{T} \mathbf{H}_{\mu \mu}^{-1} \mathbf{b}_{\mu, 0}}_{\mathbf{b}_{\lambda_{1}, 0}^{*}}-\mathbf{H}_{\lambda_{1} \lambda_{1}}^{*} \Delta \chi_{\lambda_{1}}
bλ1∗=bλ1,0∗
bλ1,0−Hλ1μTHμμ−1bμ,0−Hλ1λ1∗Δχλ1
然后就可以不断的迭代求解了。