Jetson nanoにROSを導入をしてRealSenseD435iで物体認識を行おう！

# 本記事の目的
Jetson nanoのセットアップ(その他関連事項)とROSの導入を行い、D435iとYOLO V3を用いて物体検出までを行います。

# 環境
本記事は以下の環境で実験しています。

| 項目 | バージョン |
|:-:|:-:|
| Ubuntu | 18.04 |
| ROS | Melodic |
| IntelRealsense | D435i |

# Jetson nanoの導入

jetson nanoを動かすには以下の物が必要になります。

- [Jetson nano 4GB](https://www.amazon.co.jp/NVIDIA-Jetson-Nano-Development-Kit/dp/B085NQTKS9/ref=sr_1_1_sspa?dchild=1&keywords=jetson+nano&qid=1619190240&s=computers&sr=1-1-spons&psc=1&smid=A3A9CLKQ7Y9T2V&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUFWRzRaM0pWRkwwWlEmZW5jcnlwdGVkSWQ9QTA4MDM3MTYzUVY2RjRaQU1SS0JIJmVuY3J5cHRlZEFkSWQ9QTFONEJNVEFYWjAzSjYmd2lkZ2V0TmFtZT1zcF9hdGYmYWN0aW9uPWNsaWNrUmVkaXJlY3QmZG9Ob3RMb2dDbGljaz10cnVl)
- [電源(5V 4A)](https://www.amazon.co.jp/-/en/Certified-Adapter-Security-External-Wireless/dp/B07TY3HGLP/ref=sr_1_5?dchild=1&keywords=5V+4A&qid=1619190067&s=electronics&sr=1-5)
- [MicroSDカード](https://www.amazon.co.jp/-/en/Nintendo-Manufacturers-Operation-Confirmed-SDSQUA4-128G-EPK/dp/B08K41Q79R/ref=sr_1_5?dchild=1&keywords=SD%E3%82%AB%E3%83%BC%E3%83%89&qid=1619190101&s=computers&sr=1-5)
- HDMIモニター
- HDMIケーブル
- キーボード＆マウス
- [wifiドングル](https://www.amazon.co.jp/gp/product/B008IFXQFU/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1)

電源については最低でも3A以上必要です。Jetson nano 4GBではMicro USBコネクターから5V電源を供給することが出来ます。私はリモートで動作させたかったので5V 3Aの[モバイルバッテリー](https://www.amazon.co.jp/dp/B07YRK5BCF?tag=homemadegarba-22&linkCode=ogi&th=1&psc=1)を購入しました。

![S__18948099](https://user-images.githubusercontent.com/52307432/115889567-040a6200-a48f-11eb-9612-44afcdecb61e.jpg)

Jetson nano 4GBではACアダプターからもMicro USBコネクターからも5V電源供給を行えますが、注意点があります。

### ACアダプターを使用する場合

Jetson nanoのJ48ヘッダーに付属のジャンパーピンでショートさせる事で、J25電源ジャックにACアダプターを接続して起動する事が出来ます。

![S__18948100](https://user-images.githubusercontent.com/52307432/115893080-c7406a00-a492-11eb-8ebd-045e4ff15dc5.jpg)

### Micro USBを使用する場合

Jetson nanoのJ48ヘッダーに取り付けたジャンパーピンを取り外し、Micro USBにモバイルバッテリーを接続して起動する事が出来ます。

![S__18948102](https://user-images.githubusercontent.com/52307432/115893489-33bb6900-a493-11eb-87c2-4fb7917dd7de.jpg)

# ブートイメージをつくる

基本的には以下のサイトに沿って進めれば問題なくブートイメージの作成と初期セットアップは出来ます。

https://digital-light.jp/2019/04/28/how-to-set-up-nvidia-jetson-nano/

# ROSの導入

以下のサイトを見ながらROSのインストールを行いましょう。
http://wiki.ros.org/melodic/Installation/Ubuntu

サイト内で必要なコマンドのみここでは抜粋しました。基本的にはこの通りターミナルに打っていけばインストール出来ます。

```bash
$ sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
$ sudo apt-get install curl
$ curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -
$ sudo apt update
$ sudo apt install ros-melodic-desktop-full
$ echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc
$ source ~/.bashrc
$ source /opt/ros/melodic/setup.bash
$ sudo apt install python-rosdep python-rosinstall python-rosinstall-generator python-wstool build-essential
$ sudo apt install python-rosdep
$ rosdep update
$ sudo rosdep init
```

もしくはシェルスクリプトを作成して一括でインストールすると良いと思います。からあげ先生がmelodic用のシェルスクリプトを作成してくれているのでこちらを利用するのが速いかもしれません。

https://github.com/karaage0703/jetson-nano-tools/blob/master/install-ros-melodic.sh

## ROSの動作確認
以下のコマンドを順に打ってROSの動作確認を行ってみましょう

- Step1  
ros masterを起動します

```
roscore
```

- Step2  
別のターミナルを開いて以下を実行します

```
rosrun turtlesim turtlesim_node
```
- Step3  
更に別のターミナルを開いて以下を実行します

```
rosrun turtlesim turtle_teleop_key
```

テンキーで適当に動かせれば動作確認は完了です！

# Intel RealSense SDKのインストール
以下のサイトと同様にSDKを導入したのですが、なぜか**sudo apt-get install librealsense2-dkms**が上手くインストール出来ませんでした。

https://qiita.com/MMM-lab/items/5614e2cd2e525e6d6286

そこでJetson nanoでRealSenseを動かすためのSDKとROSを一括でインストール出来る以下のパッケージを見つけたので、こちらを導入します。

https://www.youtube.com/watch?v=eSAsLAzYzm4

https://github.com/JetsonHacksNano/installRealSenseROS

以下の手順で上記パッケージを導入します

```
$ cd ~/
$ git clone https://github.com/JetsonHacksNano/installRealSenseROS.git
```
```
$ cd installRealSenseROS/
$ ./installRealSenseROS.sh 
```

上記のコマンドを実行した事で、無事インストールする事が出来ました。~~結局**sudo apt-get install librealsense2-dkms**でエラーが出た原因は分かっていません（笑）~~

**sudo apt-get install librealsense2-dkms**が上手く行かなかった原因は、librealsense2-dkms がx86/amd64用のパッケージしか提供していないからです。Jetson boardはCPUがArm Cortexのため、通常のlibrealsense2-dkmsは利用出来ません!!

以下のissueやリポジトリをご参照ください。

https://github.com/IntelRealSense/librealsense/issues/7310

https://github.com/IntelRealSense/librealsense/blob/master/doc/distribution_linux.md


# YOLO V3のインストール
以下に示す元のdarknet_rosをcloneしてbuildしたところ、

https://github.com/leggedrobotics/darknet_ros

以下のようなエラーが出ました。

```
# error "OpenCV 4.x+ requires enabled C++11 support"
# error "OpenCV 4.x+ requires enabled C++11 support"
```
元のdarknet_rosはOpenCVのバージョンは3.3.1を利用しています。他のバージョンではdarknet_rosが動かない可能性があるのでエラーの内容によってはOpenCVのバージョンを変更する必要が出てくると思います。私の場合、OpenCVの4.1.1を入れていたためdarknet_rosが動きませんでした。

OpenCVのバージョンを確認したい場合は以下のコマンドを実行します。

```
$ python
>> import cv2
>> cv2.__version__
```
そこで以下のissueを参照したところ、kunaltygiさんがopencv4系にも対応したdartnet_rosを実装してくれていたので、こちらをcloneしました。

https://github.com/leggedrobotics/darknet_ros/issues/290

こちらのコマンドを順に打ってcloneをします。

```bash
$ cd catkin_ws/src
$ git clone --recursive https://github.com/kunaltyagi/darknet_ros.git
$ git branch -a
$ git checkout -b opencv4 origin/opencv4
$ git submodule update --recursive
```

またそのままビルドするとnvccでエラーするので、 環境変数を設定します。
.bashrcに以下を追加し、環境変数を設定し直します。

```bash
$ cd ~/
$ vi .bashrc
export PATH=$PATH:/usr/local/cuda/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib64
```

更にdarknet_rosのCMAKElist.txtの内容を以下の内容に書き換えます。

```vim
-gencode arch=compute_72,code=sm_72
${CUDA_TOOLKIT_ROOT_DIR}/lib64
```

![無題](https://user-images.githubusercontent.com/52307432/116041445-2cb97400-a6a8-11eb-8630-43bd9a496a13.png)

![無題](https://user-images.githubusercontent.com/52307432/116041642-668a7a80-a6a8-11eb-8215-cd85b9c796bf.png)

ここまで出来たらbuildが出来るはずです！

```bash
$ catkin_make -DCMAKE_BUILD_TYPE=Release
```

## YOLO V3の動作確認
以下のコマンドを順に実行します。

- 一つ目のターミナル

```
$ roslaunch realsense2_camera rs_camera.launch
```

- 二つ目のターミナル

```
$ roslaunch darknet_ros darknet_ros.launch
```
- 三つ目のターミナル

```
$ rosrun rqt_image_view rqt_image_view
```

- 認識結果

```
FPS:8.2
Objects:

laptop: 82%
tvmonitor: 70%
keyboard: 53%
pottedplant: 47%
mouse: 40%
```

fps値は8程度でした。精度はそれなりですね。

![Screenshot from 2021-04-24 02-00-53](https://user-images.githubusercontent.com/52307432/115906321-54d78600-a4a2-11eb-950c-5fdd8e6b57fc.png)

## 動作速度を上げる

以下の様に設定ファイル(Makefile)を書き換えましょう。

![無題](https://user-images.githubusercontent.com/52307432/116041973-d8fb5a80-a6a8-11eb-8251-cb600c79ab29.png)

- 認識結果

```
FPS:9.5
Objects:

motorbike: 52%
laptop: 46%
```

お気持ち若干fps値が上がった気がしますが大して向上しませんでした。ただし前回CPUのみのノートPCで動作させた際のfps値が0.8程度だったのでGPUの力強さは感じますね。

https://qiita.com/MMM-lab/items/5614e2cd2e525e6d6286

## その他関連事項(追加したいものだけ参照してください)

### SWAP領域確保
installSwapfileというリポジトリのスクリプトファイルを使えば、以下2行実行するだけで6GのSwapファイルが生成されます。

```bash
$ git clone https://github.com/JetsonHacksNano/installSwapfile
$ cd installSwapfile
$ ./installSwapfile.sh
```
### VS Codeの導入
VS CodeエディタをJetson Nanoにインストールしたい場合は、以下コマンドで可能です。

```bash
$ cd && wget -O insider.deb https://update.code.visualstudio.com/latest/linux-deb-arm64/insider
$ sudo apt install ./insider.deb
$ sudo mv /usr/bin/code-insiders /usr/bin/code
```

```bash
$ code .
```

### VNC(リモートデスクトップ)

リモートデスクトップ環境を構築したい場合は以下の手順に沿って実行してください。

```
$ sudo apt install vino
```

インストールが完了したら、Remote Desktopの設定を行います。以下のコマンドで設定ファイルを開きます。

```
$ sudo vi /usr/share/glib-2.0/schemas/org.gnome.Vino.gschema.xml
```

上記ファイルを開いたら、<key>タブの一番下に以下の内容を追加して保存してください。

```xml
    <key name='enabled' type='b'>
      <summary>Enable remote access to the desktop</summary>
        <description>
          If true, allows remote access to the desktop via the RFB
          protocol. Users on remote machines may then connect to the
          desktop using a VNC viewer.
        </description>
      <default>false</default>
    </key>
```

追加後に以下のコマンドを実行してください。

```
$ sudo glib-compile-schemas /usr/share/glib-2.0/schemas
```

コマンドを実行すると、[設定]の一番上に[デスクトップの共有]が現れるので、以下の様に設定を行います。

![無題](https://user-images.githubusercontent.com/52307432/116042220-1d86f600-a6a9-11eb-8a71-39d789784568.png)

更に起動時にリモートアクセスできるように、[自動起動するアプリケーションの設定]の[追加]で以下の画像のように登録をします。

![無題](https://user-images.githubusercontent.com/52307432/116042386-4dce9480-a6a9-11eb-81bf-f0539d52243f.png)

最後に下記のコマンドを実行すると、リモートからVNCでアクセスできるようになります。

```bash
$ sudo gsettings set org.gnome.Vino prompt-enabled false
$ sudo gsettings set org.gno
```

# まとめ

- Jetson nanoのセットアップから、ROSとYOLO V3用いて物体認識を行いました
- GPUを搭載しているマシンでは、やはりfps値は高く出ました！(あくまでCPUのみ搭載のマシンに比べて)
- その他関連事項についても軽く触れました

# 今後の予定
- 独自のオブジェクトを学習させて認識したいと思ってます
- Lidarとデプスカメラのセンサフュージョンをしたいと思ってます
- RTABMAPが気になるので試してみたいと思います
- FPS値を向上させる方法について調査します

# 参考文献
https://digital-light.jp/2019/04/28/how-to-set-up-nvidia-jetson-nano/

https://www.youtube.com/watch?v=eSAsLAzYzm4

http://www1.meijo-u.ac.jp/~kohara/cms/remote-desktop-for-ubuntu18-04

https://www.hackster.io/news/getting-started-with-the-nvidia-jetson-nano-developer-kit-43aa7c298797

https://www.youtube.com/watch?v=VBIWbpM0SaU

https://qiita.com/karaage0703/items/b14c249aa33112669ee4

http://kazuki-room.com/how_to_detect_objects_by_putting_darknet_ros_in_jetson_nano/

https://www.nakasha.co.jp/future/ai/vol10_yolov3nvidia_jetson_agx_xavier2opencv4.html