描述

Ubuntu系统下安装cartographer

需要说明的是:
每个人电脑配置是不同的,而cartographer的依赖库又比较多,所以难免出来各种各样的问题

由于我的电脑安装库比较多也比较杂,本文章只是描述我的安装过程,不一定通用
安装命令
1. 安装依赖

"VERSION="的那句一定要执行
#后面的语句是注释

以下的命令都是摘抄官网,不信任的话可以去cartographer官网找命令来执行https://google-cartographer.readthedocs.io/en/latest/,都是一样的

# Install the required libraries that are available as debs.
sudo apt-get update
sudo apt-get install -y \
    clang \
    cmake \
    g++ \
    git \
    google-mock \
    libboost-all-dev \
    libcairo2-dev \
    libcurl4-openssl-dev \
    libeigen3-dev \
    libgflags-dev \
    libgoogle-glog-dev \
    liblua5.2-dev \
    libsuitesparse-dev \
    lsb-release \
    ninja-build \
    stow
# Install Ceres Solver and Protocol Buffers support if available.
# No need to build it ourselves.
if [[ "$(lsb_release -sc)" = "focal" || "$(lsb_release -sc)" = "buster" ]]
then
  sudo apt-get install -y python3-sphinx libgmock-dev libceres-dev protobuf-compiler
else
  sudo apt-get install -y python-sphinx
  if [[ "$(lsb_release -sc)" = "bionic" ]]
  then
    sudo apt-get install -y libceres-dev
  fi
fi
git clone https://github.com/abseil/abseil-cpp.git
cd abseil-cpp
git checkout d902eb869bcfacc1bad14933ed9af4bed006d481
mkdir build
cd build
cmake -G Ninja \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
  -DCMAKE_INSTALL_PREFIX=/usr/local/stow/absl \
  ..
ninja
sudo ninja install
cd /usr/local/stow
sudo stow absl
VERSION="1.13.0"
# Build and install Ceres.
git clone https://ceres-solver.googlesource.com/ceres-solver
cd ceres-solver
git checkout tags/${VERSION}
mkdir build
cd build
cmake .. -G Ninja -DCXX11=ON
ninja
CTEST_OUTPUT_ON_FAILURE=1 ninja test
sudo ninja install
VERSION="v3.4.1"

# Build and install proto3.
git clone https://github.com/google/protobuf.git
cd protobuf
git checkout tags/${VERSION}
mkdir build
cd build
cmake -G Ninja \
  -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
  -DCMAKE_BUILD_TYPE=Release \
  -Dprotobuf_BUILD_TESTS=OFF \
  ../cmake
ninja
sudo ninja install

2. 安装cartographer

依旧是官网命令照抄,官网网址https://google-cartographer-ros.readthedocs.io/en/latest/compilation.html

sudo apt-get update
sudo apt-get install -y python-wstool python-rosdep ninja-build stow
mkdir catkin_google_ws
cd catkin_google_ws
wstool init src
wstool merge -t src https://raw.githubusercontent.com/cartographer-project/cartographer_ros/master/cartographer_ros.rosinstall
wstool update -t src
sudo rosdep init
rosdep update
rosdep install --from-paths src --ignore-src --rosdistro=${ROS_DISTRO} -y
src/cartographer/scripts/install_abseil.sh
sudo apt-get remove ros-${ROS_DISTRO}-abseil-cpp
catkin_make_isolated --install --use-ninja

最后一句就是编译命令
肯定会有编译问题,我在文章的最后一章列举了解决办法

3. 验证

跑一下官方数据,下载数据

wget -P ~/Downloads https://storage.googleapis.com/cartographer-public-data/bags/backpack_2d/cartographer_paper_deutsches_museum.bag

source一下

cd ~/catkin_google_ws
source install_isolated/setup.sh 

跑吧

roslaunch cartographer_ros demo_backpack_2d.launch bag_filename:=${HOME}/Downloads/cartographer_paper_deutsches_museum.bag

问题1:Boost的版本问题

    提示错误,最常见的undefined reference to 错误,显然就是没有成功链接库引起的

    undefined reference to boost::iostream
        

    查找错误
    比如你的cartographer工作空间名字叫做catkin_google_ws
    那么去catkin_google_ws/src/cartographer路径下找到CMakeLists.txt并打开,找到以下的几句话

