SVO下載編譯

參考:

https://blog.csdn.net/seymour163/article/details/53947764
https://blog.csdn.net/u011092188/article/details/77833022
https://blog.csdn.net/weixin_44684139/article/details/104803225
https://blog.csdn.net/weixin_44684139/article/details/105007316
https://blog.csdn.net/weixin_30480651/article/details/95558823

☆https://blog.csdn.net/seymour163/article/details/53947764

還是那句話,不用看參考,來看我。

Semi-direct Visual Odometry(SVO)下載編譯

玩完orbslam,slam學習彷彿進入瓶頸,所以跑幾個開源代碼試一試。這次玩SVO。

1.準備工作

(1)創建工作空間
見這篇博文:https://blog.csdn.net/weixin_44684139/article/details/105258750

只需要看這一段:
在這裏插入圖片描述

創建完工作空間後,在工作空間common_space下/src中新建一個文件夾,名叫SVO。

注意,這個文件夾不僅僅防止SVO的源碼,還有SVO的一系列支持庫也安裝在這裏,會比較方便。

在這裏插入圖片描述

2.安裝依賴庫

接下來進入SVO文件夾。

安裝一系列依賴庫,依據這個鏈接:

https://blog.csdn.net/seymour163/article/details/53947764

值得注意的是,有一個庫比較特殊,叫做vikit,這個是提供一些有用的數學工具。

總結一下依賴庫有:
1 Sophus李羣庫
2 Fast 角點檢測庫
3 g2o - General Graph Optimization (可選)
4 vikit - Some useful tools that we need
5 ROS 依賴項

但是玩了很久slam的人,除了fast檢測和vikit可能其他的都有。

注意事項:

安裝sophus庫的時候,要注意,現在sophus版本迭代的原因,導致新版模板類sophus並不適用於這個SVO的源碼。因此記得回滾:git checkout a621ff,這樣安裝纔是舊版本的非模板類sophus。流程爲:

/home/mjy/dev/common_space/src/SVO在終端打開,命令爲:

git clone https://github.com/strasdat/Sophus.git
cd Sophus
git checkout a621ff
mkdir build
cd build
cmake ..
make
sudo make install 

但是

有的童鞋已經安裝過新版sophus了,想新舊兩版共存,這樣該怎麼辦呢?需要在cmake … 的地方加上安裝路徑CMAKE_INSTALL_PREFIX= ,這個路徑我一般會選擇在/usr/local/底下

流程爲:

git clone https://github.com/strasdat/Sophus.git
cd Sophus
git checkout a621ff
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local/Sophus_not_template ..
make
sudo make install 

3.下載編譯SVO

先克隆下來

cd /home/mjy/dev/common_space/src/SVO
git clone https://github.com/uzh-rpg/rpg_svo.git

會出現一個文件夾rpg_svo

然後向bashrc中加入本ros空間(common_space)的環境變量

打開/.bashrc文件,加入這一行(如果之前加過,比如我在玩上一個orbslam的時候就加過,那就忽略這裏)

source /home/mjy/dev/common_space/devel/setup.sh

然後在終端

$ source ~/.bashrc

最後回到common_space下(工作空間下),編譯一下

catkin_make

就編譯成功了。也有可能編譯不成功。見補充

4.編譯不成功的補充

由於之前新安裝的sophus是單獨自己定義的文件夾,因此源碼並不能找到它。仔細觀察報錯內容,是vikit_common的報錯。

那就讓我們改一下sophus的尋找路徑。

找到文件
/home/mjy/dev/common_space/src/SVO/rpg_vikit/vikit_common/CMakeLists.txt

第二十六行:

# FIND_PACKAGE(Sophus REQUIRED)  先註釋掉這個,因爲直接find是find不到的
set(Sophus_INCLUDE_DIRS "/usr/local/Sophus_not_template/include")
set(Sophus_LIBS "/usr/local/Sophus_not_template/lib/libSophus.so")

第65行左右,加一行:set(Sophus_LIBRARIES libSophus.so) 這個必須加,否則也會報錯

# Create vikit library
set(Sophus_LIBRARIES libSophus.so)
ADD_LIBRARY(${PROJECT_NAME} SHARED ${SOURCEFILES})
TARGET_LINK_LIBRARIES(${PROJECT_NAME}
  ${OpenCV_LIBS}
  ${Sophus_LIBRARIES}
  ${catkin_LIBRARIES})

