Package node_manager_fkie :: Module default_cfg_handler
[frames] | no frames]

Source Code for Module node_manager_fkie.default_cfg_handler

  1  # Software License Agreement (BSD License) 
  2  # 
  3  # Copyright (c) 2012, Fraunhofer FKIE/US, Alexander Tiderko 
  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 Fraunhofer 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  import time 
 34  import threading 
 35   
 36  from python_qt_binding import QtCore 
 37  import rospy 
 38  import node_manager_fkie as nm 
 39  try: 
 40  #  from default_cfg_fkie.msg import Capability 
 41    from multimaster_msgs_fkie.srv import ListDescription, ListNodes#, LoadLaunch, Task 
 42  except ImportError, e: 
 43    import sys 
 44    print >> sys.stderr, "Can't import services of default_cfg_fkie. Is default_cfg_fkie package compiled?" 
 45    raise ImportError(str(e)) 
 46   
47 -class DefaultConfigHandler(QtCore.QObject):
48 ''' 49 A class to retrieve the list of nodes from the default configuration service. 50 The received node list will be published by sending a QT signal. To retrieve 51 the configuration a new thread will be created. 52 ''' 53 node_list_signal = QtCore.Signal(str, str, list) 54 ''' 55 node_list_signal is a signal, which is emitted, if a new list with nodes is 56 retrieved. The signal has the URI of the service, the name of the service and 57 a list with node names as parameter. 58 ''' 59 description_signal = QtCore.Signal(str, str, list) 60 ''' 61 description_signal is a signal, which is emitted, if a new list with descriptions is 62 retrieved. The signal has the URI of the service, the name of the service and 63 a list with descriptions (L{default_cfg_fkie.Description}) parameter. 64 ''' 65 err_signal = QtCore.Signal(str, str, str) 66
67 - def __init__(self):
68 QtCore.QObject.__init__(self) 69 self.__serviceThreads = {} 70 self._lock = threading.RLock()
71
72 - def stop(self):
73 print " Shutdown default config update threads..." 74 for key, service in self.__serviceThreads.iteritems(): 75 service.join(3) 76 print " Default config update threads are off!"
77
78 - def requestNodeList(self, service_uri, service, delay_exec=0.0):
79 ''' 80 This method starts a thread to get the informations about the default 81 configured nodes. If all informations are retrieved, a C{node_list_signal} of 82 this class will be emitted. If for given service a thread is 83 already running, the request will be ignored. 84 This method is thread safe. 85 86 @param service_uri: the URI of the service 87 @type service_uri: C{str} 88 @param service: the name of service to get the node list 89 @type service: C{str} 90 @param delay_exec: delayd the execution 91 @type delay_exec: C{float} 92 ''' 93 with self._lock: 94 if not (self.__serviceThreads.has_key((service_uri, service))): 95 upthread = ServiceThread(service_uri, service, delay_exec) 96 upthread.update_signal.connect(self._on_node_list) 97 upthread.err_signal.connect(self._on_err) 98 self.__serviceThreads[(service_uri, service)] = upthread 99 upthread.start()
100
101 - def requestDescriptionList(self, service_uri, service, delay_exec=0.0):
102 ''' 103 This method starts a thread to get the descriptions from the default 104 configuration node. If all informations are retrieved, a C{description_signal} of 105 this class will be emitted. If for given service a thread is 106 already running, the request will be ignored. 107 This method is thread safe. 108 109 @param service_uri: the URI of the service 110 @type service_uri: C{str} 111 @param service: the name of service to get the description 112 @type service: C{str} 113 @param delay_exec: delayd the execution 114 @type delay_exec: C{float} 115 ''' 116 with self._lock: 117 if not (self.__serviceThreads.has_key((service_uri, service))): 118 upthread = ServiceDescriptionThread(service_uri, service, delay_exec) 119 upthread.update_signal.connect(self._on_descr_list) 120 upthread.err_signal.connect(self._on_err) 121 self.__serviceThreads[(service_uri, service)] = upthread 122 upthread.start()
123
124 - def _on_node_list(self, service_uri, service, nodes):
125 with self._lock: 126 try: 127 thread = self.__serviceThreads.pop((service_uri, service)) 128 del thread 129 except KeyError: 130 pass 131 self.node_list_signal.emit(service_uri, service, nodes)
132
133 - def _on_descr_list(self, service_uri, service, items):
134 with self._lock: 135 try: 136 thread = self.__serviceThreads.pop((service_uri, service)) 137 del thread 138 except KeyError: 139 pass 140 self.description_signal.emit(service_uri, service, items)
141
142 - def _on_err(self, service_uri, service, str):
143 with self._lock: 144 try: 145 thread = self.__serviceThreads.pop((service_uri, service)) 146 del thread 147 except KeyError: 148 pass 149 self.err_signal.emit(service_uri, service, str)
150 151 152
153 -class ServiceThread(QtCore.QObject, threading.Thread):
154 ''' 155 A thread to to retrieve the list of nodes from the default configuration 156 service and publish it by sending a QT signal. 157 ''' 158 update_signal = QtCore.Signal(str, str, list) 159 err_signal = QtCore.Signal(str, str, str) 160
161 - def __init__(self, service_uri, service, delay_exec=0.0, parent=None):
162 QtCore.QObject.__init__(self) 163 threading.Thread.__init__(self) 164 self._service_uri = service_uri 165 self._service = service 166 self._delay_exec = delay_exec 167 self.setDaemon(True)
168
169 - def run(self):
170 ''' 171 ''' 172 if self._service and self._service_uri: 173 try: 174 if self._delay_exec > 0: 175 time.sleep(self._delay_exec) 176 req, resp = nm.starter().callService(self._service_uri, self._service, ListNodes) 177 self.update_signal.emit(self._service_uri, self._service, resp.nodes) 178 except: 179 import traceback 180 lines = traceback.format_exc().splitlines() 181 rospy.logwarn("Error while retrieve the node list from %s[%s]: %s", str(self._service), str(self._service_uri), str(lines[-1])) 182 self.err_signal.emit(self._service_uri, self._service, lines[-1])
183
184 -class ServiceDescriptionThread(QtCore.QObject, threading.Thread):
185 ''' 186 A thread to to retrieve the list with descriptions from the default configuration 187 service and publish it by sending a QT signal. 188 ''' 189 update_signal = QtCore.Signal(str, str, list) 190 err_signal = QtCore.Signal(str, str, str) 191
192 - def __init__(self, service_uri, service, delay_exec=0.0, parent=None):
193 QtCore.QObject.__init__(self) 194 threading.Thread.__init__(self) 195 self._service_uri = service_uri 196 self._service = service 197 self._delay_exec = delay_exec 198 self.setDaemon(True)
199
200 - def run(self):
201 ''' 202 ''' 203 if self._service: 204 try: 205 if self._delay_exec > 0: 206 time.sleep(self._delay_exec) 207 req, resp = nm.starter().callService(self._service_uri, self._service, ListDescription) 208 self.update_signal.emit(self._service_uri, self._service, [resp]) 209 except: 210 import traceback 211 lines = traceback.format_exc().splitlines() 212 rospy.logwarn("Error while retrieve the description from %s[%s]: %s", str(self._service), str(self._service_uri), str(lines[-1])) 213 self.err_signal.emit(self._service_uri, self._service, lines[-1])
214