G2O 的安装和使用注意事项

2020/02/09 Library

本文记录 G2O 在 Ubuntu 和 Mac 中的安装和使用时的一些小问题。


安装

G2O 的安装主要按照 G2O 的 GitHub 官网 的要求就行。有一点要注意,虽然该官网中说,在 Mac 中可以使用 brew install g2o 直接安装而不需要从源码编译,但是经测试,它安装的版本是 2017 年的老版本,而这之后 G2O 的新代码做了很多修改,例如使用了智能指针。因此,如果你使用老版本的代码编译新的 G2O 的例子时,极有可能会出现指针相关的错误。因此,笔者的建议是:安安心心的从官网 clone 最新的源码并编译安装。然后,如果遇到老代码的例子,修改相应位置的代码即可。

在 Ubuntu 18.04 和 Mac 都测试通过。

Dependencies

在编译之前,最好按照要求提前安装包括 Qt 在内的几个第三方库(虽然官网显示它们是 Optional,但是经过测试,没有 Qt 时有时候会出错)。在 Ubuntu 中,需要提前安装

libsuitesparse-dev
qtdeclarative5-dev
qt5-qmake
libqglviewer-dev

这几个和 SuiteSparse 和 Qt 相关的库。直接用 sudo apt-get install XXX 就行了。

在 Mac 中,笔者测试过,只用安装 qt5 和 suite-sparse 就行了,libQGLViewer 不用安装(如果你想安装的话,参考其官网,可能需要从源码编译)。这两个库的安装都可以用 brew:

brew install qt5 suitesparse

安装完成后,如果是用编译 G2O 源码的方式安装的话,有可能会遇到找不到 FindQt5.cmake 之类的问题,此时可以显式指定你的 Qt5Config.cmake 文件的位置,笔者的该文件就在 /usr/local/opt/qt5/lib/cmake/Qt5 路径下。于是,使用 cmake 命令时增加 Qt5 的位置:

cmake -DQt5_DIR=/usr/local/opt/qt5/lib/cmake/Qt5 ..

如果在 Mac 中,也可以用 brew 命令找到 qt5 的安装路径后直接使用:

cmake -DQt5_DIR=$(brew --prefix qt5)/lib/cmake/Qt5 ..

这样就能找到 Qt5 了。大约十分钟编译后,G2O 成功编译。最后再用 sudo make install 安装到默认位置即可。

G2O 在 CMake 中的使用

需要额外使用 CSparse 库

根据笔者了解,G2O 中的 g2o_solver_csparse 等和 csparse 相关的库都是基于 CSparse 库写的(包含在 suite-sparse 中),因此,如果要使用前者,就必须也要链接上后者。因此,在你的 CMakeLists.txt 中也要加上 CSparse。G2O 官网的 cmake_modules 文件夹中提供了 FindCSparse.cmake 文件供使用。它定义了 CSPARSE_INCLUDE_DIR 和 CSPARSE_LIBRARY。将两者加到相应位置即可。

官方提供的 FindG2O.cmake 不够完善

G2O 的官网中同样提供了一个 FindG2O.cmake 文件供使用:G2O 官网的 cmake_modules 文件夹。但是,该文件存在一个问题:G2O 包含了很多个库文件,但是不知道为什么,这个官方提供的 Find 文件中并没有定义类似 G2O_LIBRARIES 这样的包含了全部 G2O 库文件的变量,而是只单独为每一个库定义了一个变量,例如 G2O_CORE_LIBRARY, G2O_SOLVER_CSPARSE 等。这样的话,在 CMakeLists.txt 中使用时就要一个一个添加,很是麻烦。于是,笔者自己在官方的 Find 文件最后修改了几行,定义了 G2O_LIBRARIES 变量供使用。最后几行是这样子的:

...

IF(G2O_STUFF_LIBRARY AND G2O_CORE_LIBRARY AND G2O_INCLUDE_DIR AND G2O_SOLVERS_FOUND)
  SET(G2O_FOUND "YES")
  # (Newly added) Set relevant library variables
  SET(G2O_SOLVER_LIBRARIES 
    ${G2O_SOLVER_CHOLMOD}
    ${G2O_SOLVER_CSPARSE}
    ${G2O_SOLVER_CSPARSE_EXTENSION}
    ${G2O_SOLVER_DENSE}
    ${G2O_SOLVER_PCG}
    ${G2O_SOLVER_SLAM2D_LINEAR}
    ${G2O_SOLVER_STRUCTURE_ONLY}
    ${G2O_SOLVER_EIGEN}
  )
  SET(G2O_TYPE_LIBRARIES 
    ${G2O_TYPES_DATA}
    ${G2O_TYPES_ICP}
    ${G2O_TYPES_SBA}
    ${G2O_TYPES_SCLAM2D}
    ${G2O_TYPES_SIM3}
    ${G2O_TYPES_SLAM2D}
    ${G2O_TYPES_SLAM3D}
  )
  SET(G2O_LIBRARIES 
    ${G2O_STUFF_LIBRARY} 
    ${G2O_CORE_LIBRARY} 
    ${G2O_CLI_LIBRARY} 
    ${G2O_SOLVER_LIBRARIES}
    ${G2O_TYPE_LIBRARIES}
  )
ENDIF(G2O_STUFF_LIBRARY AND G2O_CORE_LIBRARY AND G2O_INCLUDE_DIR AND G2O_SOLVERS_FOUND)

用上面这些替换掉官方的 FindG2O.cmake 文件的最后几行就行了。

G2O 最新版本中的智能指针和旧版本的 raw 指针冲突的 bug

有时候编译老的 G2O 代码,例如《SLAM十四讲》中的代码时,会遇到类似 pointer 或者 unique_ptr 之类的报错。这其实是因为,这些代码通常使用的是老版本的 G2O,它在新建 solver 时使用的是 raw 指针,于是并不适用于基于智能指针的新版本。因此,解决方法是,使用最新的从官网 github repo 中下载的代码编译安装,然后参考官方代码中的 examples,简单修改和新建 solver 相关的那几行代码就行了。

Search

    Table of Contents