ROS2 Tutorials – Topics, Services, Parameters, and Actions

はじめに

今回は通信方法関連のチュートリアルをトレースする備忘.

ROS2 では DDS(Data Distribution Service) をベースにしたトピック,サービス,パラメータ,アクションといった通信方式やインタフェースを利用してノード間通信を行う.

公式ドキュメントではそれぞれチュートリアルが別々に用意されているが,全体像を整理したかったのでこれらのチュートリアルを適当にまとめる.なお,長くなりそうなのでチュートリアル Understanding nodes 及びいくつかの細かい説明は省略する.長くなりそうなので rqt の説明も端折るが,ros2 コマンドでの状態確認とあわせて rqt でも対応する状態確認をすることをおすすめする.

Understanding topics — ROS 2 Documentation: Iron documentation
Understanding services — ROS 2 Documentation: Iron documentation
Understanding parameters — ROS 2 Documentation: Iron documentation
Understanding actions — ROS 2 Documentation: Iron documentation

Topics

Topic は Publish-Subscribe モデルの通信方式で,Topic を介して1対多,多対1,多対多のノード間通信ができる.

turtlesim で利用しているトピックは次のように確認でき,cmd_vel ではPublisher が1つ,Subscriber が1つとなっていることが分かる.また各トピックには型が定義されており,cmd_vel は3つの要素からなる2つのベクトルとして設定されている.

$ ros2 node list
/teleop_turtle
/turtlesim
$ ros2 topic list --show-types 
/parameter_events [rcl_interfaces/msg/ParameterEvent]
/rosout [rcl_interfaces/msg/Log]
/turtle1/cmd_vel [geometry_msgs/msg/Twist]
/turtle1/color_sensor [turtlesim/msg/Color]
/turtle1/pose [turtlesim/msg/Pose]
$ ros2 topic info /turtle1/cmd_vel 
Type: geometry_msgs/msg/Twist
Publisher count: 1
Subscription count: 1
$ ros2 interface show geometry_msgs/msg/Twist
# This expresses velocity in free space broken into its linear and angular parts.

Vector3  linear
        float64 x
        float64 y
        float64 z
Vector3  angular
        float64 x
        float64 y
        float64 z

トピックで公開されているデータは echo コマンドで確認することができる.矢印キーでカメを動かしながら,以下の ros2 topic echo コマンドを使うとカメの移動データを見ることができる.

$ ros2 topic echo /turtle1/cmd_vel 
linear:
  x: 0.0
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 2.0
---

逆に ros2 コマンドからメッセージを Publish することでカメを操作することもできる.--once オプションを使うとメッセージを1度だけ発行することができ,--rate オプションを使うと継続的に(ここでは 1Hz の周期で)メッセージを発行することができる.

$ ros2 topic pub --once /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"
publisher: beginning loop
publishing #1: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=2.0, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=1.8))

$ ros2 topic pub --rate 1 /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"
publisher: beginning loop
publishing #1: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=2.0, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=1.8))

publishing #2: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=2.0, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=1.8))

publishing #3: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=2.0, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=1.8))
...

Services

Service は call-and-response モデルの通信方式で,Service Client が Request Message を送信すると Service Server が Response Message を返す.Service Client は複数設定できるが,Service Server は1つのみしか設定できない.

turtlesim で利用しているサービスは次のように確認できる.本節ではハイライトした Turtlesim 固有のサービスについてフォーカスする.両ノードのサービス名には parameteres と含まれるサービスが設定されているが,これらは Infrastructure services と呼ばれるもので,パラメータの節で説明する.

$ ros2 node list
/teleop_turtle
/turtlesim
$ ros2 service list --show-types 
/clear [std_srvs/srv/Empty]
/kill [turtlesim/srv/Kill]
/reset [std_srvs/srv/Empty]
/spawn [turtlesim/srv/Spawn]
/teleop_turtle/describe_parameters [rcl_interfaces/srv/DescribeParameters]
/teleop_turtle/get_parameter_types [rcl_interfaces/srv/GetParameterTypes]
/teleop_turtle/get_parameters [rcl_interfaces/srv/GetParameters]
/teleop_turtle/get_type_description [type_description_interfaces/srv/GetTypeDescription]
/teleop_turtle/list_parameters [rcl_interfaces/srv/ListParameters]
/teleop_turtle/set_parameters [rcl_interfaces/srv/SetParameters]
/teleop_turtle/set_parameters_atomically [rcl_interfaces/srv/SetParametersAtomically]
/turtle1/set_pen [turtlesim/srv/SetPen]
/turtle1/teleport_absolute [turtlesim/srv/TeleportAbsolute]
/turtle1/teleport_relative [turtlesim/srv/TeleportRelative]
/turtlesim/describe_parameters [rcl_interfaces/srv/DescribeParameters]
/turtlesim/get_parameter_types [rcl_interfaces/srv/GetParameterTypes]
/turtlesim/get_parameters [rcl_interfaces/srv/GetParameters]
/turtlesim/get_type_description [type_description_interfaces/srv/GetTypeDescription]
/turtlesim/list_parameters [rcl_interfaces/srv/ListParameters]
/turtlesim/set_parameters [rcl_interfaces/srv/SetParameters]
/turtlesim/set_parameters_atomically [rcl_interfaces/srv/SetParametersAtomically]

