ROSの通信

ここは自分用の開発メモですので,一部のマニアにしか関係ないと思いますが,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メソッドを参照しています.