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
rospy std_msgs message_generation rospy std_msgs message_runtime
Step 2: Add the following in CMakeLists.txt
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:
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”:
#!/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”:
#!/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:
rosrun package_name service_server.py
You should see the following in the terminal:
Service server is ready.
The call the service, run the “service_client” node and impose the request variables:
rosrun package_name service_client.py [REQUEST_VARIABLES]
Let’s say you want to add a = 1 and b = 3, then the command is:
rosrun package_name service_client.py 1 3
You should see the following in the service client’s terminal:
Request: 1 + 3 Result: 1 + 3 = 4
And you should see the following in the service servers’s terminal:
Sending back response: [1 + 3 = 4]
