一、ch3学习记录 (8.23)
1、可视化演示
关于运行Pangolin plotTrajectory.cpp,主要参考这个博客
关于Pangolin的下载:
(1)在3rdparty文件夹下面,作者已经给了压缩包
(2)或者自己去git下载
安装和编译在上面的链接了,比较简单不再赘述
关于 plotTrajectory.cpp 的运行:
(1)记得把 plotTrajectory.cpp 中的路径修改一下
string trajectory_file = "../../examples/trajectory.txt";
(2)在examples文件夹下创建一个build文件夹并编译
mkdir build
cd build/
cmake ..
make
./plotTrajectory
(3)结果就是这样:
(4)关于代码,作者没有写注释,我找到这个注释比较详细的博客,可以方便理解
2、显示相机的位姿
直接根据txt文件进行配置,ldconfig的作用这里讲的比较详细,大概就是链接库;我直接ldconfig时显示权限不够,于是使用sudo命令运行来配置。
遇到的问题:make 的时候报错
根据这个博主的解决方法,就是把cmakelist里的c++11改成c++14就好了
set(CMAKE_CXX_FLAGS "-std=c++14")
成功截图如下:
二、Ch4(9.2)
这章学的有点费劲,看书看了快一周,数学基础较差,看李代数的内容有点吃力。。
流程如下:我首先删除example文件包,单独运行useSophus.cpp (记得注释掉cmakelist里的add_subdirectory(example) )
1.首先下载Sophus的安装包,这个博客对这个库有详细的说明还有这个博客也不错
在编译Sophus库时,报错:
查了一下,这个帖子给了解决方法
意思是等号左边应该是一个能赋值的左值,而不是一个函数。所以修改如下:
unit_complex_.real(1.0);
unit_complex_.imag(0.);
再次编译就成功了。
虽然原书说不需要安装,但其实仍然需要?流程如下,不能少了sudo make install
2.cmake功能包ch4时,报错:
将CMakeLists.txt中的
target_link_libraries(useSophus Sophus::Sophus)
改成
target_link_libraries(useSophus ${Sophus_LIBRARIES})
cmake成功
2.make报错 fatal error: sophus/se3.hpp: 没有那个文件或目录
将useSophus.cpp里的
#include "sophus/se3.hpp"
改成
#include "sophus/se3.h"
#include "sophus/so3.h"
3.报错 error: ‘SO3d’ is not a member of ‘Sophus’; did you mean ‘SO3’?
将 SO3d、SE3d全部改成SO3、SE3
再次编译,通过,用./useSophus 进行运行,结果如下:
4.加入example文件包进行编译(不要忘记解开 cmakelist里的add_subdirectory(example)的注释)
make后的报错如下:
/home/wangchen/slamstudy/ch4/example/trajectoryError.cpp:5:10: fatal error: sophus/se3.hpp: 没有那个文件或目录
5 | #include <sophus/se3.hpp>
| ^~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [example/CMakeFiles/trajectoryError.dir/build.make:63:example/CMakeFiles/trajectoryError.dir/trajectoryError.cpp.o] 错误 1
make[1]: *** [CMakeFiles/Makefile2:123:example/CMakeFiles/trajectoryError.dir/all] 错误 2
make: *** [Makefile:84:all] 错误 2
解决方法:如上述2
5.接下来报错
/home/wangchen/slamstudy/ch4/example/trajectoryError.cpp:15:24: error: ‘SE3d’ is not a member of ‘Sophus’; did you mean ‘SE3’?
15 | typedef vector<Sophus::SE3d, Eigen::aligned_allocator<Sophus::SE3d>> TrajectoryType;
解决方法:如上述3
6.接下来报错:
/usr/bin/ld: CMakeFiles/trajectoryError.dir/trajectoryError.cpp.o: in function `main':
trajectoryError.cpp:(.text+0x14a): undefined reference to `Sophus::SE3::SE3(Sophus::SE3 const&)'
/usr/bin/ld: trajectoryError.cpp:(.text+0x178): undefined reference to `Sophus::SE3::SE3(Sophus::SE3 const&)'
/usr/bin/ld: trajectoryError.cpp:(.text+0x191): undefined reference to `Sophus::SE3::inverse() const'
/usr/bin/ld: trajectoryError.cpp:(.text+0x1ae): undefined reference to `Sophus::SE3::operator*(Sophus::SE3 const&) const'
解决方法:报错原因是因为trajectoryError.cpp引用了Sophus库,但是cmakelist没有关联库
加入这两行即可:
编译成功:
7.使用./example/trajectoryError时,报错
trajectory ./example/groundtruth.txt not found.
trajectory ./example/estimated.txt not found.
trajectoryError: /home/wangchen/slamstudy/ch5/example/trajectoryError.cpp:24: int main(int, char**): Assertion `!groundtruth.empty() && !estimated.empty()' failed.
已放弃 (核心已转储)
表示找不到txt,把trajectoryError.cpp中的
string groundtruth_file = "./example/groundtruth.txt";
string estimated_file = "./example/estimated.txt";
改成绝对路径
string groundtruth_file = "/home/wangchen/slamstudy/ch5/example/groundtruth.txt";
string estimated_file = "/home/wangchen/slamstudy/ch5/example/estimated.txt";
就成功了
8.代码的详细解释:这篇博客写的不错
9.关于编译遇到的一些问题这个博客记录了将要踩的大多数坑
三、Ch5 (9.4)
- 安装open3.4费了点时间,由于我安装也是十分混乱的,用了很多博客的方法才成功,所以就不放在这里了。
- 最好是在ch5下面创建build并编译,如果在 imageBasics 文件夹下面创建build文件,那么需要在imageBasics下面的CMakeLists.txt里面加入“找到opencv库、引用头文件“的两句代码。
- 运行 imageBasics.cpp 是没什么问题的,唯一需要注意的是,显示png的命令:
(1) 根据原书的方法,在ch5文件夹下面运行:
build/imageBasics/imageBasics imageBasics/ubuntu.png
意思为:运行 build/imageBasics中的imageBasics可执行文件 ,后面接了一个图片的路径
(2)另一种方法:进入ch5/build/imageBasics下面,
然后执行:
./imageBasics /home/wangchen/slamstudy/ch5/imageBasics/ubuntu.png
4.RGB-D的代码,需要更改的是
(1) 需要在rgb文件夹下面的cmakelist,增加一个${Sophus_LIBRARIES},否则会报错。是我用这个博客的cmakelist内容发现的
target_link_libraries(joinMap ${OpenCV_LIBS} ${Pangolin_LIBRARIES} ${Sophus_LIBRARIES} )
报错这个:加上Sophus的链接库就好了
/usr/bin/ld: CMakeFiles/joinMap.dir/joinMap.cpp.o: in function `void std::vector<Sophus::SE3, Eigen::aligned_allocator<Sophus::SE3> >::_M_realloc_insert<Sophus::SE3 const&>(__gnu_cxx::__normal_iterator<Sophus::SE3*, std::vector<Sophus::SE3, Eigen::aligned_allocator<Sophus::SE3> > >, Sophus::SE3 const&)':
joinMap.cpp:(.text._ZNSt6vectorIN6Sophus3SE3EN5Eigen17aligned_allocatorIS1_EEE17_M_realloc_insertIJRKS1_EEEvN9__gnu_cxx17__normal_iteratorIPS1_S5_EEDpOT_[_ZNSt6vectorIN6Sophus3SE3EN5Eigen17aligned_allocatorIS1_EEE17_M_realloc_insertIJRKS1_EEEvN9__gnu_cxx17__normal_iteratorIPS1_S5_EEDpOT_]+0x94): undefined reference to `Sophus::SE3::SE3(Sophus::SE3 const&)'
/usr/bin/ld: joinMap.cpp:(.text._ZNSt6vectorIN6Sophus3SE3EN5Eigen17aligned_allocatorIS1_EEE17_M_realloc_insertIJRKS1_EEEvN9__gnu_cxx17__normal_iteratorIPS1_S5_EEDpOT_[_ZNSt6vectorIN6Sophus3SE3EN5Eigen17aligned_allocatorIS1_EEE17_M_realloc_insertIJRKS1_EEEvN9__gnu_cxx17__normal_iteratorIPS1_S5_EEDpOT_]+0xc7): undefined reference to `Sophus::SE3::SE3(Sophus::SE3 const&)'
/usr/bin/ld: joinMap.cpp:(.text._ZNSt6vectorIN6Sophus3SE3EN5Eigen17aligned_allocatorIS1_EEE17_M_realloc_insertIJRKS1_EEEvN9__gnu_cxx17__normal_iteratorIPS1_S5_EEDpOT_[_ZNSt6vectorIN6Sophus3SE3EN5Eigen17aligned_allocatorIS1_EEE17_M_realloc_insertIJRKS1_EEEvN9__gnu_cxx17__normal_iteratorIPS1_S5_EEDpOT_]+0x12c): undefined reference to `Sophus::SE3::SE3(Sophus::SE3 const&)'
/usr/bin/ld: joinMap.cpp:(.text._ZNSt6vectorIN6Sophus3SE3EN5Eigen17aligned_allocatorIS1_EEE17_M_realloc_insertIJRKS1_EEEvN9__gnu_cxx17__normal_iteratorIPS1_S5_EEDpOT_[_ZNSt6vectorIN6Sophus3SE3EN5Eigen17aligned_allocatorIS1_EEE17_M_realloc_insertIJRKS1_EEEvN9__gnu_cxx17__normal_iteratorIPS1_S5_EEDpOT_]+0x157): undefined reference to `Sophus::SE3::SE3(Sophus::SE3 const&)'
/usr/bin/ld: CMakeFiles/joinMap.dir/joinMap.cpp.o: in function `main':
joinMap.cpp:(.text.startup+0x93f): undefined reference to `Sophus::SE3::SE3(Eigen::Quaternion<double, 0> const&, Eigen::Matrix<double, 3, 1, 0, 3, 1> const&)'
/usr/bin/ld: joinMap.cpp:(.text.startup+0x95d): undefined reference to `Sophus::SE3::SE3(Sophus::SE3 const&)'
/usr/bin/ld: joinMap.cpp:(.text.startup+0xbae): undefined reference to `Sophus::SE3::SE3(Sophus::SE3 const&)'
/usr/bin/ld: joinMap.cpp:(.text.startup+0xc7e): undefined reference to `Sophus::SE3::operator*(Eigen::Matrix<double, 3, 1, 0, 3, 1> const&) const'
collect2: error: ld returned 1 exit status
make[2]: *** [rgbd/CMakeFiles/joinMap.dir/build.make:150:rgbd/joinMap] 错误 1
make[1]: *** [CMakeFiles/Makefile2:219:rgbd/CMakeFiles/joinMap.dir/all] 错误 2
make: *** [Makefile:84:all] 错误 2
(2)运行./rgbd/joinMap的时候,报错
[ WARN:0@0.002] imread_('.//home/wangchen/slamstudy/ch5/rgbd/color/1.png'): can't open/read file: check file path/integrity
[ WARN:0@0.002] imread_('.//home/wangchen/slamstudy/ch5/rgbd/depth/1.pgm'): can't open/read file: check file path/integrity
[ WARN:0@0.002] imread_('.//home/wangchen/slamstudy/ch5/rgbd/color/2.png'): can't open/read file: check file path/integrity
[ WARN:0@0.002] imread_('.//home/wangchen/slamstudy/ch5/rgbd/depth/2.pgm'): can't open/read file: check file path/integrity
[ WARN:0@0.002] imread_('.//home/wangchen/slamstudy/ch5/rgbd/color/3.png'): can't open/read file: check file path/integrity
[ WARN:0@0.002] imread_('.//home/wangchen/slamstudy/ch5/rgbd/depth/3.pgm'): can't open/read file: check file path/integrity
[ WARN:0@0.002] imread_('.//home/wangchen/slamstudy/ch5/rgbd/color/4.png'): can't open/read file: check file path/integrity
[ WARN:0@0.003] imread_('.//home/wangchen/slamstudy/ch5/rgbd/depth/4.pgm'): can't open/read file: check file path/integrity
[ WARN:0@0.003] imread_('.//home/wangchen/slamstudy/ch5/rgbd/color/5.png'): can't open/read file: check file path/integrity
[ WARN:0@0.003] imread_('.//home/wangchen/slamstudy/ch5/rgbd/depth/5.pgm'): can't open/read file: check file path/integrity
转换图像中: 1
转换图像中: 2
转换图像中: 3
转换图像中: 4
转换图像中: 5
点云共有0个点.
Point cloud is empty!
经过几次尝试之后,将joinMap.cpp中的
boost::format fmt("./%s/%d.%s"); //图像文件格式
修改成
boost::format fmt("/home/wangchen/slamstudy/ch5/rgbd/%s/%d.%s"); //图像文件格式
就ok了
5.一些详细解释:
(1)读取图片及像素操作
imageBasics.cpp 详解
(2)双目图片->点云
stereoSGBM的函数和参数说明、注释比较全面;
这个注释也还行;
这个讲了一些基本原理。
(3)RGBD图片点云拼接
这个函数,主要是直接通过相机的位姿+深度图(直接获得每个像素点的深度信息)来获得点云的世界坐标,同时通过颜色图获得点云的颜色。
四、Ch6
这张数学比较多,需要看较长时间,所以先跳过
五、Ch7
1.编译orb_cv、orb_self.cpp,在cmake时报错:
CMake Error at CMakeLists.txt:10 (find_package):
By not providing "FindG2O.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "G2O", but
CMake did not find one.
Could not find a package configuration file provided by "G2O" with any of
the following names:
G2OConfig.cmake
g2o-config.cmake
Add the installation prefix of "G2O" to CMAKE_PREFIX_PATH or set "G2O_DIR"
to a directory containing one of the above files. If "G2O" provides a
separate development package or SDK, be sure it has been installed.
-- Configuring incomplete, errors occurred!
See also "/home/wangchen/slamstudy/ch7/build/CMakeFiles/CMakeOutput.log".
于是下载并安装了G20的库,但还是报错,解决方法:
在ch7下面的cmakelist里添加,list里面的路径是下载的g2o下面的cmake_modules文件夹的路径
set(G2O_ROOT /usr/local/include/g2o)
list( APPEND CMAKE_MODULE_PATH /home/wangchen/下载/g2o/cmake_modules )
编译后,在ch7文件夹下面使用命令
build/orb_self 1.png 2.png
PS:这里写一下cmakelist多行注释的方法:
开头 #[[
结尾是 ]]
2.编译 pose_estimation_3d2d.cpp 和 pose_estimation_3d3d.cpp 报错:
In file included from /usr/local/include/g2o/core/base_unary_edge.h:30,
from /home/wangchen/slamstudy/ch7/pose_estimation_3d3d.cpp:10:
/usr/local/include/g2o/core/base_fixed_sized_edge.h:39:10: fatal error: ceres/internal/fixed_array.h: 没有那个文件或目录
39 | #include <ceres/internal/fixed_array.h>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [CMakeFiles/pose_estimation_3d3d.dir/build.make:63:CMakeFiles/pose_estimation_3d3d.dir/pose_estimation_3d3d.cpp.o] 错误 1
make[1]: *** [CMakeFiles/Makefile2:138:CMakeFiles/pose_estimation_3d3d.dir/all] 错误 2
make: *** [Makefile:84:all] 错误 2
解决方法:安装ceres库
3.接下来报错:
In file included from /usr/local/include/g2o/core/base_unary_edge.h:30,
from /home/wangchen/slamstudy/ch7/pose_estimation_3d3d.cpp:10:
/usr/local/include/g2o/core/base_fixed_sized_edge.h:200:32: error: ‘index_sequence’ is not a member of ‘std’
200 | struct HessianTupleType<std::index_sequence<Ints...>> {
| ^~~~~~~~~~~~~~
/usr/local/include/g2o/core/base_fixed_sized_edge.h:200:32: error: ‘index_sequence’ is not a member of ‘std’
/usr/local/include/g2o/core/base_fixed_sized_edge.h:200:51: error: expected parameter pack before ‘...’
200 | struct HessianTupleType<std::index_sequence<Ints...>> {
| ^~~
/usr/local/include/g2o/core/base_fixed_sized_edge.h:200:51: error: template argument 1 is invalid
/usr/local/include/g2o/core/base_fixed_sized_edge.h:200:54: error: expected unqualified-id before ‘>’ token
200 | struct HessianTupleType<std::index_sequence<Ints...>> {
| ^~
解决方法:error: ‘index_sequence’,修改cmakelist里的
set(CMAKE_CXX_FLAGS "-std=c++11 -O2 ${SSE_FLAGS} -msse4")
改成
set(CMAKE_CXX_FLAGS "-std=c++14 -O2 ${SSE_FLAGS} -msse4")
4.报错#include <cs.h>
In file included from /usr/local/include/g2o/solvers/csparse/csparse_helper.h:30,
from /usr/local/include/g2o/solvers/csparse/linear_solver_csparse.h:32,
from /home/wangchen/slamstudy/ch7/pose_estimation_3d2d.cpp:12:
/usr/local/include/g2o/solvers/csparse/csparse_extension.h:27:10: fatal error: cs.h: 没有那个文件或目录
27 | #include <cs.h>
| ^~~~~~
compilation terminated.
make[2]: *** [CMakeFiles/pose_estimation_3d2d.dir/build.make:63:CMakeFiles/pose_estimation_3d2d.dir/pose_estimation_3d2d.cpp.o] 错误 1
make[1]: *** [CMakeFiles/Makefile2:84:CMakeFiles/pose_estimation_3d2d.dir/all] 错误 2
make: *** [Makefile:84:all] 错误 2
参考了这篇文章的解决方法,在cmakelist里添加了一些内容
find_package( CSparse)
include_directories(
${OpenCV_INCLUDE_DIRS}
${G2O_INCLUDE_DIRS}
${Sophus_INCLUDE_DIRS}
"/usr/include/eigen3/"
${CSPARSE_INCLUDE_DIR}
add_executable(pose_estimation_3d2d pose_estimation_3d2d.cpp)
target_link_libraries(pose_estimation_3d2d
g2o_core g2o_stuff
${OpenCV_LIBS}
${CSPARSE_LIB}
)
结果如下:
5.报错:
[ 80%] Linking CXX executable orb_self
In file included from /usr/local/include/g2o/core/base_unary_edge.h:30,
from /home/wangchen/slamstudy/ch7/pose_estimation_3d2d.cpp:9:
/usr/local/include/g2o/core/base_fixed_sized_edge.h:200:32: error: ‘index_sequence’ is not a member of ‘std’
200 | struct HessianTupleType<std::index_sequence<Ints...>> {
| ^~~~~~~~~~~~~~
/usr/local/include/g2o/core/base_fixed_sized_edge.h:200:32: error: ‘index_sequence’ is not a member of ‘std’
/usr/local/include/g2o/core/base_fixed_sized_edge.h:200:51: error: expected parameter pack before ‘...’
200 | struct HessianTupleType<std::index_sequence<Ints...>> {
| ^~~
/usr/local/include/g2o/core/base_fixed_sized_edge.h:200:51: error: template argument 1 is invalid
/usr/local/include/g2o/core/base_fixed_sized_edge.h:200:54: error: expected unqualified-id before ‘>’ token
200 | struct HessianTupleType<std::index_sequence<Ints...>> {
| ^~
/usr/local/include/g2o/core/base_fixed_sized_edge.h:208:12: error: ‘make_index_sequence’ is not a member of ‘std’
208 | std::make_index_sequence<_nr_of_vertex_pairs>>::type;
| ^~~~~~~~~~~~~~~~~~~
/usr/local/include/g2o/core/base_fixed_sized_edge.h:208:12: error: ‘make_index_sequence’ is not a member of ‘std’
/usr/local/include/g2o/core/base_fixed_sized_edge.h:208:32: error: template argument 1 is invalid
解决方法:标准不匹配
,添加:
set(CMAKE_CXX_STANDARD 14)
6.报错:
/usr/local/include/g2o/core/base_fixed_sized_edge.hpp:251:57: error: ‘_hessianTuple’ was not declared in this scope; did you mean ‘HessianTupleType’?
251 | tuple_apply_i(MapHessianMemoryK{d, vi_dim, vj_dim}, _hessianTuple, k);
| ^~~~~~~~~~~~~
| HessianTupleType
[ 90%] Built target triangulation
/home/wangchen/slamstudy/ch7/pose_estimation_3d2d.cpp: In function ‘void bundleAdjustment(std::vector<cv::Point3_<float> >, std::vector<cv::Point_<float> >, const cv::Mat&, cv::Mat&, cv::Mat&)’:
/home/wangchen/slamstudy/ch7/pose_estimation_3d2d.cpp:151:50: error: no matching function for call to ‘g2o::BlockSolver<g2o::BlockSolverTraits<6, 3> >::BlockSolver(g2o::BlockSolver<g2o::BlockSolverTraits<6, 3> >::LinearSolverType*&)’
151 | Block* solver_ptr = new Block ( linearSolver ); // 矩阵块求解器
| ^
解决方法:借鉴这篇
将pose_estimation_3d2d.cpp里的这段修改以下就行
// 初始化g2o
typedef g2o::BlockSolver< g2o::BlockSolverTraits<6,3> > Block; // pose 维度为 6, landmark 维度为 3
Block::LinearSolverType* linearSolver = new g2o::LinearSolverCSparse<Block::PoseMatrixType>(); // 线性方程求解器
Block* solver_ptr = new Block (std::unique_ptr<Block::LinearSolverType>(linearSolver)); // 矩阵块求解器
g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg(std::unique_ptr<Block>(solver_ptr));
g2o::SparseOptimizer optimizer;
optimizer.setAlgorithm ( solver );
7.报错:
home/wangchen/slamstudy/ch7/pose_estimation_3d2d.cpp:173:14: error: ‘VertexSBAPointXYZ’ is not a member of ‘g2o’; did you mean ‘VertexPointXYZ’?
173 | g2o::VertexSBAPointXYZ* point = new g2o::VertexSBAPointXYZ();
| ^~~~~~~~~~~~~~~~~
| VertexPointXYZ
/home/wangchen/slamstudy/ch7/pose_estimation_3d2d.cpp:173:33: error: ‘point’ was not declared in this scope
173 | g2o::VertexSBAPointXYZ* point = new g2o::VertexSBAPointXYZ();
| ^~~~~
将cpp里对应的VertexSBAPointXYZ全部改成VertexPointXYZ。原因是,作者使用的g20的版本比较老。