cmake_mrpt_g2o_ceres - yuhannah/skills_map GitHub Wiki

MRPT 应用 CMake

编译及配置mrpt库的过程中,下载源码,新建build文件夹,cmake以及make的过程都执行顺利。

如何在工程中调用mrpt库呢?

(1)一种方法,将mrpt安装到系统中,make install命令,mrpt的库就安装到比如/usr 或/usr/local 中。直接调用。(未测试)

(2)另一种方法,用户提供MRPTConfig.cmake 文件路径,该文件在编译mrpt后生成,在/mrpt-1.5.6/build/下。意思是,在创建的工程中,在CMakeLists.txt文件中,添加include(/home/yu/mrpt-1.5.6/build/MRPTConfig.cmake REQUIRED)这句话,该文件指明了mrpt库在哪里。

摘自mrpt指导:

  • 在 Linux/Windows 系统,需要用户提供 MRPTConfig.cmake 文件路径(在创建 MRPT库的过程中已经生成),有时候 CMake 会自动找到 MRPT 目录不需要用户提供路径。
  • 在 Linux 中,如果 MRPT 已经安装在系统中(比如/usr 或/usr/local 或),cmake 会自动找到 MRPT 配置文件,不要额外操作。

g2o 和 ceres 应用 cmake

目标:

  • 在源码库基础上,调用安装好的依赖库(usr/include中),外部构建和编译,调用测试源码仿真
  • 在源码库基础上,调用安装好的依赖库(usr/include中),外部构建和编译(及安装),另外建立工程调用 g2o / ceres 编写测试程序
  • 在源码库基础上,调用内部构建的依赖库,外部构建和编译,调用测试源码仿真
  • 在源码库基础上,调用内部构建的依赖库,外部构建和编译(及安装),另外建立工程调用 g2o / ceres 编写测试程序
  • 在源码库基础上,调用内部构建的依赖库,交叉编译

g2o 应用 cmake

测试 1

下载 g2o 源码库,安装依赖。在工程目录 g2o 下新建目录build,进入目录build,执行cmake ..命令:

-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Compiling on Unix
-- Found CHOLMOD: /usr/include/suitesparse # 内部MESSAGE 
-- Looking for sgemm_
-- Looking for sgemm_ - found
-- A library with BLAS API found. # MESSAGE
-- Looking for cheev_
-- Looking for cheev_ - found
-- A library with LAPACK API found. # MESSAGE
-- Found CHOLMOD and its dependencies # MESSAGE
-- Found CSPARSE: /usr/include/suitesparse # 内部MESSAGE   
-- Found OpenGL: /usr/lib/x86_64-linux-gnu/libGL.so # 内部MESSAGE   
-- Compiling with OpenGL support # MESSAGE
-- Found QGLVIEWER: /usr/include/QGLViewer # 内部MESSAGE  
-- Compiling g2o apps # MESSAGE
-- Compiling g2o examples # MESSAGE
-- Compiling with GCC # MESSAGE
-- Found Eigen3: /usr/include/eigen3 (Required is at least version "2.91.0") # 内部MESSAGE 
-- Generating position indpendent code for slam2d because Qt5 was built with -reduce-relocations
-- Configuring done
-- Generating done
-- Build files have been written to: /home/yu/sources/g2o/build # 编译结果目录

继续执行make命令,编译成功。生成的库在工程目录 g2o 下的目录 lib 中,生成的可执行文件在工程目录 g2o 下的目录 bin 中。

进入目录 g2o/bin,可以看到所有的可执行文件,执行./slam2d_g2o

在窗口菜单栏点击File,添加原始 2d g2o数据集(数据集来自 openSlam-vertigo ),加载 manhattanOlson3500.g2o数据集,并选择 Optimize

Graph loaded with 3500 vertices and 5598 measurments
graph is fixed by node 3499
iteration= 0	 chi2= 8851.536592	 time= 0.0369276	 cumTime= 0.0369276	 edges= 5598	 schur= 0
iteration= 1	 chi2= 189.465178	 time= 0.00820572	 cumTime= 0.0451333	 edges= 5598	 schur= 0
iteration= 2	 chi2= 146.566132	 time= 0.0068049	 cumTime= 0.0519382	 edges= 5598	 schur= 0
iteration= 3	 chi2= 146.076641	 time= 0.00668695	 cumTime= 0.0586251	 edges= 5598	 schur= 0
iteration= 4	 chi2= 146.076613	 time= 0.00656356	 cumTime= 0.0651887	 edges= 5598	 schur= 0
iteration= 5	 chi2= 146.076613	 time= 0.00667749	 cumTime= 0.0718662	 edges= 5598	 schur= 0
iteration= 6	 chi2= 146.076613	 time= 0.00651187	 cumTime= 0.0783781	 edges= 5598	 schur= 0
iteration= 7	 chi2= 146.076613	 time= 0.00650471	 cumTime= 0.0848828	 edges= 5598	 schur= 0
iteration= 8	 chi2= 146.076613	 time= 0.00652948	 cumTime= 0.0914123	 edges= 5598	 schur= 0
iteration= 9	 chi2= 146.076613	 time= 0.00675476	 cumTime= 0.098167	 edges= 5598	 schur= 0

测试 2

清除工程目录 g2o 下目录build的内容,进入目录build,执行cmake -DCMAKE_INSTALL_PREFIX=/home/yu/sources/g2o/install ..命令,将 g2o 安装到指定目录/home/yu/sources/g2o/install下。

-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- CMAKE_RUNTIME_OUTPUT_DIRECTORY is /home/yu/sources/g2o/bin
-- CMAKE_LIBRARY_OUTPUT_DIRECTORY is /home/yu/sources/g2o/lib
-- CMAKE_INSTALL_PREFIX is /home/yu/sources/g2o/install # 自定义安装目录
-- Compiling on Unix
-- Found CHOLMOD: /usr/include/suitesparse  
-- Looking for sgemm_
-- Looking for sgemm_ - found
-- A library with BLAS API found.
-- Looking for cheev_
-- Looking for cheev_ - found
-- A library with LAPACK API found.
-- Found CHOLMOD and its dependencies
-- Found CSPARSE: /usr/include/suitesparse  
-- Found OpenGL: /usr/lib/x86_64-linux-gnu/libGL.so  
-- Compiling with OpenGL support
-- Found QGLVIEWER: /usr/include/QGLViewer  
-- Compiling g2o apps
-- Compiling g2o examples
-- Compiling with GCC
-- Found Eigen3: /usr/include/eigen3 (Required is at least version "2.91.0") 
-- INCLUDES_DESTINATION is /home/yu/sources/g2o/install/include
-- G2O_CONFIG_INSTALL_DIR is lib/cmake/g2o
-- Generating position indpendent code for slam2d because Qt5 was built with -reduce-relocations
-- Configuring done
-- Generating done
-- Build files have been written to: /home/yu/sources/g2o/build

执行makemake install安装成功。

为了找到自定义安装路径中的 g2o 库,需要修改 g2o 库中原有的FindG2O.cmake文件:

