This tutorial is a practical guide on how to use rosservice and rossrv command line tools to debug a ROS service.
You know those command line tools are useful, but it’s hard for you to really understand how to use them efficiently?
Well, this tutorial is for you. I’ll show you step by step exactly how to do through a real example.
Table of Contents
Let’s create a simple ROS service server. For this example I’m using Python to create a “/add_two_ints” service which receives 2 numbers and return the sum.
import rospy from rospy_tutorials.srv import AddTwoInts def handle_add_two_ints(req): result = req.a + req.b rospy.loginfo("Sum of " + str(req.a) + " and " + str(req.b) + " is " + str(result)) return result if __name__ == '__main__': rospy.init_node("add_two_ints_server") rospy.loginfo("Add two ints server node created") service = rospy.Service("/add_two_ints", AddTwoInts, handle_add_two_ints) rospy.loginfo("Service server has been started") rospy.spin()
Let’s run this code:
- Don’t forget to start
roscorein another terminal, to create a ROS master.
- Make the file executable:
chmod +x add_two_ints.py.
- Start the node:
python add_two_ints.py(you can also use
rosrunif you want).
Alright, the node is now running and it is advertising a Service server. Let’s now find out everything about this service server we’ve just created, using the ROS command line tools!
You are learning ROS?
Check out ROS For Beginners and learn ROS step by step.
Find the advertised service (rosservice list)
rosservice list to find all the currently active services that where launched after you started the ROS master.
$ rosservice list /add_two_ints /add_two_ints_server/get_loggers /add_two_ints_server/set_logger_level /rosout/get_loggers /rosout/set_logger_level
First good news, we found the “/add_two_ints” service. As you can see, 5 services are currently active.
If you have a long list and want to find a particular service, use
$ rosservice list | grep add_two_ints /add_two_ints /add_two_ints_server/get_loggers /add_two_ints_server/set_logger_level
Get more details about this service (rosservice info)
Now that we have found the service, let’s see if we can get more details about it.
$ rosservice info /add_two_ints Node: /add_two_ints_server URI: rosrpc://ros-pc:38201 Type: rospy_tutorials/AddTwoInts Args: a b
A few useful info here:
- Node: this is the node advertising the service, so you know where it comes from.
- Type: maybe the most important info here. This is the service definition (.srv file) you need to use in order to call the service.
- Args: a quick resume about the request part of the service definition. This gives you the name of the arguments you need to send (without the detailed types).
Find out what data you need to send and receive (rossrv show)
Once you have found the definition (type) of the service you want to use, you’d like to know what exactly is in this definition.
$ rossrv show rospy_tutorials/AddTwoInts int64 a int64 b --- int64 sum
Now, you know that:
- The request consists of two int64 numbers, ‘a’ and ‘b’ (with only the “Args” field we got from
rosservice info, we couldn’t know for sure the type).
- The service will return a response, which consists of one int64 number called ‘sum’.
Call the service (rosservice call)
You now have all the required info to call the service. You know the name of the service, the service definition you need to use, and precisely what’s inside this definition.
$ rosservice call /add_two_ints "a: 4 b: 3" sum: 7
(hint: after you’ve written the name of the service, press “TAB” 2 times to get the structure of the request message auto-completed. Then with your keyboard arrows you can change the values)
And… It works!
Note that calling services with many arguments in the request message won’t be practical. Anyway, using the command line tool is only useful for testing and debugging. The obvious next step is to create a service client in another node (rospy or roscpp), using all the info that you got from the previous steps.
Closing the loop
So, from the name of the service we were able to find many info, including the name of the node which advertises it.
Let’s execute rosnode info on this node we found:
$ rosnode info /add_two_ints_server -------------------------------------------------------------------------------- Node [/add_two_ints_server] Publications: * /rosout [rosgraph_msgs/Log] Subscriptions: None Services: * /add_two_ints * /add_two_ints_server/get_loggers * /add_two_ints_server/set_logger_level contacting node http://ros-pc:33215/ ... Pid: 4944 Connections: * topic: /rosout * to: /rosout * direction: outbound * transport: TCPROS
As you can see, from a node info we can also retrieve all services started from this node.
The loop is now complete. From any info you have (node, service name) you can find all the other info using ROS command line tools.
ROS Service command line tools: more about rosservice and rossrv
You have now all the required practical knowledge to debug your ROS services with a terminal.
Note that I didn’t list all the rosservice and rossrv functions, only the most useful ones.
So that you know, you can list all service definitions (.srv files) available on your ROS environment with
rossrv list. Using
grep with this command line tool can be useful to see if you’re missing a service definition (not installed or not compiled) so that you can fix it.
For the reference of all available functions, just type
rossrv with no argument.