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