# g2o的cmake_modules的FindG2O.cmake
find_path(G2O_INCLUDE_DIR g2o/core/base_vertex.h
	...
	/home/yu/sources/g2o/install/include # 添加自定义安装路径
)
find_library("${MYLIBRARY}_DEBUG"
	NAMES "g2o_${MYLIBRARYNAME}_d"
	PATHS
	...
	/home/yu/sources/g2o/install/lib # 添加自定义安装路径
)  
...

在新的工程中的 CMakeLists.txt文件中添加 g2o 库的cmake modules 路径:

# testG2O的CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(testG2O)

set(CMAKE_CXX_STANDARD 11)

SET(CMAKE_MODULE_PATH /home/yu/sources/g2o/cmake_modules) # 添加 g2o 库的cmake_modeles路径
MESSAGE(STATUS "MODULE_PATH: " ${CMAKE_MODULE_PATH})

find_package(G2O REQUIRED)
MESSAGE(STATUS "G2O_INCLUDE_DIR is ${G2O_INCLUDE_DIR}") # 输出信息
MESSAGE(STATUS "G2O_STUFF_LIBRARY is ${G2O_STUFF_LIBRARY}")
MESSAGE(STATUS "G2O_CORE_LIBRARY is ${G2O_CORE_LIBRARY}")
MESSAGE(STATUS "G2O_CLI_LIBRARY is ${G2O_CLI_LIBRARY}")
MESSAGE(STATUS "G2O_SOLVER_CHOLMOD is ${G2O_SOLVER_CHOLMOD}")

IF(G2O_FOUND)
    include_directories(${G2O_INCLUDE_DIR})
    message(STATUS "G2O lib is found:" ${G2O_INCLUDE_DIR}) # 输出信息
ENDIF(G2O_FOUND)

find_package(Eigen3 REQUIRED)
find_package(CSparse REQUIRED)
#find_package(Cholmod REQUIRED)
include_directories(${CSPARSE_INCLUDE_DIR})
include_directories(${EIGEN3_INCLUDE_DIR})

add_executable(testG2O main.cpp)
SET(G2O_LIBS g2o_cli g2o_ext_freeglut_minimal g2o_simulator g2o_solver_slam2d_linear g2o_types_icp g2o_types_slam2d g2o_core g2o_interface g2o_solver_csparse g2o_solver_structure_only g2o_types_sba g2o_types_slam3d g2o_csparse_extension g2o_opengl_helper g2o_solver_dense g2o_stuff g2o_types_sclam2d g2o_parser g2o_solver_pcg g2o_types_data g2o_types_sim3 cxsparse )
target_link_libraries(testG2O ${G2O_LIBS})

构建,添加了部分输出信息:

-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- MODULE_PATH: /home/yu/sources/g2o/cmake_modules
-- G2O_INCLUDE_DIR is /home/yu/sources/g2o/install/include
-- G2O_STUFF_LIBRARY is /home/yu/sources/g2o/install/lib/libg2o_stuff.so
-- G2O_CORE_LIBRARY is /home/yu/sources/g2o/install/lib/libg2o_core.so
-- G2O_CLI_LIBRARY is /home/yu/sources/g2o/install/lib/libg2o_cli.so
-- G2O_SOLVER_CHOLMOD is /home/yu/sources/g2o/install/lib/libg2o_solver_cholmod.so
-- G2O lib is found:/home/yu/sources/g2o/install/include # 找到g2o噢
-- Found Eigen3: /usr/include/eigen3 (Required is at least version "2.91.0") 
-- Found CSPARSE: /usr/include/suitesparse   
-- Configuring done
-- Generating done
-- Build files have been written to: /home/yu/CLionProjects/testG2O/build

但是在编译时还是出现找不到库的问题:

