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 print(' '.join(args))
110 except RLException as e:
111 print(str(e), file=sys.stderr)
112 sys.exit(1)
113
115 if node.name:
116
117 if node.name.startswith('$'):
118 return node.name
119 else:
120 return rosgraph.names.ns_join(node.namespace, node.name)
121 else:
122 return None
123
125 try:
126
127 node_name = script_resolve_name('roslaunch', node_name)
128
129 loader = roslaunch.xmlloader.XmlLoader(resolve_anon=False)
130 config = load_config_default(roslaunch_files, None, loader=loader, verbose=False, assign_machines=False)
131 nodes = [n for n in config.nodes if _resolved_name(n) == node_name] + \
132 [t for t in config.tests if _resolved_name(t) == node_name]
133
134 if len(nodes) > 1:
135 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)))
136 if not nodes:
137 print('ERROR: cannot find node named [%s]. Run \n\troslaunch --nodes <files>\nto see list of node names.' % (node_name), file=sys.stderr)
138 else:
139 print(nodes[0].filename)
140
141 except RLException as e:
142 print(str(e), file=sys.stderr)
143 sys.exit(1)
144
146 """
147 Get the node arguments for a node in roslaunch_files.
148
149 @param node_name: name of node in roslaunch_files.
150 @type node_name: str
151 @param roslaunch_files: roslaunch file names
152 @type roslaunch_files: [str]
153 @return: list of command-line arguments used to launch node_name
154 @rtype: [str]
155 @raise RLException: if node args cannot be retrieved
156 """
157
158
159
160
161 loader = roslaunch.xmlloader.XmlLoader(resolve_anon=False)
162 config = load_config_default(roslaunch_files, None, loader=loader, verbose=False, assign_machines=False)
163 (node_name) = substitution_args.resolve_args((node_name), resolve_anon=False)
164 node_name = script_resolve_name('roslaunch', node_name) if not node_name.startswith('$') else node_name
165
166 node = [n for n in config.nodes if _resolved_name(n) == node_name] + \
167 [n for n in config.tests if _resolved_name(n) == node_name]
168 if not node:
169 node_list = get_node_list(config)
170 node_list_str = '\n'.join([" * %s"%x for x in node_list])
171 raise RLException("ERROR: Cannot find node named [%s] in [%s].\nNode names are:\n%s"%(node_name, ', '.join(roslaunch_files), node_list_str))
172 elif len(node) > 1:
173 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)))
174 node = node[0]
175
176 master_uri = rosgraph.get_master_uri()
177 machine = local_machine()
178 env = setup_env(node, machine, master_uri)
179
180
181 to_remove = []
182 for k in env.keys():
183 if env[k] == os.environ.get(k, None):
184 to_remove.append(k)
185 for k in to_remove:
186 del env[k]
187
188
189 args = create_local_process_args(node, machine)
190
191 return ["%s=%s"%(k, v) for k, v in env.items()] + args
192
194 if node.launch_prefix:
195 prefix = node.launch_prefix
196 try:
197 if type(prefix) == unicode:
198 prefix = prefix.encode('UTF-8')
199 except NameError:
200 pass
201 return shlex.split(prefix)
202 else:
203 return []
204
205 _rospack = None
206
207
209 """
210 Subroutine for creating node arguments.
211
212 :param env: override os.environ. Warning, this does not override
213 substitution args in node configuration (for now), ``dict``
214 :returns: arguments for node process, ``[str]``
215 :raises: :exc:`NodeParamsException` If args cannot be constructed for Node
216 as specified (e.g. the node type does not exist)
217 """
218 global _rospack
219 if not node.name:
220 raise ValueError("node name must be defined")
221
222 if not _rospack or env is not None:
223 rospack = rospkg.RosPack(rospkg.get_ros_paths(env=env))
224
225 if env is None:
226 _rospack = rospack
227 else:
228 rospack = _rospack
229
230
231 remap_args = ["%s:=%s"%(src,dst) for src, dst in node.remap_args]
232 resolve_dict = {}
233
234
235
236
237
238 (node_name) = substitution_args.resolve_args((node.name), context=resolve_dict, resolve_anon=True)
239 node.name = node_name
240 remap_args.append('__name:=%s'%node_name)
241
242 resolved = substitution_args.resolve_args(node.args, context=resolve_dict, resolve_anon=True)
243 try:
244 if type(resolved) == unicode:
245 resolved = resolved.encode('UTF-8')
246 except NameError:
247 pass
248 args = shlex.split(resolved) + remap_args
249 try:
250
251 matches = roslib.packages.find_node(node.package, node.type, rospack=rospack)
252 except rospkg.ResourceNotFound as e:
253
254 raise NodeParamsException(str(e))
255 if not matches:
256 raise NodeParamsException("can't locate node [%s] in package [%s]"%(node.type, node.package))
257 else:
258
259 cmd = matches[0]
260 if not cmd:
261 raise NodeParamsException("Cannot locate node of type [%s] in package [%s]"%(node.type, node.package))
262 cmd = [cmd]
263 if sys.platform in ['win32']:
264 if os.path.splitext(cmd[0])[1] == '.py':
265 cmd = ['python'] + cmd
266 return _launch_prefix_args(node) + cmd + args
267