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