|
Package node_manager_fkie
|
|
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
34 __author__ = "Alexander Tiderko (Alexander.Tiderko@fkie.fraunhofer.de)"
35 __copyright__ = "Copyright (c) 2012 Alexander Tiderko, Fraunhofer FKIE/US"
36 __license__ = "BSD"
37 __version__ = "0.4.1"
38 __date__ = "2015-04-28"
39
40 import os
41 import sys
42 import socket
43 import threading
44 import argparse
45
46 PKG_NAME = 'node_manager_fkie'
47
48 import roslib; roslib.load_manifest(PKG_NAME)
49 import rospy
50 import roslib.network
51
52
53
54
55
56 from settings import Settings
57 from start_handler import StartHandler, StartException, BinarySelectionRequest
58 from ssh_handler import SSHhandler, AuthenticationRequest
59 from screen_handler import ScreenHandler, ScreenSelectionRequest
60 from progress_queue import InteractionNeededError
61 from name_resolution import NameResolution
62 from history import History
63 from file_watcher import FileWatcher
64 from common import get_ros_home, masteruri_from_ros
65 from master_view_proxy import LaunchArgsSelectionRequest
66
67 HOSTS_CACHE = dict()
68 '''
69 the cache directory to store the results of tests for local hosts.
70 @see: L{is_local()}
71 '''
72
73 _lock = threading.RLock()
74
75 main_form = None
76 _settings = None
77 _ssh_handler = None
78 _screen_handler = None
79 _start_handler = None
80 _name_resolution = None
81 _history = None
82 _file_watcher = None
83 _file_watcher_param = None
84 app = None
85
87 '''
88 @return: The global settings
89 @rtype: L{Settings}
90 '''
91 global _settings
92 return _settings
93
95 '''
96 @return: The SSH handler to handle the SSH connections
97 @rtype: L{SSHhandler}
98 '''
99 global _ssh_handler
100 return _ssh_handler
101
103 '''
104 @return: The screen handler to the screens.
105 @rtype: L{ScreenHandler}
106 @see: U{http://linuxwiki.de/screen}
107 '''
108 global _screen_handler
109 return _screen_handler
110
112 '''
113 @return: The start handler to handle the start of new ROS nodes on local or
114 remote machines.
115 @rtype: L{StartHandler}
116 '''
117 global _start_handler
118 return _start_handler
119
121 '''
122 @return: The name resolution object translate the the name to the host or
123 ROS master URI.
124 @rtype: L{NameResolution}
125 '''
126 global _name_resolution
127 return _name_resolution
128
130 '''
131 @return: The history of entered parameter.
132 @rtype: L{History}
133 '''
134 global _history
135 return _history
136
138 '''
139 @return: The file watcher object with all loaded configuration files.
140 @rtype: L{FileWatcher}
141 '''
142 global _file_watcher
143 return _file_watcher
144
146 '''
147 @return: The file watcher object with all configuration files referenced by parameter value.
148 @rtype: L{FileWatcher}
149 '''
150 global _file_watcher_param
151 return _file_watcher_param
152
153
155 '''
156 Test whether the given host name is the name of the local host or not.
157 @param hostname: the name or IP of the host
158 @type hostname: C{str}
159 @return: C{True} if the hostname is local or None
160 @rtype: C{bool}
161 @raise Exception: on errors while resolving host
162 '''
163 if (hostname is None):
164 return True
165 with _lock:
166 if hostname in HOSTS_CACHE:
167 if isinstance(HOSTS_CACHE[hostname], threading.Thread):
168 return False
169 return HOSTS_CACHE[hostname]
170
171 try:
172 socket.inet_aton(hostname)
173 local_addresses = ['localhost'] + roslib.network.get_local_addresses()
174
175 result = hostname.startswith('127.') or hostname in local_addresses
176 with _lock:
177 HOSTS_CACHE[hostname] = result
178 return result
179 except socket.error:
180
181 if wait:
182 result = __is_local(hostname)
183 return result
184 else:
185 thread = threading.Thread(target=__is_local, args=((hostname,)))
186 thread.daemon = True
187 with _lock:
188 HOSTS_CACHE[hostname] = thread
189 thread.start()
190 return False
191
193 try:
194 machine_addr = socket.gethostbyname(hostname)
195 except socket.gaierror:
196 import traceback
197 print traceback.format_exc()
198 with _lock:
199 HOSTS_CACHE[hostname] = False
200 return False
201 local_addresses = ['localhost'] + roslib.network.get_local_addresses()
202
203 result = machine_addr.startswith('127.') or machine_addr in local_addresses
204 with _lock:
205 HOSTS_CACHE[hostname] = result
206 return result
207
229
230
232 '''
233 Change the terminal name.
234 @param name: New name of the terminal
235 @type name: C{str}
236 '''
237 sys.stdout.write("\x1b]2;%s\x07"%name)
238
240 '''
241 Change the process name.
242 @param name: New process name
243 @type name: C{str}
244 '''
245 try:
246 from ctypes import cdll, byref, create_string_buffer
247 libc = cdll.LoadLibrary('libc.so.6')
248 buff = create_string_buffer(len(name)+1)
249 buff.value = name
250 libc.prctl(15, byref(buff), 0, 0, 0)
251 except:
252 pass
253
257
278
280 parser = argparse.ArgumentParser()
281 parser.add_argument("--version", action="version", version="%s %s" % ( "%(prog)s", __version__))
282 parser.add_argument("-f", "--file", nargs=1, help="loads the given file as default on start")
283
284 group = parser.add_argument_group('echo')
285 group.add_argument("--echo", nargs=2, help="starts an echo dialog instead of node manager", metavar=('name', 'type'))
286 group.add_argument("--hz", action="store_true", help="shows only the Hz value instead of topic content in echo dialog")
287 group.add_argument("--ssh", action="store_true", help="connects via SSH")
288
289 return parser
290
291 -def init_echo_dialog(prog_name, masteruri, topic_name, topic_type, hz=False, use_ssh=False):
302
303 -def init_main_window(prog_name, masteruri, launch_files=[]):
304
305 StartHandler._prepareROSMaster(masteruri)
306
307 try:
308 log_level = getattr(rospy, rospy.get_param('/%s/log_level'%prog_name, "INFO"))
309 except Exception as e:
310 print "Error while set the log level: %s\n->INFO level will be used!"%e
311 log_level = rospy.INFO
312 rospy.init_node(prog_name, anonymous=False, log_level=log_level)
313 setTerminalName(prog_name)
314 setProcessName(prog_name)
315 import main_window
316 local_master = init_globals(masteruri)
317 return main_window.MainWindow(launch_files, not local_master, launch_files)
318
319
320
321
322
324 try:
325 from python_qt_binding import QtGui
326 except:
327 print >> sys.stderr, "please install 'python_qt_binding' package!!"
328 sys.exit(-1)
329
330 init_settings()
331 masteruri = settings().masteruri()
332 parser = init_arg_parser()
333 args = rospy.myargv(argv=sys.argv)
334 parsed_args = parser.parse_args(args[1:])
335
336 global app
337 app = QtGui.QApplication(sys.argv)
338
339
340 global main_form
341 try:
342 if parsed_args.echo:
343 main_form = init_echo_dialog(name, masteruri, parsed_args.echo[0], parsed_args.echo[1], parsed_args.hz, parsed_args.ssh)
344 else:
345 main_form = init_main_window(name, masteruri, parsed_args.file)
346 except Exception as e:
347 sys.exit("%s"%e)
348
349 exit_code = 0
350
351 if not rospy.is_shutdown():
352 os.chdir(settings().PACKAGE_DIR)
353
354 screen_size = QtGui.QApplication.desktop().availableGeometry()
355 if main_form.size().width() >= screen_size.width() or main_form.size().height() >= screen_size.height()-24:
356 main_form.showMaximized()
357 else:
358 main_form.show()
359 exit_code = -1
360 rospy.on_shutdown(finish)
361 exit_code = app.exec_()
362 return exit_code
363