Creating ROS1 Service in Python
The following are some steps to create a ROS1 service in Python:
Step 1: Add the following in package.xml
1 2 3 4 5 6 |
<build_depend>rospy</build_depend> <build_depend>std_msgs</build_depend> <build_depend>message_generation</build_depend> <run_depend>rospy</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 |
find_package(catkin REQUIRED COMPONENTS message_generation std_msgs rospy) add_service_files(FILES ServiceName.srv) generate_messages(DEPENDENCIES std_msgs) catkin_package( LIBRARIES package_name CATKIN_DEPENDS std_msgs rospy ) catkin_install_python(PROGRAMS script/service_server.py DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} ) catkin_install_python(PROGRAMS script/service_client.py DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} ) |
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 Python file namely “service_server.py”, inside “script” 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 |
#!/usr/bin/env python from __future__ import print_function from ServiceName.srv import MyService,MyServiceResponse import rospy def performing_request(req): print("Sending back response: [%s + %s = %s]"%(req.a, req.b, (req.a + req.b))) return MyServiceResponse(req.a + req.b) def service_server(): rospy.init_node('service_server') s = rospy.Service('MyService', MyService, performing_request) print("Service server is ready.") rospy.spin() if __name__ == "__main__": service_server() |
Step 5: Write the “service_client” node in a Python file namely “service_client.py”, inside “script” 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 |
#!/usr/bin/env python from __future__ import print_function import sys import rospy from ServiceName.srv import * def service_client(x, y): rospy.wait_for_service('MyService') try: MyService = rospy.ServiceProxy('MyService', MyService) resp1 = MyService(x, y) return resp1.sum except rospy.ServiceException as e: print("Service call failed: %s"%e) def usage(): return "%s [x y]"%sys.argv[0] if __name__ == "__main__": if len(sys.argv) == 3: x = int(sys.argv[1]) y = int(sys.argv[2]) else: print(usage()) sys.exit(1) print("Request: %s + %s"%(x, y)) print("Result: %s + %s = %s"%(x, y, service_client(x, y))) |
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.py |
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.py [REQUEST_VARIABLES] |
Let’s say you want to add a = 1 and b = 3, then the command is:
1 |
rosrun package_name service_client.py 1 3 |
You should see the following in the service client’s terminal:
1 2 |
Request: 1 + 3 Result: 1 + 3 = 4 |
And you should see the following in the service servers’s terminal:
1 |
Sending back response: [1 + 3 = 4] |