再找到文件
/home/mjy/dev/common_space/src/SVO/rpg_vikit/vikit_ros/CMakeLists.txt
改動同上面一樣。

然後重新回到common_space下:

cd /home/mjy/dev/common_space
catkin_make

就成功了。

5.測試無g2o版本

下載數據集鏈接:http://rpg.ifi.uzh.ch/datasets/airground_rig_s3_2013-03-18_21-38-48.bag

然後在/home/mjy/dev/common_space/src/SVO/rpg_svo下新建一個Data文件夾存放數據集

在這裏插入圖片描述
然後開啓四個終端:

  1. terminal for roscore
roscore
  1. terminal for roslaunch
roslaunch svo_ros test_rig3.launch
  1. terminal for rviz (robot visualizer)
rosrun rviz rviz -d /home/mjy/dev/common_space/src/SVO/rpg_svo/svo_ros/rviz_config.rviz 
  1. terminal for rosbag
cd /home/mjy/dev/common_space/src/SVO/rpg_svo/Data
rosbag play airground_rig_s3_2013-03-18_21-38-48.bag

測試成功:
在這裏插入圖片描述

6.測試有g2o版本

即,把svo/CmakeLists.txt裏的HAVE_G20設置爲TRUE。
至於如何保證搜索到g2o,我的方法見:https://blog.csdn.net/weixin_44684139/article/details/104876193
也就是添加了g2o/cmake_modules的所在位置並SET( G2O_ROOT /usr/local/include/g2o )

但是可以先不添加,先只改true試一下,要是以後編譯報錯,顯示g2o庫找不到,再回來將svo/CmakeLists.txt中加入合適的set設置

重新編譯:catkin_make

但是報錯:

/home/mjy/dev/common_space/src/SVO/rpg_svo/svo/src/bundle_adjustment.cpp: In function ‘void svo::ba::setupG2o(g2o::SparseOptimizer*)’:
/home/mjy/dev/common_space/src/SVO/rpg_svo/svo/src/bundle_adjustment.cpp:356:76: error: no matching function for call to ‘g2o::BlockSolver<g2o::BlockSolverTraits<6, 3> >::BlockSolver(g2o::BlockSolver<g2o::BlockSolverTraits<6, 3> >::LinearSolverType*&)’
   g2o::BlockSolver_6_3 * solver_ptr = new g2o::BlockSolver_6_3(linearSolver);
                                                                            ^
In file included from /usr/local/include/g2o/core/block_solver.h:199:0,
                 from /home/mjy/dev/common_space/src/SVO/rpg_svo/svo/src/bundle_adjustment.cpp:20:
/usr/local/include/g2o/core/block_solver.hpp:40:1: note: candidate: g2o::BlockSolver<Traits>::BlockSolver(std::unique_ptr<typename Traits::LinearSolverType>) [with Traits = g2o::BlockSolverTraits<6, 3>; typename Traits::LinearSolverType = g2o::LinearSolver<Eigen::Matrix<double, 6, 6> >]
 BlockSolver<Traits>::BlockSolver(std::unique_ptr<LinearSolverType> linearSolver)
 ^
/usr/local/include/g2o/core/block_solver.hpp:40:1: note:   no known conversion for argument 1 from ‘g2o::BlockSolver<g2o::BlockSolverTraits<6, 3> >::LinearSolverType* {aka g2o::LinearSolver<Eigen::Matrix<double, 6, 6> >*}’ to ‘std::unique_ptr<g2o::LinearSolver<Eigen::Matrix<double, 6, 6> >, std::default_delete<g2o::LinearSolver<Eigen::Matrix<double, 6, 6> > > >’
/home/mjy/dev/common_space/src/SVO/rpg_svo/svo/src/bundle_adjustment.cpp:357:100: error: no matching function for call to ‘g2o::OptimizationAlgorithmLevenberg::OptimizationAlgorithmLevenberg(g2o::BlockSolver_6_3*&)’
   g2o::OptimizationAlgorithmLevenberg * solver = new g2o::OptimizationAlgorithmLevenberg(solver_ptr);

這個錯誤太常見了,就是g2o版本迭代導致的問題,使得優化器初始化的時候報錯,因此我將源碼改爲適配新版g2o的形式:

打開文件

/home/mjy/dev/common_space/src/SVO/rpg_svo/svo/src/bundle_adjustment.cpp

