Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009 from python_qt_binding.QtCore import QObject
00010
00011 import rospy
00012 import threading
00013 import rocon_uri
00014 import rocon_python_comms
00015 import concert_service_msgs.msg as concert_service_msgs
00016 from rocon_std_msgs.msg import StringArray
00017
00018 class ResourceChooserInterface(QObject):
00019
00020 def __init__(self, capture_timeout=15.0, available_resource_topic='avaialble_resource', capture_resource_pair_topic='capture_resource', capture_resource_callbacks=[], release_resource_callbacks=[], error_resource_callbacks=[], refresh_resource_list_callbacks=[]):
00021 super(ResourceChooserInterface, self).__init__()
00022 self.destroyed.connect(self.close)
00023
00024 self._capture_timeout = capture_timeout
00025 self._resource_list = []
00026 self._service_pair_msg_q = []
00027
00028 self.available_resource_topic = available_resource_topic
00029 self.capture_resource_pair_topic = capture_resource_pair_topic
00030
00031 self._callback = {}
00032 self._callback['capture'] = capture_resource_callbacks
00033 self._callback['release'] = release_resource_callbacks
00034 self._callback['error'] = error_resource_callbacks
00035 self._callback['refresh_list'] = refresh_resource_list_callbacks
00036
00037 self._init_ros_api()
00038
00039 def _init_ros_api(self):
00040 self._sub_avail_resource = rospy.Subscriber(self.available_resource_topic, StringArray, self._update_resource_list)
00041 self._pair_capture_resource = rocon_python_comms.ServicePairClient(self.capture_resource_pair_topic, concert_service_msgs.CaptureResourcePair)
00042
00043 def capture_resource(self, uri):
00044 """
00045 Initiate a request to capture an available robot.
00046
00047 :param str rocon_uri: robot information as a rocon uri
00048 """
00049 request = concert_service_msgs.CaptureResourceRequest()
00050 request.rocon_uri = uri
00051 request.release = False
00052
00053 self.captured_resource_uri = request.rocon_uri
00054 msg_id = self._pair_capture_resource(request, timeout=rospy.Duration(self._capture_timeout), callback=self._capture_resource_callback, error_callback=self._error_resource_callback)
00055 self._service_pair_msg_q.append(msg_id)
00056
00057 def _capture_resource_callback(self, msg_id, msg):
00058 """
00059 Handle the response from a capture service pair request.
00060
00061 :param uuid_msgs.UniqueID msg_id: id of the request-response pair.
00062 :param concert_service_msgs.CaptureTeleopPairResponse msg: message response received
00063 """
00064 if msg_id in self._service_pair_msg_q:
00065 self._service_pair_msg_q.remove(msg_id)
00066 for callback in self._callback['capture']:
00067 callback(self.captured_resource_uri, msg)
00068
00069 def _error_resource_callback(self, msg_id, error_message):
00070 """ User callback to feed into non-blocking requests.
00071
00072 @param msg_id : id of the request-response pair.
00073 @type uuid_msgs.UniqueID
00074
00075 @param error_message : error string received
00076 @type str
00077 """
00078 for callback in self._callback['error']:
00079 callback(error_message)
00080
00081 def release_resource(self, uri):
00082 """
00083 caputre the resource with rocon uri
00084
00085 @param rocon_uri: resource information as uri type
00086 @type rocon_uri class
00087 """
00088 request = concert_service_msgs.CaptureResourceRequest()
00089 request.rocon_uri = uri
00090 request.release = True
00091 self.captured_resource_uri = request.rocon_uri
00092 msg_id = self._pair_capture_resource(request, timeout=rospy.Duration(self._capture_timeout), callback=self._release_resource_callback, error_callback=self._error_resource_callback)
00093 self._service_pair_msg_q.append(msg_id)
00094
00095 def _release_resource_callback(self, msg_id, msg):
00096 """ User callback to feed into non-blocking requests.
00097
00098 @param msg_id : id of the request-response pair.
00099 @type uuid_msgs.UniqueID
00100
00101 @param msg : message response received
00102 @type <name>Response
00103 """
00104 if msg_id in self._service_pair_msg_q:
00105 self._service_pair_msg_q.remove(msg_id)
00106 self.captured_resource_uri = None
00107 for callback in self._callback['release']:
00108 callback(self.captured_resource_uri, msg)
00109
00110 def _update_resource_list(self, msg):
00111 '''
00112 Receives available resource list from resource pimp.
00113 '''
00114 diff = lambda l1, l2: [x for x in l1 if x not in [l for l in l2]]
00115 new_resources = diff(msg.strings, self._resource_list)
00116 gone_resources = diff(self._resource_list, msg.strings)
00117
00118 if new_resources or gone_resources:
00119 self._resource_list = msg.strings
00120 for callback in self._callback['refresh_list']:
00121 callback(msg.strings)
00122
00123 def close(self):
00124 if self.captured_resource_uri:
00125 self.release_resource(self.captured_resource_uri)
00126 super(ResourceChooserInterface, self).close()