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