SLAM本质剖析-Ceres

简介: SLAM本质剖析-Ceres

0. 前言


在了解SLAM的原理、流程后,个人经常实时困惑该如何去从零开始去设计编写一套能够符合我们需求的SLAM框架。作者认为Ceres、Eigen、Sophus、G2O这几个函数库无法避免,尤其是Ceres函数库在激光SLAM和V-SLAM的优化中均有着大量的应用。所以作者从Ceres作为开端,来对手写SLAM开个头,来方便各位后续的开发。


这里分享以为博主写的博客,个人看了感觉写的不错,对SLAM的剖析很细致


1.Ceres示例


首先我们需要明确Ceres函数库在SLAM中主要起到的作用是优化。目前Bundle Adjustment 其本质还是离不开最小二乘原理(几乎所有优化问题其本质都是最小二乘),目前Bundle Adjustment 优化框架最为代表的是Ceres solver和G2O(这里主要介绍ceres solver)。Ceres中的优化需要四步,构建优化的残差函数,构建优化问题,在每次获取到数据后添加残差块,总体优化。


构建残差函数:


//构建代价函数结构体,residual为残差。
//last_point_a_为这一帧中的点a,curr_point_b_为点a旋转后和上一帧里最近的点
//curr_point_c_为点b同线或上线号的点,curr_point_d_为点b下线号的点
//b,c,d与a点距离不超过3m
//plane_norm为根据向量bc和bd求出的法向量
struct CURVE_FITTING_COST
{
  //类似构造函数
  CURVE_FITTING_COST(Eigen::Vector3d _curr_point_a_, Eigen::Vector3d _last_point_b_,
       Eigen::Vector3d _last_point_c_, Eigen::Vector3d _last_point_d_):
       curr_point_a_(_curr_point_a_),last_point_b_(_last_point_b_),
       last_point_c_(_last_point_c_),last_point_d_(_last_point_d_)
  {
     plane_norm = (last_point_d_ - last_point_b_).cross(last_point_c_ - last_point_b_);
     plane_norm.normalize();
  }
  template <typename T>
  //plane_norm点乘向量ab为a点距面bcd的距离,即残差
  bool operator()(const T* q,const T* t,T* residual)const
  {
    Eigen::Matrix<T, 3, 1> p_a_curr{T(curr_point_a_.x()), T(curr_point_a_.y()), T(curr_point_a_.z())};
    Eigen::Matrix<T, 3, 1> p_b_last{T(last_point_b_.x()), T(last_point_b_.y()), T(last_point_b_.z())};
    Eigen::Quaternion<T> rot_q{q[3], q[0], q[1], q[2]};
    Eigen::Matrix<T, 3, 1> rot_t{t[0], t[1], t[2]};
    Eigen::Matrix<T, 3, 1> p_a_last;
    p_a_last=rot_q * p_a_curr + rot_t;
    residual[0]=abs((p_a_last - p_b_last).dot(plane_norm));
    return true;
  }
  const Eigen::Vector3d curr_point_a_,last_point_b_,last_point_c_,last_point_d_;
  Eigen::Vector3d plane_norm;
};


20200801115913834.gif


构建优化问题:


//优化问题构建
ceres::LossFunction *loss_function = new ceres::HuberLoss(0.1);
ceres::LocalParameterization *q_parameterization =
new ceres::EigenQuaternionParameterization();
ceres::Problem::Options problem_options;
ceres::Problem problem(problem_options);
problem.AddParameterBlock(para_q, 4, q_parameterization);
problem.AddParameterBlock(para_t, 3);


每次求出abcd点后,将他们的坐标构建成Eigen::Vector3d数据,添加残差块:


Eigen::Vector3d curr_point_a(laserCloudIn_plane.points[i].x,
       laserCloudIn_plane.points[i].y,
       laserCloudIn_plane.points[i].z);
Eigen::Vector3d last_point_b(laserCloudIn_plane_last.points[closestPointInd].x,laserCloudIn_plane_last.points[closestPointInd].y,
       laserCloudIn_plane_last.points[closestPointInd].z);
Eigen::Vector3d last_point_c(laserCloudIn_plane_last.points[minPointInd2].x,
       laserCloudIn_plane_last.points[minPointInd2].y,
       laserCloudIn_plane_last.points[minPointInd2].z);
Eigen::Vector3d last_point_d(laserCloudIn_plane_last.points[minPointInd3].x,
       laserCloudIn_plane_last.points[minPointInd3].y,
       laserCloudIn_plane_last.points[minPointInd3].z);
