Creating ROS2 Action in C++
Below are the steps to create a ROS2 action. Notice that we are going to have two packages involved: 1) a package called “my_package” which contains the action file, and 2) a package called “action_nodes_cpp” which contains the action server and client nodes. Separating the package which contains the action file(s) like this, in general, is a good practice.
Step 1: Creating an action file.
Create a folder called “action” (if you still don’t have it) inside a package folder called “my_package”. And then make the action file (.action) called “ActionFile.action”. For example, if the action is to compute Fibonacci numbers, you may call it “Fibonacci.action” which looks like below:
#goal definition int32 order --- #result definition int32[] sequence --- #feedback int32[] partial_sequence
The lines of three dashes above separate between the request variable(s), the result variable(s), and the feedback variable(s).
Step 2: Add the following in package.xml
rosidl_default_generators action_msgs rosidl_interface_packages
Step 3: Add the following in CMakeLists.txt, before ament_package().
find_package(rosidl_default_generators REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME} "action/ActionFile.action")
add_library(action_server SHARED src/my_action_server.cpp)
target_include_directories(action_server PRIVATE
&
&)
target_compile_definitions(action_server
PRIVATE "ACTION_NODES_CPP_BUILDING_DLL")
ament_target_dependencies(action_server
"my_package"
"rclcpp"
"rclcpp_action"
"rclcpp_components")
rclcpp_components_register_node(action_server PLUGIN "action_nodes_cpp::MyActionServer" EXECUTABLE my_action_server)
install(TARGETS
action_server
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin)
add_library(action_client SHARED src/my_action_client.cpp)
target_include_directories(action_client PRIVATE
&
&)
target_compile_definitions(action_client
PRIVATE "ACTION_NODES_CPP_BUILDING_DLL")
ament_target_dependencies(action_client
"my_package"
"rclcpp"
"rclcpp_action"
"rclcpp_components")
rclcpp_components_register_node(action_client PLUGIN "action_nodes_cpp::MyActionClient" EXECUTABLE my_action_client)
install(TARGETS
action_client
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin)
Step 4: Write the “action_server” node.
Write the action_server node in a file namely “my_action_server.cpp”, inside “src” folder of the package.
Step 5: Write the “action_client” node.
Write the action_client node in a file namely “my_action_client.cpp”, inside “src” folder of the package.
Example of action_server and action_client nodes in C++ can be found here: https://docs.ros.org/en/foxy/Tutorials/Actions/Writing-a-Cpp-Action-Server-Client.html#actionscpp
Step 6: Build the package by using “colcon build” command.
Running the action
Type the following in the terminal to run the “action_server” node:
ros2 run action_nodes_cpp my_action_server
Type the following in the terminal to run the “action_client” node:
ros2 run action_nodes_cpp my_action_client
To show the stream of the action feedback:
ros2 topic echo /action_name/feedback
Official documentation:
