Creating C++ Service in ROS2
Step 1: Create the service (.srv) file, namely ServiceName.srv, inside an “srv” folder.
Step 2: Modify CMakeLists.txt.
Add the following:
1 2 3 4 5 6 7 8 |
find_package(builtin_interfaces REQUIRED) find_package(rosidl_default_generators REQUIRED) # and put below before ament_package(): rosidl_generate_interfaces(ros2_exercise_cpp "srv/ServiceName.srv" DEPENDENCIES builtin_interfaces ) |
Step 3: Modify package.xml.
Add the following:
1 2 3 4 5 6 |
<build_depend>builtin_interfaces</build_depend> <build_depend>rosidl_default_generators</build_depend> <exec_depend>builtin_interfaces</exec_depend> <exec_depend>rosidl_default_runtime</exec_depend> <member_of_group>rosidl_interface_packages</member_of_group> |
Step 4: Write your service_server node in the “src” folder inside the package. The following is an example of a service_server node, taken from here: https://github.com/ros2/examples/tree/foxy/rclcpp/services/minimal_service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#include <inttypes.h> #include <memory> #include "example_interfaces/srv/add_two_ints.hpp" #include "rclcpp/rclcpp.hpp" using AddTwoInts = example_interfaces::srv::AddTwoInts; rclcpp::Node::SharedPtr g_node = nullptr; void handle_service( const std::shared_ptr<rmw_request_id_t> request_header, const std::shared_ptr<addtwoints::request> request, const std::shared_ptr<addtwoints::response> response) { (void)request_header; RCLCPP_INFO( g_node->get_logger(), "request: %" PRId64 " + %" PRId64, request->a, request->b); response->sum = request->a + request->b; } int main(int argc, char ** argv) { rclcpp::init(argc, argv); g_node = rclcpp::Node::make_shared("minimal_service"); auto server = g_node->create_service<addtwoints>("add_two_ints", handle_service); rclcpp::spin(g_node); rclcpp::shutdown(); g_node = nullptr; return 0; }</addtwoints></addtwoints::response></addtwoints::request></rmw_request_id_t></memory></inttypes.h> |
Step 5: Write your service_client node in the “src” folder inside the package. The following is an example of a service_client node, taken from here: https://github.com/ros2/examples/tree/foxy/rclcpp/services/minimal_client
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#include #include #include #include "example_interfaces/srv/add_two_ints.hpp" #include "rclcpp/rclcpp.hpp" using AddTwoInts = example_interfaces::srv::AddTwoInts; int main(int argc, char * argv[]) { rclcpp::init(argc, argv); auto node = rclcpp::Node::make_shared("minimal_client"); auto client = node->create_client("add_two_ints"); while (!client->wait_for_service(std::chrono::seconds(1))) { if (!rclcpp::ok()) { RCLCPP_ERROR(node->get_logger(), "client interrupted while waiting for service to appear."); return 1; } RCLCPP_INFO(node->get_logger(), "waiting for service to appear..."); } auto request = std::make_shared(); request->a = 41; request->b = 1; auto result_future = client->async_send_request(request); if (rclcpp::spin_until_future_complete(node, result_future) != rclcpp::FutureReturnCode::SUCCESS) { RCLCPP_ERROR(node->get_logger(), "service call failed :("); return 1; } auto result = result_future.get(); RCLCPP_INFO( node->get_logger(), "result of %" PRId64 " + %" PRId64 " = %" PRId64, request->a, request->b, result->sum); rclcpp::shutdown(); return 0; } |
Step 6: Build the package using “colcon build” command.