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

Source Code for Module node_manager_fkie.parameter_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  import xmlrpclib 
 36   
 37  import rospy 
 38   
 39   
40 -class ParameterHandler(QObject):
41 ''' 42 A class to retrieve the parameter list and their values from a ROS parameter 43 server. The results are published by sending a QT signal. To parameter a new 44 thread will be created. 45 ''' 46 parameter_list_signal = Signal(str, int, str, list) 47 ''' 48 parameter_list_signal is a signal, which is emitted if a new list with 49 parameter names is retrieved. The signal has the URI of the ROS parameter 50 server and (code, statusMessage, parameterNameList) - the response of the 51 server U{http://www.ros.org/wiki/ROS/Parameter%20Server%20API#getParamNames}. 52 ''' 53 parameter_values_signal = Signal(str, int, str, dict) 54 ''' 55 parameter_values_signal is a signal, which is emitted if a new list with 56 parameter names and their values is retrieved. The signal has the URI of the 57 ROS parameter server and (code, statusMessage, parameterNameValueDictionary) 58 as parameter. The dictionary has the format C{dict(paramName : (code, statusMessage, parameterValue))}. 59 For details see U{http://www.ros.org/wiki/ROS/Parameter%20Server%20API#getParam}. 60 ''' 61 62 delivery_result_signal = Signal(str, int, str, dict) 63 ''' 64 delivery_result_signal a signal is emitted after the parameter value was 65 set. For format see C{parameter_values_signal} signal. ''' 66
67 - def __init__(self):
68 QObject.__init__(self) 69 self.setObjectName('ParameterHandler') 70 self.__requestListThreads = [] 71 self.__requestValuesThreads = [] 72 self.__deliveryThreads = [] 73 self._lock = threading.RLock()
74 # print '=============== create', self.objectName() 75 # 76 # def __del__(self): 77 # print "************ destroy", self.objectName() 78 # print self.__requestListThreads 79 # print self.__requestValuesThreads 80 # print self.__deliveryThreads 81
82 - def requestParameterList(self, masteruri, ns='/'):
83 ''' 84 This method starts a thread to get the parameter list from ROS parameter 85 server. If all informations are retrieved, a C{parameter_list_signal} of 86 this class will be emitted. 87 This method is thread safe. 88 89 @param masteruri: the URI of the ROS parameter server 90 @type masteruri: C{str} 91 @param ns: the namespace of delivered parameter (Default: /) 92 @type ns: C{str} 93 ''' 94 with self._lock: 95 reqthread = RequestListThread(masteruri, ns) 96 reqthread.parameter_list_signal.connect(self._on_param_list) 97 self.__requestListThreads.append(reqthread) 98 reqthread.start()
99
100 - def requestParameterValues(self, masteruri, params):
101 ''' 102 This method starts a thread to get the parameter values from ROS parameter 103 server. If all informations are retrieved, a C{parameter_values_signal} of 104 this class will be emitted. 105 This method is thread safe. 106 107 @param masteruri: the URI of the ROS parameter server 108 @type masteruri: C{str} 109 @param params: List with parameter names 110 @type params: C{[str]} 111 ''' 112 with self._lock: 113 reqthread = RequestValuesThread(masteruri, params) 114 reqthread.parameter_values_signal.connect(self._on_param_values) 115 self.__requestValuesThreads.append(reqthread) 116 reqthread.start()
117
118 - def deliverParameter(self, masteruri, params):
119 ''' 120 This method starts a thread to load the parameter values into ROS parameter 121 server. If all informations are retrieved, a C{delivery_result_signal} of 122 this class will be emitted. 123 This method is thread safe. 124 125 @param masteruri: the URI of the ROS parameter server 126 @type masteruri: C{str} 127 @param params: The dictinary the parameter name and their value, see U{http://www.ros.org/wiki/ROS/Parameter%20Server%20API#setParam} 128 @type params: C{dict(str:value)} 129 ''' 130 with self._lock: 131 reqthread = DeliverValuesThread(masteruri, params) 132 reqthread.result_signal.connect(self._on_set_result) 133 self.__deliveryThreads.append(reqthread) 134 reqthread.start()
135
136 - def _on_param_list(self, masteruri, code, msg, params):
137 self.parameter_list_signal.emit(masteruri, code, msg, params) 138 with self._lock: 139 try: 140 thread = self.__requestListThreads.pop(0) 141 del thread 142 except KeyError: 143 pass
144
145 - def _on_param_values(self, masteruri, code, msg, values):
146 self.parameter_values_signal.emit(masteruri, code, msg, values) 147 with self._lock: 148 try: 149 thread = self.__requestValuesThreads.pop(0) 150 del thread 151 except KeyError: 152 pass
153
154 - def _on_set_result(self, masteruri, code, msg, values):
155 self.delivery_result_signal.emit(masteruri, code, msg, values) 156 with self._lock: 157 try: 158 thread = self.__deliveryThreads.pop(0) 159 del thread 160 except KeyError: 161 pass
162 163
164 -class RequestListThread(QObject, threading.Thread):
165 ''' 166 A thread to to retrieve the parameter list from ROSparameter server 167 and publish it by sending a QT signal. 168 ''' 169 parameter_list_signal = Signal(str, int, str, list) 170
171 - def __init__(self, masteruri, ns, parent=None):
172 QObject.__init__(self) 173 threading.Thread.__init__(self) 174 self._masteruri = masteruri 175 self._ns = ns 176 self.setDaemon(True)
177
178 - def run(self):
179 ''' 180 ''' 181 if self._masteruri: 182 try: 183 name = rospy.get_name() 184 master = xmlrpclib.ServerProxy(self._masteruri) 185 code, msg, params = master.getParamNames(name) 186 # filter the parameter 187 result = [] 188 for p in params: 189 if p.startswith(self._ns): 190 result.append(p) 191 self.parameter_list_signal.emit(self._masteruri, code, msg, result) 192 except: 193 import traceback 194 err_msg = "Error while retrieve the parameter list from %s: %s" % (self._masteruri, traceback.format_exc(1)) 195 rospy.logwarn(err_msg) 196 # lines = traceback.format_exc(1).splitlines() 197 self.parameter_list_signal.emit(self._masteruri, -1, err_msg, [])
198 199
200 -class RequestValuesThread(QObject, threading.Thread):
201 ''' 202 A thread to to retrieve the value for given parameter from ROSparameter server 203 and publish it by sending a QT signal. 204 ''' 205 parameter_values_signal = Signal(str, int, str, dict) 206
207 - def __init__(self, masteruri, params, parent=None):
208 QObject.__init__(self) 209 threading.Thread.__init__(self) 210 self._masteruri = masteruri 211 self._params = params 212 self.setDaemon(True)
213
214 - def run(self):
215 ''' 216 ''' 217 if self._masteruri: 218 result = dict() 219 for p in self._params: 220 result[p] = None 221 try: 222 name = rospy.get_name() 223 master = xmlrpclib.ServerProxy(self._masteruri) 224 param_server_multi = xmlrpclib.MultiCall(master) 225 for p in self._params: 226 param_server_multi.getParam(name, p) 227 r = param_server_multi() 228 for index, (code, msg, value) in enumerate(r): 229 result[self._params[index]] = (code, msg, value) 230 self.parameter_values_signal.emit(self._masteruri, 1, '', result) 231 except: 232 import traceback 233 # err_msg = "Error while retrieve parameter values from %s: %s"%(self._masteruri, traceback.format_exc(1)) 234 # rospy.logwarn(err_msg) 235 # lines = traceback.format_exc(1).splitlines() 236 self.parameter_values_signal.emit(self._masteruri, -1, traceback.format_exc(1), result)
237 238
239 -class DeliverValuesThread(QObject, threading.Thread):
240 ''' 241 A thread to to deliver the value for given parameter to ROSparameter server 242 and publish the result by sending a QT signal. 243 ''' 244 result_signal = Signal(str, int, str, dict) 245
246 - def __init__(self, masteruri, params, parent=None):
247 ''' 248 @param masteruri: The URI of the ROS parameter server 249 @type masteruri: C{str} 250 @param params: The dictinary the parameter name and their value, see U{http://www.ros.org/wiki/ROS/Parameter%20Server%20API#setParam} 251 @type params: C{dict(str: value)} 252 ''' 253 QObject.__init__(self) 254 threading.Thread.__init__(self) 255 self._masteruri = masteruri 256 self._params = params 257 self.setDaemon(True)
258
259 - def run(self):
260 ''' 261 ''' 262 if self._masteruri: 263 result = dict() 264 names = self._params.keys() 265 for p in names: 266 result[p] = None 267 try: 268 name = rospy.get_name() 269 master = xmlrpclib.ServerProxy(self._masteruri) 270 param_server_multi = xmlrpclib.MultiCall(master) 271 for p, v in self._params.items(): 272 param_server_multi.setParam(name, p, v) 273 r = param_server_multi() 274 for index, (code, msg, value) in enumerate(r): 275 result[names[index]] = (code, msg, value) 276 self.result_signal.emit(self._masteruri, 1, '', result) 277 except: 278 import traceback 279 err_msg = "Error while deliver parameter values to %s: %s" % (self._masteruri, traceback.format_exc(1)) 280 rospy.logwarn(err_msg) 281 # lines = traceback.format_exc(1).splitlines() 282 self.result_signal.emit(self._masteruri, -1, err_msg, result)
283