ここは自分用の開発メモですので,一部のマニアにしか関係ないと思いますが,ROSについて深く知る助けくらいにはなるかもしれませんね.
通信全体の流れ
ROSはXML-RPC通信から始まる
ROSでは,roscoreプロセスで実行される<マスター: Master>と,ノードである<スレーブ: Slave>の通信から始まります.この通信はAPIと呼ばれており,XML-RPCで通信します.つまり,マスター側もスレーブ側にもXML-RPCのサーバープロセスが動作していることになります.
実際のデータの流れは簡易なパケット通信
XML-RPCでの通信では,各種のIPアドレスやポートの問い合わせに対応しており,実際のデータ通信は行われていません.
トピックやサービスにおける実際のデータ通信は,簡易なソケットによるTCPもしくはUDPによるパケット転送ですので非常に軽量です.
TCPソケットの接続までの流れ(トピックの場合)
まずはトピックにおける通信について解説しましょう.
まず,トピックのパブリッシャーが実行されたとします.パブリッシャーはマスターに対して,特定のトピック1に対してパブリッシャーとして登録します.
次に,サブスクライバーがトピック1に対してサブスクライブすることをマスターに登録すると,トピック1に対して登録中のパブリッシャーのURIが返ってきます.
サブスクライバーは返却されたURIに対して,再度XML-RPCで接続要求を行います.するとパブリッシャーは接続のための対応プロトコルとソケットのアドレス,ポート番号を返しますので,サブスクライバーはTCPの場合はパブリッシャー側のソケットに接続を行います.
TCPソケットが接続されると,ヘッダー情報が交換されます.ヘッダー情報にはトピックの名前や,お互いのノードの名前,通信に関するオプションが記述されています.
この後は,パブリッシャー側からトピックのデータが流され続けます.
サブスクライバーが実行中に当該トピックのパブリッシャーに変更があった場合は,マスターからサブスクライバーに対して,変更の通知がなされます.この通知では当該トピックにおけるパブリッシャーの一覧が渡されますので,これを参照すればサブスクライバーはパブリッシャーが減ったのか,増えたのかがわかります.
TCPソケットの接続までの流れ(サービスの場合)
サービスの場合もTCPソケットで通信します.
XML-RPC API
マスターはスレーブに対して以下の機能を提供しています.
- サービスの登録(registerService)
- サービスの解除(unregisterService)
- サブスクライバーの登録(registerSubscriber)
- サブスクライバーの解除(unregisterSubscriber)
- パブリッシャーの登録(registerPublisher)
- パブリッシャーの解除(unregisterPublisher)
- 登録中のノードのXML-RPC用URIの検索(lookupNode)
- システムの状態(トピックやサービス,登録ノードの一覧)の取得(getSystemState)
- マスター自身のXML-RPC用URIの確認(getUri)
- 登録されているサービスのXML-RPC用URIの確認(lookupService)
以上のように,マスターは基本的に登録されているトピック,サービス,ノードに関する問い合わせに応じます.
また,スレーブ側は以下の問い合わせに対応します.
- 接続状態の確認(getBusStats)
- 接続に関する情報の確認(getBusInfo)
- 登録しているマスター側のXML-RPC用URI(getMasterUri)
- 停止(shutdown)
- プロセスIDの取得(getPid)
- subscribeしているトピック一覧の確認(getSubscriptions)
- publishしているトピックの一覧の確認(getPublications)
- パラメータ変更の通知(paramUpdate)
- サブスクライバー登録中のトピックに対するパブリッシャーの変更通知(publisherUpdate)
- パブリッシャー登録中のトピックに対するサブスクライバーからの接続要求(requestTopic)
たとえば,rxgraphコマンドでノード間の接続を確認する場合は,マスター側のgetSystemStateとスレーブ側のgetBusInfoメソッドを参照しています.