はじめに
連載の第1回に引き続き、RaspberryPiで動作する小型ロボット「GoPiGo」を使って、遠隔見守りロボットを作っていきます。
前回から少々時間がたっているので、第2回の本題に入る前に第1回のおさらいを簡単にしておきます。第1回では、今回利用するGoPiGoがどんなロボットなのかということと、ROSを活用する意義および作成する遠隔見守りロボットの仕組みについて概要を説明し、ROSのセットアップまでを行いました。
前回の内容から興味を持っていただき、実際にGoPiGoを入手してROSのセットアップを行った方もいらっしゃるかもしれません。今回は前回の内容を引き継ぎ、セットアップした中身を説明する形で、ROSとはどんなものなのかということや、ROSの基本的な要素の説明、新たな機能の組み込みまでをやってみようと思います。
もし手元にGoPiGoがなくても、読み進めていただくとROSの使い方の概要が大まかにつかめるように説明していきます。
ROSでロボットを動かすための基本的な要素
GoPiGoを動かしていくための詳細に入る前に、ROSでロボットを動かす際の基本的な要素を整理しておきたいと思います。本連載を通してROSを使っていくうちに、詳細な内容については理解が進んでいくはずなので、今回は手を動かすために最低限必要なレベルの説明にとどめておきます。より詳細な内容を知りたい方は、ぜひ公式のドキュメントであるROS Wiki Documentを参照してください。ROSのドキュメントは比較的丁寧に説明されているので、次回以降に向けてより理解が進むはずです。
ROSの位置付け
前回解説したインストール手順からもお分かりかと思いますが、ROSはオペレーティング・システムという名前はついていても、実際にはOS上(通常はUbuntu Linux)で動作するロボット制御用のフレームワーク、ミドルウェア群となります。
大ざっぱな表現でスタックを書くと以下のようになります。
要素はさらにたくさんあるので、この図で全てを表すことはできません。ただ、OS上にインストールして利用されるミドルウェアやライブラリ群の1つとして位置づけられていることと、ROS以外の他のミドルウェアやライブラリはROSの内部的なライブラリに隠蔽されて利用されるか、ユーザーの作成するコード内であわせて使えることは分かると思います。通常、ユーザーがROSの機能群を使うコードを書く場合、C++やPythonといった汎用言語が利用可能になっています。
実際の開発では制御ソフトを記述して、1つのまとまったパッケージとして構成するのに必要なツールやライブラリ、それらが動作する際に必要な通信系ライブラリ、ROS公式もしくはROSを普段利用しているコミュニティの人たちが公開しているパッケージ群を、適宜組み合わせて活用していきます。
分散処理を実現する2つの通信モデル
ROSはロボットを制御するシステム全体を構成する各ソフトウェアが、ネットワーク的に分散/連携して動作するアーキテクチャを採用しています。分散して通信しながら動作する、各実行プログラムの単位をNodeと呼びます。ネットワーク関連に普段から接している方にとっては、Nodeという言葉とそのイメージは受け入れやすいのではないでしょうか?
構成されるシステム全体は、このNode間のメッセージのやり取りで動作することになります。ROSで採用されてメインで使われている、基本的なメッセージの通信モデルには以下の2つがあります。
- Pub/Subメッセージングモデル
- Serviceモデル
Pub/Subモデルについても、ROS以外で触れたことがある方はいるかもしれません。こちらは非同期型のメッセージングモデルで、各NodeはPublisherと呼ばれる、実行処理に関わるメッセージの送り手と、そのメッセージを購読という形で受け取るSubscriberに分かれます。
PublisherとSubscriber間のメッセージのやり取りはメッセージのブローカーとなるプロセスが仲介しています。Topicと呼ばれる名前付きの通信チャンネルに対してPub側はそれぞれメッセージを送信し、Sub側はどのTopicを購読するかをブローカーに登録しておいて受け取るという方式です。非同期かつ結合が粗な方式ですので、メッセージの受け手が存在しているかどうかに関わらず、(言い方は悪いですが)メッセージを投げっぱなしにして、次々と処理をこなしていくことができる利点があります。
一方のServiceモデルも、普段からWeb系の開発などに親しんでいる人であればイメージしやすいと思います。同期型のメッセージングモデルで、各Nodeは特定の処理を実行して結果を返すサービスのサーバーと、それを呼び出して結果を受け取るクライアントに分かれます。同期型の処理なので、クライアントが結果を受け取るまで処理は終了しません。Pub/Subモデルは、多対多かつ非同期の通信を実現することができる反面、確実なリクエスト、レスポンスの組み合わせが必要な処理には不向きです。Pub/Subでは不向きな処理の実行をカバーし、Node間にて1対1の関係で処理実行を実現する目的のため、Serviceモデルは用意されています。
例えば、通常のロボットの動作を構成するリアルタイムに近い処理はPub/Subで行い、作動時に一度だけ呼び出して確実に結果を得て、その後の処理を進めなければならないような初期化などの用途にはServiceを使う、というような使い分けをすることが多いと思います。
ここで、いったん用語の整理をしておきましょう。
- Node:ROSを利用したシステムでの、各処理を実行する役割を担ったプロセス
- Pub/Subメッセージングモデル:多対多でNode間の処理を実行した際にメッセージングを実現する非同期の通信
- Topic:Pub/Subでのメッセージをやり取りするために利用される名前付きのチャンネル
- Publisher:Pub/Subでのメッセージ配信側Node
- Subscriber:Pub/Subでのメッセージ受信側Node
- Serviceモデル:Node間で1対1のリクエスト、レスポンスを行う形式の通信