services.py
Go to the documentation of this file.
1 # Software License Agreement (BSD License)
2 #
3 # Copyright (c) 2012, Willow Garage, Inc.
4 # All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 #
10 # * Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 # * Redistributions in binary form must reproduce the above
13 # copyright notice, this list of conditions and the following
14 # disclaimer in the documentation and/or other materials provided
15 # with the distribution.
16 # * Neither the name of Willow Garage, Inc. nor the names of its
17 # contributors may be used to endorse or promote products derived
18 # from this software without specific prior written permission.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 # POSSIBILITY OF SUCH DAMAGE.
32 
33 from threading import Thread
34 from rospy import ServiceProxy, resolve_name
35 from rosservice import get_service_type
36 from rosbridge_library.internal.ros_loader import get_service_class
37 from rosbridge_library.internal.ros_loader import get_service_request_instance
38 from rosbridge_library.internal.message_conversion import populate_instance
39 from rosbridge_library.internal.message_conversion import extract_values
40 
41 
42 class InvalidServiceException(Exception):
43  def __init__(self, servicename):
44  Exception.__init__(self, "Service %s does not exist" % servicename)
45 
46 
47 class ServiceCaller(Thread):
48 
49  def __init__(self, service, args, success_callback, error_callback):
50  """ Create a service caller for the specified service. Use start()
51  to start in a separate thread or run() to run in this thread.
52 
53  Keyword arguments:
54  service -- the name of the service to call
55  args -- arguments to pass to the service. Can be an
56  ordered list, or a dict of name-value pairs. Anything else will be
57  treated as though no arguments were provided (which is still valid for
58  some kinds of service)
59  success_callback -- a callback to call with the JSON result of the
60  service call
61  error_callback -- a callback to call if an error occurs. The
62  callback will be passed the exception that caused the failure
63 
64  """
65  Thread.__init__(self)
66  self.daemon = True
67  self.service = service
68  self.args = args
69  self.success = success_callback
70  self.error = error_callback
71 
72  def run(self):
73  try:
74  # Call the service and pass the result to the success handler
75  self.success(call_service(self.service, self.args))
76  except Exception as e:
77  # On error, just pass the exception to the error handler
78  self.error(e)
79 
80 
81 def args_to_service_request_instance(service, inst, args):
82  """ Populate a service request instance with the provided args
83 
84  args can be a dictionary of values, or a list, or None
85 
86  Propagates any exceptions that may be raised. """
87  msg = {}
88  if isinstance(args, list):
89  msg = dict(zip(inst.__slots__, args))
90  elif isinstance(args, dict):
91  msg = args
92 
93  # Populate the provided instance, propagating any exceptions
94  populate_instance(msg, inst)
95 
96 
97 def call_service(service, args=None):
98  # Given the service name, fetch the type and class of the service,
99  # and a request instance
100 
101  service = resolve_name(service)
102 
103  service_type = get_service_type(str(service))
104  if service_type is None:
105  raise InvalidServiceException(service)
106  service_class = get_service_class(service_type)
107  inst = get_service_request_instance(service_type)
108 
109  # Populate the instance with the provided args
110  args_to_service_request_instance(service, inst, args)
111 
112  # Call the service
113  proxy = ServiceProxy(service, service_class)
114  response = proxy.call(inst)
115 
116  # Turn the response into JSON and pass to the callback
117  json_response = extract_values(response)
118 
119  return json_response
def get_service_request_instance(typestring)
Definition: ros_loader.py:112
def call_service(service, args=None)
Definition: services.py:97
def __init__(self, service, args, success_callback, error_callback)
Definition: services.py:49
def args_to_service_request_instance(service, inst, args)
Definition: services.py:81


rosbridge_library
Author(s): Jonathan Mace
autogenerated on Wed Jun 3 2020 03:55:14