Scanning dependencies of target testG2O
[ 50%] Building CXX object CMakeFiles/testG2O.dir/main.cpp.o
[100%] Linking CXX executable testG2O
/usr/bin/ld: cannot find -lg2o_cli
/usr/bin/ld: cannot find -lg2o_ext_freeglut_minimal
/usr/bin/ld: cannot find -lg2o_simulator
/usr/bin/ld: cannot find -lg2o_solver_slam2d_linear
/usr/bin/ld: cannot find -lg2o_types_icp
/usr/bin/ld: cannot find -lg2o_types_slam2d
/usr/bin/ld: cannot find -lg2o_core
/usr/bin/ld: cannot find -lg2o_interface
/usr/bin/ld: cannot find -lg2o_solver_csparse
/usr/bin/ld: cannot find -lg2o_solver_structure_only
/usr/bin/ld: cannot find -lg2o_types_sba
/usr/bin/ld: cannot find -lg2o_types_slam3d
/usr/bin/ld: cannot find -lg2o_csparse_extension
/usr/bin/ld: cannot find -lg2o_opengl_helper
/usr/bin/ld: cannot find -lg2o_solver_dense
/usr/bin/ld: cannot find -lg2o_stuff
/usr/bin/ld: cannot find -lg2o_types_sclam2d
/usr/bin/ld: cannot find -lg2o_parser
/usr/bin/ld: cannot find -lg2o_solver_pcg
/usr/bin/ld: cannot find -lg2o_types_data
/usr/bin/ld: cannot find -lg2o_types_sim3
collect2: error: ld returned 1 exit status
CMakeFiles/testG2O.dir/build.make:94: recipe for target 'testG2O' failed
make[2]: *** [testG2O] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/testG2O.dir/all' failed
make[1]: *** [CMakeFiles/testG2O.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

暴力解决方案,强行添加库搜索路径set(CMAKE_CXX_FLAGS "-L/home/yu/sources/g2o/install/lib"),修改CMakeLists.txt文件:

# testG2O的CMakeLists.txt
add_executable(testG2O main.cpp)
set(CMAKE_CXX_FLAGS "-L/home/yu/sources/g2o/install/lib") # add by cjj: force find path
SET(G2O_LIBS g2o_cli g2o_ext_freeglut_minimal g2o_simulator g2o_solver_slam2d_linear g2o_types_icp g2o_types_slam2d g2o_core g2o_interface g2o_solver_csparse g2o_solver_structure_only g2o_types_sba g2o_types_slam3d g2o_csparse_extension g2o_opengl_helper g2o_solver_dense g2o_stuff g2o_types_sclam2d g2o_parser g2o_solver_pcg g2o_types_data g2o_types_sim3 cxsparse )
target_link_libraries(testG2O ${G2O_LIBS})

编译成功:

Scanning dependencies of target testG2O
[ 50%] Building CXX object CMakeFiles/testG2O.dir/main.cpp.o
[100%] Linking CXX executable testG2O
[100%] Built target testG2O

执行./testG2O,还是找不到库:

./testG2O: error while loading shared libraries: libg2o_core.so: cannot open shared object file: No such file or directory

百度后的解决方案,添加临时库路径export LD_LIBRARY_PATH=/home/yu/tmp/g2oinstall/lib:$LD_LIBRARY_PATH,之后顺利执行。

测试 3

CMakeLists.txt中看出只有 Eigen 库是必须的,没有 Eigen 库会导致构建失败。所以先来解决 Eigen 库的问题。

Eigen 库是纯头文件的库,只用将 Eigen 库源码下载下来,放到 g2o 项目的某个目录中,并在 CMakeLists.txt中添加 Eigen 库的目录即可。不需要FindEigen3.cmake模块去寻找本地 Eigen 库。

在下载好的 Eigen 项目中,新建 build 目录和 install 目录,在 build 目录中执行构建,添加自定义安装目录:cmake -DCMAKE_INSTALL_PREFIX=/home/yu/sources/eigen/install ..,构建编译及安装后,在 install 目录下生成两个文件夹includeshare,将这两个文件夹拷贝到 g2o 目录的 EXTERNAL 目录下。

修改 CMakeLists.txt文件:

# yuh - for local eigen
#find_package(Eigen3 REQUIRED)
#if (TARGET Eigen3::Eigen)
#  set(G2O_EIGEN3_EIGEN_TARGET Eigen3::Eigen)
#  MESSAGE(STATUS "G2O_EIGEN3_EIGEN_TARGET is: ${G2O_EIGEN3_EIGEN_TARGET}")
#else()
#  include_directories(${EIGEN3_INCLUDE_DIR})
#  MESSAGE(STATUS "EIGEN3_INCLUDE_DIR is: ${EIGEN3_INCLUDE_DIR}")
#endif ()
# yuh - for inside eigen
include_directories(EXTERNAL/eigen3)

构建的结果中没有出现如[测试 1](#测试 1)和[测试 2](#测试 2)中的Found Eigen3输出信息,说明没有在/usr/include目录下搜索 Eigen 库,用的是 g2o 项目内的 Eigen 库。编译通过。

执行 bin 目录下的可执行文件./slam2d_g2o,能够运行。

PS:找到usr/include下的 eigen3 目录,里面只有 Eigen 目录, unsupported 目录和一个文件,按照这个最简单的库的内容重新简化 g2o 项目中添加的 Eigen 库的内容。

其他库的植入尚未完成。

测试 4

测试 5

在工程目录 g2o 下新建目录 build_px3se ,进入目录 build_px3se ,执行交叉编译cmake .. -DCMAKE_TOOLCHAIN_FILE=~/sources/eva/cmakemodules/px3se.cmake命令。

交叉编译工具px3se.cmake如下:

SET(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

SET(ROBOT_FULL_FEATURE ON)

SET(CMAKE_C_COMPILER   /opt/tools/cross-toolchain/usr/bin/arm-rockchip-linux-gnueabihf-gcc)
SET(CMAKE_CXX_COMPILER /opt/tools/cross-toolchain/usr/bin/arm-rockchip-linux-gnueabihf-g++)

SET(CMAKE_SYSROOT /opt/tools/cross-toolchain/usr/arm-rockchip-linux-gnueabihf/sysroot)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

初次交叉编译结果:

-- The C compiler identification is GNU 4.9.4
-- The CXX compiler identification is GNU 4.9.4
-- Check for working C compiler: /opt/tools/cross-toolchain/usr/bin/arm-rockchip-linux-gnueabihf-gcc 
-- Check for working C compiler: /opt/tools/cross-toolchain/usr/bin/arm-rockchip-linux-gnueabihf-gcc -- works # c 工具链地址
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /opt/tools/cross-toolchain/usr/bin/arm-rockchip-linux-gnueabihf-g++
-- Check for working CXX compiler: /opt/tools/cross-toolchain/usr/bin/arm-rockchip-linux-gnueabihf-g++ -- works # c++ 工具链地址
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- CMAKE_RUNTIME_OUTPUT_DIRECTORY is /home/yu/sources/g2o/bin
-- CMAKE_LIBRARY_OUTPUT_DIRECTORY is /home/yu/sources/g2o/lib
-- CMAKE_INSTALL_PREFIX is /usr/local
-- Compiling on Unix
-- Could NOT find CHOLMOD (missing:  CHOLMOD_INCLUDE_DIR CHOLMOD_LIBRARIES) 
-- A library with BLAS API not found. Please specify library location.
-- A library with BLAS API not found. Please specify library location.
-- LAPACK requires BLAS.
-- Could NOT find CSPARSE (missing:  CSPARSE_INCLUDE_DIR CSPARSE_LIBRARY) 
-- Could NOT find OpenGL (missing:  OPENGL_gl_LIBRARY OPENGL_INCLUDE_DIR) 
-- Could NOT find QGLVIEWER (missing:  QGLVIEWER_INCLUDE_DIR QGLVIEWER_LIBRARY) 
-- Compiling g2o apps
-- Compiling g2o examples
-- Compiling with GCC
CMake Error at /usr/share/cmake-3.5/Modules/FindPackageHandleStandardArgs.cmake:148 (message):
  Could NOT find Eigen3 (missing: EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK)
  (Required is at least version "2.91.0") # Eigen库是必须的
Call Stack (most recent call first):
  /usr/share/cmake-3.5/Modules/FindPackageHandleStandardArgs.cmake:388 (_FPHSA_FAILURE_MESSAGE)
  cmake_modules/FindEigen3.cmake:82 (find_package_handle_standard_args)
  CMakeLists.txt:362 (find_package)


-- Configuring incomplete, errors occurred!
See also "/home/yu/sources/g2o/build_px3se/CMakeFiles/CMakeOutput.log".

对比[测试 2](#测试 2)的输出,可以看出交叉编译的 c c++ 工具链发生了变化,指定了路径。而且依赖库都没有找到。但是其中只有 Eigen 库是必须的,没有 Eigen 库会导致构建失败。所以先来解决 Eigen 库的问题。参考[测试 3](#测试 3)。

构建成功,但是编译不通过:

Scanning dependencies of target csparse
[  1%] Building C object EXTERNAL/csparse/CMakeFiles/csparse.dir/cs_add.c.o
arm-rockchip-linux-gnueabihf-gcc.br_real: error: unrecognized command line option ‘-msse2’
arm-rockchip-linux-gnueabihf-gcc.br_real: error: unrecognized command line option ‘-msse3’
arm-rockchip-linux-gnueabihf-gcc.br_real: error: unrecognized command line option ‘-mssse3’
arm-rockchip-linux-gnueabihf-gcc.br_real: error: unrecognized command line option ‘-msse4.1’
arm-rockchip-linux-gnueabihf-gcc.br_real: error: unrecognized command line option ‘-msse4.2’
EXTERNAL/csparse/CMakeFiles/csparse.dir/build.make:62: recipe for target 'EXTERNAL/csparse/CMakeFiles/csparse.dir/cs_add.c.o' failed
make[2]: *** [EXTERNAL/csparse/CMakeFiles/csparse.dir/cs_add.c.o] Error 1
CMakeFiles/Makefile2:103: recipe for target 'EXTERNAL/csparse/CMakeFiles/csparse.dir/all' failed
make[1]: *** [EXTERNAL/csparse/CMakeFiles/csparse.dir/all] Error 2
Makefile:149: recipe for target 'all' failed
make: *** [all] Error 2

估计是交叉编译器无法识别上述 sse 加速算法,直接屏蔽对应的CMakeLists.txt的内容,再次编译通过。

将 build_px3se 目录下生成的 lib 和 bin 目录打包压缩,放到开发板上,解压并添加当前 bin 的路径:

LD_LIBRARY_PATH=`pwd`/lib

即可执行 bin 目录下的可执行文件了。

其他依赖库如何添加,未完。

ceres 应用 cmake

测试 1

下载 ceres 源码库,安装依赖。在工程目录 ceres 下新建目录build,进入目录build,执行cmake ..命令:

-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- CMAKE_RUNTIME_OUTPUT_DIRECTORY is: /home/yu/sources/ceres-solver/build/bin
-- CMAKE_LIBRARY_OUTPUT_DIRECTORY is: /home/yu/sources/ceres-solver/build/lib
-- Detected Ceres version: 2.0.0 from /home/yu/sources/ceres-solver/include/ceres/version.h
-- Detected available Ceres threading models: [CXX11_THREADS, OPENMP, NO_THREADS]
-- Building with C++11
-- No preference for use of exported Eigen CMake configuration set, and no hints for include directory provided. Defaulting to preferring an installed/exported Eigen CMake configuration if available.
-- Found installed version of Eigen: /usr/lib/cmake/eigen3
-- Found Eigen: /usr/include/eigen3 (found version "3.2.92") 
-- Found Eigen version 3.2.92: /usr/include/eigen3
-- Enabling use of Eigen as a sparse linear algebra library.
-- Looking for sgemm_
-- Looking for sgemm_ - found
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- A library with BLAS API found.
-- Found LAPACK library: /usr/lib/liblapack.so;/usr/lib/libblas.so
-- A library with BLAS API found.
-- Found AMD headers in: /usr/include/suitesparse
-- Found AMD library: /usr/lib/x86_64-linux-gnu/libamd.so
-- Found CAMD headers in: /usr/include/suitesparse
-- Found CAMD library: /usr/lib/x86_64-linux-gnu/libcamd.so
-- Found COLAMD headers in: /usr/include/suitesparse
-- Found COLAMD library: /usr/lib/x86_64-linux-gnu/libcolamd.so
-- Found CCOLAMD headers in: /usr/include/suitesparse
-- Found CCOLAMD library: /usr/lib/x86_64-linux-gnu/libccolamd.so
-- Found CHOLMOD headers in: /usr/include/suitesparse
-- Found CHOLMOD library: /usr/lib/x86_64-linux-gnu/libcholmod.so
-- Found SUITESPARSEQR headers in: /usr/include/suitesparse
-- Found SUITESPARSEQR library: /usr/lib/x86_64-linux-gnu/libspqr.so
-- Did not find Intel TBB library, assuming SuiteSparseQR was not compiled with TBB.
-- Found SUITESPARSE_CONFIG headers in: /usr/include/suitesparse
-- Found SUITESPARSE_CONFIG library: /usr/lib/x86_64-linux-gnu/libsuitesparseconfig.so
-- Found LIBRT library: /usr/lib/x86_64-linux-gnu/librt.so
-- Adding librt: /usr/lib/x86_64-linux-gnu/librt.so to SuiteSparse_config libraries (required on Linux & Unix [not OSX] if SuiteSparse is compiled with timing).
-- Did not find METIS library (optional SuiteSparse dependency)
-- Found SuiteSparse: TRUE (found version "4.4.6") 
-- Found SuiteSparse 4.4.6, building with SuiteSparse.
-- Found CXSparse: /usr/include/suitesparse (found version "3.1.4") 
-- Found CXSparse version: 3.1.4, building with CXSparse.
-- Building without Apple's Accelerate sparse support.
-- No preference for use of exported gflags CMake configuration set, and no hints for include/library directories provided. Defaulting to preferring an installed/exported gflags CMake configuration if available.
-- Failed to find installed gflags CMake configuration, searching for gflags build directories exported with CMake.
-- Found exported gflags build directory: /home/yu/tmp/lib/cmake/gflags
-- Detected gflags version: 2.2.2
-- Found Gflags: /home/yu/tmp/include  
-- Found Google Flags header in: /home/yu/tmp/include, in namespace: google
-- No preference for use of exported glog CMake configuration set, and no hints for include/library directories provided. Defaulting to preferring an installed/exported glog CMake configuration if available.
-- Failed to find installed glog CMake configuration, searching for glog build directories exported with CMake.
-- Found exported glog build directory: /home/yu/sources/eva/cmake-build-debug/apps/third-party-libs/glog-0.3.5
-- Detected glog version: 0.3.5
-- Found Glog: glog::glog  
-- Found Google Log (glog). Assuming glog was built with gflags support as gflags was found. This will make gflags a public dependency of Ceres.
-- Using Ceres threading model: CXX11_THREADS
-- Failed to find Google benchmark library, disabling build of benchmarks.
-- Building Ceres as a static library.
-- No build type specified; defaulting to CMAKE_BUILD_TYPE=Release.
-- Performing Test CHECK_CXX_FLAG_Wmissing_declarations
-- Performing Test CHECK_CXX_FLAG_Wmissing_declarations - Success
-- Performing Test CHECK_CXX_FLAG_Wno_unknown_pragmas
-- Performing Test CHECK_CXX_FLAG_Wno_unknown_pragmas - Success
-- Performing Test CHECK_CXX_FLAG_Wno_sign_compare
-- Performing Test CHECK_CXX_FLAG_Wno_sign_compare - Success
-- Performing Test CHECK_CXX_FLAG_Wno_unused_parameter
-- Performing Test CHECK_CXX_FLAG_Wno_unused_parameter - Success
-- Performing Test CHECK_CXX_FLAG_Wno_missing_field_initializers
-- Performing Test CHECK_CXX_FLAG_Wno_missing_field_initializers - Success
-- Creating configured Ceres config.h output directory: /home/yu/sources/ceres-solver/build/config/ceres/internal
-- Enabling CERES_USE_EIGEN_SPARSE in Ceres config.h
-- Enabling CERES_NO_ACCELERATE_SPARSE in Ceres config.h
-- Enabling CERES_USE_CXX11_THREADS in Ceres config.h
-- Performing Test CHECK_CXX_FLAG_Wno_missing_declarations
-- Performing Test CHECK_CXX_FLAG_Wno_missing_declarations - Success
-- Build the examples.
-- Configuring done
CMake Error in internal/ceres/CMakeLists.txt:
  Imported target "glog::glog" includes non-existent path

    "/home/yu/sources/eva/apps/third-party-libs/glog-0.3.5/src"

  in its INTERFACE_INCLUDE_DIRECTORIES.  Possible reasons include:

  * The path was deleted, renamed, or moved to another location.

  * An install or uninstall procedure did not complete successfully.

  * The installation package was faulty and references files it does not
  provide.



CMake Error in internal/ceres/CMakeLists.txt:
  Imported target "glog::glog" includes non-existent path

    "/home/yu/sources/eva/apps/third-party-libs/glog-0.3.5/src"

  in its INTERFACE_INCLUDE_DIRECTORIES.  Possible reasons include:

  * The path was deleted, renamed, or moved to another location.

  * An install or uninstall procedure did not complete successfully.

  * The installation package was faulty and references files it does not
  provide.



CMake Error in internal/ceres/CMakeLists.txt:
  Imported target "glog::glog" includes non-existent path

    "/home/yu/sources/eva/apps/third-party-libs/glog-0.3.5/src"

  in its INTERFACE_INCLUDE_DIRECTORIES.  Possible reasons include:

  * The path was deleted, renamed, or moved to another location.

  * An install or uninstall procedure did not complete successfully.

  * The installation package was faulty and references files it does not
  provide.



CMake Error in internal/ceres/CMakeLists.txt:
  Imported target "glog::glog" includes non-existent path

    "/home/yu/sources/eva/apps/third-party-libs/glog-0.3.5/src"

  in its INTERFACE_INCLUDE_DIRECTORIES.  Possible reasons include:

  * The path was deleted, renamed, or moved to another location.

  * An install or uninstall procedure did not complete successfully.

  * The installation package was faulty and references files it does not
  provide.



-- Generating done
-- Build files have been written to: /home/yu/sources/ceres-solver/build

首先,发现在/usr/lib/x86_64-linux-gnu/目录下是安装了 gflags 和 glog 库的,在/usr/include/目录下也能找到 gflags 和 glog 的头文件。但是上述 cmake 过程不是在该目录下找到 glog 库的。查看 ceres 的 cmake 目录下的FindGflags.cmake文件和FindGlog.cmake文件,其中说明了如果未指定GFLAGS_PREFER_EXPORTED_GFLAGS_CMAKE_CONFIGURATIONGLOG_PREFER_EXPORTED_GLOG_CMAKE_CONFIGURATION,cmake 将优先查找已经 install / exported 的库,其次再进行遍历,在/usr/include目录下查找对应的头文件。当前未指定搜索路径。

从上述 cmake 结果的 gflags 库部分看,找到了 exported 的某个 gflags 库:

-- No preference for use of exported gflags CMake configuration set, and no hints for include/library directories provided. Defaulting to preferring an installed/exported gflags CMake configuration if available. # 没有指定搜索方式
-- Failed to find installed gflags CMake configuration, searching for gflags build directories exported with CMake. # 没有找到 installed 的 gflags,尝试找 exported 的 gflags
-- Found exported gflags build directory: /home/yu/tmp/lib/cmake/gflags # 找到了 exported 的 gflags,在某个目录下
-- Detected gflags version: 2.2.2 # 输出 gflags 的安装版本
-- Found Gflags: /home/yu/tmp/include  # gflags 的头文件路径
-- Found Google Flags header in: /home/yu/tmp/include, in namespace: google

从上述 cmake 结果的 glog 库部分看,找到了 exported 的某个 glog 库:

-- No preference for use of exported glog CMake configuration set, and no hints for include/library directories provided. Defaulting to preferring an installed/exported glog CMake configuration if available. # 没有指定搜索方式
-- Failed to find installed glog CMake configuration, searching for glog build directories exported with CMake. # 没有找到 installed 的 glog,尝试找 exported 的 glog
-- Found exported glog build directory: /home/yu/sources/eva/cmake-build-debug/apps/third-party-libs/glog-0.3.5 # 找到了 exported 的 glog,在某个目录下
-- Detected glog version: 0.3.5 # 输出 glog 的安装版本
-- Found Glog: glog::glog  
-- Found Google Log (glog). Assuming glog was built with gflags support as gflags was found. This will make gflags a public dependency of Ceres.

之后的 error 也是因为找到的是在别的项目中安装的 glog 库,文件并不完整,导致找不到库,进而在编译过程中产生其他未知错误:

CMake Error in internal/ceres/CMakeLists.txt:
  Imported target "glog::glog" includes non-existent path

    "/home/yu/sources/eva/apps/third-party-libs/glog-0.3.5/src"

  in its INTERFACE_INCLUDE_DIRECTORIES.  Possible reasons include:

  * The path was deleted, renamed, or moved to another location.

  * An install or uninstall procedure did not complete successfully.

  * The installation package was faulty and references files it does not
  provide.



CMake Error in internal/ceres/CMakeLists.txt:
  Imported target "glog::glog" includes non-existent path

    "/home/yu/sources/eva/apps/third-party-libs/glog-0.3.5/src"

  in its INTERFACE_INCLUDE_DIRECTORIES.  Possible reasons include:

  * The path was deleted, renamed, or moved to another location.

  * An install or uninstall procedure did not complete successfully.

  * The installation package was faulty and references files it does not
  provide.



CMake Error in internal/ceres/CMakeLists.txt:
  Imported target "glog::glog" includes non-existent path

    "/home/yu/sources/eva/apps/third-party-libs/glog-0.3.5/src"

  in its INTERFACE_INCLUDE_DIRECTORIES.  Possible reasons include:

  * The path was deleted, renamed, or moved to another location.

  * An install or uninstall procedure did not complete successfully.

  * The installation package was faulty and references files it does not
  provide.



CMake Error in internal/ceres/CMakeLists.txt:
  Imported target "glog::glog" includes non-existent path

    "/home/yu/sources/eva/apps/third-party-libs/glog-0.3.5/src"

  in its INTERFACE_INCLUDE_DIRECTORIES.  Possible reasons include:

  * The path was deleted, renamed, or moved to another location.

  * An install or uninstall procedure did not complete successfully.

  * The installation package was faulty and references files it does not
  provide.

由于电脑中存在多个项目,安装了不同的 gflags 库和 glog 库,为了统一搜索路径,避免上述问题,需要指定搜索方式,重新构建:

cmake \
-DGFLAGS_PREFER_EXPORTED_GFLAGS_CMAKE_CONFIGURATION=FALSE \ # 指定优先搜索/usr/include路径
-DGLOG_PREFER_EXPORTED_GLOG_CMAKE_CONFIGURATION=FALSE ..# 指定优先搜索/usr/include路径

构建结果:

-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- CMAKE_RUNTIME_OUTPUT_DIRECTORY is: /home/yu/sources/ceres-solver/build/bin
-- CMAKE_LIBRARY_OUTPUT_DIRECTORY is: /home/yu/sources/ceres-solver/build/lib
-- Detected Ceres version: 2.0.0 from /home/yu/sources/ceres-solver/include/ceres/version.h
-- Detected available Ceres threading models: [CXX11_THREADS, OPENMP, NO_THREADS]
-- Building with C++11
-- No preference for use of exported Eigen CMake configuration set, and no hints for include directory provided. Defaulting to preferring an installed/exported Eigen CMake configuration if available.
-- Found installed version of Eigen: /usr/lib/cmake/eigen3
-- Found Eigen: /usr/include/eigen3 (found version "3.2.92") 
-- Found Eigen version 3.2.92: /usr/include/eigen3
-- Enabling use of Eigen as a sparse linear algebra library.
-- Looking for dgemm_
-- Looking for dgemm_ - found
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- A library with BLAS API found.
-- Found LAPACK library: /usr/lib/liblapack.so;/usr/lib/libf77blas.so;/usr/lib/libatlas.so
-- A library with BLAS API found.
-- Found AMD headers in: /usr/include/suitesparse
-- Found AMD library: /usr/lib/x86_64-linux-gnu/libamd.so
-- Found CAMD headers in: /usr/include/suitesparse
-- Found CAMD library: /usr/lib/x86_64-linux-gnu/libcamd.so
-- Found COLAMD headers in: /usr/include/suitesparse
-- Found COLAMD library: /usr/lib/x86_64-linux-gnu/libcolamd.so
-- Found CCOLAMD headers in: /usr/include/suitesparse
-- Found CCOLAMD library: /usr/lib/x86_64-linux-gnu/libccolamd.so
-- Found CHOLMOD headers in: /usr/include/suitesparse
-- Found CHOLMOD library: /usr/lib/x86_64-linux-gnu/libcholmod.so
-- Found SUITESPARSEQR headers in: /usr/include/suitesparse
-- Found SUITESPARSEQR library: /usr/lib/x86_64-linux-gnu/libspqr.so
-- Did not find Intel TBB library, assuming SuiteSparseQR was not compiled with TBB.
-- Found SUITESPARSE_CONFIG headers in: /usr/include/suitesparse
-- Found SUITESPARSE_CONFIG library: /usr/lib/x86_64-linux-gnu/libsuitesparseconfig.so
-- Found LIBRT library: /usr/lib/x86_64-linux-gnu/librt.so
-- Adding librt: /usr/lib/x86_64-linux-gnu/librt.so to SuiteSparse_config libraries (required on Linux & Unix [not OSX] if SuiteSparse is compiled with timing).
-- Did not find METIS library (optional SuiteSparse dependency)
-- Found SuiteSparse: TRUE (found version "4.4.6") 
-- Found SuiteSparse 4.4.6, building with SuiteSparse.
-- Found CXSparse: /usr/include/suitesparse (found version "3.1.4") 
-- Found CXSparse version: 3.1.4, building with CXSparse.
-- Building without Apple's Accelerate sparse support.
-- GFLAGS_INCLUDE_DIR is: /usr/include # 指定优先搜索路径后
-- GFLAGS_LIBRARY is: /usr/lib/x86_64-linux-gnu/libgflags.so # 指定优先搜索路径后
-- Performing Test GFLAGS_IN_GOOGLE_NAMESPACE
-- Performing Test GFLAGS_IN_GOOGLE_NAMESPACE - Success
-- Found Gflags: /usr/include # 指定优先搜索路径后  
-- Found Google Flags header in: /usr/include, in namespace: google # 指定优先搜索路径后
-- GLOG_INCLUDE_DIR is: /usr/include # 指定优先搜索路径后
-- GLOG_LIBRARY is: /usr/lib/x86_64-linux-gnu/libglog.so # 指定优先搜索路径后
-- Found Glog: /usr/include # 指定优先搜索路径后  
-- Found Google Log (glog). Assuming glog was built with gflags support as gflags was found. This will make gflags a public dependency of Ceres.
-- Using Ceres threading model: CXX11_THREADS
-- Failed to find Google benchmark library, disabling build of benchmarks.
-- Building Ceres as a static library. # 后续值得关注
-- No build type specified; defaulting to CMAKE_BUILD_TYPE=Release.
-- Performing Test CHECK_CXX_FLAG_Wmissing_declarations
-- Performing Test CHECK_CXX_FLAG_Wmissing_declarations - Success
-- Performing Test CHECK_CXX_FLAG_Wno_unknown_pragmas
-- Performing Test CHECK_CXX_FLAG_Wno_unknown_pragmas - Success
-- Performing Test CHECK_CXX_FLAG_Wno_sign_compare
-- Performing Test CHECK_CXX_FLAG_Wno_sign_compare - Success
-- Performing Test CHECK_CXX_FLAG_Wno_unused_parameter
-- Performing Test CHECK_CXX_FLAG_Wno_unused_parameter - Success
-- Performing Test CHECK_CXX_FLAG_Wno_missing_field_initializers
-- Performing Test CHECK_CXX_FLAG_Wno_missing_field_initializers - Success
-- Creating configured Ceres config.h output directory: /home/yu/sources/ceres-solver/build/config/ceres/internal
-- Enabling CERES_USE_EIGEN_SPARSE in Ceres config.h
-- Enabling CERES_NO_ACCELERATE_SPARSE in Ceres config.h
-- Enabling CERES_USE_CXX11_THREADS in Ceres config.h
-- Performing Test CHECK_CXX_FLAG_Wno_missing_declarations
-- Performing Test CHECK_CXX_FLAG_Wno_missing_declarations - Success
-- Build the examples.
-- Configuring done
-- Generating done
-- Build files have been written to: /home/yu/sources/ceres-solver/build

干净的构建结果。继续编译,成功。

在 build 目录下执行./bin/pose_graph_2d文件。第一次尝试下面的输入:

# build目录下
./bin/pose_graph_2d ~/sources/openslam_vertigo/datasets/city10000/originalDataset/city10000.g2o

结果出错:

input: 
F1031 09:28:06.848613 14240 pose_graph_2d.cc:163] Check failed: FLAGS_input != "" Need to specify the filename to read. # 文件名是空的
*** Check failure stack trace: ***
    @     0x7f51972275cd  google::LogMessage::Fail()
    @     0x7f5197229433  google::LogMessage::SendToLog()
    @     0x7f519722715b  google::LogMessage::Flush()
    @     0x7f5197229e1e  google::LogMessageFatal::~LogMessageFatal()
    @           0x406e64  main
    @     0x7f51956cf830  __libc_start_main
    @           0x4072f9  _start
    @              (nil)  (unknown)
Aborted

输入的参数并没有传入进代码。直接在代码中修改文件路径:

// pose_graph_2d.cc
DEFINE_string(input, "~/sources/openslam_vertigo/datasets/city10000/originalDataset/city10000.g2o", "The pose graph definition filename in g2o format."); # 将路径添加到代码中

文件路径能输出,但是读取文件又失败了。根据ReadG2oFile()函数的说明,文件的内容是正确的。但是没有读出来。

input: ~/sources/openslam_vertigo/datasets/city10000/originalDataset/city10000.g2o
F1031 09:32:49.220307 15534 pose_graph_2d.cc:176] Check failed: ceres::examples::ReadG2oFile(FLAGS_input, &poses, &constraints) Error reading the file:  ~/sources/openslam_vertigo/datasets/city10000/originalDataset/city10000.g2o # 读取文件内容失败
*** Check failure stack trace: ***
    @     0x7f3f362b95cd  google::LogMessage::Fail()
    @     0x7f3f362bb433  google::LogMessage::SendToLog()
    @     0x7f3f362b915b  google::LogMessage::Flush()
    @     0x7f3f362bbe1e  google::LogMessageFatal::~LogMessageFatal()
    @           0x406eca  main
    @     0x7f3f34761830  __libc_start_main
    @           0x4072f9  _start
    @              (nil)  (unknown)
Aborted

可能是文件有问题,更换其他普通文件尝试读取,比如某个 .txt文件,结果读取成功。对比差异发现问题:文件路径输入为~/前缀时,无法正常读取文件内容,当文件路径输入为/home/yu/前缀时,可以正确读取文件内容。

继续修改输入文件的路径,用/home/yu/前缀添加到代码中:

// pose_graph_2d.cc
DEFINE_string(input, "/home/yu/sources/openslam_vertigo/datasets/city10000/originalDataset/city10000.g2o", "The pose graph definition filename in g2o format.");

得到正常的算法输出:

input: /home/yu/sources/openslam_vertigo/datasets/city10000/originalDataset/city10000.g2o
Number of poses: 10000
Number of constraints: 20687

Solver Summary (v 2.0.0-eigen-(3.2.92)-lapack-suitesparse-(4.4.6)-cxsparse-(3.1.4)-eigensparse-no_openmp)

                                     Original                  Reduced
Parameter blocks                        30000                    29997
Parameters                              30000                    29997
Residual blocks                         20687                    20687
Residuals                               62061                    62061

Minimizer                        TRUST_REGION

Sparse linear algebra library    SUITE_SPARSE
Trust region strategy     LEVENBERG_MARQUARDT

                                        Given                     Used
Linear solver          SPARSE_NORMAL_CHOLESKY   SPARSE_NORMAL_CHOLESKY
Threads                                     1                        1
Linear solver ordering              AUTOMATIC                    29997

Cost:
Initial                          3.270813e+08
Final                            2.559927e+02
Change                           3.270811e+08

Minimizer iterations                       10
Successful steps                           10
Unsuccessful steps                          0

Time (in seconds):
Preprocessor                         0.026131

  Residual only evaluation           0.030149 (10)
  Jacobian & residual evaluation     0.086377 (10)
  Linear solver                      0.373010 (10)
Minimizer                            0.539330

Postprocessor                        0.001327
Total                                0.566788

Termination:                      CONVERGENCE (Function tolerance reached. |cost_change|/cost: 5.698316e-07 <= 1.000000e-06)

再次试验教程上的说明,在可执行文件后添加数据集的路径:

/path/to/bin/pose_graph_2d /path/to/dataset/dataset.g2o

重置原始代码(即不在源代码中添加数据集的路径),执行以下命令:

./bin/pose_graph_2d /home/yu/sources/openslam_vertigo/datasets/city10000/originalDataset/city10000.g2o 

得到错误的输出提示,说明文件路径没有输入到算法中:

input: 
F1031 09:43:32.214087 19312 pose_graph_2d.cc:163] Check failed: FLAGS_input != "" Need to specify the filename to read.
*** Check failure stack trace: ***
    @     0x7fc525c1a5cd  google::LogMessage::Fail()
    @     0x7fc525c1c433  google::LogMessage::SendToLog()
    @     0x7fc525c1a15b  google::LogMessage::Flush()
    @     0x7fc525c1ce1e  google::LogMessageFatal::~LogMessageFatal()
    @           0x406e64  main
    @     0x7fc5240c2830  __libc_start_main
    @           0x4072f9  _start
    @              (nil)  (unknown)
Aborted

需要研究一下 gflags 和输入参数之间的关系。百度中例程说在输入参数时需要添加对应的 flag 名,如下在数据集路径前添加-input=前缀:

./bin/pose_graph_2d -input=/home/yu/sources/openslam_vertigo/datasets/city10000/originalDataset/city10000.g2o

能正常读取数据集文件并且输出算法结果。

参考 gflags 官方文档Setting Flags on the Command Line小结:

https://gflags.github.io/gflags/

测试 2

清除工程目录 ceres 下目录build的内容,进入目录build,执行cmake -DGFLAGS_PREFER_EXPORTED_GFLAGS_CMAKE_CONFIGURATION=FALSE -DGLOG_PREFER_EXPORTED_GLOG_CMAKE_CONFIGURATION=FALSE -DCMAKE_INSTALL_PREFIX=/home/yu/sources/ceres-solver/install ..命令,将 ceres 安装到指定目录/home/yu/sources/ceres-solver/install下。

执行makemake install安装成功。

另外建立新的工程 testCERES ,新建 CMakeLists.txt,按照 g2o 的调用方式修改文件如下:

# testCERES的CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(testCERES)
set(CMAKE_CXX_STANDARD 11)

SET(CMAKE_MODULE_PATH /home/yu/sources/ceres-solver/install/lib/cmake/Ceres)
MESSAGE(STATUS "MODULE_PATH: " ${CMAKE_MODULE_PATH})

find_package(Ceres REQUIRED)
MESSAGE(STATUS "CERES_LIBRARIES is ${CERES_LIBRARIES}")

IF(Ceres_FOUND)
    message(STATUS "Ceres lib is found:" ${CERES_INCLUDE_DIRS})
ENDIF(Ceres_FOUND)

构建出错:

-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- MODULE_PATH: /home/yu/sources/ceres-solver/install/lib/cmake/Ceres
CMake Error at CMakeLists.txt:11 (find_package):
  By not providing "FindCeres.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "Ceres", but
  CMake did not find one. # 找不到FindCeres.cmake

  Could not find a package configuration file provided by "Ceres" with any of
  the following names:

    CeresConfig.cmake # 找不到CeresConfig.cmake
    ceres-config.cmake

  Add the installation prefix of "Ceres" to CMAKE_PREFIX_PATH or set
  "Ceres_DIR" to a directory containing one of the above files.  If "Ceres"
  provides a separate development package or SDK, be sure it has been
  installed.


-- Configuring incomplete, errors occurred!
See also "/home/yu/CLionProjects/testCERES/build/CMakeFiles/CMakeOutput.log".

指明找不到FindCeres.cmake或者CeresConfig.cmake文件。但是路径/home/yu/sources/ceres-solver/install/lib/cmake/Ceres确实包含了CeresConfig.cmake文件。

参考ceres-solver.org官网使用 ceres 的教程,指明了如果安装或者导出了 ceres ,需要将安装后的 CeresConfig.cmake文件所在的路径指定给Ceres_DIR变量。

Irrespective of whether Ceres was installed or exported, if multiple versions are detected, set: Ceres_DIR to control which is used. If Ceres was installed Ceres_DIR should be the path to the directory containing the installed CersConfig.cmake file (e.g. /usr/local/share/Ceres). If Ceres was exported, then Ceres_DIR should be the path to the exported Ceres build directory.

修改上述CMakeLists.txt文件,将CeresConfig.cmake文件的路径指定给Ceres_DIR变量,而不是CMAKE_MODULE_PATH变量:

# testCERES的CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(testCERES)
set(CMAKE_CXX_STANDARD 11)

SET(Ceres_DIR /home/yu/sources/ceres-solver/install/lib/cmake/Ceres)
MESSAGE(STATUS "Ceres_DIR: " ${Ceres_DIR})

find_package(Ceres REQUIRED)
MESSAGE(STATUS "CERES_LIBRARIES is ${CERES_LIBRARIES}")

IF(Ceres_FOUND)
    message(STATUS "Ceres lib is found:" ${CERES_INCLUDE_DIRS})
ENDIF(Ceres_FOUND)

构建成功。

-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Ceres_DIR: /home/yu/sources/ceres-solver/install/lib/cmake/Ceres
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Found installed version of Eigen: /usr/lib/cmake/eigen3
-- Found required Ceres dependency: Eigen version 3.2.92 in /usr/include/eigen3
-- GLOG_INCLUDE_DIR is: /usr/include
-- GLOG_LIBRARY is: /usr/lib/x86_64-linux-gnu/libglog.so
-- Found required Ceres dependency: glog
-- GFLAGS_INCLUDE_DIR is: /usr/include
-- GFLAGS_LIBRARY is: /usr/lib/x86_64-linux-gnu/libgflags.so
-- Performing Test GFLAGS_IN_GOOGLE_NAMESPACE
-- Performing Test GFLAGS_IN_GOOGLE_NAMESPACE - Success
-- Found required Ceres dependency: gflags
-- Found Ceres version: 2.0.0 installed in: /home/yu/sources/ceres-solver/install with components: [EigenSparse, SparseLinearAlgebraLibrary, LAPACK, SuiteSparse, CXSparse, SchurSpecializations]
-- CERES_LIBRARIES is ceres
-- Ceres lib is found:
-- Configuring done
-- Generating done
-- Build files have been written to: /home/yu/CLionProjects/testCERES/build

参考 ceres-solver.org官网安装及使用教程的Local installations部分,指明了一种自定义 ceres 库的寻找方法:

# cmake 过程
-DCMAKE_INSTALL_PREFIX="/some/where/local" # 自定义 ceres 安装路径
# 工程 CMakeLists.txt 文件
find_package(Ceres REQUIRED PATHS "/some/where/local/") # 添加安装路径
# testCERES的CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(testCERES)
set(CMAKE_CXX_STANDARD 11)

find_package(Ceres REQUIRED PATHS /home/yu/sources/ceres-solver/install)
IF(Ceres_FOUND)
    include_directories(${CERES_INCLUDE_DIRS})
    MESSAGE(STATUS "CERES_INCLUDE_DIRS is ${CERES_INCLUDE_DIRS}")
    MESSAGE(STATUS "CERES_LIBRARIES is ${CERES_LIBRARIES}")
ENDIF(Ceres_FOUND)

能够得到上述一样的构建结果。

但是,两者目前都有一个问题,能找到安装位置的 ceres 库,但是没有CERES_INCLUDE_DIRS路径的输出。ceres 的 CeresConfig.cmake文件中说:

NOTE: There is no equivalent of CERES_INCLUDE_DIRS as the exported ​ CMake target already includes the definition of its public ​ include directories.

暂时忽略这个问题。

继续添加只依赖 ceres 的测试程序。修改CMakeLists.txt文件:

# testCERES的CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(testCERES)
set(CMAKE_CXX_STANDARD 11)

# method 1
#SET(Ceres_DIR /home/yu/sources/ceres-solver/install/lib/cmake/Ceres)
#MESSAGE(STATUS "Ceres_DIR: " ${Ceres_DIR})

# method 2
find_package(Ceres REQUIRED PATHS /home/yu/sources/ceres-solver/install)
IF(Ceres_FOUND)
    include_directories(${CERES_INCLUDE_DIRS})
    MESSAGE(STATUS "CERES_INCLUDE_DIRS is ${CERES_INCLUDE_DIRS}")
    MESSAGE(STATUS "CERES_LIBRARIES is ${CERES_LIBRARIES}")
ENDIF(Ceres_FOUND)

add_executable(testCERES main.cpp)
target_link_libraries(testCERES ${CERES_LIBRARIES})

编译运行成功。

PS: ceres 的 CeresConfig.cmake文件中已经包含了对 gflags 和 glog 和 Eigen3 库的搜索和添加,所以在测试代码的 CMakeLists.txt文件中不再需要单独搜索上述库。

继续修改需要同时调用 ceres ,gflags ,和 glog 的库的测试程序,上述CMakeLists.txt编译通过,但是运行时出现问题:

Scanning dependencies of target testCERES
[ 50%] Building CXX object CMakeFiles/testCERES.dir/main.cpp.o
/home/yu/CLionProjects/testCERES/main.cpp: In function ‘int main(int, char**)’:
/home/yu/CLionProjects/testCERES/main.cpp:160:5: error: ‘CERES_GFLAGS_NAMESPACE’ has not been declared
     CERES_GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
     ^
CMakeFiles/testCERES.dir/build.make:62: recipe for target 'CMakeFiles/testCERES.dir/main.cpp.o' failed
make[2]: *** [CMakeFiles/testCERES.dir/main.cpp.o] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/testCERES.dir/all' failed
make[1]: *** [CMakeFiles/testCERES.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

说明CERES_GFLAGS_NAMESPACE未定义。该测试代码来自原 ceres 的例程 pose_graph_2d.cc,在原 ceres 中全局搜索变量CERES_GFLAGS_NAMESPACE,发现以下定义:

# ceres的CMakeLists.txt
# GFlags.
if (GFLAGS)
  # Don't search with REQUIRED as we can continue without gflags.
  find_package(Gflags)
  if (GFLAGS_FOUND)
    message("-- Found Google Flags header in: ${GFLAGS_INCLUDE_DIRS}, "
      "in namespace: ${GFLAGS_NAMESPACE}")
    add_definitions(-DCERES_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
  else (GFLAGS_FOUND)
    message("-- Did not find Google Flags (gflags), Building without gflags "
      "- no tests or tools will be built!")
    update_cache_variable(GFLAGS OFF)
  endif (GFLAGS_FOUND)
else (GFLAGS)
  message("-- Google Flags disabled; no tests or tools will be built!")
  # Mark as advanced (remove from default GUI view) the gflags search
  # variables in case user enabled GFLAGS, FindGflags did not find it, so
  # made search variables visible in GUI for user to set, but then user disables
  # GFLAGS instead of setting them.
  mark_as_advanced(FORCE GFLAGS_INCLUDE_DIR
                         GFLAGS_LIBRARY
                         GFLAGS_NAMESPACE)
endif (GFLAGS)

其中对DCERES_GFLAGS_NAMESPACE有独立的定义。不包含在 ceres 的 CeresConfig.cmake文件中。因此需要在测试代码的CMakeLists.txt文件中添加对该变量的定义,修改如下:

# testCERES的CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(testCERES)
set(CMAKE_CXX_STANDARD 11)

# method 1
#SET(Ceres_DIR /home/yu/sources/ceres-solver/install/lib/cmake/Ceres)
#MESSAGE(STATUS "Ceres_DIR: " ${Ceres_DIR})

# method 2
find_package(Ceres REQUIRED PATHS /home/yu/sources/ceres-solver/install)
IF(Ceres_FOUND)
    include_directories(${CERES_INCLUDE_DIRS})
    MESSAGE(STATUS "CERES_INCLUDE_DIRS is ${CERES_INCLUDE_DIRS}")
    MESSAGE(STATUS "CERES_LIBRARIES is ${CERES_LIBRARIES}")
ENDIF(Ceres_FOUND)

MESSAGE(STATUS "GFLAGS_NAMESPACE is: ${GFLAGS_NAMESPACE}")
if (GFLAGS_FOUND)
    MESSAGE(STATUS "Found Google Flags header in: ${GFLAGS_INCLUDE_DIRS}, "
            "in namespace: ${GFLAGS_NAMESPACE}")
    add_definitions(-DCERES_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
ENDIF(GFLAGS_FOUND)
MESSAGE(STATUS "CERES_GFLAGS_NAMESPACE is: ${CERES_GFLAGS_NAMESPACE}")

add_executable(testCERES main.cpp)
target_link_libraries(testCERES ${CERES_LIBRARIES})

编译运行通过。

测试 3

测试 4

测试 5

图优化数据集

https://github.com/OpenSLAM-org/openslam_vertigo

位于上述工程的datasets目录下,包含 2d 和 3d 图优化 g2o 数据集。