Skip to content

アクションの理解

目標: ROS 2のアクションについて内部検査する。

チュートリアルレベル: 初心者

所要時間: 15分

背景

アクションはROS 2の通信タイプの一つで、長時間実行されるタスクを対象としています。 アクションは3つの部分から構成されます:ゴール(目標)、フィードバック、および結果です。

アクションはトピックとサービスの上に構築されています。 機能はサービスに似ていますが、アクションはキャンセルが可能です。 また、単一のレスポンスを返すサービスとは異なり、継続的なフィードバックを提供します。

アクションは、パブリッシャー-サブスクライバーモデル(トピックチュートリアルで説明)と同様に、クライアント-サーバーモデルを使用します。 「アクションクライアント」ノードが「アクションサーバー」ノードにゴールを送信し、サーバーはゴールを受信してフィードバックのストリームと結果を返します。

アクション通信の図

前提条件

このチュートリアルは、以前のチュートリアルで扱ったノードトピックなどの概念に基づいています。

このチュートリアルではturtlesimパッケージを使用します。

いつものように、新しいターミナルを開くたびにROS 2をソースすることを忘れないでください。

タスク

1 セットアップ

2つのturtlesimノード、/turtlesim/teleop_turtleを起動します。

新しいターミナルを開いて実行します:

bash
ros2 run turtlesim turtlesim_node

別のターミナルを開いて実行します:

bash
ros2 run turtlesim turtle_teleop_key

2 アクションの使用

/teleop_turtleノードを起動すると、ターミナルに以下のメッセージが表示されます:

Use arrow keys to move the turtle.
Use G|B|V|C|D|E|R|T keys to rotate to absolute orientations. 'F' to cancel a rotation.

2行目に注目しましょう。これがアクションに対応しています。 (1行目の指示は、以前のトピックチュートリアルで説明した「cmd_vel」トピックに対応しています。)

文字キーG|B|V|C|D|E|R|Tが、US QWERTYキーボードのFキーを囲む「ボックス」を形成していることに注意してください(QWERTYキーボードを使用していない場合は、このリンクを参照してください)。 F周りの各キーの位置は、turtlesimでのその方向に対応しています。 例えば、Eはタートルの方向を左上角に回転させます。

/turtlesimノードが実行されているターミナルに注意してください。 これらのキーのいずれかを押すたびに、/turtlesimノードの一部であるアクションサーバーにゴールを送信しています。 ゴールは、タートルを特定の方向に向けて回転させることです。 タートルが回転を完了すると、ゴールの結果を伝えるメッセージが表示されるはずです:

[INFO] [turtlesim]: Rotation goal completed successfully

Fキーはゴールの実行中にキャンセルします。

Cキーを押してから、タートルが回転を完了する前にFキーを押してみてください。 /turtlesimノードが実行されているターミナルに、以下のメッセージが表示されます:

[INFO] [turtlesim]: Rotation goal canceled

クライアント側(teleopでの入力)だけでなく、サーバー側(/turtlesimノード)もゴールを停止することができます。 サーバー側がゴールの処理を停止することを選択した場合、そのゴールを「中断」したと言います。

Dキーを押してから、最初の回転が完了する前にGキーを押してみてください。 /turtlesimノードが実行されているターミナルに、以下のメッセージが表示されます:

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

このアクションサーバーは、新しいゴールを受け取ったため最初のゴールを中断することを選択しました。 新しいゴールを拒否したり、最初のゴールが終了した後に2番目のゴールを実行するなど、他の選択肢もありました。 すべてのアクションサーバーが新しいゴールを受け取ったときに現在のゴールを中断することを選択するとは限りません。

3 ros2 node info

ノードが提供するアクションのリストを確認するには、この場合は/turtlesimについて、新しいターミナルを開いてコマンドを実行します:

bash
ros2 node info /turtlesim

出力:

/turtlesim
  Subscribers:
    /parameter_events: rcl_interfaces/msg/ParameterEvent
    /turtle1/cmd_vel: geometry_msgs/msg/Twist
  Publishers:
    /parameter_events: rcl_interfaces/msg/ParameterEvent
    /rosout: rcl_interfaces/msg/Log
    /turtle1/color_sensor: turtlesim/msg/Color
    /turtle1/pose: turtlesim/msg/Pose
  Service Servers:
    /clear: std_srvs/srv/Empty
    /kill: turtlesim/srv/Kill
    /reset: std_srvs/srv/Empty
    /spawn: turtlesim/srv/Spawn
    /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/list_parameters: rcl_interfaces/srv/ListParameters
    /turtlesim/set_parameters: rcl_interfaces/srv/SetParameters
    /turtlesim/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomically
  Service Clients:

  Action Servers:
    /turtle1/rotate_absolute: turtlesim/action/RotateAbsolute
  Action Clients:

このコマンドは、/turtlesimのサブスクライバー、パブリッシャー、サービス、アクションサーバー、およびアクションクライアントのリストを返します。

/turtlesim/turtle1/rotate_absoluteアクションがAction Serversの下にあることに注意してください。 これは、/turtlesim/turtle1/rotate_absoluteアクションに応答し、フィードバックを提供することを意味します。

/teleop_turtleノードはAction Clientsの下に名前/turtle1/rotate_absoluteを持っており、そのアクション名のゴールを送信することを意味します。 それを確認するために実行します:

bash
ros2 node info /teleop_turtle

出力:

/teleop_turtle
  Subscribers:
    /parameter_events: rcl_interfaces/msg/ParameterEvent
  Publishers:
    /parameter_events: rcl_interfaces/msg/ParameterEvent
    /rosout: rcl_interfaces/msg/Log
    /turtle1/cmd_vel: geometry_msgs/msg/Twist
  Service Servers:
    /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/list_parameters: rcl_interfaces/srv/ListParameters
    /teleop_turtle/set_parameters: rcl_interfaces/srv/SetParameters
    /teleop_turtle/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomically
  Service Clients:

  Action Servers:

  Action Clients:
    /turtle1/rotate_absolute: turtlesim/action/RotateAbsolute

4 ros2 action list

ROSグラフ内のすべてのアクションを識別するために、コマンドを実行します:

bash
ros2 action list

出力:

/turtle1/rotate_absolute

これは現在ROSグラフ内で唯一のアクションです。 これは、先ほど見たようにタートルの回転を制御します。 ros2 node info <node_name>コマンドを使用することで、このアクションに対して1つのアクションクライアント(/teleop_turtleの一部)と1つのアクションサーバー(/turtlesimの一部)があることもすでに分かっています。

4.1 ros2 action list -t

アクションには、トピックやサービスと同様にタイプがあります。 /turtle1/rotate_absoluteのタイプを見つけるには、コマンドを実行します:

bash
ros2 action list -t

出力:

/turtle1/rotate_absolute [turtlesim/action/RotateAbsolute]

各アクション名(この場合は/turtle1/rotate_absoluteのみ)の右側の括弧内に、アクションタイプturtlesim/action/RotateAbsoluteがあります。 コマンドラインまたはコードからアクションを実行したい場合に、これが必要になります。

5 ros2 action info

/turtle1/rotate_absoluteアクションをさらに詳しく調べるには、コマンドを使用します:

bash
ros2 action info /turtle1/rotate_absolute

出力:

Action: /turtle1/rotate_absolute
Action clients: 1
    /teleop_turtle
Action servers: 1
    /turtlesim

これは、各ノードでros2 node infoを実行することで先ほど学んだことを教えてくれます: /teleop_turtleノードはアクションクライアントを持ち、/turtlesimノードは/turtle1/rotate_absoluteアクションのアクションサーバーを持っています。

6 ros2 interface show

アクションゴールを自分で送信または実行する前に必要な情報のもう一つは、アクションタイプの構造です。

ros2 action list -tコマンドを実行したときに/turtle1/rotate_absoluteのタイプを識別したことを思い出してください。 ターミナルでアクションタイプを指定して以下のコマンドを入力します:

bash
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

最初の---より上のこのメッセージのセクションは、ゴールリクエストの構造(データタイプと名前)です。 次のセクションは結果の構造です。 最後のセクションはフィードバックの構造です。

7 ros2 action send_goal

それでは、以下の構文でコマンドラインからアクションゴールを送信しましょう:

bash
ros2 action send_goal <action_name> <action_type> <values>

<values>はYAML形式である必要があります。

turtlesimウィンドウに注意を向けて、ターミナルに以下のコマンドを入力します:

bash
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: f8db8f44410849eaa93d3feb747dd444

Result:
  delta: -1.568000316619873

Goal finished with status: SUCCEEDED

タートルが回転するのが見えるはずです。

すべてのゴールには、戻りメッセージに表示される一意のIDがあります。 また、開始位置からの変位であるdeltaという名前のフィールドの結果も確認できます。

このゴールのフィードバックを見るには、ros2 action send_goalコマンドに--feedbackを追加します:

bash
ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: -1.57}" --feedback

出力:

Sending goal:
   theta: -1.57

Goal accepted with ID: e6092c831f994afda92f0086f220da27

Feedback:
  remaining: -3.1268222332000732

Feedback:
  remaining: -3.1108222007751465



Result:
  delta: 3.1200008392333984

Goal finished with status: SUCCEEDED

ゴールが完了するまで、残りのラジアンというフィードバックを継続的に受信します。

まとめ

アクションは、長時間実行されるタスクを実行し、定期的なフィードバックを提供し、キャンセル可能なサービスのようなものです。

ロボットシステムでは、ナビゲーションにアクションを使用する可能性があります。 アクションゴールは、ロボットに位置まで移動するよう指示することができます。 ロボットがその位置にナビゲートしている間、途中で更新(つまりフィードバック)を送信し、目的地に到達したら最終的な結果メッセージを送信できます。

Turtlesimには、アクションクライアントがタートルを回転させるためのゴールを送信できるアクションサーバーがあります。 このチュートリアルでは、そのアクション/turtle1/rotate_absoluteを内部検査して、アクションとは何か、どのように動作するかについてより良いアイデアを得ました。

次のステップ

これで、ROS 2のすべてのコア概念をカバーしました。 このセットの最後のいくつかのチュートリアルでは、ROS 2の使用を簡単にするツールとテクニックを紹介します。rqt_consoleを使用したログの表示から始まります。

関連コンテンツ

ROS 2でのアクションの設計決定についてより詳しく読むことができますこちら

Released under the MIT License.