g2o内部实现初探

研究SLAM的同学应该对g2o并不陌生。用了一段时间之后,一直对其内部实现方式不太清楚,今天打算仔细研究一下。

首先祭出官方提供的g2o类层次结构图。

g2o类层次结构图

这个图需要分块来看。

左上角HyperGraph提供了顶点和边构成的拓扑图,它只关注图的连接关系,不负责优化相关的工作。其派生类OptimizableGraph为顶点和边提供了可优化的功能。再往下是OptimizableGraph的派生类SparseOptimizer,显然,对于构建的图优化问题,SparseOptimizer提供了稀疏求解的方案,这也是SLAM能够达到实时性所依赖的关键技术。以上,是优化器相关的部分。

再往下,优化器包含了一个OptimizationAlgorithm,这是优化算法的基类,优化器会调用该优化算法实现优化。右边给出了优化算法的具体实现,OptimizationWithHessian包含了一系列基于Hessian矩阵求解增量方程的优化算法,包括OptimizationAlgorithmGaussNewtonOptimizationAlgorithmLevenbergOptimizationAlgorithmDogleg。不同的优化算法给出了不同的梯度下降策略,也就是说,用不同的方式找出增量的方向和大小,但迭代求解的本质是一样的。

再往右,优化算法包含一个Solver,也就是求解器。不论使用了什么优化算法,每次迭代都需要求解一个 H∆x=g 的增量方程,其中H是Hessian矩阵或其变体,∆x是待求的优化变量的更新量。那么如何求解这个方程,就是Solver的工作了。在g2o中,只提供了一个实现类BlockSolver<>。所谓块求解器,就是利用A矩阵的稀疏性,每个优化变量和误差项都体现为固定大小的矩阵块,可以利用它的一些性质加速计算。在块求解器中,包含了一个SparseBlockMatrix<T>LinearSolver,其实前者用来存放H矩阵的数据,后者用来指定具体的线性求解器。之所以叫线性求解器,是因为增量方程是一个线性方程。g2o提供的线性求解器有三个,分别是LinearSolverCSparse<>LinearSolverCholmod<>LinearSolverPCG<>。它们之间的不同大概只是对矩阵求逆的方式不同,可能会有速度上的差异,但结果一定一致。

最后,右上角的一大部分是顶点和边,这些比较容易理解,也是我们编程中接触得最多的,这里不再详述。

分析完这个图,基本上g2o的优化流程也就差不多清晰了。但有几个关键的环节刚才并没有提到,而且我的理解也不敢保证没有偏差,写在下面和大家一起交流。

SLAM中有一个加速增量方程求解的方法,称为边缘化。边缘化是说,如果我们把待优化的相机位姿放在H矩阵的左上角,把待优化的路标点放在H矩阵的右下角,再把H矩阵分为四块,就可以对H的矩阵块进行高斯消元,使得对相机位姿的求解不依赖于路标点。这种方法奏效的原因是因为相机矩阵相比于路标点稀疏得多,因此相机矩阵块求逆更容易。当然,具体的分析建议阅读高翔的《视觉SLAM十四讲》。这里我们更关注g2o中的实现。边缘化部分的操作在BlockSolver<>中,块求解器会把对增量方程的求解分为两步,先求解相机位姿的增量,再求解路标点的增量。当然,每次求解增量仍然是调用内部的LinearSolver。思路很清晰,但g2o在这里的实现却有待商榷,块求解器中根据顶点是否被边缘化决定该顶点是位姿顶点还是路标点顶点,也就是说,它默认所有位姿顶点都不被边缘化,所有路标点顶点都被边缘化。假如你尝试不边缘化路标点顶点,或边缘化位姿顶点,求解器都会报错,这就限制了我们优化的灵活性。在我看来,这可能是g2o作者实现过程中的一个瑕疵。BlockSolver并没有体现出其应有的抽象,它应该根据实际的顶点类型来决定如何实现边缘化,而不是一股脑地认为只有路标点应该被边缘化。(注意,这里提到的边缘化只用于加速增量方程求解,不同于滑动窗口中的边缘化。)

对于上面的问题,其实并非不能解决。如果我们不用固定大小的BlockSolver_6_3,而是用动态大小的BlockSolverX,就不会出问题。因为前者默认维度为6的位姿顶点被边缘化,维度为3的路标点顶点不被边缘化,不符合维度要求的顶点会导致出错。而后者并不要求边缘化的顶点维度为6,也不要求不边缘化的顶点维度为3,允许同时存在维度为6和维度为3的顶点被边缘化。但问题解决并不意味着g2o的设计没有问题,BlockSolver中把顶点维度和是否边缘化在语义层面绑定了起来,很容易造成误解。举个例子,如果我想边缘化所有位姿顶点,不边缘化路标点顶点,最简单的解决方案是使用BlockSolverX。但一般认为,固定矩阵大小可以把一部分运行时时间转移到编译期。所以我可能需要typedef g2o::BlockSolver<g2o::BlockSolverTraits<3, 6>> BlockSolver_3_6;,相当于把BlockSolverTraits的第一个模板参数_PoseDim设为3,第二个模板参数_LandmarkDim设为6,也就是把路标点当成位姿,把位姿当成路标点。虽然可以用,但实在太过别扭。

总体上看,我认为g2o是一个结构良好的图优化框架,它的类层次结构提供了很高的可扩展性。但遗憾的是,实际实现的功能并不多,很多类的派生类都只有一个,比如只有SparseOptimizer而没有DenseOptimizer,只有OptimizationWithHessian而没有OptimizationWithOthers,只有BlockSolver<>而没有PlainSolver。以至于g2o只能用于求解视觉SLAM问题,应用范围有些狭隘。但毕竟g2o没有企业在背后支持,不像Ceres有谷歌撑腰,搞不好以后做SLAM的标配会变成Ceres吧,感觉有些可惜。

文末给出了一些详细的参考资料,比本文更有价值,大家可以参考。

参考资料

《视觉SLAM十四讲》 高翔
g2o学习——g2o整体框架 无人的回忆
g2o学习——顶点和边之外的solver 无人的回忆
A General Framework for Graph Optimization R Kümmerle

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,490评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,581评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,830评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,957评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,974评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,754评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,464评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,847评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,995评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,137评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,819评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,482评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,023评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,149评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,409评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,086评论 2 355

推荐阅读更多精彩内容

  • by jie 2018.7 一. g2o的整体结构 说到整体的结构,不得不用一张比较概括的图来说明: 这张图最好跟...
    远行_2a22阅读 11,100评论 1 8
  • 1. 前言 开始做SLAM(机器人同时定位与建图)研究已经近一年了。从一年级开始对这个方向产生兴趣,到现在为止,...
    壹米玖坤阅读 1,143评论 4 8
  • 一、什么是后端优化 上一篇文章介绍了视觉里程计的设计与实现,也就是所谓的“前端”。既然有前端就一定有后端,本文就来...
    金戈大王阅读 11,498评论 2 6
  • 多年来,有很多时刻,看到一些话,都觉得说的太对了,但当时对我而言只是一种精神认同,而没有感同身受。确实要经历过,才...
    Tsahao阅读 431评论 1 0
  • I met my soulmate,he didn't.
    Zorazora阅读 209评论 0 0