rosで、何ができるのかまとめてみた(初学者向け)
今回、rosについて改めて振り返ることがあったのでまとめてみました。いきなり本題から入ろうと思います。
一体、rosでは何ができるのか
rosは公式ページにもある通り、ロボットアプリケーションを構築するためのソフトウェアライブラリ、ツールセットです。ロボットを動かすと一言で表したとしても、その中身はとても複雑です。それでは、何が複雑なのかをまとめていきます。
さまざまなSensing moduleを使用する
ロボットを動かすにも、基本的には周囲環境の把握が必要です。つまり、さまざまなセンサーを使用することになります。rosではそれらセンサーデータを扱うためのドライバーやライブラリが準備されています。例としてよく使われるセンサーの一部をおいておきます。
カメラセンサー
センサーと言われて最初に思い浮かぶのはこのセンサーではないでしょうか。一般的には、RGBカメラが想像つくと思います。しかし、その他さまざまな用途にあったカメラがあります。気になったものがあったら調べてみてください。
Lidar
レーザー光を使ったセンサの一種で、対象物までの距離はもちろん、位置や形状まで正確に検知できることが特徴です。三次元空間における自己位置推定等によく使われます。
Radar
ミリ波帯の電波を利用して対象物との距離を計測し、周囲のセンシングに利用されます。Lidar同様物体形状や位置の特定を行えます。
imu
慣性計測装置のことで、3次元の慣性運動(直行3軸方向の並進運動および回転運動)を検出する装置です。オドメトリ計算等に使われます。
GNSS
衛星測位システムのことでよくGPSと呼ばれていて、自己位置推定で利用されています。
基本概念
上記は簡単なイメージ図です。この中で、矢印図(Publish,Sucscribe)のような通信部分や個々のプロセスをサポートしているのがrosです。図の赤い枠で囲まれている部分は個々のプロセス部分に相当し、nodeと言います。また、青い枠で囲まれた部分をTopicといい、node間でやりとりされるメッセージのことを指します。このように、rosではnode1つ1つが各処理を行い、それに必要な情報のやり取りをtopicという形で行っています。
それでは、もう少し細かくまとめていきます。
Node
上記の各処理に該当するのがNodeです。Nodeは、同じプロセス内、異なるプロセス内、別マシン上のNodeと通信することができます。また、Nodeを実行する際に動作を変更するためのパラメータを設定、提供することができます。
Discovery
Nodeで配信されているtopicは、特に設定されていない場合、容易に別マシンや別プロセスからアクセスすることができます。しかし、さまざまなプロセスが混在している環境や、他のロボットが複数存在する場合同一Topic名でやり取りを行うと競合を起こします。そこでrosでは、適切な通信を行うための機能が存在しています。具体的には、nodeを立ち上げると同じROSドメイン(環境変数でROS_DOMAIN_IDを設定)を持つネットワーク上のnodeにのみ、情報を公開することができます。また、同一タイミングで起動する必要はなく、あるnodeが公開するtopicをsubscribeするnodeが出現しだい、自動的にお互いを発見し、msg交換をし始めることができる。
Interfaces
ROSアプリケーションは通常、トピック、サービス、アクションの3つのタイプのいずれかのインターフェースを介して通信します。ROSは、簡略化された記述言語であるインターフェース定義言語(IDL)を使用して、これらのインターフェースを記述します。この記述により、ROSツールを使用することで、いくつかのターゲット言語でインターフェースタイプのソースコードを自動的に生成することが容易になります。これから提供されるインターフェースについて細かくまとめます。
1. Message
メッセージは、ROSノードがネットワーク上の他のROSノードにデータを送信するための方法です。例えば、ROSノードがセンサーから温度データを読み取った場合、Temperatureメッセージを使用してROSネットワーク上にそのデータを公開することができます。ROSネットワーク上の他のノードは、そのデータをサブスクライブし、Temperatureメッセージを受信することができるという仕組みです。
Fields
各フィールドは型と名前で構成され、スペースで区切られている。
fieldtype1 fieldname1
fieldtype2 fieldname2
fieldtype3 fieldname3
具体例として
int32 my_int
string my_string
Field types
使用できる型の一覧
Type name | C++ | Python | DDS type |
---|---|---|---|
bool | bool | builtins.bool | boolean |
byte | uint8_t | builtins.bytes* | octet |
char | char | builtins.str* | char |
float32 | float | builtins.float* | float |
float64 | double | builtins.float* | float |
int8 | int8_t | builtins.int* | octet |
uint8 | uint8_t | builtins.int* | octet |
int16 | int16_t | builtins.int* | short |
uint16 | uint16_t | builtins.int* | unsigned short |
int32 | int32_t | builtins.int* | long |
uint32 | uint32_t | builtins.int* | unsigned long |
int64 | int64_t | builtins.int* | long long |
uint64 | uint64_t | builtins.int* | unsigned long long |
string | std::string | builtins.str | string |
wstring | std::u16string | builtins.str | wstring |
配列の型も以下のように利用できる
Type name | C++ | Python | DDS type |
---|---|---|---|
static array | std::array<T, N> | builtins.list* | T[N] |
unbounded dynamic array | std::vector | builtins.list | sequence |
bounded dynamic array | custom_class<T, N> | builtins.list* | sequence<T, N> |
bounded string | std::string | builtins.str* | string |
Field names
変数名はすべて小文字の英数字でなければならない。また、単語の区切りにはアンダースコア(_)を使用する。さらに、アンダースコアを2回以上続けて使うことはできない。
Field default value
デフォルト値はメッセージ・タイプのどのフィールドにも設定できます。現在のところ、デフォルト値は文字列配列と複合型(上記の組み込み型の表にない型)には対応していない。
宣言方法は以下の通りです
fieldtype fieldname fielddefaultvalue
具体例は以下の通り
uint8 x 42
int16 y -2000
string full_name "John Doe"
int32[] samples [-200, -100, 0, 100, 200]
Constants
定数定義は、デフォルト値を持つフィールド記述のようなものであるが、この値を プログラムで変更することはできない。定数定義は以下に示すようにイコール(=)が用いられる。
宣言方法は以下の通り
constanttype CONSTANTNAME=constantvalue
具体例は以下の通り
int32 X=123
int32 Y=-123
string FOO="foo"
string EXAMPLE='bar'
2. Services
サービスはリクエスト/レスポンス型の通信を使用する。
Servicesには、Client(リクエスト側)とServer(レスポンス側)が存在し、Clientが送信した情報に対して、Serverが処理しレスポンスを返すという処理を行う。ここでやり取りを行うメッセージは.srv
というファイルで定義する必要がある。---
の上段でclientが送信するデータタイプの宣言をし、下段はServerで処理したresponseのデータタイプの宣言をする必要がある。
例として以下のように宣言する
string str
---
string str
また、定数を使用したい場合は以下のように宣言する
# request constants
int8 FOO=1
int8 BAR=2
# request fields
int8 foobar
another_pkg/AnotherMessage msg
---
# response constants
uint32 SECRET=123456
# response fields
another_pkg/YetAnotherMessage val
CustomMessageDefinedInThisPackage value
uint32 an_integer
Parameters
ROSのパラメータは個々のノードに関連付けられています。パラメータは、コードを変更することなく、起動時(および実行時)にノードを設定するために使用されます。各パラメータは、キー、値、記述子で構成される。キーは文字列で、値はbool
、int64
、float64
、string
、byte[]
、bool[]
、int64[]
、float64[]
、string[]
のいずれかの型です。rosは、ソースコードを変更するたびに基本的にbuildする必要があるがパラメータを用いることでソースコードを変更することなく定数値の値変更が可能。
Launch
rosのnodeを起動する際、まとめてnodeを起動したいケースなどが想定される。その際、Launchを使用することでまとめて起動することが可能になる。
以上がrosを扱う上で基本的に必要な概念となっています。
その他、重要事項としてROS_DOMAIN_ID,rqt tools,Ts2などあるので目を通しておくと良いと思います。
今回はrosの基本部分をまとめました。次回は実際にInstallおよびTutorialを勧めて行こうと思います。
Discussion