RaspberryPi2 v1.1でもROS2 Dashing Diademataを動かしたい

# 記事概要

ROS2 Dashing Diademataの主たるターゲットは64bitアーキテクチャであり，RaspberryPiをターゲットとする場合でも同様である．32bitアーキテクチャであるRaspberryPi2 v1.1をROS2 Dashing Diademataのターゲットとして活用するために，セルフビルドのための変更点とポイントを明らかにし，Pub/Subデモによる動作確認を実施したので報告する．

# 動機

筆者はROS2のロボット制御への活用に興味を持っている．行動計画などの高次機能やシミュレーションなどの計算負荷の高い処理はPCベースのプラットフォームに任せるとして，移動ロボットなどに搭載する組み込みプラットフォームでフルスタックのROS2を動かすことを考えると，シングルボードコンピュータ，とりわけRaspberryPiを外すわけにもいかない（完全に余談であるが，筆者はシングルボードコンピュータの中ではRaspberryPiは好きではない．GPUのファームウェアがブラックボックスであり，その助けを借りなければOSをブートできないからだ）．

RaspberryPiへROS2 Dashing Diademata（以下ROS2DD）をバイナリインストールする記事はQiita内外で散見されるが，対象は基本的にRaspberryPi3（および3+）である．これは，ROS2DDのTier1 Targetが64bitアーキテクチャに限定されていることが関係していると考えられる（参考リンク：[REP 2000 -- ROS 2 Target Platforms(ROS.org)][1]）．RaspberryPi3（および3+）は元々64bitのSoCを搭載していて，ROS2DDの土台となるUbuntu18.04 for ARMも64bit版のISOイメージが用意されている．RaspberryPi2 v1.2について扱う記事は非常に少ないと思われるが，SoCがRaspberryPi3と同じBCM2837であるため，バイナリインストールはRaspberryPi3を対象としたのと同様の方法で可能と思われる．

本記事投稿時点においては，ROS2DDのプラットフォームとして新規にRaspberryPi2（v1.1およびv1.2）を採用することにメリットはほとんどないと考えられる．入手性はもはやRaspberryPi3（および3+）の方が上であるし，価格差もそれほど優位とは言えない．筆者はRaspberryPi2 v1.1からv1.2への店頭在庫切り替えの時期に，放出価格でv1.1を購入したため，これを活用したかった．また，世の中にも使われなくなったv1.1が多く死蔵されているであろう．これをROS2DDのプラットフォームとして活用する方法が確立されればそれなりに役に立つと筆者は考える．

しかし，RaspberryPi2 v1.1のSoCはv1.2とは異なり32bitアーキテクチャであるため，RaspberryPi3のバイナリを動かすことはできない．ROS2DDにおける32bit ARM（arm32）プラットフォームの扱いはTier2であり，一応のバイナリアーカイブは用意されているが，ボード上でセルフビルドしたものが使えるならそれに越したことはないだろう．

# 目的

32bitアーキテクチャであるRaspberryPi2 v1.1上でROS2DDをビルドし，PCなど別のコンピュータとの間でPub/Subデモが動作するまでの手順を確立する．

# 本論

ROS2DDのビルドは，基本的には公式の手順に則る．ポイントは以下の3つである．

1. 速度と容量が十分なスワップ領域を確保する
2. ビルドしようとするとエラーが出るパッケージ群をビルドから除外する
3. 運用する見込みがなくかつ巨大すぎるパッケージ群をビルドから除外する

## 事前準備

### Ubuntu for ARMのインストール

RaspberryPi2 v1.1のmicroSDカードにUbuntu for ARMがインストールされていること．Ubuntu for ARMのイメージファイルはアーキテクチャごとに異なるものが用意されており，RaspberryPi2 v1.1には[Raspberry Pi 2 preinstalled server image][2]を用いる．バージョンとしては本記事投稿時点における最新版として18.04.3を想定する．
また，apt-getコマンドなどによりアップデートの適用を済ませておくことを推奨する．

### スワップ領域用ストレージの準備

ROS2DDをビルドするにはメモリを多く必要とする．colconのオプションを指定し並列ビルドを抑制することで，ある程度は必要メモリ容量を抑えることはできるが，それでもスワップ領域の確保なしではメモリ不足によりビルド中にシステムがハングアップするようである．

Ubuntuのルートファイルシステム以下にスワップファイルとして確保するのも手ではあるが，ビルドに伴うファイルI/Oと帯域が競合するのと，そもそもRaspberryPiのmicroSDスロットはさほど高速ではないので，所謂USBフラッシュのようなUSB接続のストレージを用意する．容量が足りていれば速度が早い方がビルド時間短縮につながるが，最近のデバイスであればさほど気にしなくて良いだろう．~~お金持ちな方はプロ写真家が使うような高価なUSB-SSDでも使ってくれ．~~

筆者はあきば○〜で購入したSandisk Ultra Flair 16GB（SDCZ73-016G-G46）の全領域を，1つのLinux Swapパーティションとして割り当てて使いまわしている．本記事においてもその前提で進める．

## ROS2DDのビルド手順

### スワップ領域の確保

スワップ領域の設定を確認する．

```
$ sudo swapon -s
```

[Raspberry Pi 2 preinstalled server image][2]の初期状態ではスワップ領域は設定されないようである．
USBポートにスワップ領域用ストレージを挿入し，dmesgコマンドにより確認する．他にUSBストレージなどを使用していなければ，デバイスは/dev/sdaとしてアタッチされ，Linux Swapパーティションは/dev/sda1としてアタッチされるはず．

