[从零写VIO|第五节]——后端优化实践:逐行手写求解器(作业)

在这里插入图片描述
1.1 信息矩阵H的计算

对于每一条边都要进行这样两个for循环,分别是遍历方阵H的行和列,第一个i的for循环是行数,当遍历到行列相等,也就是对角的时候,只用放入一次hessian,而其他情况下都要放入关于对角对称的两个hessian,这是由于这两个位置的hessian是转置的关系。而b则在行遍历的时候一行行填入。

MatXX hessian = JtW * jacobian_j;                
// 所有的信息矩阵叠加起来                
// TODO:: home work. 完成 H index 的填写.                
H.block(index_i,index_j, dim_i, dim_j).noalias() += hessian;                
if (j != i) {                    
    // 对称的下三角            
    // TODO:: home work. 完成 H index 的填写.                    
    H.block(index_j,index_i, dim_j, dim_i).noalias() += hessian.transpose();                     
    }          

1.2. SLAM问题的求解
将问题转换成normal equation,其中, H p p H_{pp} Hpp表示相机位姿之间的关系,下图中 H l l H_{ll} Hll对应代码中的 H m m H_{mm} Hmm表示路标点之间的关系, H p l H_{pl} Hpl对应代码中的 H p m H_{pm} Hpm表示相机和路标之间的关系。
在这里插入图片描述
矩阵块的取值:

// TODO:: home work. 完成矩阵块取值,Hmm,Hpm,Hmp,bpp,bmm:landmark        
MatXX Hmm = Hessian_.block(reserve_size,reserve_size, marg_size, marg_size);        
MatXX Hmp = Hessian_.block(reserve_size,0, marg_size, reserve_size);        
MatXX Hpm = Hessian_.block(0,reserve_size,reserve_size, marg_size);        
VecX bmm = b_.segment(reserve_size,marg_size );        
VecX bpp = b_.segment(0,reserve_size);

完成舒尔补代码:

// TODO:: home work. 完成舒尔补 Hpp, bpp 代码        
MatXX tempH = Hpm * Hmm_inv;        
H_pp_schur_ = Hessian_.block(0,0,reserve_size,reserve_size) - tempH * Hmp;        
b_pp_schur_ = bpp - tempH * bmm;

求解路标点 δ x l \delta x_l δxl

// TODO:: home work. step3: solve landmark        
VecX delta_x_ll(marg_size);        
delta_x_ll =  Hmm_inv * (bmm - Hmp * delta_x_pp) ;        
delta_x_.tail(marg_size) = delta_x_ll; // x_ll 路标点信息
  1. 滑动窗口算法测试函数
    4.
    其信息矩阵为:

在这里插入图片描述
现在要从这个例子中marg掉 x 2 x_2 x2(绿色部分),求解之后的信息矩阵。需要将绿色部分移动到信息矩阵的右下角,具体操作为先二、三行互换,再二、三列互换。然后进行舒尔补运算,marg掉 x 2 x_2 x2

// 将 row i 移动矩阵最下面    
Eigen::MatrixXd temp_rows = H_marg.block(idx, 0, dim, reserve_size); //第二行    
Eigen::MatrixXd temp_botRows = H_marg.block(idx + dim, 0, reserve_size - idx - dim, reserve_size); // 第三行    
H_marg.block(idx, 0,reserve_size - idx - dim, reserve_size) = temp_botRows; // 二、三行颠倒    
H_marg.block(reserve_size - dim, 0, dim, reserve_size) = temp_rows;

舒尔补运算:

// TODO:: home work. 完成舒尔补操作    
Eigen::MatrixXd Arm = H_marg.block(0,n2,n2,m2);    
Eigen::MatrixXd Amr = H_marg.block(n2,0,m2,n2);    
Eigen::MatrixXd Arr = H_marg.block(0,0,n2,n2);
    
Eigen::MatrixXd tempB = Arm * Amm_inv;    
Eigen::MatrixXd H_prior = Arr - tempB * Amr;

编译说明:

cd BA_schur  \\ 进入文件夹
mkdir build   
cd build
cmake ..
make -j4    
cd app
./testMonoBA

运行结果如下:

在这里插入图片描述在这里插入图片描述

【提升题】论文总结
在我的另一篇博客,指路

另,关于BA的相关代码解析在我的另一篇博客——指路

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值