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 from python_qt_binding.QtCore import QObject, Signal
34 import threading
35 import time
36
37 import rospy
38
39 import node_manager_fkie as nm
40
41
42 try:
43 from multimaster_msgs_fkie.srv import ListDescription, ListNodes
44 except ImportError, e:
45 import sys
46 print >> sys.stderr, "Can't import services of default_cfg_fkie. Is default_cfg_fkie package compiled?"
47 raise ImportError(str(e))
48
49
51 '''
52 A class to retrieve the list of nodes from the default configuration service.
53 The received node list will be published by sending a QT signal. To retrieve
54 the configuration a new thread will be created.
55 '''
56 node_list_signal = Signal(str, str, list)
57 '''
58 node_list_signal is a signal, which is emitted, if a new list with nodes is
59 retrieved. The signal has the URI of the service, the name of the service and
60 a list with node names as parameter.
61 '''
62 description_signal = Signal(str, str, list)
63 '''
64 description_signal is a signal, which is emitted, if a new list with descriptions is
65 retrieved. The signal has the URI of the service, the name of the service and
66 a list with descriptions (U{multimaster_msgs_fkie.srv.ListDescription<http://docs.ros.org/api/multimaster_msgs_fkie/html/srv/ListDescription.html>} Response) parameter.
67 '''
68 err_signal = Signal(str, str, str)
69
71 QObject.__init__(self)
72 self.__serviceThreads = {}
73 self._lock = threading.RLock()
74
76 print " Shutdown default config update threads..."
77 for _, service in self.__serviceThreads.iteritems():
78 service.join(3)
79 print " Default config update threads are off!"
80
82 '''
83 This method starts a thread to get the informations about the default
84 configured nodes. If all informations are retrieved, a C{node_list_signal} of
85 this class will be emitted. If for given service a thread is
86 already running, the request will be ignored.
87 This method is thread safe.
88
89 @param service_uri: the URI of the service
90 @type service_uri: C{str}
91 @param service: the name of service to get the node list
92 @type service: C{str}
93 @param delay_exec: delayd the execution
94 @type delay_exec: C{float}
95 '''
96 with self._lock:
97 if (service_uri, service) not in self.__serviceThreads:
98 upthread = ServiceThread(service_uri, service, delay_exec)
99 upthread.update_signal.connect(self._on_node_list)
100 upthread.err_signal.connect(self._on_err)
101 self.__serviceThreads[(service_uri, service)] = upthread
102 upthread.start()
103
105 '''
106 This method starts a thread to get the descriptions from the default
107 configuration node. If all informations are retrieved, a C{description_signal} of
108 this class will be emitted. If for given service a thread is
109 already running, the request will be ignored.
110 This method is thread safe.
111
112 @param service_uri: the URI of the service
113 @type service_uri: C{str}
114 @param service: the name of service to get the description
115 @type service: C{str}
116 @param delay_exec: delayd the execution
117 @type delay_exec: C{float}
118 '''
119 with self._lock:
120 if (service_uri, service) not in self.__serviceThreads:
121 upthread = ServiceDescriptionThread(service_uri, service, delay_exec)
122 upthread.update_signal.connect(self._on_descr_list)
123 upthread.err_signal.connect(self._on_err)
124 self.__serviceThreads[(service_uri, service)] = upthread
125 upthread.start()
126
128 with self._lock:
129 try:
130 thread = self.__serviceThreads.pop((service_uri, service))
131 del thread
132 except KeyError:
133 pass
134 self.node_list_signal.emit(service_uri, service, nodes)
135
137 with self._lock:
138 try:
139 thread = self.__serviceThreads.pop((service_uri, service))
140 del thread
141 except KeyError:
142 pass
143 self.description_signal.emit(service_uri, service, items)
144
145 - def _on_err(self, service_uri, service, msg):
146 with self._lock:
147 try:
148 thread = self.__serviceThreads.pop((service_uri, service))
149 del thread
150 except KeyError:
151 pass
152 self.err_signal.emit(service_uri, service, msg)
153
154
156 '''
157 A thread to to retrieve the list of nodes from the default configuration
158 service and publish it by sending a QT signal.
159 '''
160 update_signal = Signal(str, str, list)
161 err_signal = Signal(str, str, str)
162
163 - def __init__(self, service_uri, service, delay_exec=0.0, parent=None):
164 QObject.__init__(self)
165 threading.Thread.__init__(self)
166 self._service_uri = service_uri
167 self._service = service
168 self._delay_exec = delay_exec
169 self.setDaemon(True)
170
172 '''
173 '''
174 if self._service and self._service_uri:
175 try:
176 if self._delay_exec > 0:
177 time.sleep(self._delay_exec)
178 _, resp = nm.starter().callService(self._service_uri, self._service, ListNodes)
179 self.update_signal.emit(self._service_uri, self._service, resp.nodes)
180 except:
181 import traceback
182 lines = traceback.format_exc(1).splitlines()
183 rospy.logwarn("Error while retrieve the node list from %s[%s]: %s", str(self._service), str(self._service_uri), str(lines[-1]))
184 self.err_signal.emit(self._service_uri, self._service, lines[-1])
185
186
188 '''
189 A thread to to retrieve the list with descriptions from the default configuration
190 service and publish it by sending a QT signal.
191 '''
192 update_signal = Signal(str, str, list)
193 err_signal = Signal(str, str, str)
194
195 - def __init__(self, service_uri, service, delay_exec=0.0, parent=None):
196 QObject.__init__(self)
197 threading.Thread.__init__(self)
198 self._service_uri = service_uri
199 self._service = service
200 self._delay_exec = delay_exec
201 self.setDaemon(True)
202
204 '''
205 '''
206 if self._service:
207 try:
208 if self._delay_exec > 0:
209 time.sleep(self._delay_exec)
210 _, resp = nm.starter().callService(self._service_uri, self._service, ListDescription)
211 self.update_signal.emit(self._service_uri, self._service, [resp])
212 except:
213 import traceback
214 lines = traceback.format_exc(1).splitlines()
215 rospy.logwarn("Error while retrieve the description from %s[%s]: %s", str(self._service), str(self._service_uri), str(lines[-1]))
216 self.err_signal.emit(self._service_uri, self._service, lines[-1])
217