proxy_service_caller.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 import rospy
3 from threading import Timer
4 
5 from flexbe_core.logger import Logger
6 
7 
8 class ProxyServiceCaller(object):
9  """
10  A proxy for calling services.
11  """
12  _services = {}
13 
14  def __init__(self, topics={}, persistent=False, wait_duration=10):
15  """
16  Initializes the proxy with optionally a given set of clients.
17 
18  @type topics: dictionary string - message class
19  @param topics: A dictionay containing a collection of topic - message type pairs.
20 
21  @type persistent: bool
22  @param persistent: Defines if the service callers are persistent.
23 
24  @type wait_duration: int
25  @param wait_duration: Defines how long to wait for the given services if not available right now.
26  """
27  for topic, msg_type in topics.items():
28  self.setupService(topic, msg_type, persistent, wait_duration)
29 
30  def setupService(self, topic, msg_type, persistent=False, wait_duration=10):
31  """
32  Tries to set up a service caller for calling it later.
33 
34  @type topic: string
35  @param topic: The topic of the service to call.
36 
37  @type msg_type: service class
38  @param msg_type: The type of messages of this service.
39 
40  @type persistent: bool
41  @param persistent: Defines if this service caller is persistent.
42 
43  @type wait_duration: int
44  @param wait_duration: Defines how long to wait for the given service if it is not available right now.
45  """
46  if topic not in ProxyServiceCaller._services:
47  ProxyServiceCaller._services[topic] = rospy.ServiceProxy(topic, msg_type, persistent)
48  self._check_service_available(topic, wait_duration)
49 
50  def is_available(self, topic):
51  """
52  Checks if the service on the given topic is available.
53 
54  @type topic: string
55  @param topic: The topic of interest.
56  """
57  return self._check_service_available(topic)
58 
59  def call(self, topic, request):
60  """
61  Performs a service call on the given topic.
62 
63  @type topic: string
64  @param topic: The topic to call.
65 
66  @type request: service
67  @param request: The request to send to this service.
68  """
69  if not self._check_service_available(topic):
70  raise ValueError('Cannot call service client %s: Topic not available.' % topic)
71  # call service (forward any exceptions)
72  return ProxyServiceCaller._services[topic].call(request)
73 
74  def _check_service_available(self, topic, wait_duration=1):
75  """
76  Checks whether a service is available.
77 
78  @type topic: string
79  @param topic: The topic of the service.
80 
81  @type wait_duration: int
82  @param wait_duration: Defines how long to wait for the given service if it is not available right now.
83  """
84  client = ProxyServiceCaller._services.get(topic)
85  if client is None:
86  Logger.logerr("Service client %s not yet registered, need to add it first!" % topic)
87  return False
88  warning_sent = False
89  available = False
90  try:
91  t = Timer(1, self._print_wait_warning, [topic])
92  t.start()
93  rospy.wait_for_service(topic, wait_duration)
94  available = True
95  except rospy.exceptions.ROSException:
96  available = False
97 
98  try:
99  t.cancel()
100  except Exception:
101  # already printed the warning
102  warning_sent = True
103 
104  if not available:
105  Logger.logerr("Service client %s timed out!" % topic)
106  return False
107  else:
108  if warning_sent:
109  Logger.loginfo("Finally found service %s..." % (topic))
110  return True
111 
112  def _print_wait_warning(self, topic):
113  Logger.logwarn("Waiting for service %s..." % (topic))
def __init__(self, topics={}, persistent=False, wait_duration=10)
def setupService(self, topic, msg_type, persistent=False, wait_duration=10)


flexbe_core
Author(s): Philipp Schillinger
autogenerated on Sun Dec 13 2020 04:01:39