Cartographer
毕设工作设计到与cartographer进行定量实验比较。本人在Enigmatisms/cartographer_tester 中整理了cartographer以及ros驱动代码,添加了自动化轨迹读取等功能,两周前在Ubuntu
18.04上已经完成了测试,但在Ubuntu
20.04上一直编译不通过,调了一下午才调出来。本文记录了cartographer在不同版本的Ubuntu上(尤其是20.04)的一些典型编译问题以及解决方案。笔者现已经通过文中所说的解决方案完成了cartographer的编译。
Lua Not Found
从Github上下载Lua,本地编译安装并且sudo make install
是可以使得这个错误消失。但是,我在Ubuntu 18.04用此方法安装Lua
5.3之后,编译导致ABSL库问题(与Lua有关的)。遂sudo make uninstall
卸载,使用
通过apt安装。但是这样安装的lua5.2
,编译时仍然说找不到(即使重启,仍然也找不到)。不过,其实我跳过了官网的rosdep
步骤,先走完rosdep
步骤再编译就能找到lua 5.2
了。关于如何解决rosdep update
速度慢的问题,见
[这篇博客,亲测有效] .
这篇博客虽然针对20.04,对于18.04,只需要修改python3为python2.7即可。
Undefined Reference to ABSL
absl
库可能产生问题:
1 2 3 4 5 6 7 8 9 10 11 [241/387] Linking CXX executable cartographer_pbstream FAILED: cartographer_pbstream : && /usr/bin/c++ -O3 -DNDEBUG -rdynamic CMakeFiles/cartographer_pbstream.dir/cartographer/io/pbstream_main.cc.o -o cartographer_pbstream libcartographer.a /usr/local/lib/libceres.a -lglog -lspqr -ltbb -lcholmod -lccolamd -lcamd -lcolamd -lamd -llapack -lf77blas -latlas -lsuitesparseconfig -lrt -lcxsparse -llapack -lf77blas -latlas -lsuitesparseconfig -lrt -lcxsparse -llua5.2 -lm /usr/lib/x86_64-linux-gnu/libboost_iostreams.so.1.71.0 -lglog /usr/lib/x86_64-linux-gnu/libgflags.so.2.2.2 -lcairo /usr/local/lib/libprotobuf.a /usr/local/lib/libabsl_leak_check.a /usr/local/lib/libabsl_cord.a /usr/local/lib/libabsl_cordz_info.a /usr/local/lib/libabsl_cord_internal.a /usr/local/lib/libabsl_cordz_functions.a /usr/local/lib/libabsl_cordz_handle.a /usr/local/lib/libabsl_hash.a /usr/local/lib/libabsl_city.a /usr/local/lib/libabsl_bad_variant_access.a /usr/local/lib/libabsl_low_level_hash.a /usr/local/lib/libabsl_raw_hash_set.a /usr/local/lib/libabsl_bad_optional_access.a /usr/local/lib/libabsl_hashtablez_sampler.a /usr/local/lib/libabsl_exponential_biased.a /usr/local/lib/libabsl_str_format_internal.a /usr/local/lib/libabsl_synchronization.a /usr/local/lib/libabsl_stacktrace.a /usr/local/lib/libabsl_graphcycles_internal.a /usr/local/lib/libabsl_symbolize.a /usr/local/lib/libabsl_malloc_internal.a /usr/local/lib/libabsl_debugging_internal.a /usr/local/lib/libabsl_demangle_internal.a /usr/local/lib/libabsl_time.a /usr/local/lib/libabsl_strings.a /usr/local/lib/libabsl_strings_internal.a /usr/local/lib/libabsl_base.a -lpthread /usr/local/lib/libabsl_spinlock_wait.a -lrt /usr/local/lib/libabsl_throw_delegate.a /usr/local/lib/libabsl_raw_logging_internal.a /usr/local/lib/libabsl_log_severity.a /usr/local/lib/libabsl_int128.a /usr/local/lib/libabsl_civil_time.a /usr/local/lib/libabsl_time_zone.a -lpthread && : /usr/bin/ld: libcartographer.a(histogram.cc.o): in function `cartographer::common::Histogram::ToString[abi:cxx11](int) const': histogram.cc:(.text+0x43c): undefined reference to `absl::strings_internal::CatPieces[abi:cxx11](std::initializer_list<std::basic_string_view<char, std::char_traits<char> > >)' /usr/bin/ld: histogram.cc:(.text+0x95a): undefined reference to `absl::strings_internal::AppendPieces(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::initializer_list<std::basic_string_view<char, std::char_traits<char> > >)' collect2: error: ld returned 1 exit status [256/387] Building CXX object CMakeFiles/cartographer.mapping.internal.3d.scan_matching.fast_correlative...er_3d_test.dir/cartographer/mapping/internal/3d/scan_matching/fast_correlative_scan_matcher_3d_test.cc.o ninja: build stopped: subcommand failed. <== Failed to process package 'cartographer': Command '['ninja', '-j16', '-l16']' returned non-zero exit status 1.
此问题可能由两部分原因 导致:
Ubuntu
20.04上,cartographer,cartographer_ros等模块以及abseil-cpp
模块均需要使用c++17标准编译(来源于这个Github
issue:8.0
fails: undefined reference to absl::lts_2020_09_23::Status::Status
#2196 ),原始的install_abseil.sh
是这样的:
1 2 3 4 5 cmake -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ -DCMAKE_INSTALL_PREFIX=/usr/local/stow/absl \ ..
如果修改为:
1 2 3 4 5 6 7 8 cmake -G Ninja \ -std=c++17 \ -DABSL_CXX_STANDARD=17 \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ -DCMAKE_INSTALL_PREFIX=/usr/local/stow/absl \ -DABSL_PROPAGATE_CXX_STD=ON \ ..
增加-std=c++17
,-DABSL_CXX_STANDARD=17
,-DABSL_PROPAGATE_CXX_STD=ON
,前两个选项为了使得编译使用c++17标准,最后一个选项防止编译warning。而其他cartographer相关模块,只需要在每个模块下的CMakeLists.txt
中的project(xxx)
后添加
1 set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17" )
Google查找问题时,在abseil-cpp
库的issue里找到了这么一个issue:
undefined
reference errors (absl::strings_internal::CatPieces and
absl::ByChar::Find) 。其中有个人提到:
Confirmed on my end: if I add back what was removed from
AbseilConfigureCopts.make
in commit c695489
then it works.
于是我修改install_abseil.sh
:
1 git checkout c6954897f7ece5011f0126db9117361dc1a6ff36 # 修改到这个commit
编译abseil-cpp
,完成后删除cartographer之前的build_isolated
以及devel_isolated
并重新编译cartographer。则不再出现absl
库问题。
PythonInterp 版本问题
Ubuntu 20.04首次摒弃 python
2.7,包括ROS(rospy)在内全面转向python3,但是可能还是存在一些余孽?继续编译后我遇到了如下问题:
1 2 3 4 5 6 7 8 9 10 CMake Error at /usr/share/cmake-3.16/Modules/FindPackageHandleStandardArgs.cmake:146 (message): Could NOT find PythonInterp: Found unsuitable version "2.7.18", but required is at least "3" (found /usr/bin/python) Call Stack (most recent call first): /usr/share/cmake-3.16/Modules/FindPackageHandleStandardArgs.cmake:391 (_FPHSA_FAILURE_MESSAGE) /usr/share/cmake-3.16/Modules/FindPythonInterp.cmake:169 (FIND_PACKAGE_HANDLE_STANDARD_ARGS) /opt/ros/noetic/share/catkin/cmake/python.cmake:4 (find_package) /opt/ros/noetic/share/catkin/cmake/all.cmake:164 (include) /opt/ros/noetic/share/catkin/cmake/catkinConfig.cmake:20 (include) CMakeLists.txt:55 (find_package)
emmm,我查了一下trace
stack中的所有cmake文件,没有什么发现,只是cmake无法找到python3,并且在which python
时显示的是2.7.18的
python2。看来是默认python有问题,只需要使用:
1 2 sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1 sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.8 2
就可以解决问题,自此所有问题都得到了解决,cartographer顺利安装。
其他记录
成功无bug适配了cartographer的cere-solver版本是2.0.0,在Ubuntu
18.04以及20.04上通用。
cartographer的
CMakeLists.txt
很复杂,但是读一读还是能学到一些有趣的东西,比如:cmake_parse_arguments