problem.AddResidualBlock(new ceres::AutoDiffCostFunction<CURVE_FITTING_COST,1,4,3>
    (new CURVE_FITTING_COST(last_point_a,curr_point_b,
     curr_point_c,curr_point_d)),loss_function,para_q,para_t);


遍历过所有的a点后,就可以优化求解了。


//所有前一帧里的点都当a点遍历过后,进行优化
ceres::Solver::Options options;
options.linear_solver_type = ceres::DENSE_QR;
//迭代数
options.max_num_iterations = 5;
//进度是否发到STDOUT
options.minimizer_progress_to_stdout = false;
ceres::Solver::Summary summary;
ceres::Solve(options, &problem, &summary);


而在V-SLAM中Ceres则用的更多,我们可以看下下面的例子


7c20e788a992488cb2361b95cd06e51b.png

相关文章
|
21天前
|
机器学习/深度学习 人工智能
类人神经网络再进一步!DeepMind最新50页论文提出AligNet框架:用层次化视觉概念对齐人类
【10月更文挑战第18天】这篇论文提出了一种名为AligNet的框架,旨在通过将人类知识注入神经网络来解决其与人类认知的不匹配问题。AligNet通过训练教师模型模仿人类判断,并将人类化的结构和知识转移至预训练的视觉模型中,从而提高模型在多种任务上的泛化能力和稳健性。实验结果表明,人类对齐的模型在相似性任务和出分布情况下表现更佳。
49 3
|
传感器 机器学习/深度学习 人工智能
苏黎世理工最新!maplab2.0:模块化的多模态建图定位框架
将多传感器模态和深度学习集成到同时定位和mapping(SLAM)系统中是当前研究的重要领域。多模态是在具有挑战性的环境中实现鲁棒性和具有不同传感器设置的异构多机器人系统的互操作性的一块垫脚石。借助maplab 2.0,这个多功能的开源平台,可帮助开发、测试新模块和功能,并将其集成到一个成熟的SLAM系统中。
苏黎世理工最新!maplab2.0:模块化的多模态建图定位框架
|
2月前
|
知识图谱
KDD 2024:Emory提出最新PolygonGNN框架:可捕捉通用多边形内外的空间关系
【9月更文挑战第16天】近年来,多边形表示学习在形状编码、建筑模式分类和地理问答等应用中至关重要。然而,现有研究多聚焦于单个多边形,忽视了多边形间复杂关系。为解决此问题,Emory大学团队提出了PolygonGNN框架,通过异质可见性图整合内外关系,并引入异质生成树采样提升计算效率。该框架设计了旋转平移不变的几何表示,适用于多种场景。实验结果显示,PolygonGNN在多个任务上表现优异,但在处理大规模场景时仍面临计算复杂度挑战,并未充分考虑拓扑结构和语义信息的影响。
32 2
|
3月前
|
机器学习/深度学习 vr&ar
Sora视频重建与创新路线问题之Perceiver AR模型模态无关的自回归生成如何处理
Sora视频重建与创新路线问题之Perceiver AR模型模态无关的自回归生成如何处理
|
5月前
|
数据采集 算法 安全
CVPR 2024:给NeRF开透视眼!稀疏视角下用X光进行三维重建,9类算法工具包全开源
【6月更文挑战第28天】CVPR 2024亮点:SAX-NeRF框架开源!融合X光与NeRF,提升3D重建效果。X3D数据集验证,Lineformer+MLG策略揭示物体内部结构,增强几何理解。虽有计算成本及泛化挑战,但为计算机视觉和医学影像开辟新路径。[论文链接](https://arxiv.org/abs/2311.10959)**
159 5
|
4月前
|
存储 安全 程序员
【C++11】C++11深度解剖(上)
【C++11】C++11深度解剖(上)
33 0
|
4月前
|
存储 算法 编译器
【C++11】C++11深度解剖(下)
【C++11】C++11深度解剖(下)
34 0
|
6月前
|
机器学习/深度学习 编解码 计算机视觉
|
机器学习/深度学习 传感器 自动驾驶
视觉BEV基本原理和方案解析
视觉BEV在高德高精地图地面要素识别、车道线拓扑构建、车端融合定位等业务场景中都扮演了重要角色。
|
机器学习/深度学习
神经网络核心原理关键点纪要
神经网络核心原理关键点纪要
79 0