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 random
35 import socket
36 import threading
37 import time
38 import xmlrpclib
39
40 import rospy
41
42 from master_discovery_fkie.master_info import MasterInfo
43
44
46 '''
47 A thread to retrieve the state about ROS master from remote discovery node and
48 publish it be sending a QT signal.
49 '''
50 update_signal = Signal(MasterInfo)
51 '''
52 @ivar: update_signal is a signal, which is emitted, if a new
53 U{master_discovery_fkie.MasterInfo<http://docs.ros.org/api/master_discovery_fkie/html/modules.html#module-master_discovery_fkie.master_info>} is retrieved.
54 '''
55
56 master_errors_signal = Signal(str, list)
57 '''
58 @ivar: master_errors_signal is a signal (masteruri, list of errors),
59 which is emitted, if we get a list with errors from remote master_discovery.
60 '''
61
62 error_signal = Signal(str, str)
63 '''
64 @ivar: error_signal is a signal (masteruri, error message), which is emitted,
65 if an error while retrieving a master info was occurred.
66 '''
67
68 timediff_signal = Signal(str, float)
69 '''
70 @ivar: timediff_signal is a signal (masteruri, time difference), which is emitted
71 after the difference of time to the remote host is determined.
72 '''
73
74 - def __init__(self, monitoruri, masteruri, delayed_exec=0., parent=None):
75 '''
76 @param masteruri: the URI of the remote ROS master
77 @type masteruri: C{str}
78 @param monitoruri: the URI of the monitor RPC interface of the master_discovery node
79 @type monitoruri: C{str}
80 @param delayed_exec: Delay the execution of the request for given seconds.
81 @type delayed_exec: C{float}
82 '''
83 QObject.__init__(self)
84 threading.Thread.__init__(self)
85 self._monitoruri = monitoruri
86 self._masteruri = masteruri
87 self._delayed_exec = delayed_exec
88 self.setDaemon(True)
89
91 '''
92 '''
93 try:
94 delay = self._delayed_exec + 0.5 + random.random()
95
96 time.sleep(delay)
97
98 socket.setdefaulttimeout(25)
99 remote_monitor = xmlrpclib.ServerProxy(self._monitoruri)
100
101 try:
102 muri, errors = remote_monitor.masterErrors()
103 self.master_errors_signal.emit(muri, errors)
104 except xmlrpclib.Fault as _err:
105 rospy.logwarn("Older master_discovery on %s detected. It does not support master error reports!" % self._masteruri)
106
107 try:
108 myts = time.time()
109 muri, remote_ts = remote_monitor.getCurrentTime()
110 self.timediff_signal.emit(muri, remote_ts - myts - (time.time() - myts) / 2.0)
111 except xmlrpclib.Fault as _errts:
112 rospy.logwarn("Older master_discovery on %s detected. It does not support master error reports!" % self._masteruri)
113
114 remote_info = remote_monitor.masterInfo()
115 master_info = MasterInfo.from_list(remote_info)
116 master_info.check_ts = time.time()
117
118 self.update_signal.emit(master_info)
119 except:
120 import traceback
121
122 formatted_lines = traceback.format_exc(1).splitlines()
123 rospy.logwarn("Cannot update ROS state, connection to %s failed:\n\t%s", str(self._monitoruri), formatted_lines[-1])
124
125 self.error_signal.emit(self._masteruri, formatted_lines[-1])
126 finally:
127 if socket is not None:
128 socket.setdefaulttimeout(None)
129