"逆转鹈鹕”
以下是本人在学习SLAM中遇到的全部问题汇总(主要是依赖和软件方面的)。
0. 视觉SLAM十四讲
1. ch3-------Eigen3
- 测试EIGEN3中错误,没有eigen3这个库,如下方法解决:
上github或者gitee找EIGEN3的源码包拉下来编译安装即可,正常的构建build/, cmake, 然后再make 即可
- ch3,测试EIGEN3中错误“Could NOT find OpenGL (missing: OPENGL_opengl_LIBRARY OPENGL_glx_LIBRARY”,这主要是缺少opengl库,解决方法如下
sudo apt-get install libgl1-mesa-dev
- ch3,测试EIGEN3中的错误"Could not find GLEW",解决方法如下:
sudo apt-get install libglew
- ch3,测试EIGEN3中出现警告"Policy CMP0072 is not set: FindOpenGL prefers GLVND by default when
available",打开cmake的CMakeLists.txt文件,加入如下代码:
if (POLICY CMP0072)
set(OpenGL_GL_PREFERENCE LEGACY)
endif()
- ch3,测试ch3的时候发现有问题找不到<Eigen/Core>或者之类的,这是因为我们的安装是<eigen3/Eigen/Core>找到即可。
#include <eigen3/Eigen/Core>
#include <eigen3/Eigen/Dense>
其他包也一样
- 可视化程序Pangolin,直接源码安装即可。
2. ch4-------Sophus
- 在Sophus
cmake ..
过程结束后的make
过程中出现:
error: lvalue required as left operand of assignment
32 | unit_complex_.real() = 1.;
| ~~~~~~~~~~~~~~~~~~^~
/home/s/Myself/tool_learn_pkgs/Sophus/sophus/so2.cpp:33:21: error: lvalue required as left operand of assignment
33 | unit_complex_.imag() = 0.;
- 解决:打开 Sophus/sophus/so2.cpp,在30–35行,如下图
改为:
SO2::SO2()
{
unit_complex_.real() = 1.;
unit_complex_.imag() = 0.;
}
重新cmake-make即可。
- make程序的时候出现
std::make_unsigned<int>::type fmt::v8::detail::to_unsigned<int>(int)
,这是因为sophus库依赖FMT,得装一个这个
git clone https://github.com/fmtlib/fmt.git
cd fmt
mkdir build
cd build
cmake ..
make
sudo make install
然后加入到程序(CMakeLists.txt)中(就最后一个FMT link到我们的库中就行):
target_link_libraries( useSophus ${Sophus_LIBRARIES} fmt)
2. ch5-------JoinMap
- 如果你没装pcl 和 boost库, 会cmake提示找不到,一种简单的安装方法如下::
sudo apt-get install libboost-all-dev #装boost
sudo apt-get install libpcl-dev pcl-tools #装pcl,它会自动装vtk哦,在usr/include/下
重新cmake-make即可。(我这里是VTK9.1.0 和 PCL1.12.1)
- 在完成1后,make可能报错
error: #error PCL requires C++14 or above
,这个也比较简单,找到你正在cmake的哪个CMakeList.txt文件,将开头(可能是第5行)
set( CMAKE_CXX_FLAGS "-std=c++11 -O3" )
改为:
set( CMAKE_CXX_FLAGS "-std=c++14 -O3" )
因为我的是C++14,你也可以直接删掉
重新cmake-make即可。
3. ch6
3.1 — ceres
- 源码安装ceres,cmake …报错
Can't find Google Log. Please set GLOG_INCLUDE_DIR & GLOG_LIBRARY or enable MINIGLOG option to use minimal glog implementation.
, 解决,查看报错信息缺少项并安装,全部如下:
sudo apt-get install libcxsparse3 libsuitesparse-dev libgoogle-glog-dev libgtest-dev
- cmake结束以后
make
又会报错,这个时候大概率报错信息如下:
In file included from /usr/local/include/eigen3/Eigen/Core:348:0,
from /home/ubuntu/cartographer/ceres-solver-1.11.0/include/ceres/jet.h:165,
from /home/ubuntu/cartographer/ceres-solver-1.11.0/internal/ceres/jet_test.cc:31:
/usr/local/include/eigen3/Eigen/src/Core/util/XprHelper.h: In instantiation of ‘struct Eigen::internal::promote_scalar_arg<ceres::Jet<double, 2>, Eigen::Matrix<ceres::Jet<double, 2>, 2, 2>, false>’:
/usr/local/include/eigen3/Eigen/src/plugins/CommonCwiseBinaryOps.h:50:1: required by substitution of ‘template<class T> typename Eigen::internal::enable_if<true, const Eigen::CwiseBinaryOp<Eigen::internal::scalar_product_op<typename Eigen::internal::promote_scalar_arg<ceres::Jet<double, 2>, T, Eigen::internal::has_ReturnType<Eigen::ScalarBinaryOpTraits<T, ceres::Jet<double, 2>, Eigen::internal::scalar_product_op<T, ceres::Jet<double, 2> > > >::val
这是由于eigen版本和ceres版本不匹配,要么降级eigen版本(不推荐),要么自己下载最新ceres就可通过(推荐),运行如下代码:
git clone https://github.com/ceres-solver/ceres-solver.git
- 运行代码
cmake
报错
error: ‘ParameterBlockIndices’ was not declared in this scope
78 | functor, input, output, IsDynamic(), ParameterBlockIndices());
| ~~~~~~~~~~~~~~~~~~~~~^~
make[2]: *** [CMakeFiles/curve_fitting.dir/build.make:76: CMakeFiles/curve_fitting.dir/main.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/curve_fitting.dir/all] Error 2
运行make,报错
/usr/local/include/ceres/product_manifold.h:315:59: error: expected constructor, destructor, or type conversion before ‘;’ token
315 | -> ProductManifold<Manifold0, Manifold1, Manifolds...>;
仔细检查,是CMakeLists.txt的C++版本问题,我指定的C++11但是电脑已经是c++17了,所以改成17就好,如下
set( CMAKE_CXX_FLAGS "-std=c++17 -O3" )
3.2 — g2o
- 和3.1一样的版本会有问题,这边建议先装新的
git clone https://github.com/RainerKuemmerle/g2o.git
- cmake的过程中一定要仔细查看
could not found xxx
,缺少什么就装什么,直到不报错为止,比如缺少xxx,就安装libxxx,如下
sudo apt-get install libqglviewer-dev-qt5
- 在装完新版本后,会报错如下
rom /home/s/Myself/Prj/SLAM/SLAM14_Course/ch6/g2o_curve_fitting/main.cpp:3:
/usr/local/include/g2o/stuff/tuple_tools.h: In function ‘void g2o::tuple_apply_i(F&&, T&, int)’:
/usr/local/include/g2o/stuff/tuple_tools.h:45:35: error: ‘tuple_size_v’ is not a member of ‘std’
45 | std::make_index_sequence<std::tuple_size_v<std::decay_t<T>>>());
可能我们需要改代码了,首先确定cmakelist.txt中的C++版本,然后修改代码如下(注释中是修改之前),没注释是修改之后
// 构建图优化,先设定g2o
typedef g2o::BlockSolver< g2o::BlockSolverTraits<3,1> > Block; // 每个误差项优化变量维度为3,误差值维度为1
// Block::LinearSolverType* linearSolver = new g2o::LinearSolverDense<Block::PoseMatrixType>(); // 线性方程求解器
std::unique_ptr<Block::LinearSolverType> linearSolver ( new g2o::LinearSolverDense<Block::PoseMatrixType>()); // Block* solver_ptr = new Block( linearSolver ); // 矩阵块求解器
std::unique_ptr<Block> solver_ptr ( new Block ( std::move(linearSolver)));
// 梯度下降方法,从GN, LM, DogLeg 中选
g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg ( std::move(solver_ptr));
// g2o::OptimizationAlgorithmGaussNewton* solver = new g2o::OptimizationAlgorithmGaussNewton( solver_ptr );
// g2o::OptimizationAlgorithmDogleg* solver = new g2o::OptimizationAlgorithmDogleg( solver_ptr );
g2o::SparseOptimizer optimizer; // 图模型
optimizer.setAlgorithm( solver ); // 设置求解器
optimizer.setVerbose( true ); // 打开调试输出
- 以上做完,编译到100%后会报错如下:
/usr/bin/ld: CMakeFiles/curve_fitting.dir/main.cpp.o: undefined reference to symbol '_ZN3fmt2v86detail18throw_format_errorEPKc'
/usr/bin/ld: /lib/x86_64-linux-gnu/libfmt.so.8: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/curve_fitting.dir/build.make:112: curve_fitting] Error 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/curve_fitting.dir/all] Error 2
很简单,没有连接fmt库,修改cmakelist.txt文件,在target_link_libraries
中链接一下fmt就行
target_link_libraries( curve_fitting
${OpenCV_LIBS}
g2o_core g2o_stuff
fmt
)
4. ch7–视觉里程计
- cmake过程中报警告
CMake Warning (dev) at /usr/share/cmake-3.22/Modules/FindPackageHandleStandardArgs.cmake:438 (message): The package name passed to `find_package_handle_standard_args` (CSPARSE) does not match the name of the calling package (CSparse). This can lead to problems in calling code that expects `find_package` result variables (e.g., `_FOUND`) to follow a certain pattern. Call Stack (most recent call first): cmake_modules/FindCSparse.cmake:24 (find_package_handle_standard_args) CMakeLists.txt:13 (find_package) This warning is for project developers. Use -Wno-dev to suppress it.
,具体就是find.cmake这个子模块文件中的名称和CMakeList.txt中的文件不对应,打开/cmake_modules下的FindCSparse.cmake文件,将最后一行
find_package_handle_standard_args(CSPARSE DEFAULT_MSG
CSPARSE_INCLUDE_DIR CSPARSE_LIBRARY)
改为
find_package_handle_standard_args(CSparse DEFAULT_MSG
CSPARSE_INCLUDE_DIR CSPARSE_LIBRARY)
即可。
- make报错
SLAM14_Course/ch7/feature_extraction.cpp:17:35: error: ‘CV_LOAD_IMAGE_COLOR’ was not declared in this scope 17 | Mat img_1 = imread ( argv[1], CV_LOAD_IMAGE_COLOR );
,这是opencv3中的,现在用了opencv4已经没有了,添加如下头文件即可
#include <opencv2/imgcodecs/legacy/constants_c.h>
或者在C++14中取消了这种写法,改为如下:
IMREAD_COLOR //而不是CV_LOAD_IMAGE_COLOR
- make报错
SLAM14_Course/ch7/pose_estimation_2d2d.cpp:155:65: error: ‘CV_FM_8POINT’ was not declared in this scope 155 | fundamental_matrix = findFundamentalMat ( points1, points2, CV_FM_8POINT );
还是版本问题,将对应代码中
CV_FM_8POINT
更改为
FM_8POINT
即可。
5.–ch8 associate.py
执行
python associate.py rgb.txt depth.txt > associate.txt
对齐数据时,报错如下
File "associate.py", line 96, in associate
first_keys.remove(a)
AttributeError: 'dict_keys' object has no attribute 'remove'
错误原因是python版本过高,需要将文件中第86行的两行程序删除,由
first_keys = first_list.keys()
second_keys = second_list.keys()
改为
first_keys = list(first_list)
second_keys = list(second_list)
6.–ch9 project
- 关于提示没有
VIZ
可视化模块的报错,我是Opencv4.7
- 首先这个模块在cmake的时候,需要手动指定才会编译;
- 其次,源码编译需要取opencv4.7的源码下查看是否有viz这个文件夹,是在
module
文件夹下,如果显示没有,则需要自己去gitxxx上找包,我找的opencv-contrib下载下来,把这里边的vis
文件夹复制到opencv下就行了。
最后,重新编译opencv(会自动更新因此不用卸载):
cmake -DWITH_VTK=ON ..
后边的和以前一样
- opencv的图像窗口持续,但是VIS窗口一闪而过:
将
vis.spinOnce(1, false);
改成
vis.spinOnce(1, true);
即可,自己点进去看参数解释就好