將345行開始的setupG2o函數改爲如下版本:

void setupG2o(g2o::SparseOptimizer * optimizer)
{
  // TODO: What's happening with all this HEAP stuff? Memory Leak?
  optimizer->setVerbose(false);

#if SCHUR_TRICK
  // solver
  
  // ---------------------------------------------源代碼報錯,可能是g2o的版本問題

  // g2o::BlockSolver_6_3::LinearSolverType* linearSolver;
  //linearSolver = new g2o::LinearSolverCholmod<g2o::BlockSolver_6_3::PoseMatrixType>();
  // // linearSolver = new g2o::LinearSolverCSparse<g2o::BlockSolver_6_3::PoseMatrixType>();
  //g2o::BlockSolver_6_3 * solver_ptr = new g2o::BlockSolver_6_3(linearSolver);
  // g2o::OptimizationAlgorithmLevenberg * solver = new g2o::OptimizationAlgorithmLevenberg(solver_ptr);
  
  
  typedef g2o::BlockSolver_6_3 BlockSolverType;
  typedef g2o::LinearSolverCholmod<g2o::BlockSolver_6_3::PoseMatrixType> LinearSolverType; // 線性求解器類型
  auto solver = new g2o::OptimizationAlgorithmLevenberg(  // 這裏用高斯牛頓會報錯
    g2o::make_unique<BlockSolverType>(g2o::make_unique<LinearSolverType>()));

  // 更改代碼說明:
  // 我的代碼 == 舊代碼
  // (g2o::make_unique<LinearSolverType>()) == linearSolver
  // solver_ptr == g2o::make_unique<BlockSolverType>(g2o::make_unique<LinearSolverType>())
  
  
#else
//   g2o::BlockSolverX::LinearSolverType * linearSolver;
//   linearSolver = new g2o::LinearSolverCholmod<g2o::BlockSolverX::PoseMatrixType>();
//   //linearSolver = new g2o::LinearSolverCSparse<g2o::BlockSolverX::PoseMatrixType>();
//   g2o::BlockSolverX * solver_ptr = new g2o::BlockSolverX(linearSolver);
//   g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg(solver_ptr);
  
  typedef g2o::BlockSolverX BlockSolverType;
  typedef g2o::LinearSolverDense<BlockSolverType::PoseMatrixType> LinearSolverType; // 線性求解器類型
  auto solver = new g2o::OptimizationAlgorithmLevenberg(  // 這裏用高斯牛頓會報錯
    g2o::make_unique<BlockSolverType>(g2o::make_unique<LinearSolverType>()));
#endif
  
  
    // ---------------------------------------------源代碼報錯,可能是g2o的版本問題


  solver->setMaxTrialsAfterFailure(5);
  optimizer->setAlgorithm(solver);

  // setup camera
  g2o::CameraParameters * cam_params = new g2o::CameraParameters(1.0, Vector2d(0.,0.), 0.);
  cam_params->setId(0);
  if (!optimizer->addParameter(cam_params)) {
    assert(false);
  }
}

修改部分集中在兩條分割線中間 // ---------------------------------------------源代碼報錯,可能是g2o的版本問題

然後再次編譯:
catkin_make
成功

但是

真正測試roslaunch的時候又報錯!!!!!

報錯內容爲:

[svo-1] process has died [pid 28239, exit code -6, cmd /home/mjy/dev/common_space/devel/lib/svo_ros/vo __name:=svo __log:=/home/mjy/.ros/log/0a3287a2-7a83-11ea-b077-d43b0495d50d/svo-1.log].

內存泄漏?!

發現只要g2o打開就報這個錯誤。我一度以爲,還是這個g2o的問題。因此我又對BA文件的setupG2O進行了一次修改,這是另外一種修改方式——unique_ptr問題

下面將我第一版改的代碼註釋掉了。

分界線很清晰

