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

Source Code for Module node_manager_fkie.update_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  from python_qt_binding.QtCore import QObject, Signal 
 34  import threading 
 35   
 36  from master_discovery_fkie.master_info import MasterInfo 
 37  from update_thread import UpdateThread 
 38   
 39   
40 -class UpdateHandler(QObject):
41 ''' 42 A class to retrieve the state about ROS master from remote discovery node and 43 publish it be sending a QT signal. To retrieve the state a new thread will be 44 created. 45 ''' 46 master_info_signal = Signal(MasterInfo) 47 ''' 48 @ivar: master_info_signal is a signal, which is emitted, if a new 49 U{master_discovery_fkie.MasterInfo<http://docs.ros.org/api/master_discovery_fkie/html/modules.html#module-master_discovery_fkie.master_info>} is retrieved. 50 ''' 51 master_errors_signal = Signal(str, list) 52 ''' 53 @ivar: master_errors_signal is a signal (masteruri, error list) with errors which 54 are occured on remote master_discovery. 55 ''' 56 57 error_signal = Signal(str, str) 58 ''' 59 @ivar: error_signal is a signal (masteruri, error message), which is emitted, 60 if an error while retrieving a master info was occurred. 61 ''' 62 63 timediff_signal = Signal(str, float) 64 ''' 65 @ivar: timediff_signal is a signal (masteruri, time difference), which is emitted 66 after the difference of time to the remote host is determined. 67 ''' 68
69 - def __init__(self):
70 QObject.__init__(self) 71 self.__updateThreads = {} 72 self.__requestedUpdates = {} 73 self._lock = threading.RLock()
74
75 - def stop(self):
76 if len(self.__updateThreads) > 0: 77 print " Shutdown update threads..." 78 self.__requestedUpdates.clear() 79 for _, thread in self.__updateThreads.iteritems(): 80 thread.join(3) 81 print " Update threads are off!"
82
83 - def requestMasterInfo(self, masteruri, monitoruri, delayed_exec=0.0):
84 ''' 85 This method starts a thread to get the informations about the ROS master by 86 the given RCP uri of the master_discovery node. If all informations are 87 retrieved, a C{master_info_signal} of this class will be emitted. If for given 88 masteruri a thread is already running, it will be inserted to the requested 89 updates. For the same masteruri only one requested update can be stored. 90 On update error the requested update will be ignored. 91 This method is thread safe. 92 93 @param masteruri: the URI of the remote ROS master 94 @type masteruri: C{str} 95 @param monitoruri: the URI of the monitor RPC interface of the master_discovery node 96 @type monitoruri: C{str} 97 @param delayed_exec: Delay the execution of the request for given seconds. 98 @type delayed_exec: C{float} 99 ''' 100 with self._lock: 101 try: 102 if masteruri in self.__updateThreads: 103 self.__requestedUpdates[masteruri] = (monitoruri, delayed_exec) 104 else: 105 self.__create_update_thread(monitoruri, masteruri, delayed_exec) 106 except: 107 pass
108
109 - def _on_master_info(self, minfo):
110 self.master_info_signal.emit(minfo) 111 self.__handle_requests(minfo.masteruri)
112
113 - def _on_master_errors(self, masteruri, error_list):
114 self.master_errors_signal.emit(masteruri, error_list)
115
116 - def _on_timediff(self, masteruri, timediff):
117 self.timediff_signal.emit(masteruri, timediff)
118
119 - def _on_error(self, masteruri, error):
120 self.error_signal.emit(masteruri, error) 121 self.__handle_requests(masteruri)
122
123 - def __handle_requests(self, masteruri):
124 with self._lock: 125 try: 126 thread = self.__updateThreads.pop(masteruri) 127 del thread 128 monitoruri, delayed_exec = self.__requestedUpdates.pop(masteruri) 129 self.__create_update_thread(monitoruri, masteruri, delayed_exec) 130 except KeyError: 131 pass 132 except: 133 import traceback 134 print traceback.format_exc(1)
135
136 - def __create_update_thread(self, monitoruri, masteruri, delayed_exec):
137 upthread = UpdateThread(monitoruri, masteruri, delayed_exec) 138 self.__updateThreads[masteruri] = upthread 139 upthread.update_signal.connect(self._on_master_info) 140 upthread.master_errors_signal.connect(self._on_master_errors) 141 upthread.error_signal.connect(self._on_error) 142 upthread.timediff_signal.connect(self._on_timediff) 143 upthread.start()
144