View on GitHub

Rosworkshop

HOME

ROS services

The publish / subscribe model is a very flexible communication paradigm, but its many-to-many one-way transport is not appropriate for RPC request / reply interactions, which are often required in a distributed system. Request / reply is done via a Service, which is defined by a pair of messages: one for the request and one for the reply. A providing ROS node offers a service under a string name, and a client calls the service by sending the request message and awaiting the reply. Client libraries usually present this interaction to the programmer as if it were a remote procedure call.

Services are defined using srv files, which are compiled into source code by a ROS client library.

A client can make a persistent connection to a service, which enables higher performance at the cost of less robustness to service provider changes.

Understand ROS Services

To understand ros services we run ‘Myfirst.launch’

roslaunch rosbasics Myfirst.launch

To know the running services .In new terminal we use roscommand

rosservice list

which outputs

/clear
/controller/get_loggers
/controller/set_logger_level
/kill
/reset
/rosout/get_loggers
/rosout/set_logger_level
/spawn
/turtle1/get_loggers
/turtle1/set_logger_level
/turtle1/set_pen
/turtle1/teleport_absolute
/turtle1/teleport_relative

Since services are RPC request / reply interactions to call a service say ‘/clear’ run command

rosservice call /clear

above command clears the background of the turtlesim_node.

Like topics uses ROSmsgs Serivice use ROSsrv files which has extention ‘.srv’ Like to view Topic type that is published using

rostopic type /turtle1/cmd_vel |rosmsg show

we can view the srv parmaeter using

rosservice type /clear |rossrv show

will output empty srv structure ie,

---

Lets see another service

rosservice type /spawn |rossrv show

will output empty srv structure ie,

float32 x
float32 y
float32 theta
string name
---
string name

So How to use this idea to make service call let us see which has inputs x,y theta ,name like below

rosservice call /spawn <float32 x> <float32 y> <float32 theta> <string name>

So above command will be like

rosservice call /spawn 2 2 0.2 ""

which outputs

name: "turtle2"

and you can see new turtle in screen


Let’s create a ROS service

for this we need to create ‘mysrv.srv’ file in srv folder located in rosbasics

A typical ‘xxx.srv’ file has two parts requst side and result side you have have any combination for navtive ROSmsgs in both requst and result side the in ‘.srv’ file request and result sides are seprated by ’—‘

requst side
---
result side

So mysrv.srv will be like

float64 x
float64 y
float64 z
---
float64 addxy
float64 addxz
float64 addyz

The following steps are same as in create in ROSmsgs except one.

message_generation message_runtime
* then open ***'CMakeLists.txt'*** located in rosbasics Folder add lines and savefile and close
* >Ctrl+F and search **"find_package"** and add the line

```python
 find_package(catkin REQUIRED COMPONENTS
   roscpp
   rospy
   std_msgs
   message_generation ##add this line
)
 catkin_package(
  # INCLUDE_DIRS include
  #  LIBRARIES rosbasics
  CATKIN_DEPENDS roscpp rospy std_msgs message_runtime #remove comment
  # also add message_runtime
  #  DEPENDS system_lib
 )

step which is differnt is below

add_service_files(
  FILES
  mysrv.srv
#   Service1.srv
#   Service2.srv
)

After above steps save and close ‘CMakeLists.txt’ and open terminal

 cd cd ROS_Worksop/
 catkin_make

# ROS Service Server and Service Client

Serivceserver

Let us create service server

myserviceserver.py

 #!/usr/bin/python
 import rospy
 from rosbasics.srv import mysrv,mysrvResponse

 def mysrvhandle(req):
     return mysrvResponse(req.x+req.y,req.x+req.z,req.y+req.z)


 def myserver():
     rospy.init_node(name="service_server_node",anonymous=False)
     ser=rospy.Service("addallthree",mysrv,mysrvhandle)
     rospy.loginfo("ready at your service")
     while not rospy.is_shutdown():
         pass

 if __name__ == '__main__':
     try:
         myserver()
     except rospy.ROSInterruptException:
         pass

DIY

  1. create your own rosnode with serviceserver and publisher in it
  2. create your own rosnode with serviceserver and subscriber in it
  3. create your own rosnode with serviceserver ,publisher and subscriber

Back to:Chapter 5
Back to:Chapter 7