サービスの型には Request と Response のデータ構造が定義されている.データ構造は次のコマンドで確認することができる.— の上側は Request,下側は Response のデータ構造を表す.特に /clear/reset は Empty という型で,Request や Response でデータを送受信しない.

$ ros2 interface show turtlesim/srv/Spawn
float32 x
float32 y
float32 theta
string name # Optional.  A unique name will be created and returned if this is empty
---
string name
$ ros2 interface show turtlesim/srv/Kill
string name
---
$ ros2 interface show std_srvs/srv/Empty
---

ros2 service call コマンドを使うとサービスを call することができる.例えば Empty 型の /clear を呼び出すには次のようにする.カメの軌跡を消すことができた.

$ ros2 service call /clear std_srvs/srv/Empty
requester: making request: std_srvs.srv.Empty_Request()

response:
std_srvs.srv.Empty_Response()

/spawn を呼ぶには次のようにする.2匹目のカメが生成された.

$ ros2 service call /spawn turtlesim/srv/Spawn "{x: 2, y: 2, theta: 0.2, name: ''}"
requester: making request: turtlesim.srv.Spawn_Request(x=2.0, y=2.0, theta=0.2, name='')

response:
turtlesim.srv.Spawn_Response(name='turtle2')

Parameters

パラメータはノードの設定値として,整数,浮動小数点,ブール値,文字列,リストを保持できる.

各ノードのパラメータ一覧は次のように確認できる.どちらのノードにも use_sim_time というパラメータがあるが,これは turtlesim 特有のものではない.

$ ros2 node list 
/teleop_turtle
/turtlesim
$ ros2 param list 
/teleop_turtle:
  qos_overrides./parameter_events.publisher.depth
  qos_overrides./parameter_events.publisher.durability
  qos_overrides./parameter_events.publisher.history
  qos_overrides./parameter_events.publisher.reliability
  scale_angular
  scale_linear
  start_type_description_service
  use_sim_time
/turtlesim:
  background_b
  background_g
  background_r
  holonomic
  qos_overrides./parameter_events.publisher.depth
  qos_overrides./parameter_events.publisher.durability
  qos_overrides./parameter_events.publisher.history
  qos_overrides./parameter_events.publisher.reliability
  start_type_description_service
  use_sim_time

ここでは background_g を使ってパラメータ値の確認と変更を行ってみる.背景が紫色に変わった.

$ ros2 param get /turtlesim background_g
Integer value is: 86
$ ros2 param set /turtlesim background_r 150
Set parameter successful

パラメータは Yaml 形式で dump/load することができる.

$ ros2 param dump /turtlesim > turtlesim.yaml
$ cat turtlesim.yaml 
/turtlesim:
  ros__parameters:
    background_b: 255
    background_g: 86
    background_r: 150
    holonomic: false
    qos_overrides:
      /parameter_events:
        publisher:
          depth: 1000
          durability: volatile
          history: keep_last
          reliability: reliable
    start_type_description_service: true
    use_sim_time: false
$ ros2 param load /turtlesim turtlesim.yaml
Set parameter background_b successful
Set parameter background_g successful
Set parameter background_r successful
Set parameter holonomic successful
Set parameter qos_overrides./parameter_events.publisher.depth failed: parameter 'qos_overrides./parameter_events.publisher.depth' cannot be set because it is read-only
Set parameter qos_overrides./parameter_events.publisher.durability failed: parameter 'qos_overrides./parameter_events.publisher.durability' cannot be set because it is read-only
Set parameter qos_overrides./parameter_events.publisher.history failed: parameter 'qos_overrides./parameter_events.publisher.history' cannot be set because it is read-only
Set parameter qos_overrides./parameter_events.publisher.reliability failed: parameter 'qos_overrides./parameter_events.publisher.reliability' cannot be set because it is read-only
Set parameter start_type_description_service failed: parameter 'start_type_description_service' cannot be set because it is read-only
Set parameter use_sim_time successful

