ROSメッセージとサービス
Simple Wiki Based Contents Management System
関心分野 >> Ros4Winのインストール >> ROSメッセージとサービス

ROSメッセージとサービス

メッセージとサービス

ROSにおけるノード間の通信には、大きく分けてメッセージとサービスがあります。メッセージは、ノード間の一方向のデータ通信である、サービスは、リクエスト‐レスポンスからなる遠隔手続きの呼出しです。
それぞれの通信時のデータ型を定義するためにメッセージファイル(.msg)とサービスファイル(.srv)を設定しなればいけません。ROSシステムでは、よく使うデータ型については予め定義されているものもありますが、独自のデータ型を設定することもできます。

メッセージ定義ファイル

メッセージのデータ型は、メッセージのデータ型名と変数名のペアを一行ごとに記述したテキストファイルです。拡張子は、「.msg」を使います。C言語のstruct型の宣言にも似ています。
例えば、2次元の整数(x, y)からなるデータ型は、下のように記述できます。
int64 x
int64 y
上記の例では、64ビットの整数型2要素からなるデータ型になります。

サービス定義ファイル

サービスファイルは、リクエストとレスポンスの2つのメッセージを合わせたテキストファイルのようなものです。データ型の定義は、メッセージと同じようにデータ型名と変数名のペアを一行ごと記述し、リクエストとリプライの間を'---'で区切ります。
例えば、リクエストに2つの整数(x, y)でレスポンスに1つの整数(s)であるサービスの場合、下のように記述できます。
int64 x
int64 y
---
int64 s

独自メッセージを定義

先ほど作成したROSパッケージ mytutに新しいメッセージを定義します。

msgファイルの作成

ROSにおいて独自メッセージを定義するには、パッケージのディレクトリの下の'msg'というディレクトリにmsgファイル配置する必要があります。例えば、下のようにNum.msgというmsgファイルを作ることができます。
 > cd /d C:\catkin_ws\src
 C:\catkin_ws\src> mkdir msg
 C:\catkin_ws\src> echo int64 num > msg\Num.msg
この例では、1つの整数型の要素を持つ独自データ型になります。もちろん下のような複雑なmsgファイルを作成することができます。
string first_name
string last_name
uint8 age
uint32 score
これでメッセージ型の定義は完了なのですが、このメッセージ型をC++やPythonのプログラムで利用するには、package.xmlとCMakeists.txtを修正し、catkin_makeのプロセスにメッセージ生成のしなければいけません。まず、package.xmlを修正します。

package.xmlの修正

package.xmlをエディタで開き下の2か所を探して、コメントタグを外してください。
  <!-- Use build_depend for packages you need at compile time: -->
     <build_depend>message_generation</build_depend> 
   ...

  <!-- Use exec_depend for packages you need at runtime: -->
     <exec_depend>message_runtime</exec_depend> 
     ...
''build_dependタグ''はビルド時に有効になっている必要があり、''exec_dependタグ''は実行時に有効になっている必要があります。

CMakeLists.txtの修正

次に、CMakeLists.txtを開き修正を行います。Ros4Winでもrosedコマンドを使用することができますが、デフォルトの設定は、Visual Studio Code(code.exe)になっています。もし他のエディタをインストールしていない場合には、Ros4Winには、vimが同梱されえていますので、環境変数 EDITORに \local\vim\gvim.exeを設定しても良いと思います。
メッセージ型の変換のためのCMakeLists.txtは、
  • find_packageの項にmessage_generationの依存項目を追加
  • catkin_packageの項にmessage_runtimeの依存項目を追加
  • add_message_filesの項に該当するファイル名を追加
  • generate_messagesの項を追加
