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