ubuntu 18.04 编译octomap

源码位置

https://github.com/OctoMap/octomap/blob/devel/octovis/README.md

commit 74c48ae on Apr 26, 2020.

本机系统Ubuntu 18.04,qt5,cmake 3.14.6。

编译

libQGLViewer for octovis

直接cmake configure octomap会报出无法编译libQGLViewer的错误,忽略该错误会导致octovis不能编译,尝试手工编译libQGLViewer。具体报错信息如下

-- QGLViewer includes found in /home/yaoyu/Libraries/octomap/octovis/src/extern/QGLViewer
-- QGLViewer library not found.
-- Trying to build libQGLViewer from source in /home/yaoyu/Libraries/octomap/octovis/src/extern/QGLViewer
-- 	 generating Makefile using qmake
-- 	 building library (this may take some time...)
make: *** No targets specified and no makefile found.  Stop.
CMake Warning at octovis/CMakeModules/FindQGLViewer.cmake:111 (MESSAGE):
  Could not find libQGLViewer.so, failed to build?
Call Stack (most recent call first):
  octovis/CMakeLists.txt:79 (FIND_PACKAGE)

libQGLViewer could not be found or generated.
Unfortunately, the viewer (octovis) can not be built because some requirements are missing.
This will not affect the compilation of the stand-alone library and tools (octomap)
See README.txt or http://octomap.sf.net for further information.

进入octomap/octovis/src/extern/QGLViewer,执行qmakemake。成功生成了libQGLViewer.so。最后sudo make install

OpenGL

cmake configure octomap时还有关于OpenGL的警告,需要用户手工指定OpenGL_GL_PREFERENCE

CMake Warning (dev) at /usr/local/share/cmake-3.14/Modules/FindOpenGL.cmake:275 (message):
  Policy CMP0072 is not set: FindOpenGL prefers GLVND by default when
  available.  Run "cmake --help-policy CMP0072" for policy details.  Use the
  cmake_policy command to set the policy and suppress this warning.

  FindOpenGL found both a legacy GL library:

    OPENGL_gl_LIBRARY: /usr/lib/x86_64-linux-gnu/libGL.so

  and GLVND libraries for OpenGL and GLX:

    OPENGL_opengl_LIBRARY: /usr/lib/x86_64-linux-gnu/libOpenGL.so
    OPENGL_glx_LIBRARY: /usr/lib/x86_64-linux-gnu/libGLX.so

  OpenGL_GL_PREFERENCE has not been set to "GLVND" or "LEGACY", so for
  compatibility with CMake 3.10 and below the legacy GL library will be used.
Call Stack (most recent call first):
  octovis/CMakeLists.txt:71 (FIND_PACKAGE)
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Found OpenGL: /usr/lib/x86_64-linux-gnu/libOpenGL.so   

尝试cmake -DOpenGL_GL_PREFERENCE=GLVND,但编译过程中出现错误

/usr/bin/ld: CMakeFiles/octovis.dir/src/ViewerWidget.cpp.o: undefined reference to symbol 'glEnable'
//usr/lib/x86_64-linux-gnu/libGL.so.1: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
octovis/CMakeFiles/octovis.dir/build.make:356: recipe for target '../bin/octovis' failed
make[2]: *** [../bin/octovis] Error 1
CMakeFiles/Makefile2:2232: recipe for target 'octovis/CMakeFiles/octovis.dir/all' failed
make[1]: *** [octovis/CMakeFiles/octovis.dir/all] Error 2
Makefile:162: recipe for target 'all' failed
make: *** [all] Error 2

尝试cmake -DOpenGL_GL_PREFERENCE=LEGACY,编译未报错。

prefix

最终cmake configure时指定了custom安装位置
cmake -DOpenGL_GL_PREFERENCE=LEGACY -DCMAKE_INSTALL_PREFIX=<octomap-install-path>

编译安装

make && sudo make install

测试

octomap

解压octomap/octomap/share/example-project.tgz,得到octomap-example文件夹。修改octomap-example/CMakeLists.txt,将octomap的搜索路径明确指定。

find_package(octomap REQUIRED PATHS <octomap-install-path>/share/octomap)

执行cmake进行configure,之后make
编译完毕后得到simple可执行文件。运行simple得到如下屏幕输出

generating example map

performing some queries:
occupancy probability at (0 0 0):	 0.971
occupancy probability at (-1 -1 -1):	 0.1192
occupancy probability at (1 1 1):	 is unknown

Writing 801 nodes to output stream...wrote example file simple_tree.bt

now you can use octovis to visualize: octovis simple_tree.bt
Hint: hit 'F'-key in viewer to see the freespace

使用octovis来visualize 生成的octomap

<octomap-install-path>/bin/octovis simple_tree.bt

得到的如下画面(按F键显示free space)

octovis显示simple执行结果

测试octomap::Pointcloud

为了使用octomap::OcTree::insertPointCloud()方法,需要使用octomap::Pointcloud类型。简单测试发下如下的代码片段是有问题的。

auto pPC = std::make_shared<octomap::Pointcloud>();
pPC->reserve( N );

for ( std::size_t i = 0; i < N; ++i ) {
    pT &pclPoint = pInput->at( i );
    octomap::point3d point( pclPoint.x, pclPoint.y, pclPoint.z );
    (*pPC[i]) = point;
}

原因在于reserve()函数并不改变point cloud的size。所以(*pPC[i]) = point;无法改变size。改变size属性只能通过push_back()方法。

auto pPC = std::make_shared<octomap::Pointcloud>();
pPC->reserve( N );

for ( std::size_t i = 0; i < N; ++i ) {
    pT &pclPoint = pInput->at( i );
    octomap::point3d point( pclPoint.x, pclPoint.y, pclPoint.z );
    pPC->push_back( point );
}

后记

后期需要利用octomap进行occupancy map的生成。以后再更新。