How to call a service automatically when it is needed?


I have a question regarding working logic of services. That question may arise because I may not have grasped the idea underlying ROS and services yet. Anyway. I can create publisher, subscriber and services and run them successfully (thanks to you). However, I have used them for itself alone, not together in a package. That is to say, I have not built a large project yet. Let’s say, I need to use publisher, subscriber and service together as a one package. Your example in service-client chapter is a good example. Let’s talk about it: Laser scanner, face recognition and navigation. For my question, ignore the navigation part, consider only camera (instead of laser) and traffic light detection (instead of face recognition).

Assume that we are building a robot that should move straight until it recognizes the traffic light. When it detects red light, it should stop. otherwise, it should keep moving. I want to use service, not publisher/subscriber, for traffic light detection. How can this system be automated? I mean, while the robot is moving straight, service-server is running. This is understandable, okay. But, who will call this service? Which node can call this service so that robot stops and wait for the service is finished until traffic light turns to green. Afterwards, program continues so robot start moving again. In service chapter, You have taught us starting service-server and calling this service by launching the launch file of service-client manually. How can I call the launch file of service-client automatically? Is it a kind of nested system? In short, I am curious about the way calling service-server when it is needed, not launching service-client node’s launch file manually. Is there a way to automate this system? Can you also provide some example, link or source in addition to your explanation? Thanks in advance.

Good question Ender!

You don’t need to use a launch file to call your service. You don’t even need a launch file to start your service server! You just need to be able to decide which one works best for any given case.

A launch file has the following advantages, among others

  • can start roscore for you automatically if not already started.
  • can set many parameters required for your application once.
  • can start many nodes at once, so you don’t have to start each one in a different terminal.
  • can remap topics

…but it doesn’t mean you have to it where it doesn’t make sense.

So for your sample case, you just need to call the service directly within the node (program) that controls your mini autonomous car system. I suppose for this system, you will have a main node that controls everything, doing whatever you wish. To call the service server, just put the something like following somewhere within the controlling node’s source code:

#! /usr/bin/env python

import rospy
# Import the service message used by the service /your_service
from package_containing_service_server.srv import ServiceMsg, ServiceMsgRequest

# Initialise the controlling node

# Wait for the service server to be running

# Create the connection to the service
your_service_conn = rospy.ServiceProxy('/your_service', ServiceMsg)

# Create an object of type ServiceMsgRequest
your_service_object = ServiceMsgRequest()

# Set any required parameter for your service
your_service_object.stop_at_red_light = True

# Send your request through the connection
result = your_service_conn(your_service_object)

# Do something with the response from the server
print result

So, for instance, you could start all the nodes for your application (service server, other nodes) with a single launch file, and then within one of the started nodes, you call your service and/or action server(s) to run some errand for you. :slight_smile:

I hope this clarifies a bit. Let me know if you need further clarifications.

Your answer is what I needed exactly. Pinpoint. Thanks :slight_smile: @bayodesegun

1 Like