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 import os
36 import logging
37 import sys
38 import traceback
39
40
41
42 if sys.version_info[:3] == (2, 7, 3):
43 import threading
44 threading._DummyThread._Thread__stop = lambda _dummy: None
45
46 import rospkg
47
48 from . import core as roslaunch_core
49 from . import param_dump as roslaunch_param_dump
50
51
52 from .core import Node, Test, Master, RLException
53 from .config import ROSLaunchConfig
54 from .launch import ROSLaunchRunner
55 from .xmlloader import XmlLoader, XmlParseException
56
57
58
59 from .scriptapi import ROSLaunch
60 from .pmon import Process
61
62 try:
63 from rosmaster import DEFAULT_MASTER_PORT
64 except:
65 DEFAULT_MASTER_PORT = 11311
66
67 NAME = 'roslaunch'
68
88
90 if options_pid_fn or options_core:
91
92 ros_home = rospkg.get_ros_home()
93 if options_pid_fn:
94 pid_fn = os.path.expanduser(options_pid_fn)
95 if os.path.dirname(pid_fn) == ros_home and not os.path.exists(ros_home):
96 os.makedirs(ros_home)
97 else:
98
99 if port is None:
100 port = DEFAULT_MASTER_PORT
101 pid_fn = os.path.join(ros_home, 'roscore-%s.pid'%(port))
102
103 if not os.path.exists(ros_home):
104 os.makedirs(ros_home)
105
106 with open(pid_fn, "w") as f:
107 f.write(str(os.getpid()))
108
110 from optparse import OptionParser
111
112 parser = OptionParser(usage="usage: %prog [options] [package] <filename> [arg_name:=value...]", prog=NAME)
113 parser.add_option("--files",
114 dest="file_list", default=False, action="store_true",
115 help="Print list files loaded by launch file, including launch file itself")
116 parser.add_option("--args",
117 dest="node_args", default=None,
118 help="Print command-line arguments for node", metavar="NODE_NAME")
119 parser.add_option("--nodes",
120 dest="node_list", default=False, action="store_true",
121 help="Print list of node names in launch file")
122 parser.add_option("--find-node",
123 dest="find_node", default=None,
124 help="Find launch file that node is defined in", metavar="NODE_NAME")
125 parser.add_option("-c", "--child",
126 dest="child_name", default=None,
127 help="Run as child service 'NAME'. Required with -u", metavar="NAME")
128 parser.add_option("--local",
129 dest="local_only", default=False, action="store_true",
130 help="Do not launch remote nodes")
131
132 parser.add_option("--screen",
133 dest="force_screen", default=False, action="store_true",
134 help="Force output of all local nodes to screen")
135 parser.add_option("-u", "--server_uri",
136 dest="server_uri", default=None,
137 help="URI of server. Required with -c", metavar="URI")
138 parser.add_option("--run_id",
139 dest="run_id", default=None,
140 help="run_id of session. Required with -c", metavar="RUN_ID")
141
142 parser.add_option("--wait", action="store_true",
143 dest="wait_for_master", default=False,
144 help="wait for master to start before launching")
145 parser.add_option("-p", "--port",
146 dest="port", default=None,
147 help="master port. Only valid if master is launched", metavar="PORT")
148 parser.add_option("--core", action="store_true",
149 dest="core", default=False,
150 help="Launch core services only")
151 parser.add_option("--pid",
152 dest="pid_fn", default="",
153 help="write the roslaunch pid to filename")
154 parser.add_option("-v", action="store_true",
155 dest="verbose", default=False,
156 help="verbose printing")
157
158 parser.add_option("--dump-params", default=False, action="store_true",
159 dest="dump_params",
160 help="Dump parameters of all roslaunch files to stdout")
161 parser.add_option("--skip-log-check", default=False, action="store_true",
162 dest="skip_log_check",
163 help="skip check size of log folder")
164 parser.add_option("--ros-args", default=False, action="store_true",
165 dest="ros_args",
166 help="Display command-line arguments for this launch file")
167 parser.add_option("--disable-title", default=False, action="store_true",
168 dest="disable_title",
169 help="Disable setting of terminal title")
170
171 return parser
172
174
175 if options.child_name:
176 if not options.server_uri:
177 parser.error("--child option requires --server_uri to be set as well")
178 if not options.run_id:
179 parser.error("--child option requires --run_id to be set as well")
180 if options.port:
181 parser.error("port option cannot be used with roslaunch child mode")
182 if args:
183 parser.error("Input files are not allowed when run in child mode")
184 elif options.core:
185 if args:
186 parser.error("Input files are not allowed when launching core")
187 if options.run_id:
188 parser.error("--run_id should only be set for child roslaunches (-c)")
189
190
191
192
193 elif len(args) == 0:
194 parser.error("you must specify at least one input file")
195 elif [f for f in args if not os.path.exists(f)]:
196 parser.error("The following input files do not exist: %s"%f)
197
198 if len([x for x in [options.node_list, options.find_node, options.node_args, options.ros_args] if x]) > 1:
199 parser.error("only one of [--nodes, --find-node, --args --ros-args] may be specified")
200
201 -def main(argv=sys.argv):
202 options = None
203 try:
204 from . import rlutil
205 parser = _get_optparse()
206
207 (options, args) = parser.parse_args(argv[1:])
208 args = rlutil.resolve_launch_arguments(args)
209 _validate_args(parser, options, args)
210
211
212 if any([options.node_args, options.node_list, options.find_node, options.dump_params, options.file_list, options.ros_args]):
213 if options.node_args and not args:
214 parser.error("please specify a launch file")
215
216 from . import node_args
217 if options.node_args:
218 node_args.print_node_args(options.node_args, args)
219 elif options.find_node:
220 node_args.print_node_filename(options.find_node, args)
221
222 elif options.dump_params:
223 roslaunch_param_dump.dump_params(args)
224 elif options.file_list:
225 rlutil.print_file_list(args)
226 elif options.ros_args:
227 import arg_dump as roslaunch_arg_dump
228 roslaunch_arg_dump.dump_args(args)
229 else:
230 node_args.print_node_list(args)
231 return
232
233
234 if options.wait_for_master:
235 if options.core:
236 parser.error("--wait cannot be used with roscore")
237 rlutil._wait_for_master()
238
239
240 write_pid_file(options.pid_fn, options.core, options.port)
241
242
243 uuid = rlutil.get_or_generate_uuid(options.run_id, options.wait_for_master)
244 configure_logging(uuid)
245
246
247 if not options.child_name and not options.skip_log_check:
248
249 rlutil.check_log_disk_usage()
250
251 logger = logging.getLogger('roslaunch')
252 logger.info("roslaunch starting with args %s"%str(argv))
253 logger.info("roslaunch env is %s"%os.environ)
254
255 if options.child_name:
256 logger.info('starting in child mode')
257
258
259
260
261 from . import child as roslaunch_child
262 c = roslaunch_child.ROSLaunchChild(uuid, options.child_name, options.server_uri)
263 c.run()
264 else:
265 logger.info('starting in server mode')
266
267
268 if not options.disable_title:
269 rlutil.change_terminal_name(args, options.core)
270
271
272
273 from . import parent as roslaunch_parent
274 try:
275
276 if options.core:
277 options.port = options.port or DEFAULT_MASTER_PORT
278 p = roslaunch_parent.ROSLaunchParent(uuid, args, is_core=options.core, port=options.port, local_only=options.local_only, verbose=options.verbose, force_screen=options.force_screen)
279 p.start()
280 p.spin()
281 finally:
282
283 if options.pid_fn:
284 try: os.unlink(options.pid_fn)
285 except os.error, reason: pass
286
287 except RLException as e:
288 roslaunch_core.printerrlog(str(e))
289 sys.exit(1)
290 except ValueError as e:
291
292 roslaunch_core.printerrlog(str(e))
293 sys.exit(1)
294 except Exception as e:
295 traceback.print_exc()
296 sys.exit(1)
297
298 if __name__ == '__main__':
299 main()
300