ししかわです。
社員研修の一環で二足歩行ロボットを作って、競技会「Humanoid Autonomous Challenge(HAC)」に参加します。
M5Stackの画像認識モジュール「M5Stack UnitV2」をスタンドアロン(単体)で使って、ロボットを制御しよう!というマニアックな計画を進めています。
システム構成では「認識」「プランニング」「制御」の3つのモジュールが登場しました。今までにUnitV2のカメラを使った画像認識と、MAX-E1(Dynamixel)を使ったロボットの動きの制御を行っています。プランニングはUnitV2内のプログラムで完結するので、あとはゴリゴリと実装していけばHAC攻略のためのロボットが完成します!
…しかし、その前に考えるべきことがもうちょっとあります。「モジュール間の連携」についてです。
最後のピース:モジュール間の連携
ロボットを構成する3つのモジュールは互いに連携し合って動作します。例えばプランニングモジュールは認識モジュールから「認識結果」を受取り、制御モジュールに「行動目標」を送ります。このような情報のやりとり=メッセージ通信(図中の破線矢印)は、ロボットの機能が増えるに従って重要になってきます。
そこで導入を検討したいのが、アールティの多くの製品でも使われているROSです。
ROSとは
ROSはロボットアプリケーション開発のためのミドルウェアです。ROSのプログラムはグラフ構造をとります。ロボットのある機能を実現するプログラムのまとまりがノードとなり、ノード同士がメッセージ通信を通じて連携します。ノードの起動や終了、メッセージ通信の各種方式(トピック、サービス、アクション)がROSのコア機能として提供されます。
ROSのメッセージ通信の方法に従ってプログラムを実装して、複数のノードを相互につなぐことでROSアプリケーションを構築していきます。
また、複数のノードをパッケージとしてまとめて公開したり、再利用したりできます。現在ROSのリポジトリでは膨大な数のパッケージが公開されています。
- Dynamixelのようなハードウェアのドライバ
- 物体認識などの画像処理
- ロボットや周辺環境の状態を3D表示できる可視化ツール
- シミュレーター
このようなパッケージを組み合わせることで、アプリケーションを簡単に、素早く構築できます。
詳しくは公式ページの紹介を参照ください。
HAC-ChanにROSを導入するメリット
今回製作するHAC-ChanにもROSを導入します。これによって次のようなメリットが得られると考えています。
- メッセージ通信処理のフレームワークを使うことで車輪の再発明を防ぐ
- 各モジュールをノードとして作ることで、後から一部を修正したり、差し替えたりが簡単にできるようになる
- ROSの決まりに従って実装〜パッケージ化しておけば、他の人からも使いやすくなる。また、必要に応じてHAC-Chanの一部の機能(たとえばプランニング)のみ抜き出して使うこともできるようになる
- シミュレータを利用できれば開発用PC上のシミュレーション環境で実装し、実機で動作確認の流れが実現できる。開発の高速化が見込める。
シミュレータについては、しょうたさんが作成したHACフィールドのGazeboモデルを手元で動かすまでは確認していたのでぜひ使いたいと思っていました。
#二足ロボ研修
HACの競技フィールドのGazeboモデルをブラウザで表示できた!https://t.co/cWftmpk36g
認識モジュールの開発はシミュレーション環境で行う予定。
UnitV2で無事にROSが動かせれば、ロボットに組み込むプログラムもROSベースで作りたいけどどうなるかな… pic.twitter.com/S73U7Qn7qR— ししかわ/Shinya Ishikawa (@meganetaaan) October 14, 2021
どのROSを使う?
ROSには様々なバージョンが存在し、特にROS1とROS2では性能や内部の仕組みが大きく異なります。その違いについてここでは詳しく触れません。書籍「ROS2ではじめよう 次世代ロボットプログラミング」などの説明が詳しいです。
今回はROS2を使います。ROS1はEOLが2023年に迫ってきているのと、ROS2では特にリアルタイム制御やマイコンでの動作も考慮されている面が主な採用理由です。
ROS1/ROS2にはリリース年毎にディストリビューションが存在し、偶数年にリリースされたものは長期サポートされます。HAC-Chanでは2020年にリリースされたFoxy Fitzroyを使います。
さて、ここでひとつ問題が。ROS2がサポートするLinuxディストリビューションはUbuntuまたはDebian、それも対応するバージョンが決まっています。ROS2 DashingはUbuntu18.04、ROS2 Foxyの場合はUbuntu20.04、といった具合です。一方、UnitV2のOSはUbuntuやDebianのようなディストリビューションではなく、buildrootというツールで作られたものでした。また、armhfアーキテクチャはTier3サポート、つまりバイナリが提供されないため、自分でソースからコンパイルする必要があります。
ROS2をUnitV2で動かすために幾つかの方法を検討しました。
- ROS2をソースからクロスコンパイルする。
- UnitV2にDockerをインストールし、armhf向けのROS2イメージを利用する。
- 組み込み向けの軽量版ROSフレームワークである「micro-ROS」を使う
先に結論を言うと1, 2はうまくいかず、3を採用することにしました。
ROS2をソースからクロスコンパイル→依存パッケージのインストールが難しい
前提として、buildrootにはUbuntuやDebianのようなパッケージマネージャが入っていません(厳密に言えばオプションとしてopkgというパッケージマネージャをインストールできますが、組み込み向けという性質上製品に含まれない場合が多いです)。UnitV2も同様にパッケージマネージャは使えません。
そのため、依存パッケージやミドルウェアも全てクロスコンパイル→転送の手順を踏む必要があります。依存の多いROS2ではこれがネックになり、うまくインストールできませんでした。
一応、調査のためにarmv7アーキテクチャのRaspberryPiでのROS2クロスコンパイルには成功したので、参考にしたリンクを貼っておきます。
リンク先の手順に従いビルドしました。下記の環境で動作しています。
- Raspberry Pi OS Lite 32bit(bullseye)
- Raspberry Pi Model3B+
UnitV2にDockerをインストール
buildrootを使ってDockerのみをインストールしたイメージを作成し、UnitV2のFlashに書き込む方法を検討しました。
この際UnitV2のbuildroot用設定ファイル(defconfig)が必要となるが、公開されていません。公開可能かM5Stackに問い合わせてみましたが、NDAなファイルを多く含んでおり難しいとのことでした。いずれメインラインカーネルに移行する可能性はあるということで今後に期待です。
It’s pretty hard to do that, since many files on the pipeline is under NDA. Maybe we can shift to mainline kernel with full open sourced tools later. Btw, we tried docker but it just require too much system resource
— HanxiaoMeow (@HanxiaoM) October 20, 2021
(HanxiaoMeowさんはM5StackのVシリーズを担当するエンジニアです。M5Stack公式といい反応が早すぎる)
そして「UnitV2でDocker試したけどシステムリソースを食いすぎるよ」という指摘ももらいました。クロスビルドしたイメージからDockerのバイナリ、依存ライブラリを抜き出してUnitV2にコピーすることも考えていましたが、パフォーマンスの観点からDockerは選択肢から外したほうがよさそうです。
ということで、Dockerの方法もうまくいきませんでした。そもそもこれらの方法はUnitV2のファイルシステムを大幅に書き換えてしまうため、私のロボットのコンセプトである「ブログの読者が自分でも試せる」という要件にマッチしていません。UnitV2が文鎮化するリスクを取らせるのはよろしくないですね。
なお副産物として「DockerのみインストールしたRaspberry Pi用イメージ」の作り方を習得しました。例えばRaspberry Pi 4でロボットを動かすのであればCPUパワー、メモリともにDockerを運用するのに十分な性能があるのでDocker+ROSも有力な選択肢になるかもしれません。
micro-ROS
micro-ROSはROS2をマイコン上で動作させるためのフレームワークです。
- 移植性の高さ
- 軽量、省メモリな動作
などが特徴です。
「micro」という言葉が示すとおり、主にSTM32やESP32などのマイコンでの動作を目的とするフレームワークですが、32bit版のRaspberry Pi OS向けのビルドも用意されている点に注目しました。同じarmhfアーキテクチャを持つUnitV2への移植はそれほど難しくなさそうです。そして他パッケージへの依存が最小限である点、省メモリで軽量に動作する点などは、リソースに制約のあるUnitV2においてもメリットとなります。
ROS2のソフトウェアスタックを次の図に示します。濃青の四角がmicro-ROSが提供する範囲です。

ROSのソフトウェアスタック。濃青がmicro-ROSの提供するもの(https://micro.ros.org/docs/concepts/client_library/introduction/ から引用)
ROS2のソフトウェアスタックはクライアントライブラリ、ミドルウェア、OSの3層に大きく別れますが、micro-ROSは次のソフトウェアを提供します。
- クライアントライブラリ層(RCL)…rclc:RCLの軽量なC言語実装
- ミドルウェア層(RMW)…Micro XRCE-DDS:マイコン向けの軽量、省メモリなメッセージングミドルウェア(DDS)実装
- OS層…各組み込みOS向けのドライバ
マイコン向けといっても、ROS2の共通クライアントであるRCLのインタフェースに則っているので、トピックやサービスなどのROS2の仕組みをそのまま使ってプログラムを書けます。
前置きが長くなってしまったので今回はここまで。次回はmicro-ROSをUnitV2で動かしてみます。