https://github.com/HKUST-Aerial-Robotics/A-LOAM
PCL之前已经安装过,因此只需要安装Ceres Solver
官方的安装指南
http://ceres-solver.org/installation.html
一开始是git下来的最新版本的Ceres Solver,即2.1版本,编译时报错
/usr/local/include/eigen3/Eigen/src/Core/util/XprHelper.h:78:8: error: no type named ‘Literal’ in ‘struct Eigen::NumTraits<ceres::Jet<double, 9> >’
网上搜索说是Ceres Solver版本与Eigen版本不兼容
查看Eigen版本,发现是3.3.9版本
pkg-config --modversion eigen3
于是更换Ceres Slover的版本,用的高翔博士视觉SLAM十四讲3rd_party下的Ceres Slover
用下述命令卸载原来安装的Ceres Slover
sudo rm /usr/local/lib/libceres*
sudo rm -rf /usr/local/include/ceres
sudo rm -rf /usr/include/ceres
sudo rm -rf /usr/local/lib/cmake/Ceres
sudo rm -rf /var/lib/dpkg/info/libceres*
sudo rm -rf /usr/share/doc/libceres*
卸载Eigen 3.3.9,安装Eigen 3.2.9,用下述命令卸载
sudo rm -rf /usr/include/eigen3
sudo rm -rf /usr/lib/cmake/eigen3
sudo rm -rf /usr/local/include/eigen3
sudo rm -rf /usr/share/doc/libeigen3-dev
sudo rm -rf /usr/local/share/pkgconfig/eigen3.pc /usr/share/pkgconfig/eigen3.pc /var/lib/dpkg/info/libeigen3-dev.list /var/lib/dpkg/info/libeigen3-dev.md5sums
sudo rm -rf /usr/local/lib/pkgconfig/eigen3.pc
sudo rm -rf /usr/local/share/eigen3
更换完版本后Ceres Slover可以正常编译,但是执行catkin_make命令时又会报错
find_package Error reading CMake code from "/usr/local/lib/cmake/Ceres/CeresConfig.cmake"
查询资料说是没有有效安装,并且当前Ceres Slover的版本号也不清楚,于是我又在网上搜索其它较稳定版本的Ceres Slover,选择1.14.0版本,下面是下载链接
https://ceres-solver.googlesource.com/ceres-solver/+/refs/tags/1.14.0/
此时并未更换Eigen版本
更换Ceres Slover后再次catkin_make,报了新错误
Failed to find Ceres - Missing required Ceres dependency: Eigen version 3.2.9, please set EIGEN_INCLUDE_DIR
这个报错来自CeresConfig.cmake文件,查看这个文件后发现错误输出来自下面的程序段
# Eigen.
# Flag set during configuration and build of Ceres.
set(CERES_EIGEN_VERSION 3.2.9)
set(Eigen_INCLUDE_DIRS "/usr/include/eigen3")
set(EIGEN_WAS_BUILT_WITH_CMAKE TRUE)
# Append the locations of Eigen when Ceres was built to the search path hints.
if (EIGEN_WAS_BUILT_WITH_CMAKE)
set(Eigen3_DIR "/usr/include/eigen3")
set(EIGEN_PREFER_EXPORTED_EIGEN_CMAKE_CONFIGURATION TRUE)
else()
list(APPEND EIGEN_INCLUDE_DIR_HINTS )
endif()
# Search quietly to control the timing of the error message if not found. The
# search should be for an exact match, but for usability reasons do a soft
# match and reject with an explanation below.
find_package(Eigen ${CERES_EIGEN_VERSION} QUIET)
if (EIGEN_FOUND)
if (NOT EIGEN_VERSION VERSION_EQUAL CERES_EIGEN_VERSION)
# CMake's VERSION check in FIND_PACKAGE() will accept any version >= the
# specified version. However, only version = is supported. Improve
# usability by explaining why we don't accept non-exact version matching.
ceres_report_not_found("Found Eigen dependency, but the version of Eigen "
"found (${EIGEN_VERSION}) does not exactly match the version of Eigen "
"Ceres was compiled with (${CERES_EIGEN_VERSION}). This can cause subtle "
"bugs by triggering violations of the One Definition Rule. See the "
"Wikipedia article http://en.wikipedia.org/wiki/One_Definition_Rule "
"for more details")
endif ()
message(STATUS "Found required Ceres dependency: "
"Eigen version ${CERES_EIGEN_VERSION} in ${EIGEN_INCLUDE_DIRS}")
else (EIGEN_FOUND)
ceres_report_not_found("Missing required Ceres "
"dependency: Eigen version ${CERES_EIGEN_VERSION}, please set "
"EIGEN_INCLUDE_DIR.")
endif (EIGEN_FOUND)
list(APPEND CERES_INCLUDE_DIRS ${EIGEN_INCLUDE_DIRS})
还是Eigen的问题,上述文件已经做了部分修改,有下面几处,感兴趣可以对比原文件看下
set(CERES_EIGEN_VERSION 3.2.9)
set(Eigen_INCLUDE_DIRS "/usr/include/eigen3")
set(EIGEN_WAS_BUILT_WITH_CMAKE TRUE)
set(Eigen3_DIR "/usr/include/eigen3")
这个报错的意思是没有找到Eigen的依赖,有两种解决思路
极其简单粗暴,这一段代码的最终目的是确定EIGEN_INCLUDE_DIRS,那么直接set这个变量值应该就可行,更改如下:
# Eigen.
# Flag set during configuration and build of Ceres.
set(CERES_EIGEN_VERSION 3.2.9)
set(Eigen_INCLUDE_DIRS "/usr/include/eigen3")
# set(EIGEN_WAS_BUILT_WITH_CMAKE TRUE)
# # Append the locations of Eigen when Ceres was built to the search path hints.
# if (EIGEN_WAS_BUILT_WITH_CMAKE)
# set(Eigen3_DIR "/usr/include/eigen3")
# set(EIGEN_PREFER_EXPORTED_EIGEN_CMAKE_CONFIGURATION TRUE)
# else()
# list(APPEND EIGEN_INCLUDE_DIR_HINTS )
# endif()
# # Search quietly to control the timing of the error message if not found. The
# # search should be for an exact match, but for usability reasons do a soft
# # match and reject with an explanation below.
# find_package(Eigen ${CERES_EIGEN_VERSION} QUIET)
# if (EIGEN_FOUND)
# if (NOT EIGEN_VERSION VERSION_EQUAL CERES_EIGEN_VERSION)
# # CMake's VERSION check in FIND_PACKAGE() will accept any version >= the
# # specified version. However, only version = is supported. Improve
# # usability by explaining why we don't accept non-exact version matching.
# ceres_report_not_found("Found Eigen dependency, but the version of Eigen "
# "found (${EIGEN_VERSION}) does not exactly match the version of Eigen "
# "Ceres was compiled with (${CERES_EIGEN_VERSION}). This can cause subtle "
# "bugs by triggering violations of the One Definition Rule. See the "
# "Wikipedia article http://en.wikipedia.org/wiki/One_Definition_Rule "
# "for more details")
# endif ()
# message(STATUS "Found required Ceres dependency: "
# "Eigen version ${CERES_EIGEN_VERSION} in ${EIGEN_INCLUDE_DIRS}")
# else (EIGEN_FOUND)
# ceres_report_not_found("Missing required Ceres "
# "dependency: Eigen version ${CERES_EIGEN_VERSION}, please set "
# "EIGEN_INCLUDE_DIR.")
# endif (EIGEN_FOUND)
list(APPEND CERES_INCLUDE_DIRS ${EIGEN_INCLUDE_DIRS})
再次catkin_make aloam_velodyne,编译成功
上述方法过于笨拙,不够优雅,并且没有发现问题的本质
查找资料发现如果要通过find_package(Eigen XXX)找到Eigen库,则应在/usr/lib/cmake和/usr/local/lib/cmake存在eigen3的cmake文件,然而我的笔记本上并没有(可能由于多次重装Eigen导致),所以这才是上述错误的真正原因
虚拟机上有eigen3的cmake文件,找了一个用到Eigen的文件,更改其CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(useEigen)
set(CMAKE_BUILD_TYPE "Release")
set(CMAKE_CXX_FLAGS "-O3")
# 添加Eigen头文件
# include_directories("/usr/include/eigen3")
find_package(Eigen3 REQUIRED)
include_directories(${EIGEN3_INCLUDE_DIRS})
add_executable(eigenMatrix eigenMatrix.cpp)
再次编译,报错
CMake Error at CMakeLists.txt:9 (find_package):
By not providing "FindEigen3.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "Eigen3", but
CMake did not find one.
Could not find a package configuration file provided by "Eigen3" with any
of the following names:
Eigen3Config.cmake
eigen3-config.cmake
Add the installation prefix of "Eigen3" to CMAKE_PREFIX_PATH or set
"Eigen3_DIR" to a directory containing one of the above files. If "Eigen3"
provides a separate development package or SDK, be sure it has been
installed.
将eigen3的cmake文件还原回去,则可顺利编译,验证之前的分析正确
因此将虚拟机中的eigen3的cmake文件复制到双系统中应该就可以解决问题,但是要注意版本问题,统一将cmake文件中出现版本号的地方更改为双系统中的Eigen版本,比如
# This file exports the Eigen3::Eigen CMake target which should be passed to the
# target_link_libraries command.
####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
####### Any changes to this file will be overwritten by the next CMake run ####
####### The input file was Eigen3Config.cmake.in ########
get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
# Use original install prefix when loaded through a "/usr move"
# cross-prefix symbolic link such as /lib -> /usr/lib.
get_filename_component(_realCurr "${CMAKE_CURRENT_LIST_DIR}" REALPATH)
get_filename_component(_realOrig "/usr/lib/cmake/eigen3" REALPATH)
if(_realCurr STREQUAL _realOrig)
set(PACKAGE_PREFIX_DIR "/usr")
endif()
unset(_realOrig)
unset(_realCurr)
macro(set_and_check _var _file)
set(${_var} "${_file}")
if(NOT EXISTS "${_file}")
message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
endif()
endmacro()
####################################################################################
include ("${CMAKE_CURRENT_LIST_DIR}/Eigen3Targets.cmake")
# Legacy variables, do *not* use. May be removed in the future.
set (EIGEN3_FOUND 1)
set (EIGEN3_USE_FILE "${CMAKE_CURRENT_LIST_DIR}/UseEigen3.cmake")
set (EIGEN3_DEFINITIONS "")
set (EIGEN3_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include/eigen3")
set (EIGEN3_INCLUDE_DIRS "${PACKAGE_PREFIX_DIR}/include/eigen3")
set (EIGEN3_ROOT_DIR "${PACKAGE_PREFIX_DIR}")
set (EIGEN3_VERSION_STRING "3.3.4")
set (EIGEN3_VERSION_MAJOR "3")
set (EIGEN3_VERSION_MINOR "3")
set (EIGEN3_VERSION_PATCH "4")
有3.3.4的地方都要改成3.2.9,再次catkin_make aloam_velodyne,编译成功,看到输出
-- Found installed version of Eigen: /usr/local/lib/eigen3
-- Found required Ceres dependency: Eigen version 3.2.9 in /usr/include/eigen3
下载数据集,下面是网盘链接
链接:https://pan.baidu.com/s/1b_M-Vs-524TTGNOAxu1gQA
提取码:xkqd
roslaunch aloam_velodyne aloam_velodyne_VLP_16.launch
rosbag play YOUR_DATASET_FOLDER/nsh_indoor_outdoor.bag
说明安装配置成功