1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 import threading
34 import xmlrpclib
35
36 from python_qt_binding import QtCore
37 import rospy
38
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
67 QtCore.QObject.__init__(self)
68 self.setObjectName('ParameterHandler')
69 self.__requestListThreads = []
70 self.__requestValuesThreads = []
71 self.__deliveryThreads = []
72 self._lock = threading.RLock()
73
74
75
76
77
78
79
80
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
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
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
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
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
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
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
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
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
202 self.parameter_list_signal.emit(self._masteruri, -1, err_msg, [])
203
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
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
238
239
240 self.parameter_values_signal.emit(self._masteruri, -1, traceback.format_exc(), result)
241
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
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
285 self.result_signal.emit(self._masteruri, -1, err_msg, result)
286