パラメータファイルはノードの起動時にもロードすることができる.一旦 turtlesim のウィンドウを閉じて,設定ファイルをロードしながら起動すると,先程設定した背景が紫色の状態でウィンドウが立ち上がる.

$ ros2 run turtlesim turtlesim_node --ros-args --params-file turtlesim.yaml
[INFO] [turtlesim]: Starting turtlesim with node name /turtlesim
[INFO] [turtlesim]: Spawning turtle [turtle1] at x=[5.544445], y=[5.544445], theta=[0.000000]

Actions

アクションは Goal,Feedback,Result の3要素で構成され,長時間実行されるタスクで使用される.

アクションは Client-Server モデルの通信方式で,ここまでに説明したトピックとサービスで構成され,サービスと違いアクションはキャンセルすることができる.またサービスでは単一のレスポンスを返すのみだが,アクションではフィードバックにトピックを利用できる.

アクションクライアントはアクションサーバに目標値(Goal)を送信し,アクションサーバからはフィードバック(Feedback)と結果(Result)を返す.

  1. Goal Service Request
  2. Goal Serivce Response
  3. Result Service Request
  4. Feedback
  5. Result Service Response

turtlesim_node と turtle_teleop_key を起動して Action の動作を観察してみる.

/teleop_turtle では F キーがアクションキャンセル,F キー周囲がカメの方向を決める操作ができる.

ERT
DFG
CVB

特定の方向を向き終わると回転完了結果のメッセージングが表示される.

[INFO] [turtlesim]: Rotation goal completed successfully

F キーで回転をキャンセルした場合は次のようなメッセージングが表示される.

[INFO] [turtlesim]: Rotation goal canceled

回転途中に別のゴールを指定すると最初のゴールを中止して,新しいゴールまで移動する.この動作は実装次第で,新しい目標を拒否したり,1つ目の目標が達成されたあとに次の目標まで移動したりすることもできる.

[WARN] [turtlesim]: Rotation goal received before a previous goal finished. Aborting previous goal

ros2 action コマンドから turtlesim のアクションの状態を見ると次の通り.アクションが1つ設定されており,/turtlesim が Action Server,/teleop_turtle が Action Client になっていることが分かる.

$ ros2 action list --show-types 
/turtle1/rotate_absolute [turtlesim/action/RotateAbsolute]
$ ros2 action info /turtle1/rotate_absolute 
Action: /turtle1/rotate_absolute
Action clients: 1
    /teleop_turtle
Action servers: 1
    /turtlesim

RotateAbsolute のインタフェース情報を確認してみると次のようになっている.上から Goal,Result,Feedback のデータ定義となっている.

$ ros2 interface show turtlesim/action/RotateAbsolute
# The desired heading in radians
float32 theta
---
# The angular displacement in radians to the starting position
float32 delta
---
# The remaining rotation in radians
float32 remaining

ここまで分かると ros2 action send_goal コマンドからもカメを操作することができる.すべてのゴールは一意な ID を持っている.今回のコマンドでは次のように Goal と Result が表示される.

$ ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: 1.57}"
Waiting for an action server to become available...
Sending goal:
     theta: 1.57

Goal accepted with ID: 949a5fef4d7d4a6d9b9fefc45892e6b2

Result:
    delta: 2.3359999656677246

Goal finished with status: SUCCEEDED

途中の Feedback を見たい人は --feedback オプションをつけるといい.

$ ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: -1.57}" --feedback
Waiting for an action server to become available...
Sending goal:
     theta: -1.57

Feedback:
    remaining: 3.129185199737549

Goal accepted with ID: 67d1d842a3f74b1cb886716535ffc338

Feedback:
    remaining: 3.113185167312622

--中略--

Feedback:
    remaining: 0.009185194969177246

Result:
    delta: -3.119999885559082

Goal finished with status: SUCCEEDED

おわりに

今回は ROS2 の重要な機能である Topics,Services,Parameters,Actions について整理した.公式の4つのチュートリアルをまとめているので,ちょっとだけ公式から情報落としている部分もある気がする.気になる人は公式見てどうぞ.

コメント

タイトルとURLをコピーしました