NanoPi-NEO2でROS2を動かしてみた

# はじめに

初めてAdvent Calenderを書きます。
ROSを使ったことはあるけれど、そろそろROS2にも触れておきたいな...という気分になってきたので、ROS2に挑戦してみました。

# NanoPi-NEO2とは
![IMG_0357.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248231/c8842df4-804c-4956-7e68-53f1211efa6f.jpeg)
FriendlyElecが販売しているシングルボードコンピュータです。40mm x 40mmという非常にコンパクトな基板サイズながら、64bitクアッドコアのARM Cortex-A53のCPUを搭載しています。ただし、HDMIコネクタ、WiFi、Bluetoothは付いていません。

なぜHDMIもWiFiも付いていないボードをわざわざ使うのかというと、次のような理由からです。

1. 64bitコアであること<br>
  ROS2は[多様なプラットフォーム](https://www.ros.org/reps/rep-2000.html)で動作するらしいですが、Dashing Diademataので最もサポートの厚いプラットフォームはUbuntu Bionic（18.04）64bitのようです。NanoPi-NEO2は、ArmbianというARMボード向けのDebian、UbuntuベースのOSを使用することで、この環境を作ることができます。
- 技適の問題を回避できること<br>
  最近のシングルボードコンピュータはWiFiやBluetoothを搭載していることがよくありますが、国内で技適マークのない無線機器を使用すると電波法違反になる場合があります。その点、もともとWiFi非搭載なことはむしろ利点です。（11月20日から総務省に届け出をすることで、技適なしの無線機器でも使用することができるようになりました。詳細については[こちら](https://www.tele.soumu.go.jp/j/sys/others/exp-sp/index.htm)。）
- コンパクトなこと<br>
  上にも書きましたが、40mm x 40mm（コネクタ含まず）という驚きの小ささです。これでいてUSB機器を接続できるので、ちょっと凝ったこともできるんじゃないでしょうか。
- 入手性が良いこと<br>
  [秋月電子](http://akizukidenshi.com/catalog/g/gM-12302/)で購入できます。（ただし、秋月電子で取り扱われているものはRAM 512MBモデルです。1GBモデルはAliExpress等の海外通販サイトで販売されています。）

# NanoPi-NEO2のセットアップ
[メーカーのWiki](http://wiki.friendlyarm.com/wiki/index.php/NanoPi_NEO2)が参考になります。ただし、今回使用するOSはUbuntuCoreではなくArmbianです。

### 用意するもの
 - NanoPi-NEO2（1GBモデルがおすすめ）
 - NanoPi-NEOシリーズ用ヒートシンク（かなり発熱するためほぼ必須）
 - マイクロSDカード（Class10以上、8GB以上）
 - USB ACアダプタ（2A以上）
 - LANケーブル

### SDカードの作成
 - NanoPi-NEO2用のArmbian Bionicのイメージを[ダウンロード](https://www.armbian.com/nanopi-neo-2/)して解凍します。
 - BalenaEtcher等のソフトでOSイメージをMicro SDカードに書き込みます。

### アカウント作成
 - NanoPi-NEO2をLANケーブルでご家庭のネットワークに接続します。
 - USB ACアダプタに繋いで電源を入れます。起動すると基板上の緑色のランプが点滅します。
 - NanoPi-NEO2のIPアドレスを検索します。Linux PCなら以下のようなコマンドでネットワーク上のIPアドレスの一覧を取得可能です。

```sh
$ nmap -sP 192.168.xxx.xxx/24
```
 - IPアドレスが分かったら、sshでログインします。初回パスワードは1234になっています。

```sh
$ ssh root@192.168.xxx.xxx
```
 - 自動でアカウント作成が始まります。現在のrootパスワード（1234）を入力して、新しいrootパスワード（適当に決めてください）を入力します。
 - 次に、新しいアカウントのユーザ名とパスワードを入力します。
 - その後、Full Nameなどの個人情報の入力を促されますが、空欄でも問題ないようです。
 - アカウントができたら、ログアウトして新アカウントでログインし直します。

### アップデート
 - アップデートしておきましょう。

```sh
$ sudo apt update
$ sudo apt upgrade
```

# ROS2のインストールと実行


### 用意するもの
 - ROS2インストール済みのLinux PC

### Dashing Diademataのインストール
 - 通常のPCと同様に、公式の手順でインストールすることができます。
 - [Installing ROS2 via Debian Packages](https://index.ros.org//doc/ros2/Installation/Dashing/Linux-Install-Debians/)  に従ってインストールすればOKです。
 - ただし、```$ sudo apt install ros-dashing-desktop```の実行には非常に時間がかかるので、```ros-dashing-desktop```の代わりに```ros-dashing-ros-base```をインストールすることをお勧めします。


### デモの実行
 - ```ros-dashing-ros-base```をインストールした場合、デモが入っていないので、以下のコマンドでインストールします。

```sh
$ sudo apt install ros-dashing-demo-nodes-cpp ros-dashing-demo-nodes-py
```
 - インストールできたら、1つ目のターミナルからtalkerノードを起動します。

```sh
$ ros2 run demo_nodes_cpp talker
```
 - 次に、2つ目のターミナルを立ち上げて新たにsshでログインし、listenerノードを起動します。

```sh
$ ros2 run demo_nodes_py listener
```

 - このように送受信できたら成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248231/4dfe56e1-90fe-e46b-f045-5f406e5b1966.png)


# RealSenseのテスト
せっかくなのでIntelの深度カメラ、RealSense D435iを動かしてみました。

### ros2_intel_realsenseのインストール
- RealSense用のROS2パッケージ [ros2_intel_realsense](https://github.com/intel/ros2_intel_realsense) があるので手順に従ってインストールします。
- 必要なROS2パッケージのインストール

```sh
$ sudo apt-get install ros-dashing-cv-bridge ros-dashing-librealsense2 ros-dashing-message-filters ros-dashing-image-transport
```

- ROS2以外の必要なもののインストール

```sh
$ sudo apt-get install -y libssl-dev libusb-1.0-0-dev pkg-config libgtk-3-dev
$ sudo apt-get install -y libglfw3-dev libgl1-mesa-dev libglu1-mesa-dev
```

- 2019年11月時点ではバージョン2.0.4のバイナリが提供されており、aptでインストールすることができました。しかし、このバージョンでは[YAMLファイルからパラメータを指定することができない](https://github.com/intel/ros2_intel_realsense/issues/55)ため、今回はソースからビルドすることにします。
- まずワークスペースを作って、```git```でros2_intel_realsenseのソースコードをクローンします。

```sh
$ mkdir -p ~/ros2_ws/src
$ cd ~/ros2_ws/src
$ git clone https://github.com/intel/ros2_intel_realsense.git
```

- ```colcon build```でワークスペースをビルドします。デフォルトでは並列にビルドされるようになっていますが、今回は処理能力不足のためか途中でフリーズしてしまったので、```--executor sequential```をつけて1個ずつビルドするようにしました。

```sh
$ cd ~/ros2_ws
$ source /opt/ros/dashing/setup.bash
$ colcon build --executor sequential
```

### パラメータ
 - パラメータを記述するYAMLファイルを作ります。
ファイル名は適当に```realsense_parameters.yaml```としておきます。
 - NanoPi-NEO2の性能では、RealSenseの標準の解像度だとエラーになりやすいため、解像度を落として起動した方が安定します。

```yaml
RealSenseCameraNode:
  ros__parameters:
    enable_pointcloud: false
    enable_aligned_pointcloud: false
    enable_depth: true
    enable_aligned_depth: true
    enable_infra1: false
    enable_infra2: false
    enable_fisheye: false
    depth_width: 480
    depth_height: 270
    depth_fps: 6
    color_width: 424
    color_height: 240
    color_fps: 6

```

### RealSenseの起動
 - 以下のようなコマンドでパラメータを渡しながらRealSenseノードを起動できます。

```sh
$ ros2 run realsense_ros2_camera realsense_ros2_camera __params:=realsense_parameters.yaml 
```
 - ROS2インストール済みのPCを同じネットワークに接続すれば、``rviz2``で画像を確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248231/d0959dab-0eba-5438-ca63-c5af96a950c7.png)



# その他

### ネットワーク設定
 - IPアドレスの固定化
  - 参考：[Use NetworkManager to configure network settings](http://wiki.friendlyarm.com/wiki/index.php/Use_NetworkManager_to_configure_network_settings) 
  - ネットワークの設定にはNetwork Manager (nmcli) を使用します。

    ```sh
    $ sudo nmcli connection show # Check Connection Name
    $ sudo nmcli connection modify 'Wired connection 1' \
      connection.autoconnect yes ipv4.method manual \
      ipv4.address 192.168.xxx.xxx/24 ipv4.gateway 192.168.xxx.1 ipv4.dns 8.8.8.8
    $ sudo reboot
    ```
 - WiFi USBアダプタを取り付けることで、WiFiを使用することもできます。WiFiの設定方法はここでは割愛します。

### スワップ領域拡大
 - メモリ容量が不足していると```colcon build```が通らなかったり（特に512MBモデルでは）しますが、スワップ領域を拡大することで解決することがあります。
 - 参考：[linux スワップ（swap）領域の作成](https://kazmax.zpp.jp/linux_beginner/mkswap.html)

### 音声出力
 - NanoPi-NEO2にイヤホンジャックはついていませんが、Audioピンが出ているため[ジャックDIP化キット](http://akizukidenshi.com/catalog/g/gK-05363/)などで配線すれば音声を出力することができます。
 - 以下のコマンドでArmbianの設定ツールを呼び出し、System -> Hardware -> analog-codecをチェックして音声出力を有効化します。

  ```sh
  $ sudo armbian-config
  ```
  - 次のコマンドでデバイス一覧を確認します。こんな感じになると思います。

  ```sh
  $ aplay -l
  **** List of PLAYBACK Hardware Devices ****
  card 0: Codec [H3 Audio Codec], device 0: CDC PCM Codec-0 []
    Subdevices: 1/1
    Subdevice #0: subdevice #0
  ```

 - 以下のコマンドで、接続したスピーカーやイヤホンから音がでれば成功です。

  ```sh
  $ aplay /usr/share/sounds/alsa/Front_Center.wav
  ```
### USBコネクタの追加
 - デフォルトではUSBコネクタが1つしかついていないのですが、実はポート2つ分のピンが別に付いているので、[USBコネクタDIP化キット](http://akizukidenshi.com/catalog/g/gK-07429/)などに配線すれば複数のUSB機器を使用することができます。

# おわりに
そんなわけで、NanoPi-NEO2でROS2を動かすことができました。NanoPi-NEO2自体は2年ほど前のものですが、こういうボードでもROS2を動かせると分かったので、いろいろと夢が広がります。まだまだROS2について分からないところはたくさんありますが、今後も勉強していきたいと思います。