void setupG2o(g2o::SparseOptimizer * optimizer)
{
  // TODO: What's happening with all this HEAP stuff? Memory Leak?
  optimizer->setVerbose(false);

#if SCHUR_TRICK
  // solver
  
  // ---------------------------------------------源代碼報錯,可能是g2o的版本問題

  // g2o::BlockSolver_6_3::LinearSolverType* linearSolver;
  //linearSolver = new g2o::LinearSolverCholmod<g2o::BlockSolver_6_3::PoseMatrixType>();
  // // linearSolver = new g2o::LinearSolverCSparse<g2o::BlockSolver_6_3::PoseMatrixType>();
  //g2o::BlockSolver_6_3 * solver_ptr = new g2o::BlockSolver_6_3(linearSolver);
  // g2o::OptimizationAlgorithmLevenberg * solver = new g2o::OptimizationAlgorithmLevenberg(solver_ptr);
  
  // 原基礎上改的,unique_ptr問題
  
  g2o::BlockSolver_6_3::LinearSolverType* linearSolver;
  linearSolver = new g2o::LinearSolverCholmod<g2o::BlockSolver_6_3::PoseMatrixType>();
  // linearSolver = new g2o::LinearSolverCSparse<g2o::BlockSolver_6_3::PoseMatrixType>();
  g2o::BlockSolver_6_3 * solver_ptr = new g2o::BlockSolver_6_3( std::unique_ptr<g2o::BlockSolver_6_3::LinearSolverType>(linearSolver) );
  g2o::OptimizationAlgorithmLevenberg * solver = new g2o::OptimizationAlgorithmLevenberg(std::unique_ptr<g2o::BlockSolver_6_3>(solver_ptr));
  
  
  // --------------------------------------------我的代碼
//   typedef g2o::BlockSolver_6_3 BlockSolverType;
//   typedef g2o::LinearSolverCholmod<g2o::BlockSolver_6_3::PoseMatrixType> LinearSolverType; // 線性求解器類型
//   auto solver = new g2o::OptimizationAlgorithmLevenberg(  // 這裏用高斯牛頓會報錯
//     g2o::make_unique<BlockSolverType>(g2o::make_unique<LinearSolverType>()));
  // --------------------------------------------我的代碼
  
  // 更改代碼說明:
  // 我的代碼 == 舊代碼
  // (g2o::make_unique<LinearSolverType>()) == linearSolver
  // solver_ptr == g2o::make_unique<BlockSolverType>(g2o::make_unique<LinearSolverType>())
  
  
#else
//   g2o::BlockSolverX::LinearSolverType * linearSolver;
//   linearSolver = new g2o::LinearSolverCholmod<g2o::BlockSolverX::PoseMatrixType>();
//   //linearSolver = new g2o::LinearSolverCSparse<g2o::BlockSolverX::PoseMatrixType>();
//   g2o::BlockSolverX * solver_ptr = new g2o::BlockSolverX(linearSolver);
//   g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg(solver_ptr);
  
  // 原基礎上改的,unique_ptr問題
  g2o::BlockSolverX::LinearSolverType * linearSolver;
  linearSolver = new g2o::LinearSolverCholmod<g2o::BlockSolverX::PoseMatrixType>();
  //linearSolver = new g2o::LinearSolverCSparse<g2o::BlockSolverX::PoseMatrixType>();
  g2o::BlockSolverX * solver_ptr = new g2o::BlockSolverX( std::unique_ptr<g2o::BlockSolverX::LinearSolverType>(linearSolver) );
  g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg(std::unique_ptr<g2o::BlockSolverX>(solver_ptr));
  
  
  
  // --------------------------------------------我的代碼
//   typedef g2o::BlockSolverX BlockSolverType;
//   typedef g2o::LinearSolverDense<BlockSolverType::PoseMatrixType> LinearSolverType; // 線性求解器類型
//   auto solver = new g2o::OptimizationAlgorithmLevenberg(  // 這裏用高斯牛頓會報錯
//     g2o::make_unique<BlockSolverType>(g2o::make_unique<LinearSolverType>()));
  // --------------------------------------------我的代碼
#endif
  
  
    // ---------------------------------------------源代碼報錯,可能是g2o的版本問題


  solver->setMaxTrialsAfterFailure(5);
  optimizer->setAlgorithm(solver);

  // setup camera
  g2o::CameraParameters * cam_params = new g2o::CameraParameters(1.0, Vector2d(0.,0.), 0.);
  cam_params->setId(0);
  if (!optimizer->addParameter(cam_params)) {
    assert(false);
  }
}

但是毫無意外,依然報錯。。。。。。

然後又變更了稀疏求解方式。。。。變更了迭代方式。。。。。

全都報錯

最後放棄,還是不要打開g2o了。。。。。。

我去學C++了。。。。。。。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章