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 """
38 Utility module of roslaunch that computes the command-line arguments
39 for a node.
40 """
41
42 import logging
43 import os
44 import shlex
45 import sys
46 import time
47
48 import rospkg
49 import rosgraph
50 import rosgraph.names
51 from rosgraph.names import script_resolve_name
52
53 import roslib.packages
54
55 from . import substitution_args
56
57 from roslaunch.core import setup_env, local_machine, RLException
58 from roslaunch.config import load_config_default
59 import roslaunch.xmlloader
60
62 """
63 Exception to indicate that node parameters were invalid
64 """
65 pass
66
68 """
69 @param config: roslaunch config
70 @type config: ROSLaunchConfig
71 @return: list of node names in config
72 @rtype: [str]
73 """
74 l = [_resolved_name(node) for node in config.nodes] + [_resolved_name(test) for test in config.tests]
75
76 return [x for x in l if x]
77
94
96 """
97 Print arguments of node to screen. Will cause system exit if
98 exception occurs. This is a subroutine for the roslaunch main
99 handler.
100
101 @param node_name: node name
102 @type node_name: str
103 @param roslaunch_files: list of launch files to load
104 @type roslaunch_files: str
105 """
106 try:
107 node_name = script_resolve_name('roslaunch', node_name)
108 args = get_node_args(node_name, roslaunch_files)
109 if sys.platform == 'win32':
110
111 print('cmd /c \"%s\"' % (' '.join(args)))
112 else:
113
114 print(' '.join(args))
115 except RLException as e:
116 print(str(e), file=sys.stderr)
117 sys.exit(1)
118
120 if node.name:
121
122 if node.name.startswith('$'):
123 return node.name
124 else:
125 return rosgraph.names.ns_join(node.namespace, node.name)
126 else:
127 return None
128
130 try:
131
132 node_name = script_resolve_name('roslaunch', node_name)
133
134 loader = roslaunch.xmlloader.XmlLoader(resolve_anon=False)
135 config = load_config_default(roslaunch_files, None, loader=loader, verbose=False, assign_machines=False)
136 nodes = [n for n in config.nodes if _resolved_name(n) == node_name] + \
137 [t for t in config.tests if _resolved_name(t) == node_name]
138
139 if len(nodes) > 1:
140 raise RLException("ERROR: multiple nodes named [%s] in [%s].\nPlease fix the launch files as duplicate names are not allowed."%(node_name, ', '.join(roslaunch_files)))
141 if not nodes:
142 print('ERROR: cannot find node named [%s]. Run \n\troslaunch --nodes <files>\nto see list of node names.' % (node_name), file=sys.stderr)
143 else:
144 print(nodes[0].filename)
145
146 except RLException as e:
147 print(str(e), file=sys.stderr)
148 sys.exit(1)
149
151 """
152 Get the node arguments for a node in roslaunch_files.
153
154 @param node_name: name of node in roslaunch_files.
155 @type node_name: str
156 @param roslaunch_files: roslaunch file names
157 @type roslaunch_files: [str]
158 @return: list of command-line arguments used to launch node_name
159 @rtype: [str]
160 @raise RLException: if node args cannot be retrieved
161 """
162
163
164
165
166 loader = roslaunch.xmlloader.XmlLoader(resolve_anon=False)
167 config = load_config_default(roslaunch_files, None, loader=loader, verbose=False, assign_machines=False)
168 (node_name) = substitution_args.resolve_args((node_name), resolve_anon=False)
169 node_name = script_resolve_name('roslaunch', node_name) if not node_name.startswith('$') else node_name
170
171 node = [n for n in config.nodes if _resolved_name(n) == node_name] + \
172 [n for n in config.tests if _resolved_name(n) == node_name]
173 if not node:
174 node_list = get_node_list(config)
175 node_list_str = '\n'.join([" * %s"%x for x in node_list])
176 raise RLException("ERROR: Cannot find node named [%s] in [%s].\nNode names are:\n%s"%(node_name, ', '.join(roslaunch_files), node_list_str))
177 elif len(node) > 1:
178 raise RLException("ERROR: multiple nodes named [%s] in [%s].\nPlease fix the launch files as duplicate names are not allowed."%(node_name, ', '.join(roslaunch_files)))
179 node = node[0]
180
181 master_uri = rosgraph.get_master_uri()
182 machine = local_machine()
183 env = setup_env(node, machine, master_uri)
184
185
186 to_remove = []
187 for k in env.keys():
188 if env[k] == os.environ.get(k, None):
189 to_remove.append(k)
190 for k in to_remove:
191 del env[k]
192
193
194 args = create_local_process_args(node, machine)
195 if sys.platform == "win32":
196
197
198 return ["set %s=%s&&"%(k, v) for k, v in env.items()] + args
199 else:
200
201
202 return ['%s="%s"'%(k, v) for k, v in env.items()] + args
203
205 if node.launch_prefix:
206 prefix = node.launch_prefix
207 try:
208 if type(prefix) == unicode:
209 prefix = prefix.encode('UTF-8')
210 except NameError:
211 pass
212 os_posix = os.name == "posix"
213 return shlex.split(prefix, posix=os_posix)
214 else:
215 return []
216
217 _rospack = None
218
219
221 """
222 Subroutine for creating node arguments.
223
224 :param env: override os.environ. Warning, this does not override
225 substitution args in node configuration (for now), ``dict``
226 :returns: arguments for node process, ``[str]``
227 :raises: :exc:`NodeParamsException` If args cannot be constructed for Node
228 as specified (e.g. the node type does not exist)
229 """
230 global _rospack
231 if not node.name:
232 raise ValueError("node name must be defined")
233
234 if not _rospack or env is not None:
235 rospack = rospkg.RosPack(rospkg.get_ros_paths(env=env))
236
237 if env is None:
238 _rospack = rospack
239 else:
240 rospack = _rospack
241
242
243 remap_args = ["%s:=%s"%(src,dst) for src, dst in node.remap_args]
244 resolve_dict = {}
245
246
247
248
249
250 (node_name) = substitution_args.resolve_args((node.name), context=resolve_dict, resolve_anon=True)
251 node.name = node_name
252 remap_args.append('__name:=%s'%node_name)
253
254 resolved = substitution_args.resolve_args(node.args, context=resolve_dict, resolve_anon=True)
255 try:
256 if type(resolved) == unicode:
257 resolved = resolved.encode('UTF-8')
258 except NameError:
259 pass
260 os_posix = os.name == "posix"
261 args = shlex.split(resolved, posix=os_posix) + remap_args
262 try:
263
264 matches = roslib.packages.find_node(node.package, node.type, rospack=rospack)
265 except rospkg.ResourceNotFound as e:
266
267 raise NodeParamsException(str(e))
268 if not matches:
269 raise NodeParamsException("Cannot locate node of type [%s] in package [%s]. Make sure file exists in package path and permission is set to executable (chmod +x)"%(node.type, node.package))
270 else:
271
272 cmd = matches[0]
273 if not cmd:
274 raise NodeParamsException("Cannot locate node of type [%s] in package [%s]"%(node.type, node.package))
275 cmd = [cmd]
276
277
278
279
280 if sys.platform in ['win32'] and os.path.splitext(cmd[0])[1].lower() in ['.py', '']:
281 cmd = ['python'] + cmd
282 return _launch_prefix_args(node) + cmd + args
283