LoginSignup
24
20

More than 3 years have passed since last update.

ROSノード間通信の速度について

Last updated at Posted at 2016-12-09

 ROSをPythonで書いてる人はお帰りください.
 今日はROSのノード間通信の速度について調べてみた結果をご紹介します.

Nodeletってすごいらしい

 知っての通り,ROSはノード間通信がSocketで実現されているため,物理的に離れたPC間でもroscoreを共有してROSノード同士が互いに通信を行うことができますが,同一PC内でも通信にオーバーヘッドが入ってしまって遅いという難点があります.
 それを解決するのがNodeletという仕組み.1つのプロセス内でNodelet化した複数のROSノードをスレッド化して動作させ,且つそこで動いているROSノード間の通信をshared_ptr渡しにすることで,メッセージのシリアライズ/デシリアライズ処理を無くし,共有メモリによるコピー,いわゆるゼロコピーを行って通信の高速化を行うことができると言われています.そのため,様々な画像処理を行うimage_pipelineなんてパッケージは,そのほぼ全てがNodeletで提供されていたりします.まぁ,とりあえず「Nodelet Everything」という,Clearpath Roboticsの人が書いた記事をみんな読むんだ.

評価パッケージ作った

 さて,「速くなる」って言っても,実際どれくらい速くなるのか興味があったので,メッセージのやりとりにかかる時間を計測するパッケージを作成しました.


使い方

 パッケージをROSワークスペースにダウンロードしてビルドしたら,以下のようにroslaunchを立ち上げることでそれぞれの場合におけるメッセージのやりとりにかかる時間を計測することができます.

1.1つのノード内でROSメッセージをやり取りする場合
roslaunch measure_message_passing one_node.launch
2.1つのノード内でROSメッセージをshared_ptrでやり取りする場合
roslaunch measure_message_passing one_node_ptr.launch
3.2つのノード間でROSメッセージをやり取りする場合
roslaunch measure_message_passing two_node.launch
4.2つのノード間でROSメッセージをshared_ptrでやり取りする場合
roslaunch measure_message_passing two_node_ptr.launch
5.2つのNodelet間でROSメッセージをやり取りする場合
roslaunch measure_message_passing two_nodelet.launch
6.2つのNodelet間でROSメッセージをshared_ptrでやり取りする場合
roslaunch measure_message_passing two_nodelet_ptr.launch

roslaunchを立ち上げてしばらくすると,1024x768のサイズでbgr8型(OpenCVのCV_8UC3型:符号なし8ビット3チャンネル)の画像データを1000回メッセージパッシングをしたときにかかる時間の平均値・中央値・最悪値(最大値)を出力します.

結果

 MSIのゲーミングPC GS30 2Mで実際に計測した結果は,

  1. one_node (not pointer): Mean: 0.00140118, Median: 0.00139828, Max: 0.00454532
  2. one_node (pointer): Mean: 5.4087e-06, Median: 3.53647e-06, Max: 0.000275296
  3. two_node (not_pointer): Mean: 0.00235323, Median: 0.00236079, Max: 0.00825729
  4. two_node (pointer): Mean: 0.00088381, Median: 0.00087349, Max: 0.0030891
  5. two_nodelet (not pointer): Mean: 0.000689175, Median: 0.000686938, Max: 0.00333391
  6. two_nodelet (pointer): Mean: 5.41813e-05, Median: 4.98603e-05, Max: 0.000194368

となり,だいたい 2,6 <<< 5,4 < 1 < 3 くらいの順でメッセージのやり取りにかかる時間は大きくなりました.
 この結果から,やはりNodelet+shared_ptrの効果は絶大だということがわかりました.また,それが難しい場合でも,Nodelet化かメッセージの型をshared_ptrにするかのどちらかをするだけでも,メッセージやりとりの高速化になかなか効果があることがわかりました.

おまけ

 最初,subscribeする関数について,普通の型とshared_ptrにした型の2つを同じ名前でオーバーロードで実装していたのですが,こうすると普通の型で渡そうとしても,なぜか勝手にshared_ptrで渡されてしまい,思ったとおりの結果が出ないということがありました.ROSの機能なのかC++の機能なのかコンパイラの機能なのか,shared_ptrによるゼロコピーが可能な場合は,できるだけ自動でゼロコピーになるようになっているようです.

蛇足

 12月17日(土)に秋葉原で古今東西の(自称)ロボット屋を集めて忘年会をします.もしご興味がありましたら,ぜひご参加ください.参加者は毎回流動的なので,初めての方もお気軽にご参加ください.学生歓迎.詳しくはこちらのページで.
 申込み〆切までに登録しておいてもらえれば,参加者枠を広げられると思います.

追記(20/07/27)

 やり取りしているメッセージのサイズについて追記しました。

24
20
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
20