ROS Basics – Implement Service (Service Server/Provider)
As we have defined service in previous blog, now we will learn how to implement the service using service server (which provides the service) and service client (which uses the service).
Creating Service Server
We can implement ROS standard services, however in this example we will implement the service “WordCount” that we have defined ourselves in previous blog.
Run following command to see the structure of the service message
rossrv show ros_basics/WordCount
We can see the structure in figure below
Where, the input (or request) of the service is a string type variable “words”.
While the output (or response) of the service is an unsigned integer type variable “count”.
Now we go to the package “ros_basics” and create the server node.
Run commands
roscd ros_basics cd src ls
(ls command is run just to verify that the file is not already created)
Create the file “service_server.py”
Run command
touch service_server.py
give execute permission
chmod +x service_server.py
Open the file using “gedit” command and copy and paste following code in it.
gedit service_server.py
#!/usr/bin/env python import rospy from ros_basics.srv import WordCount, WordCountResponse def count_words(request): Print "The words_count service is called." return WordCountResponse(len(request.words.split())) rospy.init_node('service_server') service = rospy.Service('words_count', WordCount, count_words) rospy.spin()
All above executed commands are shown in figure below
The “service_server.py” file will look like in figure below
Save and close the file.
Explaining the Code in Python file “service_server.py”
First two lines are already explained.
Third line is
from ros_basics.srv import WordCount, WordCountResponse
As we have seen in previous blog that the “WordCount.srv” file is created in “srv” folder of the package “ros_basics”. After defining the service, “catkin_make” command was executed to build the package. Hence, during build process three classes WordCount, WordCountResponse, and WordCountRequest were created.
In above line, we are importing two of those classes to use them in this service provider program.
Next we have defined a method
def count_words(request):
Print “The words_count service is called.”
return WordCountResponse(len(request.words.split()))
The service has callback-based mechanism similar to topic. The service provider specifies a callback method (here the method name is “count_words”). Whenever service call is made, this method will be executed.
In this method first line is a simple print line to print that the service is called.
In second line a WordCountResponse object is returning with the value of word length of the string received as a “request” parameter.
Next line
rospy.init_node('service_server')
is initiating the node.
In next line
service = rospy.Service('words_count', WordCount, count_words)
A service object is created. In parenthesis, the first parameter ‘words_count’ is service name. The second parameter WordCount is class object that we imported above. The third parameter is a
callback-based method named count_words
The last line “rospy.spin()” is to keep the node running until Ctrl+c is pressed (as explained previously).
Executing the file “service_server.py”
Now we will start the service by running the file “service_server.py”
For this, first you will have to build the package.
Let’s do it.
First run the master
roscore
open a new terminal and run
cd ~/catkin_ws
(To go the catkin_ws workspace)
Run the command
catkin_make
(To build all packages)
Run the command
source devel/setup.bash
(Dont forget to run source command)
Now the service server is ready to provide the service
Run following command in the terminal
rosrun ros_basics service_server.py
Now the service is running, the terminal will look like in figure below
Note: If there is an error (such as module ros_basics.srv is not found). You should go to “catkin_ws” and delete the folders “build”, and “devel”. You may use following commands
cd ~/catkin_ws rm -r build rm -r devel
Now execute “catkin_make” command to build the workspace.
Run in the terminal
catkin_make source devel/setup.bash
This wil refresh every thing.
Now Run the python file again as follows
rosrun ros_basics service_server.py
Run the command to verify that the service is running
rosserive list
We can see that the service “words_count” is in the list.
Get the information about the service
rosservice info words_count
You can see the service providing node, URI, service type and arguments in the output as show in figure below
Now we call the service using command line as follows
Run in new terminal
rosservice call words_count “These are four lines”
You may pass any other sentence
rosservice call words_count “How many words are in this sentence”
You will see that the number of words are displayed as a count variable in output.
The count will be printed on the terminal from where the service is called.
While “The words_count service is called.” message will be printed on the terminal where the service is running.
You may try to pass different strings while calling the service.
Conclusion
In this article, you have learned how to provide the service. In next blog, we will create a service client to use the service (instead of calling from command line).