Actions are one of the communication types in ROS 2 and are intended for long running tasks. They consist of three parts: a goal, feedback, and a result.
Actions are built on topics and services. Their functionality is similar to services, except actions can be canceled. They also provide steady feedback, as opposed to services which return a single response.
Actions use a client-server model, similar to the publisher-subscriber model of topics. An "action client" node sends a goal to an "action server" node that acknowledges the goal and returns a stream of feedback and a result.
Example: Keyboard Control
When we are trying to control the turtle via keyboard, we ran two nodes /turtlesim
and /teleop_turtle
in two terminals
ros2 run turtlesim turtlesim_node
And
ros2 run turtlesim turtle_teleop_key
When you launch the /teleop_turtle
node, you will see the following message in your terminal:
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.
Each time you press one of these keys, you are sending a goal to an action server that is part of the /turtlesim
node. The goal is to rotate the turtle to face a particular direction. A message relaying the result of the goal should display once the turtle completes its rotation:
[INFO] [turtlesim]: Rotation goal completed successfully
And the F
key will cancel a goal mid-execution, which outputs the following message
[INFO] [turtlesim]: Rotation goal canceled
Not only can the client-side (your input in the teleop
) stop a goal, but the server-side (the /turtlesim
node) can as well. When the server-side chooses to stop processing a goal, it is said to "abort" the goal.
Try hitting the D
key, then the G
key before the first rotation can complete. In the terminal where the /turtlesim
node is running, you will see the message:
[WARN] [turtlesim]: Rotation goal received before a previous goal finished. Aborting previous goal
This action server chose to abort the first goal because it got a new one. It could have chosen something else, like reject the new goal or execute the second goal after the first one finished. Don't assume every action server will choose to abort the current goal when it gets a new one.
Commands
ros2 node info
Besides the introduction in nodes, this time we focus on the information related to actions. If we run
ros2 node info /turtlesim
We will get:
/turtlesim
Subscribers:
...
Publishers:
...
Service Servers:
...
Service Clients:
...
Action Servers:
/turtle1/rotate_absolute: turtlesim/action/RotateAbsolute
Action Clients:
Notice that the /turtle1/rotate_absolute
action for /turtlesim
is under Action Servers
. This means /turtlesim
responds to and provides feedback for the /turtle1/rotate_absolute
action.
And then we run
ros2 node info /teleop_turtle
Which will return:
/teleop_turtle
Subscribers:
...
Publishers:
...
Service Servers:
...
Service Clients:
Action Servers:
Action Clients:
/turtle1/rotate_absolute: turtlesim/action/RotateAbsolute
So the /teleop_turtle
node has the name /turtle1/rotate_absolute
under Action Clients
meaning that it sends goals for that action name.
ros2 action list
To identify all the actions in the ROS graph, run the command
ros2 action list
Which will return:
/turtle1/rotate_absolute
This is the only action in the ROS graph right now. It controls the turtle's rotation, as you saw earlier. You also already know that there is one action client (part of /teleop_turtle
) and one action server (part of /turtlesim
) for this action from using the ros2 node info <node_name>
command.
If we run ros2 action list -t
, then we will get the type of the actions, which in this case will return:
/turtle1/rotate_absolute [turtlesim/action/RotateAbsolute]
In brackets to the right of each action name.
ros2 action info
You can further introspect the /turtle1/rotate_absolute
action with the command:
ros2 action info /turtle1/rotate_absolute
Which will return
Action: /turtle1/rotate_absolute
Action clients: 1
/teleop_turtle
Action servers: 1
/turtlesim
This tells us what we learned earlier from running ros2 node info
on each node: The /teleop_turtle
node has an action client and the /turtlesim
node has an action server for the /turtle1/rotate_absolute
action.
ros2 interface show
One more piece of information you will need before sending or executing an action goal yourself is the structure of the action type.
Recall that we identified /turtle1/rotate_absolute
's type when running the command ros2 action list -t
. Enter the following command with the action type in your terminal:
ros2 interface show turtlesim/action/RotateAbsolute
Which will return:
# 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
The section of this message above the first ---
is the structure (data type and name) of the goal request. The next section is the structure of the result. The last section is the structure of the feedback.
ros2 action send_goal
Send an action goal from the command line with the following syntax:
ros2 action send_goal <action_name> <action_type> <values>
<values>
need to be in YAML format.
Keep an eye on the turtlesim
window, and enter the following command into your terminal:
ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: 1.57}"
You should see the turtle rotating, as well as the following message in your terminal:
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
All goals have a unique ID, shown in the return message. You can also see the result, a field with the name delta
, which is the displacement to the starting position.
To see the feedback of this goal, add --feedback
to the ros2 action send_goal
command:
ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: -1.57}" --feedback
Your terminal will return the message:
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
You will continue to receive feedback, the remaining radians, until the goal is complete.