find_package(Boost 1.58 REQUIRED COMPONENTS ${BOOST_COMPONENTS})
find_package(Ceres REQUIRED COMPONENTS SuiteSparse)
find_package(Eigen3 REQUIRED)
find_package(LuaGoogle REQUIRED)
  • 你需要做的是
  1. 设置一下boost查找路径,让系统先从你设置的路径开始寻找boost
    命令
    set(BOOST_ROOT "/usr/")

  2. 查看一下编译找到的Boost库,它的include和lib路径究竟是什么
    命令

 `MESSAGE(${Boost_INCLUDE_DIRS})`和`MESSAGE(${Boost_LIBRARIES})`

都弄好了是这样的

set(BOOST_ROOT "/usr/")
find_package(Boost 1.58 REQUIRED COMPONENTS ${BOOST_COMPONENTS})
MESSAGE(${Boost_INCLUDE_DIRS})
MESSAGE(${Boost_LIBRARIES})

    正确的提示
    cartographer能够编译正确时,需要的是

    MESSAGE(${Boost_INCLUDE_DIRS})应该打印出的是/usr/local/include
    MESSAGE(${Boost_LIBRARIES})应该打印出的是/usr/lib/x86_64-linux-gnu/libboost_iostreams.so/usr/lib/x86_64-linux-gnu/libboost_regex.so

    而我的MESSAGE(${Boost_LIBRARIES})输出是/usr/local/lib/libboost_iostreams.so/usr/local/lib/libboost_regex.so
    显然是不对的

    解决办法
    我不太知道,为什么我的include路径没有错,但是lib文件却找的不对。没什么时间,不求甚解的解决吧。我的解决办法是,生硬的在链接命令上添加了需要的这两个so库文件
    请你在boost的target_link_libraries的最后添加/usr/lib/x86_64-linux-gnu/libboost_iostreams.so /usr/lib/x86_64-linux-gnu/libboost_regex.so

    解决
    重新执行编译命令catkin_make_isolated --install --use-ninja,这个问题已经被解决了

问题2:Eigen的版本问题

    错误提示
    执行编译命令catkin_make_isolated --install --use-ninja时,终端提示错误,错误消息如下

CMake Error at CMakeLists.txt:243 (find_package):
  Could not find a configuration file for package "Eigen3" that is compatible
  with requested version "3.3".
 
  The following configuration files were considered but not accepted:
 
    /usr/lib/cmake/eigen3/Eigen3Config.cmake, version: unknown
  • 原因:需要安装一个比3.3更新的eigen3库
  • 解决办法:
    随便cd到某个目录下,依次执行以下命令,即可解决
git clone https://github.com/eigenteam/eigen-git-mirror
cd eigen-git-mirror
mkdir build
cd build
cmake ..
sudo make install

    再次执行编译命令catkin_make_isolated --install --use-ninja时,不会再报错

问题3:Ceres的版本问题

在一个新的纯净的Ubuntu16.04系统上,我想要安装cartographer。首先安装ros-kinetic成功了,随后按照我之前上面的总结,一步步执行。却发现执行命令catkin_make_isolated --install --use-ninja编译cartographer失败

问题提示是如下这样(以下只是一部分)

