Creating ROS1 Service in C++
The following are some steps to create a ROS1 service in C++:
Step 1: Add the following in package.xml
1 2 3 4 5 6 |
<build_depend>roscpp</build_depend> <build_depend>std_msgs</build_depend> <build_depend>message_generation</build_depend> <run_depend>roscpp</run_depend> <run_depend>std_msgs</run_depend> <run_depend>message_runtime</run_depend> |
Step 2: Add the following in CMakeLists.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
find_package(catkin REQUIRED COMPONENTS message_generation std_msgs roscpp) add_service_files(FILES ServiceName.srv) generate_messages(DEPENDENCIES std_msgs) catkin_package( LIBRARIES package_name CATKIN_DEPENDS std_msgs roscpp ) include_directories(${catkin_INCLUDE_DIRS}) add_executable(service_server src/service_server.cpp) add_dependencies(service_server ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) target_link_libraries(service_server ${catkin_LIBRARIES}) add_executable(service_client src/service_client.cpp) add_dependencies(service_client ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) target_link_libraries(service_client ${catkin_LIBRARIES}) |
Step 3: Create a folder called “srv” (if you still don’t have it) inside your package folder. And then make the service file (.srv) called ServiceName.srv. Let’s say the service is to add two integers (int64) namely “a” and “b”, and the sum is namely “c”, then the service file looks like this:
1 2 3 4 |
int64 a int64 b --- int64 c |
The line of dashes above separates between the request variables (above the dashes) and the response variables (below the dashes).
Step 4: Write the “service_server” node in a C++ file namely “service_server.cpp”, inside “src” folder of the package. The following is a service server node for adding two integers “a” and “b”; the sum is returned as “c”:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include "ros/ros.h" #include "package_name/ServiceName.h" bool sum(package_name::ServiceName::Request &req, package_name::ServiceName::Response &res) { res.c = req.a + req.b; ROS_INFO("Request: x=%ld, y=%ld", (long int)req.a, (long int)req.b); ROS_INFO("Sending back response: [%ld]", (long int)res.c); return true; } int main(int argc, char **argv) { ros::init(argc, argv, "service_server"); ros::NodeHandle n; ros::ServiceServer service = n.advertiseService("my_service", sum); ROS_INFO("Service server is ready."); ros::spin(); return 0; } |
Step 5: Write the “service_client” node in a C++ file namely “service_client.cpp”, inside “src” folder of the package. The following is the service client for the addition of “a” and “b” which returns “c”:
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 "ros/ros.h" #include "package_name/ServiceName.h" #include <cstdlib><cstdlib> int main(int argc, char **argv) { ros::init(argc, argv, "service_client"); if (argc != 3) { ROS_INFO("Usage: service client for addition of integers x and y"); return 1; } ros::NodeHandle n; ros::ServiceClient client = n.serviceClient<package_name::servicename>("my_service"); package_name::ServiceName srv; srv.request.a = atoll(argv[1]); srv.request.b = atoll(argv[2]); if (client.call(srv)) { ROS_INFO("Sum: %ld", (long int)srv.response.c); } else { ROS_ERROR("Failed to call service my_service"); return 1; } return 0; }</package_name::servicename></cstdlib> |
Step 6: Build the package by using “catkin_make” command.
Running the service
After making sure that ROS Master is running (unless roslaunch is used), type the following in the terminal to run the “service_server” node:
1 |
rosrun package_name service_server |
You should see the following in the terminal:
1 |
Service server is ready. |
The call the service, run the “service_client” node and impose the request variables:
1 |
rosrun package_name service_client [REQUEST_VARIABLES] |
Let’s say you want to add a = 1 and b = 3, then the command is:
1 |
rosrun package_name service_client 1 3 |
You should see the following in the service client’s terminal:
1 |
Sum: 4 |
And you should see the following in the service servers’s terminal:
1 2 |
Request: x=1, y=3 Sending back response: [4] |