この記事は、ROSについてまとめてみる #1の続きです。
*尚、この記事の記載内容はROS1に関するものです。
#アーキテクチャ
ROSの詳細なアーキテクチャに関しては、こちらの本がとても分かりやすくまとめられています。(indigo)
ROSプログラミング(森北出版株式会社)
https://www.morikita.co.jp/books/book/3010
この本では、ROSのアーキテクチャを
- ファイルシステムレベル
- コンピュテーショングラフレベル
- コミュニティレベル
の三つに分けて記載しているので、本記事でもそれに則ってまとめていこうかと思います。
*2020/12/18追記
公式にも、Conceptとして同様の記述がありました。
http://wiki.ros.org/ja/ROS/Concepts
まずは、ファイルシステムから。
##ファイルシステム
###ワークスペース
ROSでプロジェクトを作成する際は、まずワークスペースを作成します。
そのワークスペースに対してパスを通すことで、各種ツールが使えるようになるわけです。
ワークスペース以下の構成はだいたいこんな感じです。
catkin_ws/
├ build
├ devel
└ src
ROSでのモジュールの基本単位はパッケージです。
開発者は、独自のパッケージや、gitからクローンしてきたパッケージを、/src以下に配置します。
その後、ビルドを行うことで、/build内にバイナリ、/devel内に実行ファイルなどが生成されます。
###パッケージ
パッケージはROSでの最小単位であり、おおよそ以下のような構成となります。
package/
├ bin/
├ include/
├ src/
│ ├ code1.cpp
│ └ code2.cpp
├ scripts/
│ ├ script1.py
│ └ script2.py
├ launch/
│ ├ launch1.launch
│ └ launch2.launch
├ msg/
├ srv/
├ CMakeList.txt
└ package.xml
内容はこんな感じ
- include/
.hファイルとかを置きます。 - src/
ソースコードを置きます。 - scripts/
Bashファイルや.pyファイルなどの実行ファイルを置きます。 - launch/
.launchファイルを置きます。
(ROSには、roslaunchというノードを一斉に起動するツールがあり、それが実行時に読み込むファイルです) - msg/
メッセージの型を定義するファイルを置きます。
(ROSでは独自のデータタイプを定義することもできます。その場合、ここにその定義を記したファイルを置きます。) - srv/
上のmsgと同様、サービスの型を定義するファイルを置きます。 - CMakeLists.txt
CMake用のビルドファイルです。
(ROSではcatkin_make, catkin buildを介して読み込まれるのが一般的です。) - package.xml
パッケージの基本的な情報が記載されます。パッケージ名、ライセンス情報、依存関係、コンパイルのフラグなどです。
基本的にはC++で作成する一般的なプロジェクトの沿っているのかな?と思います。
実体のあるロボットの場合は、メッシュ(.stl, .dae)や機構のデータ(.urdf, .xacro)などもあるかもしれません。
ここに記載されていないフォルダやファイルがあったり、なかったりするかもしれませんが、おおよそこんな感じになっているはずです。
ROSではこのような単位をpackageとして扱い、管理しています。
こうすることでrospackやcatkin_makeなどのツールが使えるようになったり、rosbashの各種コマンドが使えるようになったりします。
###ビルドシステム
現在のROSでは、デフォルトでcatkin_makeというビルドツールがインストールされます。
これはCMakeのマクロとPythonスクリプトを組み合わせたROS専用のビルドシステムで、先述のパッケージに対してビルドを行います。
現在は並列ビルドが可能になったり、いろいろ便利になったcatkin buildという新しいビルドシステムがあり、そちらへ移行が進んでいます。
###roscore
roscoreは、rosのノードがお互いにメッセージを通信できるよう、ノードに接続情報を提供するサービスです。Web系やってた人なら、WebRTCとかがイメージに近いかと思います。また、パラメーターサーバーという、グローバルから見える多変量辞書のようなサービスも提供しており、静的なパラメータを格納するのに使われます。
####メッセージ
ROSの分散システムを実現している目玉機能。ROSではトピック通信と呼びます。
ROSでは、一つのプロセスの単位をノードと呼びます。(ROS2ではスレッド単位らしいです)
ノードは、起動時にroscoreに自分の配信(publish)するトピックと、購読(subscribe)したいトピックを登録します。
あとはroscoreが相手のピアを見つけてくれるので、それ以降はノード同士のピアツーピアの通信となります。
後からノードを追加した場合なども、roscoreがよしなにやってくれます。
メッセージのデータ型に関しても、標準的なものは用意されており、複数言語での実装でも問題のないように取り決められています。これらのデータ型は独自に設定が可能な上、headerにタイムスタンプやフレームIDを持たせることもでき、メッセージの時系列的な管理もできます。
####サービス
ROSでは、上記のメッセージのようなPub/Sub型の通信のみでなく、Req/Rep型(クライアント-サーバ型)の通信も提供しています。サービスとは、あるノードが提供する関数(サービス)を、他のノードが利用する仕組みのことです。
使用頻度が高くなく、短い時間で処理が終わるものに適しています。
センサーのスイッチを入れたり、シャッターを押したりといったような操作などです。
#3へつづく
#参考
ROS講座64 ROSパッケージのディレクトリ構成
https://qiita.com/hatt_takumi/items/2cbaab30a237fca24357
プログラミングROS(O'Reilly Japan)
https://www.oreilly.co.jp/books/9784873118093/
ROSプログラミング(森北出版株式会社)
https://www.morikita.co.jp/books/book/3010