In file included from /usr/local/include/ceres/internal/parameter_dims.h:37:0,
                 from /usr/local/include/ceres/internal/autodiff.h:151,
                 from /usr/local/include/ceres/autodiff_cost_function.h:130,
                 from /usr/local/include/ceres/ceres.h:37,
                 from /home/fuxirobot/catkin_google_ws/src/cartographer/cartographer/common/math.h:25,
                 from /home/fuxirobot/catkin_google_ws/src/cartographer/cartographer/transform/rigid_transform.h:28,
                 from /home/fuxirobot/catkin_google_ws/src/cartographer/cartographer/ground_truth/relations_text_file.cc:22:
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:64:16: error: ‘integer_sequence’ is not a member of ‘std’
 struct SumImpl<std::integer_sequence<T, N, Ns...>> {
                ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:64:16: error: ‘integer_sequence’ is not a member of ‘std’
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:64:46: error: wrong number of template arguments (3, should be 1)
 struct SumImpl<std::integer_sequence<T, N, Ns...>> {
                                              ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:60:8: note: provided for ‘template<class Seq> struct ceres::internal::SumImpl’
 struct SumImpl;
        ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:64:49: error: expected unqualified-id before ‘>’ token
 struct SumImpl<std::integer_sequence<T, N, Ns...>> {
                                                 ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:71:16: error: ‘integer_sequence’ is not a member of ‘std’
 struct SumImpl<std::integer_sequence<T, N1, N2, Ns...>> {
                ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:71:16: error: ‘integer_sequence’ is not a member of ‘std’
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:71:51: error: wrong number of template arguments (4, should be 1)
 struct SumImpl<std::integer_sequence<T, N1, N2, Ns...>> {
                                                   ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:60:8: note: provided for ‘template<class Seq> struct ceres::internal::SumImpl’
 struct SumImpl;
        ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:71:54: error: expected unqualified-id before ‘>’ token
 struct SumImpl<std::integer_sequence<T, N1, N2, Ns...>> {
                                                      ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:78:16: error: ‘integer_sequence’ is not a member of ‘std’
 struct SumImpl<std::integer_sequence<T, N1, N2, N3, N4, Ns...>> {
                ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:78:16: error: ‘integer_sequence’ is not a member of ‘std’
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:78:59: error: wrong number of template arguments (6, should be 1)
 struct SumImpl<std::integer_sequence<T, N1, N2, N3, N4, Ns...>> {
                                                           ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:60:8: note: provided for ‘template<class Seq> struct ceres::internal::SumImpl’
 struct SumImpl;
        ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:78:62: error: expected unqualified-id before ‘>’ token
 struct SumImpl<std::integer_sequence<T, N1, N2, N3, N4, Ns...>> {
                                                              ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:85:16: error: ‘integer_sequence’ is not a member of ‘std’
 struct SumImpl<std::integer_sequence<T, N>> {
                ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:85:16: error: ‘integer_sequence’ is not a member of ‘std’
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:85:41: error: wrong number of template arguments (2, should be 1)
 struct SumImpl<std::integer_sequence<T, N>> {
                                         ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:60:8: note: provided for ‘template<class Seq> struct ceres::internal::SumImpl’
 struct SumImpl;
        ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:85:42: error: expected unqualified-id before ‘>’ token
 struct SumImpl<std::integer_sequence<T, N>> {
                                          ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:91:16: error: ‘integer_sequence’ is not a member of ‘std’
 struct SumImpl<std::integer_sequence<T>> {
                ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:91:16: error: ‘integer_sequence’ is not a member of ‘std’
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:91:38: error: template argument 1 is invalid
 struct SumImpl<std::integer_sequence<T>> {
                                      ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:91:39: error: expected unqualified-id before ‘>’ token
 struct SumImpl<std::integer_sequence<T>> {
                                       ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:135:26: error: ‘integer_sequence’ is not a member of ‘std’
                          std::integer_sequence<T, N, Ns...>,
                          ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:135:26: error: ‘integer_sequence’ is not a member of ‘std’
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:135:59: error: wrong number of template arguments (5, should be 4)
                          std::integer_sequence<T, N, Ns...>,
                                                           ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:130:8: note: provided for ‘template<class T, T Sum, class SeqIn, class SeqOut> struct ceres::internal::ExclusiveScanImpl’
 struct ExclusiveScanImpl;
        ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:146:34: error: ‘integer_sequence’ is not a member of ‘std’
 struct ExclusiveScanImpl<T, Sum, std::integer_sequence<T>, SeqOut> {
                                  ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:146:34: error: ‘integer_sequence’ is not a member of ‘std’
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:146:57: error: wrong number of template arguments (3, should be 4)
 struct ExclusiveScanImpl<T, Sum, std::integer_sequence<T>, SeqOut> {
                                                         ^
/usr/local/include/ceres/internal/integer_sequence_algorithm.h:130:8: note: provided for ‘template<class T, T Sum, class SeqIn, class SeqOut> struct ceres::internal::ExclusiveScanImpl’
 struct ExclusiveScanImpl;

原因
在安装Ceres没有执行VERSION="1.13.0",没有设定需要安装的版本,在后面的一句git checkout tags/${VERSION},checkout到了错误的tag上。
有关VERSION这一点,我已经在前面的步骤中修复,并重新用红字提示出来了

解决办法
首先,删去之前安装的ceres-solver

sudo rm -r /usr/local/lib/cmake/Ceres
sudo rm -rf /usr/local/include/ceres /usr/local/lib/libceres.a
sudo rm -r /usr/local/share/Ceres

然后,按照前面的操作指示重新安装了一遍Ceres即可