ORB-SLAM2の環境構築(Ubuntu20.04)

# 0.はじめに
本記事では特徴点ベースの単眼SLAM手法である、ORB-SLAMをUbuntu上で環境構築する方法についてご紹介します。なお、ORB-SLAMそのものの手法解説には主眼を置いておりませんが、参考になるものとして過去に東大の学生さんの[こちら](https://www.slideshare.net/MasayaKaneko/orbslam-84842802)のスライドをあげさせていただきます。ご参考までに。

また、本記事で取り上げる[ORB_SLAM2](https://github.com/raulmur/ORB_SLAM2)について、掲載元のページやその他Qiitaページでも紹介されていますが、それぞれのやり方で様々問題点があり、今回は今現在(2022/9)我々が獲得した方法としてご紹介します。

# 1.実行環境
### PC
|項目|スペック| 
|:---|:-----|
|CPU|Core i7-9750H|
|OS|Ubuntu 20.04LTS|

# 2.必要なもの
Githubページで順を追って見ていくと、いくつか必要になるライブラリがあります。ですが、どれもこれも自分で入れる必要はありません。以下の通りです。

|ライブラリ|自前の導入| 
|:---|:-----|
|Pangolin|必要|
|OpenCV3|必要|
|Eigen3|必要|
|DBoW2|不要|
|g2o|不要|

Readmeにあるとおりですが、下2つは`/Thirdparty`に含まれているので、自分で用意しなくて大丈夫です（他の記事ではこの2つの導入方法を記載していたので明記しました）。

# 3.ライブラリの導入
本体のビルドに際して事前にビルドを済ませるべきライブラリ導入方法を紹介します。
なお、PCのスペックに依存するとは思いますが、構築にかかる全体の所要時間は概ね**4〜5時間**は見積もったほうがいいです。。。
## 3.1.Pangolin
Github上のReadmeに従います。
```
#クローンする
cd ~/(PC上のわかる場所）
git clone --recursive https://github.com/stevenlovegrove/Pangolin.git
cd Pangolin

#依存関係をインストールする
./scripts/install_prerequisites.sh recommended

#ビルドする
cmake -B build
cmake --build build

#テストで動かしてみる(とくにエラーがでなければ成功)
ctest
```

## 3.2.OpenCV3
ORB_SLAM2ではバージョン2.4.3以上が必要と言っています。私はこのあと使おうと思っているROS2のラッパー依存関係の問題で3以上のものを導入しました。

なお、私は以前自分のPCでOpenCVを使ったことがあったのでここを無視して進めたらビルド時に怒られました。。。
理由は簡単で、C++版のOpenCVを導入していなかったようでした。。。

ソースは[こちら](https://opencv.org/releases/)にあります。本記事では3.4.16のビルドを行います。
ダウンロードしてZipを適当な場所で解凍します。

https://qiita.com/modu01/items/6d72a0dfcbfdffee5f15

こちらの記事の導入方法で問題なくできたので、あえてコマンドは記載せず割愛いたします。

## 3.3.Eigen3
Eigenを導入します。C++における行列計算用ライブラリです。
まずは、[公式ページ](https://eigen.tuxfamily.org/index.php?title=Main_Page)に飛び、3.4.0released!と書かれている右のGet itから適当な圧縮ファイルをダウンロードし、適当な場所で解凍します。

```
cd /eigen-3.4.0
mkdir build
cd build
cmake ..
make check
sudo make install
```

なお、Eigenのビルドに私の場合3時間ほどかかりました。
ビルドの最後の方になると、パフォーマンスのテストをするような挙動が見られ、私の場合、1項目を除いて正常と出ました。1項目エラーを出していましたが、このあとのビルドに影響が出なかったので一旦無視します。

# 4.ORB_SLAM2のビルド
一旦適当な場所へクローンします
```
git clone https://github.com/raulmur/ORB_SLAM2.git ORB_SLAM2
cd ORB_SLAM2
```

## 4.1.修正その1
2年前に試された方の言い伝え通り、このままビルドするとエラーが置きます。

https://qiita.com/okubo999/items/6c8b001e79376f594ea3

インクルードを所定のファイルに記載します。
```
~/orb_slam2_ws/ORB_SLAM2/src/LocalMapping.cc
~/orb_slam2_ws/ORB_SLAM2/src/LoopClosing.cc
~/orb_slam2_ws/ORB_SLAM2/src/System.cc
~/orb_slam2_ws/ORB_SLAM2/src/Tracking.cc
~/orb_slam2_ws/ORB_SLAM2/src/Viewer.cc
~/orb_slam2_ws/ORB_SLAM2/Examples/Monocular/mono_euroc.cc
~/orb_slam2_ws/ORB_SLAM2/Examples/Monocular/mono_kitti.cc
~/orb_slam2_ws/ORB_SLAM2/Examples/Monocular/mono_tum.cc
~/orb_slam2_ws/ORB_SLAM2/Examples/RGB-D/rgbd-tum.cc
~/orb_slam2_ws/ORB_SLAM2/Examples/Stereo/stereo_euroc.cc
~/orb_slam2_ws/ORB_SLAM2/Examples/Stereo/stereo_kitti.cc
```
これらの頭に、
```.cc
#include "unistd.h"
```
を追記します。これだけです。

## 4.2.修正その2
修正は続きます。次は、`ORB_SLAM2/CMakeLists.txt`の39行目のEigenに関わる記載を変更します。このままだとエラーが出てしまい、理由としては、EigenがC++17でORB_SLAM2がC++11を利用していることが挙げられます。
```CMakeLists.txt（修正前39行目）
find_package(Eigen3 3.1.0 REQUIRED)
```
を
```CMakeLists.txt（修正後39行目）
find_package(Eigen3 3.1.0 REQUIRED NO_MODULE)
```
に変えてください。

## 4.3.修正その3
最後に`LoopClosing.cc`でなにやら構文で怒られたので、これも修正していきます。
修正箇所は、`ORB_SLAM2/include/LoopClosing.h`の50行目、
```LoopClosing.h（修正前49,50行目）
typedef map<KeyFrame*,g2o::Sim3,std::less<KeyFrame*>,
    Eigen::aligned_allocator<std::pair<const KeyFrame*, g2o::Sim3> > > KeyFrameAndPose;
```
を
```LoopClosing.h（修正後49,50行目）
typedef map<KeyFrame*,g2o::Sim3,std::less<KeyFrame*>,
    Eigen::aligned_allocator<std::pair<KeyFrame* const, g2o::Sim3> > > KeyFrameAndPose;
```
に変えます。

## 4.4.ビルド
これでエラーなくビルドを通せる（はず）です。
```
cd ORB_SLAM2
chmod +x build.sh
./build.sh
```

# 5.サンプルを試す
サンプルはデータセットを利用して画像を読み出し、SLAMを行いビジュアライゼーションするというものになります。
まずは、適当なディレクトリに移り、データをダウンロードします（これにはなかなか時間がかかります）。
```
#どこでもいいのですが今回はDocumentsにいれます
cd Documents
wget https://vision.in.tum.de/rgbd/dataset/freiburg1/rgbd_dataset_freiburg1_xyz.tgz
tar -zxf rgbd_dataset_freiburg1_xyz.tgz
```
解凍が済んだら、
```
cd ORB_SLAM2
./Examples/Monocular/mono_tum Vocabulary/ORBvoc.txt Examples/Monocular/TUM1.yaml $HOME/Documents/rgbd_dataset_freiburg1_xyz
```
を走らせると、

<iframe width="560" height="315" src="https://www.youtube.com/embed/-PWKxXclSao" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

のようになるはずです。いかがでしょうか。。。

# 6.今後
近いうちに成功したら、[ROS2用ラッパー](https://github.com/alsora/ros2-ORB_SLAM2)を使ってウェブカメラやデプスカメラを使用した応用を行い、Qiitaにて紹介できればと思っています。

# 7.参考記事

https://www.slideshare.net/MasayaKaneko/orbslam-84842802

https://github.com/alsora/ros2-ORB_SLAM2

https://github.com/stevenlovegrove/Pangolin

https://opencv.org/releases/

https://qiita.com/modu01/items/6d72a0dfcbfdffee5f15

https://eigen.tuxfamily.org/index.php?title=Main_Page

https://qiita.com/okubo999/items/6c8b001e79376f594ea3

https://github.com/raulmur/ORB_SLAM2/issues/1015

https://github.com/raulmur/ORB_SLAM2/pull/585