Goal: Define an action in the ROS 2 package.
Tutorial level: Intermediate
Time: 5 minutes
content
background
You learned about operations previously in the Understanding ROS 2 Operations tutorial. Like other communication types and their respective interfaces (topics/msg and services/srv), you can also customize operations in the package. This tutorial shows you how to define and build actions that can be used with the action server and action client that you will write in the next tutorial.
prerequisites
You should install ROS 2 (Dashing or higher) and colcon .
Set up a workspace and create a package called action_tutorials_interfaces
:
mkdir -p action_ws/src
cd action_ws/src
ros2 pkg create action_tutorials_interfaces
Task
1 Define actions
.action
Actions are defined in files of the following form:
# Request --- # Result --- # Feedback
An action definition consists of three separated message definitions ---
.
-
A request message is sent from the action client to the action server to start a new target.
-
When the goal is completed, a result message is sent from the action server to the action client.
-
Feedback messages are periodically sent from the action server to the action client containing updates about the target.
An instance of an action is usually called a goal .
Suppose we want to define a new action "Fibonacci" to calculate the Fibonacci sequence .
action
Create a directory within our ROS 2 package action_tutorials_interfaces
:
cd action_tutorials_interfaces mkdir action
In that action
directory, create a Fibonacci.action
file named:
int32 order --- int32[] sequence --- int32[] partial_sequence
The target request is order
the Fibonacci sequence we want to calculate, the result is final sequence
, and the feedback is partial_sequence
the result of the calculation so far.
2 Build an action
Before we can use the new Fibonacci operation type in our code, we must pass the definition to the rosidl code generation pipeline.
CMakeLists.txt
This is done by adding the following line before our line :ament_package()
action_tutorials_interfaces
find_package(rosidl_default_generators REQUIRED) rosidl_generate_interfaces(${PROJECT_NAME} "action/Fibonacci.action" )
We should also add the required dependencies to our package.xml
:
<buildtool_depend>rosidl_default_generators</buildtool_depend> <depend>action_msgs</depend> <member_of_group>rosidl_interface_packages</member_of_group>
Note that we need dependencies action_msgs
because the action definition includes additional metadata (e.g. target ID).
We should now be able to build Fibonacci
the package containing the action definition:
# Change to the root of the workspace cd ~/action_ws # Build colcon build
We're done!
By convention, action types are prefixed with their package name and word action
. So when we want to reference our new action, it will have its full name action_tutorials_interfaces/action/Fibonacci
.
We can use the command line tool to check whether our operation built successfully:
# Source our workspace # On Windows: call install/setup.bat . install/setup.bash # Check that our action definition exists ros2 action show action_tutorials_interfaces/action/Fibonacci
You should see the Fibonacci action definition printed to the screen.
generalize
In this tutorial, you learned about the structure of action definitions. You also learned how to use CMakeLists.txt
and correctly build the new operator interface package.xml
, and how to verify that the build was successful.
Next step
Next, let's take advantage of your newly defined action interface by creating an action service and client (in Python or C++ ).