# メッセージ以外の通信方法
---
## ROSサービス
- ROSの要求/応答(サーバー・クライアント)タイプの通信方法
- サーバーはサービスを提供します
- クライアントは、サービスを実行するようにサーバーに要求を送信します
---
### サービスの操作
`rosservice`コマンドの使用:
```bash
# 利用可能なサービスをプリントする
rosservice list
# サービスタイプを表示
rosservice type /<サービス名>
# 特定の引数を使用したサービスコール
rosservice call /<サービス名> <引数>
```
---
### サービス用メッセージの定義
- *.srv*ファイルでの定義
- 構造はROSメッセージの定義(.msgファイル)に似ていますが、要求の形式と応答の形式は別々に定義されています("`---`"を含む行で区切られています)
例:
*std_srvs/Trigger.srv*
(要求を出すときはパラメータを使わない、応募のメッセージは成功のフラグと結果のStringが含まれている)
```txt
---
bool success
string message
```
*nav_msgs/GetPlan.srv*:
(経路計画サービス:スタートと目的地をサーバーに送れば、経路を返す)
```txt
geometry_msgs/PoseStamped start
geometry_msgs/PoseStamped goal
float32 tolerance
---
nav_msgs/Path plan
```
---
### サービスを操作するためのAPI
サーバーの作成
(ROSメッセージと同様に、呼び出しが受信されると、コールバック関数で処理します)
```python
rospy.Service('サービス名', サービスのタイプ, コールバック関数)
```
クライアント:サービスコール
```python
rospy.wait_for_service('サービス名')
try:
service = rospy.ServiceProxy('サービス名', サービスのタイプ)
service()
# ...
except rospy.ServiceException as e:
rospy.logerr("エラーメッセージ: %s"%e)
```
例については、`rospy_tutorials`パッケージ内の` add_two_ints_client`および `add_two_ints_server`を参照してください。
ドキュメント:https://wiki.ros.org/ja/rospy_tutorials/Tutorials/WritingServiceClient
---
## ROSアクション
ROSサービスでできないこと
- サービスの実行を中断する
- サービスの進行状況に関する情報を得る
このような機能が必要な時はROSの*アクション*を使用できます
ROSパッケージ*actionlib*で定義
詳細: https://wiki.ros.org/ja/actionlib
---
## 通信方法の比較
いつどの方法を使用すればいいですか?
- **トピック・メッセージ** ⇒ 継続的なデータ通信(センサの測定データ、モーターの制御命令など)
- **サービス** ⇒ 早く終了する不定期のルーチン(ノードの状況に関するクエリ、簡単な計算、タスク開始の要求など)
- **アクション** ⇒ 完了までに長い時間(数秒)かかるルーチンの場合、特に実行状態が知りたい場合
(イラストは本「ROS ロボットプログラミングバイブル」からのものです)
---
→ [実習その2](v3_2.html)
← [イントロ](v3_intro.html)
↑ [ホームページ](index.html)