📑

rosで、何ができるのかまとめてみた(初学者向け)

2023/11/22に公開

今回、rosについて改めて振り返ることがあったのでまとめてみました。いきなり本題から入ろうと思います。

一体、rosでは何ができるのか

rosは公式ページにもある通り、ロボットアプリケーションを構築するためのソフトウェアライブラリ、ツールセットです。ロボットを動かすと一言で表したとしても、その中身はとても複雑です。それでは、何が複雑なのかをまとめていきます。

さまざまなSensing moduleを使用する

ロボットを動かすにも、基本的には周囲環境の把握が必要です。つまり、さまざまなセンサーを使用することになります。rosではそれらセンサーデータを扱うためのドライバーやライブラリが準備されています。例としてよく使われるセンサーの一部をおいておきます。

カメラセンサー

センサーと言われて最初に思い浮かぶのはこのセンサーではないでしょうか。一般的には、RGBカメラが想像つくと思います。しかし、その他さまざまな用途にあったカメラがあります。気になったものがあったら調べてみてください。

Lidar

レーザー光を使ったセンサの一種で、対象物までの距離はもちろん、位置や形状まで正確に検知できることが特徴です。三次元空間における自己位置推定等によく使われます。

Radar

ミリ波帯の電波を利用して対象物との距離を計測し、周囲のセンシングに利用されます。Lidar同様物体形状や位置の特定を行えます。

imu

慣性計測装置のことで、3次元の慣性運動(直行3軸方向の並進運動および回転運動)を検出する装置です。オドメトリ計算等に使われます。

GNSS

衛星測位システムのことでよくGPSと呼ばれていて、自己位置推定で利用されています。

基本概念

describe
上記は簡単なイメージ図です。この中で、矢印図(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のパラメータは個々のノードに関連付けられています。パラメータは、コードを変更することなく、起動時(および実行時)にノードを設定するために使用されます。各パラメータは、キー、値、記述子で構成される。キーは文字列で、値はboolint64float64stringbyte[]bool[]int64[]float64[]string[]のいずれかの型です。rosは、ソースコードを変更するたびに基本的にbuildする必要があるがパラメータを用いることでソースコードを変更することなく定数値の値変更が可能。

Launch

rosのnodeを起動する際、まとめてnodeを起動したいケースなどが想定される。その際、Launchを使用することでまとめて起動することが可能になる。

以上がrosを扱う上で基本的に必要な概念となっています。
その他、重要事項としてROS_DOMAIN_ID,rqt tools,Ts2などあるので目を通しておくと良いと思います。

今回はrosの基本部分をまとめました。次回は実際にInstallおよびTutorialを勧めて行こうと思います。

Discussion