视觉与IMU对齐
修正陀螺仪的偏置
从陀螺仪传感器获取到的角速度,初始化阶段,认为角速度存在一个偏置
b
ω
b_{\omega}
bω。
已知由图像计算的两帧陀螺仪的旋转四元数:
q
b
k
+
1
c
0
,
q
b
k
c
0
q_{b_{k+1}}^{c_0},q_{b_k}^{c_0}
qbk+1c0,qbkc0 和根据陀螺仪数据预积分得到的从第
k
k
k帧到
k
+
1
k+1
k+1帧的旋转四元数:
γ
^
b
k
+
1
b
k
\hat{\gamma}_{b_{k+1}}^{b_k}
γ^bk+1bk。
保证根据视觉计算出的两帧之间的旋转变化与陀螺仪积分得到的旋转变化相等,得到如下条件约束:
min δ b ω ∑ ∥ q b k + 1 c 0 − 1 ⊗ q b k c 0 ⊗ γ b k + 1 b k ∥ 2 \min_{\delta b_{\omega}} \sum \|{q_{b_{k+1}}^{c_0}}^{-1} \otimes q_{b_k}^{c_0} \otimes \gamma_{b_{k+1}}^{b_k}\|^2 δbωmin∑∥qbk+1c0−1⊗qbkc0⊗γbk+1bk∥2
其中:
γ b k + 1 b k ≈ γ ^ b k + 1 b k ⊗ [ 1 1 2 J b ω γ δ b ω ] \gamma_{b_{k+1}}^{b_k} \approx \hat{\gamma}_{b_{k+1}}^{b_k} \otimes \begin{bmatrix} 1 \\ \frac{1}{2} J_{b_{\omega}}^{\gamma} \delta b_{\omega} \end{bmatrix} γbk+1bk≈γ^bk+1bk⊗[121Jbωγδbω]
以上公式的最小值为单位四元数,因此可将公式写为:
q b k + 1 c 0 − 1 ⊗ q b k c 0 ⊗ γ b k + 1 b k = [ 1 0 ] {q_{b_{k+1}}^{c_0}}^{-1} \otimes q_{b_k}^{c_0} \otimes \gamma_{b_{k+1}}^{b_k} = \begin{bmatrix} 1 \\ 0 \end{bmatrix} qbk+1c0−1⊗qbkc0⊗γbk+1bk=[10]
γ ^ b k + 1 b k ⊗ [ 1 1 2 J b ω γ δ b ω ] = q b k c o − 1 ⊗ q b k + 1 c 0 \hat{\gamma}_{b_{k+1}}^{b_k} \otimes \begin{bmatrix} 1 \\ \frac{1}{2}J_{b_{\omega}}^{\gamma}\delta b_{\omega} \end{bmatrix} = {q_{b_k}^{c_o}}^{-1} \otimes q_{b_{k+1}}^{c_0} γ^bk+1bk⊗[121Jbωγδbω]=qbkco−1⊗qbk+1c0
⇒ [ 1 1 2 J b ω γ δ b ω ] = γ ^ b k + 1 b k − 1 ⊗ q b k c 0 − 1 ⊗ q b k + 1 c 0 \Rightarrow \begin{bmatrix} 1 \\ \frac{1}{2}J_{b_{\omega}}^{\gamma} \delta b_{\omega} \end{bmatrix} = {\hat{\gamma}_{b_{k+1}}^{b_k}}^{-1} \otimes {q_{b_k}^{c_0}}^{-1} \otimes q_{b_{k+1}}^{c_0} ⇒[121Jbωγδbω]=γ^bk+1bk−1⊗qbkc0−1⊗qbk+1c0
只取上式虚部再进行最小二乘求解:
J b ω γ T J b ω γ δ b ω = 2 J b ω γ T ( γ ^ b k + 1 b k − 1 ⊗ q b k c 0 − 1 ⊗ q b k + 1 c 0 ) . v e c {J_{b_{\omega}}^{\gamma}}^T J_{b_{\omega}}^{\gamma} \delta b_{\omega} = 2 {J_{b_{\omega}}^{\gamma}}^T\left({\hat{\gamma}_{b_{k+1}}^{b_k}}^{-1} \otimes {q_{b_k}^{c_0}}^{-1} \otimes q_{b_{k+1}}^{c_0}\right)_{.vec} JbωγTJbωγδbω=2JbωγT(γ^bk+1bk−1⊗qbkc0−1⊗qbk+1c0).vec
VINS中对应代码
void solveGyroscopeBias(map<double, ImageFrame> &all_image_frame, Vector3d* Bgs)
{
Matrix3d A;
Vector3d b;
Vector3d delta_bg;
A.setZero();
b.setZero();
map<double, ImageFrame>::iterator frame_i;
map<double, ImageFrame>::iterator frame_j;
for (frame_i = all_image_frame.begin(); next(frame_i) != all_image_frame.end(); frame_i++)
{
frame_j = next(frame_i);
MatrixXd tmp_A(3, 3);
tmp_A.setZero();
VectorXd tmp_b(3);
tmp_b.setZero();
Eigen::Quaterniond q_ij(frame_i->second.R.transpose() * frame_j->second.R);
tmp_A = frame_j->second.pre_integration->jacobian.template block<3, 3>(O_R, O_BG);
tmp_b = 2 * (frame_j->second.pre_integration->delta_q.inverse() * q_ij).vec();
A += tmp_A.transpose() * tmp_A;
b += tmp_A.transpose() * tmp_b;
}
delta_bg = A.ldlt().solve(b);
for (int i = 0; i <= WINDOW_SIZE; i++)
Bgs[i] += delta_bg;
for (frame_i = all_image_frame.begin(); next(frame_i) != all_image_frame.end( ); frame_i++)
{
frame_j = next(frame_i);
frame_j->second.pre_integration->repropagate(Vector3d::Zero(), Bgs[0]);
}
}
初始化速度、重力向量g和尺度因子
已知:
p b k + 1 w = p b k w + v b k w Δ t k + ∫ ∫ t ∈ [ t k , t k + 1 ] ( R t w ( a ^ t − b a t − n a ) − g w ) d t 2 p_{b_{k+1}}^w = p_{b_k}^w + v_{b_k}^w \Delta t_k + \int \int_{t \in \left[t_k, t_{k+1}\right]}\left(R_t^w\left(\hat{a}_t - b_{a_t} - n_a\right)-g^w\right){dt}^2 pbk+1w=pbkw+vbkwΔtk+∫∫t∈[tk,tk+1](Rtw(a^t−bat−na)−gw)dt2
v b k + 1 w = v b k w + ∫ t ∈ [ t k , t k + 1 ] ( R t w ( a ^ t − b a t − n a ) − g w ) d t v_{b_{k+1}}^w=v_{b_k}^w + \int_{t\in\left[t_k, t_{k+1}\right]}\left(R_t^w\left(\hat{a}_t - b_{a_t} - n_a\right)-g^w\right)dt vbk+1w=vbkw+∫t∈[tk,tk+1](Rtw(a^t−bat−na)−gw)dt
q b k + 1 w = q b k w ⊗ ∫ t ∈ [ t k , t k + 1 ] 1 2 Ω ( ω ^ t − b ω t − n ω ) q t b k d t q_{b_{k+1}}^w = q_{b_k}^w \otimes \int_{t\in\left[t_k, t_{k+1}\right]}\frac{1}{2}\Omega\left(\hat{\omega}_t - b_{\omega_t} - n_{\omega}\right)q_t^{b_k}dt qbk+1w=qbkw⊗∫t∈[tk,tk+1]21Ω(ω^t−bωt−nω)qtbkdt
其中:
Ω ( ω ) = [ [ ω ] × ω − ω T 0 ] , [ ω ] = [ 0 − ω z ω y ω z 0 − ω x − ω y ω x 0 ] \Omega\left(\omega\right)=\begin{bmatrix} \left[\omega\right]_{\times} & \omega \\ -\omega^T & 0 \end{bmatrix}, \qquad \left[\omega\right] = \begin{bmatrix} 0 & -\omega_z & \omega_y \\ \omega_z & 0 & -\omega_x \\ -\omega_y & \omega_x & 0 \end{bmatrix} Ω(ω)=[[ω]×−ωTω0],[ω]=⎣⎡0ωz−ωy−ωz0ωxωy−ωx0⎦⎤
上面的三个式子写成两部分,第一部分为已知数据,第二部分为需要预积分得到部分:
R w b k p b k + 1 w = R w b k ( p b k w + v b k w Δ t k − 1 2 g w Δ t k 2 ) + α b k + 1 b k R_w^{b_k}p_{b_{k+1}}^w = R_w^{b_k}\left(p_{b_k}^w + v_{b_k}^w\Delta t_k - \frac{1}{2}g^w{\Delta t_k}^2\right) + \alpha_{b_{k+1}}^{b_k} Rwbkpbk+1w=Rwbk(pbkw+vbkwΔtk−21gwΔtk2)+αbk+1bk
R w b k v b k + 1 w = R w b k ( v b k w + g w Δ t k ) + β b k + 1 b k R_w^{b_k}v_{b_{k+1}}^w = R_w^{b_k}\left(v_{b_k}^w + g^w {\Delta t}_k\right)+\beta_{b_{k+1}}^{b_k} Rwbkvbk+1w=Rwbk(vbkw+gwΔtk)+βbk+1bk
q w b k ⊗ q b k + 1 w = γ b k + 1 b k q_w^{b_k}\otimes q_{b_{k+1}}^w = \gamma_{b_{k+1}}^{b_k} qwbk⊗qbk+1w=γbk+1bk
因为把相机的0帧的位姿当做世界坐标系的初始值,因此有
R b K w = R b k c 0 ⇒ R w b k = R b k w − 1 = R b k c 0 − 1 = R c 0 b k R_{b_K}^w = R_{b_k}^{c_0} \Rightarrow R_w^{b_k} = {R_{b_k}^w}^{-1} = {R_{b_k}^{c_0}}^{-1}=R_{c_0}^{b_k} RbKw=Rbkc0⇒Rwbk=Rbkw−1=Rbkc0−1=Rc0bk
( 1 ) α b k + 1 b k = R w b k ( p b k + 1 w − p b k w − v b k w Δ t k + 1 2 g w Δ t k 2 ) = R c 0 b k ( s ( p b k + 1 c 0 − p b k c 0 ) + 1 2 g c 0 Δ t k 2 − v b k c 0 Δ t k ) = R c 0 b k ( s ( p b k + 1 c 0 − p b k c 0 ) + 1 2 g c 0 Δ t k 2 − R b k c 0 v b k b k Δ t k ) \alpha_{b_{k+1}}^{b_k} = R_w^{b_k}\left(p_{b_{k+1}}^w - p_{b_k}^w - v_{b_k}^w\Delta t_k + \frac{1}{2}g^w{\Delta t_k}^2\right) \\ =R_{c_0}^{b_k}\left(s\left(p_{b_{k+1}}^{c_0} - p_{b_k}^{c_0}\right) + \frac{1}{2}g^{c_0}{\Delta t_k}^2 - v_{b_k}^{c_0}\Delta t_k\right) \\ = R_{c_0}^{b_k}\left(s\left(p_{b_{k+1}}^{c_0} - p_{b_k}^{c_0}\right) + \frac{1}{2}g^{c_0}{\Delta t_k}^2 - R_{b_k}^{c_0}v_{b_k}^{b_k}\Delta t_k\right) \tag{$1$} αbk+1bk=Rwbk(pbk+1w−pbkw−vbkwΔtk+21gwΔtk2)=Rc0bk(s(pbk+1c0−pbkc0)+21gc0Δtk2−vbkc0Δtk)=Rc0bk(s(pbk+1c0−pbkc0)+21gc0Δtk2−Rbkc0vbkbkΔtk)(1)
β b k + 1 b k = R w b k ( v b k + 1 w − v b k w − g w Δ t k ) \beta_{b_{k+1}}^{b_k} = R_w^{b_k}\left(v_{b_{k+1}}^w - v_{b_k}^w - g^w\Delta t_k\right) βbk+1bk=Rwbk(vbk+1w−vbkw−gwΔtk)
= R c 0 b k ( v b k + 1 c 0 − v b k c 0 + g c 0 Δ t k ) =R_{c_0}^{b_k}\left(v_{b_{k+1}}^{c_0} - v_{b_k}^{c_0} + g^{c_0}\Delta t_k\right) =Rc0bk(vbk+1c0−vbkc0+gc0Δtk)
( 2 ) = R c 0 b k ( R b k + 1 c 0 v b k + 1 b k + 1 − R b k c 0 v b k b k + g c 0 Δ t k ) =R_{c_0}^{b_k}\left(R_{b_{k+1}}^{c_0}v_{b_{k+1}}^{b_{k+1}} - R_{b_k}^{c_0}v_{b_k}^{b_k} + g^{c_0}\Delta t_k\right) \tag{$2$} =Rc0bk(Rbk+1c0vbk+1bk+1−Rbkc0vbkbk+gc0Δtk)(2)
从 C 0 C_0 C0坐标系到 IMU坐标系和世界坐标系转换位置(P),速度(V)时需要引入尺度。设从IMU到相机的旋转为 q c b q_c^b qcb,平移量为 p c b p_c^b pcb,因此有以下等式:
q b k c 0 = q c K c 0 ⊗ ( q c b ) − 1 q_{b_k}^{c_0} = q_{c_K}^{c_0} \otimes \left(q_c^b\right)^{-1} qbkc0=qcKc0⊗(qcb)−1
( 3 ) s p ‾ k k c 0 = s p ‾ c k c 0 − R b k c 0 p c b s {\overline p}_{k_k}^{c_0} = s {\overline p}_{c_k}^{c_0} - R_{b_k}^{c_0}p_c^b \tag{$3$} spkkc0=spckc0−Rbkc0pcb(3)
进而有:
( 4 ) s p ‾ b k + 1 c 0 = s p ‾ c k + 1 c 0 − R b k + 1 c 0 p c b s {\overline p}_{b_{k+1}}^{c_0}=s {\overline p}_{c_{k+1}}^{c_0} - R_{b_{k+1}}^{c_0}p_c^b\tag{$4$} spbk+1c0=spck+1c0−Rbk+1c0pcb(4)
4式减3式得:
( 5 ) s ( p ‾ b k + 1 c 0 − p ‾ b k c 0 ) = s ( p ‾ c k + 1 c 0 − p ‾ c k c 0 ) + ( R b k c 0 − R b k + 1 c 0 ) p c b s \left({\overline p}_{b_{k+1}}^{c_0} - {\overline p}_{b_k}^{c_0} \right) = s \left({\overline p}_{c_{k+1}}^{c_0} - {\overline p}_{c_k}^{c_0} \right) + \left(R_{b_k}^{c_0} - R_{b_{k+1}}^{c_0}\right) p_c^b \tag{$5$} s(pbk+1c0−pbkc0)=s(pck+1c0−pckc0)+(Rbkc0−Rbk+1c0)pcb(5)
5式代入1式得到:
( 6 ) α b k + 1 b k = R c 0 b k ( s ( p ‾ c k + 1 c 0 − p ‾ c k c 0 ) + 1 2 g c 0 Δ t k 2 − R b k c 0 v b k b k Δ t k ) + p c b − R c 0 b k R b k + 1 c 0 p c b \alpha _{b_{k+1}}^{b_k} = \\ R_{c_0}^{b_k}\left( s \left({\overline p}_{c_{k+1}}^{c_0} - {\overline p}_{c_k}^{c_0} \right) + \frac{1}{2}g^{c_0}{\Delta t_k}^2 - R_{b_k}^{c_0}v_{b_k}^{b_k}\Delta t_k\right) + p_c^b - R_{c_0}^{b_k}R_{b_{k+1}}^{c_0}p_c^b \tag{$6$} αbk+1bk=Rc0bk(s(pck+1c0−pckc0)+21gc0Δtk2−Rbkc0vbkbkΔtk)+pcb−Rc0bkRbk+1c0pcb(6)
对6式整理得到:
( 7 ) α b k + 1 b k − p c b + R c 0 b k R b k + 1 c 0 p c b = R c 0 b k ( s ( p ‾ c k + 1 c 0 − p ‾ c k c 0 ) + 1 2 g c 0 Δ t k 2 − R b k c 0 v b k b k Δ t k ) \alpha _{b_{k+1}}^{b_k} - p_c^b + R_{c_0}^{b_k}R_{b_{k+1}}^{c_0}p_c^b = \\ R_{c_0}^{b_k}\left( s \left({\overline p}_{c_{k+1}}^{c_0} - {\overline p}_{c_k}^{c_0} \right) + \frac{1}{2}g^{c_0}{\Delta t_k}^2 - R_{b_k}^{c_0}v_{b_k}^{b_k}\Delta t_k\right) \tag{$7$} αbk+1bk−pcb+Rc0bkRbk+1c0pcb=Rc0bk(s(pck+1c0−pckc0)+21gc0Δtk2−Rbkc0vbkbkΔtk)(7)
用***2式、6式***整理得到:
[ α b k + 1 b k − p c b + R c 0 b k R b k + 1 c 0 p c b β b k + 1 b k ] = [ − I Δ t k 0 1 2 R c 0 b k Δ t k 2 R c 0 b k ( p c k + 1 c 0 − p c k c 0 ) ) − I R c 0 b k R b k + 1 c 0 R c 0 b k Δ t k 0 ] [ v b k b k v b k + 1 b k + 1 g c 0 s ] = H b k + 1 b k X I \begin{bmatrix} \alpha_{b_{k+1}}^{b_k} - p_c^b + R_{c_0}^{b_k}R_{b_{k+1}}^{c_0}p_c^b\\ \beta_{b_{k+1}}^{b_k} \end{bmatrix}= \\ \begin{bmatrix} -I\Delta t_k & 0 & \frac{1}{2}R_{c_0}^{b_k}{\Delta t_k}^2 & R_{c_0}^{b_k}\left(p_{c_{k+1}}^{c_0} - p_{c_k}^{c_0)}\right) \\ -I & R_{c_0}^{b_k}R_{b_{k+1}}^{c_0} & R_{c_0}^{b_k}\Delta t_k & 0 \end{bmatrix} \begin{bmatrix} v_{b_k}^{b_k} \\ v_{b_{k+1}}^{b_{k+1}} \\ g^{c_0} \\ s \end{bmatrix}=H_{b_{k+1}}^{b_k}X_I [αbk+1bk−pcb+Rc0bkRbk+1c0pcbβbk+1bk]=[−IΔtk−I0Rc0bkRbk+1c021Rc0bkΔtk2Rc0bkΔtkRc0bk(pck+1c0−pckc0))0]⎣⎢⎢⎡vbkbkvbk+1bk+1gc0s⎦⎥⎥⎤=Hbk+1bkXI
根据预积分可以得到 α b k + 1 b k , β b k + 1 b k {\alpha}_{b_{k+1}}^{b_k},{\beta}_{b_{k+1}}^{b_k} αbk+1bk,βbk+1bk
令 z b k + 1 b k = [ α b k + 1 b k β b k + 1 b k ] {z}_{b_{k+1}}^{b_k} = \begin{bmatrix} {\alpha}_{b_{k+1}}^{b_k} \\ {\beta}_{b_{k+1}}^{b_k} \end{bmatrix} zbk+1bk=[αbk+1bkβbk+1bk]
建立求解 X I X_I XI的约束
min X I ∑ k ∈ B ∥ z b k + 1 b k − H b k + 1 b k X I ∥ \min_{X_I}\sum_{k \in B} \| {z}_{b_{k+1}}^{b_k} - H_{b_{k+1}}^{b_k}X_I \| XImink∈B∑∥zbk+1bk−Hbk+1bkXI∥
利用最小二乘法求解:
H b k + 1 b k T H b k + 1 b k X I = H b k + 1 b k T z b k + 1 b k {H_{b_{k+1}}^{b_k}}^TH_{b_{k+1}}^{b_k}X_I = {H_{b_{k+1}}^{b_k}}^T {z}_{b_{k+1}}^{b_k} Hbk+1bkTHbk+1bkXI=Hbk+1bkTzbk+1bk
即可得到 X I X_I XI
改进重力向量g的值
通过该公式得到计算出的重力 g ^ \hat{g} g^在切平面上的两个分量,其中 b b b是与真实重力 g g g和计算出的重力 g ^ \hat{g} g^在同一个平面上, a a a是与 g ^ \hat{g} g^和 b b b平面垂直的向量。
MatrixXd TangentBasis(Vector3d &g0)
{
Vector3d b, c;
Vector3d a = g0.normalized();
Vector3d tmp(0, 0, 1);
if(a == tmp)
tmp << 1, 0, 0;
// a和tmp可以看做半径为1的半球,球心在原点。
// 因为a与tmp都是单位向量,并且tmp是(0, 0, 1),所以a.transpose() * tmp
// 计算的是a在tmp上投影的长度,a*(a.transpose() * tmp)是与a同向的向量,
// 可以看做半径为(a.transpose() * tmp)的球,因此
// (tmp - a * (a.transpose() * tmp)).normalized()是与a向量垂直,
// 并且是半径为1的半球的切线,切点为a, a.cross(b) a叉乘b,垂直a,b平面的向量
b = (tmp - a * (a.transpose() * tmp)).normalized();
c = a.cross(b);
MatrixXd bc(3, 2);
bc.block<3, 1>(0, 0) = b;
bc.block<3, 1>(0, 1) = c;
return bc;
}
因为 g ^ \hat{g} g^并不是竖直向下的,所以,认为 g w = g + l x + l y g^w = g+l_x+l_y gw=g+lx+ly
代入公公式:
[ α b k + 1 b k + R c 0 b k R b k + 1 c 0 p c b − p c b − 1 2 R c 0 b k Δ t k 2 ( g w n o r m ∗ G ) β b k + 1 b k − R c 0 b k Δ t k I ( g w n o r m ∗ G ) ] = [ − I Δ t k 0 1 2 R c 0 b k Δ t k 2 I 3 × 3 l x y 3 × 2 R c 0 b k ( p c k + 1 c 0 − p c k c 0 ) ) − I R c 0 b k R b k + 1 c 0 R c 0 b k Δ t k I 3 × 3 l x y 3 × 2 0 ] [ v b k b k v b k + 1 b k + 1 δ g c 0 s ] = H b k + 1 b k X I \begin{bmatrix} \alpha_{b_{k+1}}^{b_k} + R_{c_0}^{b_k} R_{b_{k+1}}^{c_0}p_c^b - p_c^b - \frac{1}{2}R_{c_0}^{b_k} {\Delta t_k}^2 \left({{g^w}_{norm}}*G\right) \\ \beta_{b_{k+1}}^{b_k} - R_{c_0}^{b_k}{\Delta t}_kI\left({{g^w}_{norm}}*G\right) \end{bmatrix} \\ = \begin{bmatrix} -I\Delta t_k & 0 & \frac{1}{2}R_{c_0}^{b_k}{\Delta t_k}^2I_{3 \times 3}{lxy}_{3 \times 2} & R_{c_0}^{b_k}\left(p_{c_{k+1}}^{c_0} - p_{c_k}^{c0)}\right) \\ -I & R_{c_0}^{b_k}R_{b_{k+1}}^{c_0} & R_{c_0}^{b_k}\Delta t_kI_{3 \times 3}{lxy}_{3 \times 2} & 0 \end{bmatrix} \begin{bmatrix} v_{b_k}^{b_k}\\ v_{b_{k+1}}^{b_{k+1}} \\ \delta g^{c_0} \\ s \end{bmatrix} \\ =H_{b_{k+1}}^{b_k}X_I [αbk+1bk+Rc0bkRbk+1c0pcb−pcb−21Rc0bkΔtk2(gwnorm∗G)βbk+1bk−Rc0bkΔtkI(gwnorm∗G)]=[−IΔtk−I0Rc0bkRbk+1c021Rc0bkΔtk2I3×3lxy3×2Rc0bkΔtkI3×3lxy3×2Rc0bk(pck+1c0−pckc0))0]⎣⎢⎢⎡vbkbkvbk+1bk+1δgc0s⎦⎥⎥⎤=Hbk+1bkXI
根据最小二乘即可得到 δ g \delta g δg
g ^ = ( g ^ + l x l y ∗ δ g ) . n o r m a l i z e d ( ) ∗ G \hat{g} = (\hat{g} + lxly * \delta g).normalized() * G g^=(g^+lxly∗δg).normalized()∗G
通过对上式的迭代即可得到 g g g
void RefineGravity(map<double, ImageFrame> &all_image_frame, Vector3d &g, VectorXd &x)
{
Vector3d g0 = g.normalized() * G_NORM;
Vector3d lx, ly;
//VectorXd x;
int all_frame_count = all_image_frame.size();
int n_state = all_frame_count * 3 + 2 + 1;
MatrixXd A{n_state, n_state};
A.setZero();
VectorXd b{n_state};
b.setZero();
map<double, ImageFrame>::iterator frame_i;
map<double, ImageFrame>::iterator frame_j;
for(int k = 0; k < 4; k++)
{
MatrixXd lxly(3, 2);
lxly = TangentBasis(g0);
int i = 0;
for (frame_i = all_image_frame.begin(); next(frame_i) != all_image_frame.end(); frame_i++, i++)
{
frame_j = next(frame_i);
MatrixXd tmp_A(6, 9);
tmp_A.setZero();
VectorXd tmp_b(6);
tmp_b.setZero();
double dt = frame_j->second.pre_integration->sum_dt;
tmp_A.block<3, 3>(0, 0) = -dt * Matrix3d::Identity();
tmp_A.block<3, 2>(0, 6) = frame_i->second.R.transpose() * dt * dt / 2 * Matrix3d::Identity() * lxly;
tmp_A.block<3, 1>(0, 8) = frame_i->second.R.transpose() * (frame_j->second.T - frame_i->second.T) / 100.0;
tmp_b.block<3, 1>(0, 0) = frame_j->second.pre_integration->delta_p - frame_i->second.R.transpose() * dt * dt / 2 * g0;
tmp_A.block<3, 3>(3, 0) = -Matrix3d::Identity();
tmp_A.block<3, 3>(3, 3) = frame_i->second.R.transpose() * frame_j->second.R;
tmp_A.block<3, 2>(3, 6) = frame_i->second.R.transpose() * dt * Matrix3d::Identity() * lxly;
tmp_b.block<3, 1>(3, 0) = frame_j->second.pre_integration->delta_v - frame_i->second.R.transpose() * dt * Matrix3d::Identity() * g0;
Matrix<double, 6, 6> cov_inv = Matrix<double, 6, 6>::Zero();
MatrixXd r_A = tmp_A.transpose() * tmp_A;
VectorXd r_b = tmp_A.transpose() * tmp_b;
A.block<6, 6>(i * 3, i * 3) += r_A.topLeftCorner<6, 6>();
b.segment<6>(i * 3) += r_b.head<6>();
A.bottomRightCorner<3, 3>() += r_A.bottomRightCorner<3, 3>();
b.tail<3>() += r_b.tail<3>();
A.block<6, 3>(i * 3, n_state - 3) += r_A.topRightCorner<6, 3>();
A.block<3, 6>(n_state - 3, i * 3) += r_A.bottomLeftCorner<3, 6>();
}
A = A * 1000.0;
b = b * 1000.0;
x = A.ldlt().solve(b);
VectorXd dg = x.segment<2>(n_state - 3);
g0 = (g0 + lxly * dg).normalized() * G_NORM;
//double s = x(n_state - 1);
}
g = g0;
}