ROSでserviceによる通信
1. ROSパッケージを作る
cd ~/catkin_ws
catkin_create_pkg test_service rospy
新しくプロジェクトを作成した直後の~/catkin_ws/test_serviceのディレクトリ構成は以下のようなファイル階層だと思われる。
.
├── CMakeLists.txt
├── package.xml
└── src
2. サービスを定義する
新しいサービスを作成するには3ステップある。
- サービスコールの入出力のためのサービス定義ファイルの作成
- ビルドシステム1の変更
- ビルドシステム2の変更
1.サービス定義ファイルの作成
gedit ~/catkin_ws/src/test_service/srv/WordCount.srv
以下の文字列を貼り付ける
string words
---
uint32 count
2. ビルドシステム1の変更
CMakeLists.txtを3箇所変更する
find_package(catkin REQUIRED COMPONENTS
rospy
)
↓
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
message_generation
)
## Generate messages in the 'msg' folder
# add_message_files(
# FILES
# Message1.msg
# Message2.msg
# )
↓
## Generate messages in the 'msg' folder
add_message_files(
FILES
WordCount.msg
# Message2.msg
)
## Generate added messages and services with any dependencies listed here
# generate_messages(
# DEPENDENCIES
# std_msgs # Or other packages containing msgs
# )
↓
## Generate added messages and services with any dependencies listed here
generate_messages(
DEPENDENCIES
std_msgs # Or other packages containing msgs
)
3. ビルドシステム2の変更
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
3. サービスの動作確認を行う
プログラムのビルド
cd ~/catkin_ws
catkin_make
サービスコールの定義が期待したとおりかrossrvコマンドを使って確認する
rossrv show WordCount
以下のような出力が期待される
[test_service/WordCount]:
string words
---
uint32 count
次に、サービスのサーバ側のプログラムを作成する
gedit ~/catkin_ws/src/test_service/src/service_server.py
以下のコードをservice_server.pyに貼り付ける
#!/usr/bin/env python
import rospy
from test_service.srv import WordCount,WordCountResponse
# string型の引数を1つ取る
def count_words(request):
# 符号なし整数型を返す
return WordCountResponse(len(request.words.split()))
rospy.init_node('service_server')
service = rospy.Service('word_count', WordCount, count_words)
rospy.spin()
次に、サービス単体のテストを行う。 端末を1つ起動してroscoreを起動する
cd ~/catkin_ws
source devel/setup.bash
roscore
もう1つ端末を起動してservice_server.pyを起動する
cd ~/catkin_ws
chmod u+x ~/catkin_ws/src/test_service/src/service_server.py
source devel/setup.bash
rosrun test_service service_server.py
もう1つ端末を起動してservice_server.pyのテストを行う
source devel/setup.bash
rosservice call word_count 'a aa aaa'
以下のような出力が期待される
count: 3
4. サービスをプログラムから利用する
サービスのクライアント側のプログラムを作成する
gedit ~/catkin_ws/src/test_service/src/service_client.py
以下のコードをservice_client.pyに貼り付ける
#!/usr/bin/env python
import rospy
from test_service.srv import WordCount
import sys
rospy.init_node('service_client')
# word_countサービスが公開されるのを待つ
rospy.wait_for_service('word_count')
# ローカルプロキシにサービス名(word_count)と型(WordCount)を設定
word_counter = rospy.ServiceProxy('word_count', WordCount)
words = ' '.join(sys.argv[1:])
# word_counterが呼び出されたときにサービスコールが行われる
word_count = word_counter(words)
print words, '->', word_count.count
プログラムのビルド
cd ~/catkin_ws
catkin_make
端末を1つ起動してroscoreを起動する
cd ~/catkin_ws
source devel/setup.bash
roscore
もう1つ端末を起動してservice_server.pyを起動する
cd ~/catkin_ws
source devel/setup.bash
rosrun test_service service_server.py
もう1つ端末を起動してservice_client.pyを起動する
cd ~/catkin_ws
chmod u+x ~/catkin_ws/src/test_service/src/service_client.py
source devel/setup.bash
rosrun test_service service_client.py hoge poyo hoo bar
以下のような出力が期待される
hoge poyo hoo bar -> 4