最近想自己电脑(Ubuntu20.04)把OA-SLAM跑通,把所有库都配置好后,发现protobuf库在链接时总是会出问题。本人由于才疏学浅,花了2天时间才在Github找到解决方案,现在简单汇总以下出现的问题及解决方案。
OA-SLAM分别在编译和运行时各出现了一个问题,他们分别是:
Questions & Solutions
一、 编译链接时因为Osmap依赖libprotobuf在链接时出现以下错误:
/usr/lib/ld: /usr/local/lib/libprotobuf.a(arena.o): relocation R_x86_64_TPOFF32 aganist hidden symbol......
/usr/lib/ld: /usr/local/lib/libprotobuf.a(common.o): relocation R_X86_64_PC32 aganist symbol......; recompile with -fPIC
Analysis
出现这种错误的原因是因为OA-SLAM中Osmap库依赖libprotobuf库,而这个库默认构建成静态库也就是libprotobuf.a和libprotobuf-lite.a。这两个静态库无法链接到liborb_slam.so上。可能的解决办法是重新构建protobuf库,命令其生成动态库调用,并使用-fPIC编译选项。
Solutions
在Github上下载最新版本的protobuf源代码,使用CMake构建Makefile
$ mkdir build && cd build
$ cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS=-fPIC -Dprotobuf_BUILD_SHARED_LIBS=ON
$ make -j16
$ sudo make install
安装好库,在OA-SLAM的CMakeLists.txt中链接protobuf库,也可以手动链接。我手动链接libprotobufd.so可行。
二、链接protobuf库时报错
FAILED: /home/yifan/SLAM/oa-slam-main/bin/oa-slam
......
/usr/bin/ld: /home/yifan/SLAM/oa-slam-main/lib/libORB_SLAM2.so: undefined reference to `google::protobuf::internal::ThreadSafeArena::thread_cache_'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
Analysis
原因大概是因为protobuf内部不完善导致的。查找Github在protobuf首页的Issues栏下在一个极其不起眼的角落找到这个问题的解决方案。就是链接过程中找不到thread_cache_定义,这个变量的定义是在Arena.cc中,故暴力直接的解决方案是把这个源文件直接添加到工程目录下的src中。
Solutions
去刚构建protobuf的源代码文件搜索关键字Arena,找到Arena.cc,然后将它Copy至OA-SLAM的src目录下,在OA-SLAM的CMakeLists.txt中add_library末尾添加一行src/Arena.cc然后重新build即可。
......
add_library(
${PROJECT_NAME} SHARED
......src/Arena.cc
)
三、其他问题:运行时g2o报段错误:
New Map Created with 144 points
computeActiveErrors(): found NaN in an error for edge ......等等出现雅可比矩阵中有NaN的现象导致段错误
解决方案
修改CMakeLists.txt,将源CMake脚本的编译选项-march=native去掉即可。原因有可能是和底层内存分配相关,或者G2O/Eigen库不够完善导致的,具体不是很明白,如果有知道的伙伴请不吝赐教!