スワップ領域を割り当てる．

```
$ sudo swapon /dev/sda1
```
スワップ領域の大きさが正しく認識されているかどうかは，topコマンドなどにより確認すると良い．
このスワップ領域の割り当ては一時的なものであり，システムをリブートすると無効となることに注意．

### ビルド

ROS2公式の手順"[Building ROS 2 on Linux][3]"に沿って進める．32bit ARM用にビルドするために変更が必要なステップは"[Add the ROS 2 apt repository][4]"である．

公式の手順では64bitアーキテクチャを対象として

```
$ sudo sh -c 'echo "deb [arch=amd64,arm64] http://packages.ros.org/ros2/ubuntu `lsb_release -cs` main" > /etc/apt/sources.list.d/ros2-latest.list'
```

としているコマンドを，以下のように32bit ARM用に変更する．32bit ARMアーキテクチャは一般的にはarm32などと呼ばれることがあるが，ここではarmhfと指定することに注意．

```
$ sudo sh -c 'echo "deb [arch=armhf] http://packages.ros.org/ros2/ubuntu `lsb_release -cs` main" > /etc/apt/sources.list.d/ros2-latest.list'
```

以上の変更以外は公式の手順通りに実施し，"[Build the code in the workspace][5]"の手前まで進める．この段階まではコマンドのコピペを多用することになるので，sshなどでリモートログインして進めるとやり易い．

#### ビルドしようとするとエラーが出るパッケージ群をビルドから除外

本記事投稿時点においては，eclipse-cycloneddsをビルドに含めるとエラーが発生する．とりあえずビルドから除外する．

```
$ cd ~/ros2_dashing/src/eclipse-cyclonedds
$ touch AMENT_IGNORE
```

（余談）数カ月前にビルドした際はエラーが出なかったし，そもそもeclipse-cyclonedds以下はビルドから除外されていたような…．ros2.reposを覗くとeclipse-cycloneddsのブランチはdashingではなくmasterに設定されているし，リポジトリをクローンする時期によってbuggyだったり，あるいは特定ターゲットでのテストそのものが打ち切られているのかもしれない．

#### 運用する見込みがなくかつ巨大すぎるパッケージ群をビルドから除外

ros-visualization（rqt関連）とros2/rvizをビルドから除外．除外しなくてもビルド自体は通るが，ビルド時間が大きく伸びる．必要なら後で追加でビルドするのも手．

```
$ cd ~/ros2_dashing/src/ros-visualization
$ touch AMENT_IGNORE
$ cd ~/ros2_dashing/src/ros2/rviz
$ touch AMENT_IGNORE
```

ここまでの手順を終えたら，後は"[Build the code in the workspace][5]"のステップを実施するだけである．
今回の設定では，ビルド対象の全パッケージをビルドするのに4時間20分程の時間を要した．いったんリモートからログアウトし，ボードに接続しているモニタとキーボードからログインして"[Build the code in the workspace][5]"のステップを実施すると良い．

## Pub/Subデモによる動作確認

RaspberryPi2 v1.1とPCとの間で，demo_nodes_cpp talkerとdemo_nodes_cpp listenerによる動作確認を行う．RaspberryPi2 v1.1上での操作はPC上での操作とまったく同様である．
以下にPC上でdemo_nodes_cpp listenerを起動しておいて，同一ネットワーク上のRaspberryPi2 v1.1にリモートログインした上でdemo_nodes_cpp talkerを起動した際のキャプチャ動画を示す．上側のターミナルがPC，下側のターミナルがRaspberryPi2 v1.1である．
キャプチャ動画は割愛するが，talkerとlistenerを入れ替えても同様に動作することを確認した．

![demo_nodes_cpp-PC_and_Raspi2_full.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574178/bf63f54d-a95c-ae89-4fbd-659599586962.gif)

# 結論

32bitアーキテクチャであるRaspberryPi2 v1.1上でROS2DDをビルドし，Pub/Subデモが動作することを確認できた．ビルドのためのポイントは以下の3つである．

1. 速度と容量が十分なスワップ領域を確保する
2. ビルドしようとするとエラーが出るパッケージ群をビルドから除外する
3. 運用する見込みがなくかつ巨大すぎるパッケージ群をビルドから除外する

# 参考資料

1. [ROS2 Dashing Diademata Targeted platforms][1]
2. [Raspberry Pi 2 preinstalled server image（イメージファイルへのリンク）][2]
3. [Building ROS 2 on Linux][3]
4. [Building ROS 2 on Linux : Add the ROS 2 apt repository][4]
5. [Building ROS 2 on Linux : Build the code in the workspace][5]
6. [@MAEHARA_Keisukeのポータル記事][6]

[1]:https://www.ros.org/reps/rep-2000.html#dashing-diademata-may-2019-may-2021
[2]:http://old-releases.ubuntu.com/releases/18.04.3/ubuntu-18.04.3-preinstalled-server-armhf+raspi2.img.xz
[3]:https://docs.ros.org/en/dashing/Installation/Linux-Development-Setup.html
[4]:https://docs.ros.org/en/dashing/Installation/Linux-Development-Setup.html#add-the-ros-2-apt-repository
[5]:https://docs.ros.org/en/dashing/Installation/Linux-Development-Setup.html#build-the-code-in-the-workspace
[6]:https://qiita.com/MAEHARA_Keisuke/items/31faa68cf5c51831acc6