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
35 from __future__ import print_function
36
37 import os
38 import logging
39 import rospkg
40 import sys
41 import traceback
42
43
44
45 if sys.version_info[:3] == (2, 7, 3):
46 import threading
47 threading._DummyThread._Thread__stop = lambda _dummy: None
48
49 import rospkg
50
51 from . import core as roslaunch_core
52 from . import param_dump as roslaunch_param_dump
53
54
55 from .core import Node, Test, Master, RLException
56 from .config import ROSLaunchConfig
57 from .launch import ROSLaunchRunner
58 from .xmlloader import XmlLoader, XmlParseException
59
60
61
62 from .scriptapi import ROSLaunch
63 from .pmon import Process
64
65 try:
66 from rosmaster import DEFAULT_MASTER_PORT
67 except:
68 DEFAULT_MASTER_PORT = 11311
69
70 from rosmaster.master_api import NUM_WORKERS
71 from roslaunch.nodeprocess import DEFAULT_TIMEOUT_SIGINT, DEFAULT_TIMEOUT_SIGTERM
72
73 NAME = 'roslaunch'
74
94
96 if options_pid_fn or options_core:
97
98 ros_home = rospkg.get_ros_home()
99 if options_pid_fn:
100 pid_fn = os.path.expanduser(options_pid_fn)
101 if os.path.dirname(pid_fn) == ros_home and not os.path.exists(ros_home):
102 os.makedirs(ros_home)
103 else:
104
105 if port is None:
106 port = DEFAULT_MASTER_PORT
107 pid_fn = os.path.join(ros_home, 'roscore-%s.pid'%(port))
108
109 if not os.path.exists(ros_home):
110 os.makedirs(ros_home)
111
112 with open(pid_fn, "w") as f:
113 f.write(str(os.getpid()))
114
116 from optparse import OptionParser
117
118 usage = "usage: %prog [options] [package] <filename> [arg_name:=value...]\n"
119 usage += " %prog [options] <filename> [<filename>...] [arg_name:=value...]\n\n"
120 usage += "If <filename> is a single dash ('-'), launch XML is read from standard input."
121 parser = OptionParser(usage=usage, prog=NAME)
122 parser.add_option("--files",
123 dest="file_list", default=False, action="store_true",
124 help="Print list files loaded by launch file, including launch file itself")
125 parser.add_option("--args",
126 dest="node_args", default=None,
127 help="Print command-line arguments for node", metavar="NODE_NAME")
128 parser.add_option("--nodes",
129 dest="node_list", default=False, action="store_true",
130 help="Print list of node names in launch file")
131 parser.add_option("--find-node",
132 dest="find_node", default=None,
133 help="Find launch file that node is defined in", metavar="NODE_NAME")
134 parser.add_option("-c", "--child",
135 dest="child_name", default=None,
136 help="Run as child service 'NAME'. Required with -u", metavar="NAME")
137 parser.add_option("--local",
138 dest="local_only", default=False, action="store_true",
139 help="Do not launch remote nodes")
140
141 parser.add_option("--screen",
142 dest="force_screen", default=False, action="store_true",
143 help="Force output of all local nodes to screen")
144 parser.add_option("--required",
145 dest="force_required", default=False, action="store_true",
146 help="Force all nodes to be required")
147 parser.add_option("--log",
148 dest="force_log", default=False, action="store_true",
149 help="Force output of all local nodes to log")
150 parser.add_option("-u", "--server_uri",
151 dest="server_uri", default=None,
152 help="URI of server. Required with -c", metavar="URI")
153 parser.add_option("--run_id",
154 dest="run_id", default=None,
155 help="run_id of session. Required with -c", metavar="RUN_ID")
156
157 parser.add_option("--wait", action="store_true",
158 dest="wait_for_master", default=False,
159 help="wait for master to start before launching")
160 parser.add_option("-p", "--port",
161 dest="port", default=None,
162 help="master port. Only valid if master is launched", metavar="PORT")
163 parser.add_option("--core", action="store_true",
164 dest="core", default=False,
165 help="Launch core services only")
166 parser.add_option("--pid",
167 dest="pid_fn", default="",
168 help="write the roslaunch pid to filename")
169 parser.add_option("-v", action="store_true",
170 dest="verbose", default=False,
171 help="verbose printing")
172 parser.add_option("--no-summary", action="store_true",
173 dest="no_summary", default=False,
174 help="hide summary printing")
175
176 parser.add_option("--dump-params", default=False, action="store_true",
177 dest="dump_params",
178 help="Dump parameters of all roslaunch files to stdout")
179 parser.add_option("--skip-log-check", default=False, action="store_true",
180 dest="skip_log_check",
181 help="skip check size of log folder")
182 parser.add_option("--ros-args", default=False, action="store_true",
183 dest="ros_args",
184 help="Display command-line arguments for this launch file")
185 parser.add_option("--disable-title", default=False, action="store_true",
186 dest="disable_title",
187 help="Disable setting of terminal title")
188 parser.add_option("-w", "--numworkers",
189 dest="num_workers", default=NUM_WORKERS, type=int,
190 help="override number of worker threads. Only valid for core services.", metavar="NUM_WORKERS")
191 parser.add_option("-t", "--timeout",
192 dest="timeout",
193 help="override the socket connection timeout (in seconds). Only valid for core services.", metavar="TIMEOUT")
194 parser.add_option("--master-logger-level",
195 dest="master_logger_level", default=False, type=str,
196 help="set rosmaster.master logger level ('debug', 'info', 'warn', 'error', 'fatal')")
197 parser.add_option("--sigint-timeout",
198 dest="sigint_timeout",
199 default=DEFAULT_TIMEOUT_SIGINT, type=float,
200 help="the SIGINT timeout used when killing nodes (in seconds).",
201 metavar="SIGINT_TIMEOUT")
202 parser.add_option("--sigterm-timeout",
203 dest="sigterm_timeout",
204 default=DEFAULT_TIMEOUT_SIGTERM, type=float,
205 help="the SIGTERM timeout used when killing nodes if SIGINT does not stop the node (in seconds).",
206 metavar="SIGTERM_TIMEOUT")
207
208 return parser
209
211
212 if options.child_name:
213 if not options.server_uri:
214 parser.error("--child option requires --server_uri to be set as well")
215 if not options.run_id:
216 parser.error("--child option requires --run_id to be set as well")
217 if options.port:
218 parser.error("port option cannot be used with roslaunch child mode")
219 if args:
220 parser.error("Input files are not allowed when run in child mode")
221 elif options.core:
222 if args:
223 parser.error("Input files are not allowed when launching core")
224 if options.run_id:
225 parser.error("--run_id should only be set for child roslaunches (-c)")
226
227
228
229
230 elif len(args) == 0:
231 parser.error("you must specify at least one input file")
232 else:
233 missing_files = [f for f in args if not (f == '-' or os.path.exists(f))]
234 if missing_files:
235 parser.error("The following input files do not exist: %s"%', '.join(missing_files))
236
237 if args.count('-') > 1:
238 parser.error("Only a single instance of the dash ('-') may be specified.")
239
240 if len([x for x in [options.node_list, options.find_node, options.node_args, options.ros_args] if x]) > 1:
241 parser.error("only one of [--nodes, --find-node, --args --ros-args] may be specified")
242
244 roslaunch_core.printerrlog(msg + str(e))
245 roslaunch_core.printerrlog('The traceback for the exception was written to the log file')
246 if logger:
247 logger.error(traceback.format_exc())
248 sys.exit(1)
249
250 -def main(argv=sys.argv):
251 options = None
252 logger = None
253 try:
254 from . import rlutil
255 parser = _get_optparse()
256
257 (options, args) = parser.parse_args(argv[1:])
258 args = rlutil.resolve_launch_arguments(args)
259 _validate_args(parser, options, args)
260
261
262 if any([options.node_args, options.node_list, options.find_node, options.dump_params, options.file_list, options.ros_args]):
263 if options.node_args and not args:
264 parser.error("please specify a launch file")
265
266 from . import node_args
267 if options.node_args:
268 node_args.print_node_args(options.node_args, args)
269 elif options.find_node:
270 node_args.print_node_filename(options.find_node, args)
271
272 elif options.dump_params:
273 roslaunch_param_dump.dump_params(args)
274 elif options.file_list:
275 rlutil.print_file_list(args)
276 elif options.ros_args:
277 import arg_dump as roslaunch_arg_dump
278 roslaunch_arg_dump.dump_args(args)
279 else:
280 node_args.print_node_list(args)
281 return
282
283
284 if options.wait_for_master:
285 if options.core:
286 parser.error("--wait cannot be used with roscore")
287 rlutil._wait_for_master()
288
289
290 write_pid_file(options.pid_fn, options.core, options.port)
291
292
293 uuid = rlutil.get_or_generate_uuid(options.run_id, options.wait_for_master)
294 configure_logging(uuid)
295
296
297 if not options.child_name and not options.skip_log_check:
298
299 rlutil.check_log_disk_usage()
300
301 logger = logging.getLogger('roslaunch')
302 logger.info("roslaunch starting with args %s"%str(argv))
303 logger.info("roslaunch env is %s"%os.environ)
304
305 if options.child_name:
306 logger.info('starting in child mode')
307
308
309
310
311 from . import child as roslaunch_child
312 c = roslaunch_child.ROSLaunchChild(uuid, options.child_name, options.server_uri,
313 sigint_timeout=options.sigint_timeout,
314 sigterm_timeout=options.sigterm_timeout)
315 c.run()
316 else:
317 logger.info('starting in server mode')
318
319
320 if not options.disable_title:
321 rlutil.change_terminal_name(args, options.core)
322
323
324 roslaunch_strs = []
325 if '-' in args:
326 roslaunch_core.printlog("Passed '-' as file argument, attempting to read roslaunch XML from stdin.")
327 roslaunch_strs.append(sys.stdin.read())
328 roslaunch_core.printlog("... %d bytes read successfully.\n" % len(roslaunch_strs[-1]))
329 args.remove('-')
330
331
332
333 from . import parent as roslaunch_parent
334
335 if options.core:
336 options.port = options.port or DEFAULT_MASTER_PORT
337 p = roslaunch_parent.ROSLaunchParent(uuid, args, roslaunch_strs=roslaunch_strs,
338 is_core=options.core, port=options.port, local_only=options.local_only,
339 verbose=options.verbose, force_screen=options.force_screen,
340 force_log=options.force_log,
341 num_workers=options.num_workers, timeout=options.timeout,
342 master_logger_level=options.master_logger_level,
343 show_summary=not options.no_summary,
344 force_required=options.force_required,
345 sigint_timeout=options.sigint_timeout,
346 sigterm_timeout=options.sigterm_timeout)
347 p.start()
348 p.spin()
349
350 except RLException as e:
351 handle_exception(roslaunch_core, logger, "RLException: ", e)
352 except ValueError as e:
353
354 handle_exception(roslaunch_core, logger, "Value error: ", e)
355 except rospkg.ResourceNotFound as e:
356 handle_exception(roslaunch_core, logger, "Resource not found: ", e)
357 except Exception as e:
358 traceback.print_exc()
359 sys.exit(1)
360 finally:
361
362 if options is not None and options.pid_fn:
363 try: os.unlink(options.pid_fn)
364 except os.error: pass
365
366
367 if __name__ == '__main__':
368 main()
369