Package roslaunch :: Module node_args
[frames] | no frames]

Source Code for Module roslaunch.node_args

  1  # Software License Agreement (BSD License) 
  2  # 
  3  # Copyright (c) 2009, Willow Garage, Inc. 
  4  # All rights reserved. 
  5  # 
  6  # Redistribution and use in source and binary forms, with or without 
  7  # modification, are permitted provided that the following conditions 
  8  # are met: 
  9  # 
 10  #  * Redistributions of source code must retain the above copyright 
 11  #    notice, this list of conditions and the following disclaimer. 
 12  #  * Redistributions in binary form must reproduce the above 
 13  #    copyright notice, this list of conditions and the following 
 14  #    disclaimer in the documentation and/or other materials provided 
 15  #    with the distribution. 
 16  #  * Neither the name of Willow Garage, Inc. nor the names of its 
 17  #    contributors may be used to endorse or promote products derived 
 18  #    from this software without specific prior written permission. 
 19  # 
 20  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 21  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 22  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 23  # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 24  # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
 25  # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 26  # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 27  # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 28  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 29  # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
 30  # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 31  # POSSIBILITY OF SUCH DAMAGE. 
 32  # 
 33  # Revision $Id$ 
 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   
61 -class NodeParamsException(Exception):
62 """ 63 Exception to indicate that node parameters were invalid 64 """ 65 pass
66
67 -def get_node_list(config):
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 # filter out unnamed nodes 76 return [x for x in l if x]
77 94 113
114 -def _resolved_name(node):
115 if node.name: 116 # $(anon id) passthrough 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 144
145 -def get_node_args(node_name, roslaunch_files):
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 # we have to create our own XmlLoader so that we can use the same 159 # resolution context for substitution args 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 # remove setting identical to current environment for easier debugging 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 # resolve node name for generating args 189 args = create_local_process_args(node, machine) 190 # join environment vars are bash prefix args 191 return ["%s=%s"%(k, v) for k, v in env.items()] + args
192
193 -def _launch_prefix_args(node):
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
208 -def create_local_process_args(node, machine, env=None):
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 # create rospack instance if no cached value is available or for custom environments 222 if not _rospack or env is not None: 223 rospack = rospkg.RosPack(rospkg.get_ros_paths(env=env)) 224 # cache rospack instance for default environment 225 if env is None: 226 _rospack = rospack 227 else: 228 rospack = _rospack 229 230 # - Construct rosrun command 231 remap_args = ["%s:=%s"%(src,dst) for src, dst in node.remap_args] 232 resolve_dict = {} 233 234 #resolve args evaluates substitution commands 235 #shlex parses a command string into a list of args 236 # - for the local process args, we *do* resolve the anon tag so that the user can execute 237 # - the node name and args must be resolved together in case the args refer to the anon node name 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') #attempt to force to string for shlex/subprocess 246 except NameError: 247 pass 248 args = shlex.split(resolved) + remap_args 249 try: 250 #TODO:fuerte: pass through rospack and catkin cache 251 matches = roslib.packages.find_node(node.package, node.type, rospack=rospack) 252 except rospkg.ResourceNotFound as e: 253 # multiple nodes, invalid package 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 # old behavior was to take first, do we want to change this in Fuerte-style? 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