の4か所の修正が必要になります。
find_packageの項の修正
find_packageの項は、初期状態ではパッケージ生成時に設定したパケージ名のみが記載されていると思います。それに対して、''message_generation'' を追記してください。これによって、catkin_makeコマンドの実行によってメッセージの生成を行うことができます。
find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)
catkin_packageの項の修正
次にcatkin_packageの項目を修正します。この項目は、パッケージのcmakeの設定ファイルを生成します。catkin_packageの項の中は、初期状態ではコメントアウトされていますので、下のようにCATKIN_DEPENDSの項を有効にして''message_runtime'' を追記してください。
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES mytut
  CATKIN_DEPENDS message_runtime roscpp rospy std_msgs
#  DEPENDS system_lib
)
add_message_filesの項の修正
add_message_filesの項目は、変換したいメッセージ型を定義したファイル名を指定します。CMakeLists.txtの初期状態では、この項目は下のようにコメントアウトされています。
# add_message_files(
#   FILES
#   Message1.msg
#   Message2.msg
# )
この部分のコメントマーク(#)を消去し、Message*.msgを先ほど作成したmsgファイル(Num.msg)に置き換えます。
 add_message_files(
   FILES
   Num.msg
 )
generate_messagesの項の修正
最後に、generate_messagesの項目を有効にして、cmakeにメッセージ生成のプロセスを認識させます。CMakeLists.txtの初期状態では、この項目も下のようにコメントアウトされています。
# generate_messages(
#   DEPENDENCIES
#   std_msgs
# )
この項目部分のコメントマークを消去します。独自に定義したメッセージ型がstd_msgs以外に依存していれば、DEPENDENCIESの項目にパッケージ名の追加を行ってください。(このチュートリアルでは、コメントマークの消去のみで大丈夫です)
 generate_messages(
   DEPENDENCIES
   std_msgs
 )

rosmsgコマンドで確認する

rosmsgコマンドは、ROSシステムにインストールされているメッセージ型を調べることができます。rosmsgを引数なしで実行すると下のような使用方法が表示されます。
 >rosmsg
rosmsg is a command-line tool for displaying information about ROS Message types.

Commands:
        rosmsg show     Show message description
        rosmsg info     Alias for rosmsg show
        rosmsg list     List all messages
        rosmsg md5      Display message md5sum
        rosmsg package  List messages in a package
        rosmsg packages List packages that contain messages

Type rosmsg <command> -h for more detailed usage
では、先ほど作成した独自メッセージの定義を表示してみます。メッセージ型の内容を調べるには、'rosmsg show [package_name/message_name]'と実行します。
 >rosmsg show mytut/Num
int64 num
このようにmsg/Num.msgの内容が表示されると思います。この書式では、パッケージ名とメッセージ名のペアを指定していますが、rosmsgコマンドは、メッセージ名のみを引数として(パッケージ名を省略して)も実行することができます。例えば、上記の例では下のように調査したメッセージがどのパッケージで定義されているかも表示されます。
 >rosmsg show Num
[mytut/Num]:
int64 num

サービスの定義

次に、作成してパッケージmytutにサービスを定義します。

srvファイルの作成

サービスを定義するファイルは、前に述べたようにリクエストとレスポンスの組になった変数とデータ型を含んだテキストファイルです。このファイルは、srvという拡張子を持つファイル(srvファイル)でパッケージのディレクトリの直下のsrvというディレクト内に配置しなければいけません。そこで、srvファイルを置くためのディレクトリを下のように作成します。
 > roscd mytut
 C:\catkin_ws\src\mytut> mdir srv
通常は、テキストエディタでsrvファイルを作成するのですが、ここでは他のパッケージで定義されたsrvファイルをコピーしたいと思います。
ROSシステム内のパッケージに定義されているファイルをコピーする場合には、roscpコマンドを使用します。roscpコマンドは、''roscp [package] [file_name] [target]'' という書式で実行します。
では、rospy_tutorialsに定義されているAddTowInts.srvをmytutにコピーします。
 C:\catkin_ws\src\mytut>roscp rospy_tutorials srv/AddTwoInts.srv srv/
 F:\opt\ros\melodic\share\rospy_tutorials\srv\AddTwoInts.srv
1 個のファイルをコピーしました
コピーされたファイルを確認するためにtypeコマンドで内容を見てみましょう。
 C:\catkin_ws\src\mytut>type srv\AddTwoInts.srv
int64 a
int64 b
---
int64 sum
このファイルの内容がrospy_tutorialsにあるファイルと同じかどうか確認するために、roscatコマンドでrospy_tutorialsに定義されているファイルを見てみましょう。
 C:\catkin_ws\src\mytut>roscat rospy_tutorials srv/AddTwoInts.srv
int64 a
int64 b
---
int64 sum
このように別のパッケージからファイルがコピーされていることがわかりました。以上で、サービスの定義が終わりました。
次に、メッセージを定義したときと同様に、定義したサービスをC++やPythonのプログラムで利用するには、packagepackage.xmlとCMakeLists.txtを編集する必要があります。package.xmlに関しては、メッセージの場合と同様ですので、メッセージの作成をしているのであれば、特に実施することはありませんのでCMakeLists.txtの修正に進みます。

CMakeLists.txtの修正

パッケージのサービスの実装に必要な生成プロセスを有効にするには、メッセージと同様に下記の4か所の修正が必要です。
  • find_packageの項にmessage_generationの依存項目を追加
  • catkin_packageの項にmessage_runtimeの依存項目を追加
  • add_service_filesの項に該当するファイル名を追加
  • generate_messagesの項を追加
上記の4項目のうち1,2,4番目の項目に関しては、メッセージの定義と同じですので、すでにメッセージの定義を実施していれば、修正の必要はありません。
add_service_filesの項の修正
add_service_filesの項目は、変換したいサービスを定義したファイル名を指定します。CMakeLists.txtの初期状態では、この項目は下のようにコメントアウトされています。
# add_service_files(
#   FILES
#   Service1.srv
#   Service2.srv
# )
この部分のコメントマーク(#)を消去し、Service*.srvを先ほど作成したsrvファイル(AddTwoInts.srv)に置き換えます。
 add_service_files(
   FILES
   AddTwoInts.srv
 )
以上でサービスの定義からソースコードを生成する準備は終了です。

rosrvコマンドで確認する

rossrvコマンドは、ROSシステムにインストールされているサービスを調べることができます。rossrvを引数なしで実行すると下のような使用方法が表示されます。
 >rossrv
rossrv is a command-line tool for displaying information about ROS Service types.

Commands:
        rossrv show     Show service description
        rossrv info     Alias for rossrv show
        rossrv list     List all services
        rossrv md5      Display service md5sum
        rossrv package  List services in a package
        rossrv packages List packages that contain services

Type rossrv <command> -h for more detailed usage
では、先ほど作成したサービスの定義を表示してみます。サービスの内容を調べるには、'rossrv show [package_name/service_name]'と実行します。
 >rossrv show mytut/AddTwoInts
int64 a
int64 b
---
int64 sum
rossrvコマンドもrosmsgコマンドと同様に、パッケージ名を省略することもできます。上記の例と同じようにサービス名のみを指定すると下のようになると思います。
 >rossrv show AddTwoInts
[rospy_tutorials/AddTwoInts]:
int64 a
int64 b
---
int64 sum

[mytut/AddTwoInts]:
int64 a
int64 b
---
int64 sum
ここでは、2つのサービス定義が出力されました。

メッセージとサービスの生成

メッセージとサービスの定義と生成プロセスの定義が終わりましたので、C++, Pythonのプログラムで利用するためのソースコードの生成を行います。
catkin形式のパッケージでは、catkin_makeコマンドを実行すれば、メッセージ、サービスの生成を行うことができます。Ros4Winでは、最初にワークスペースを生成したときと同じように、Viusal Studio 2017 Win64を使うように ''--use-vc15''オプションを付加してワークスペースのトップで実行します。
ワークスペースのトップディレクトリで set_roswsコマンドを実行していれば、roscdコマンドで移動できます。
 > roscd
 C:\catkin_ws> catkin_make --use-vc15
 ....
 ....
以上で、ROSパッケージでのメッセージとサービスの生成は終了です。