def execute(self, context: LaunchContext): """Execute the action.""" pushed_namespace = perform_substitutions(context, self.namespace) previous_namespace = context.launch_configurations.get( 'ros_namespace', None) namespace = make_namespace_absolute( prefix_namespace(previous_namespace, pushed_namespace)) try: validate_namespace(namespace) except Exception: raise SubstitutionFailure( 'The resulting namespace is invalid:' " [previous_namespace='{}', pushed_namespace='{}']".format( previous_namespace, pushed_namespace)) context.launch_configurations['ros_namespace'] = namespace
def _perform_substitutions(self, context: LaunchContext) -> None: # Here to avoid cyclic import from ..descriptions import Parameter try: if self.__substitutions_performed: # This function may have already been called by a subclass' `execute`, for example. return self.__substitutions_performed = True if self.__node_name is not None: self.__expanded_node_name = perform_substitutions( context, normalize_to_list_of_substitutions(self.__node_name)) validate_node_name(self.__expanded_node_name) self.__expanded_node_name.lstrip('/') expanded_node_namespace: Optional[Text] = None if self.__node_namespace is not None: expanded_node_namespace = perform_substitutions( context, normalize_to_list_of_substitutions(self.__node_namespace)) base_ns = context.launch_configurations.get('ros_namespace', None) expanded_node_namespace = make_namespace_absolute( prefix_namespace(base_ns, expanded_node_namespace)) if expanded_node_namespace is not None: self.__expanded_node_namespace = expanded_node_namespace cmd_extension = ['-r', LocalSubstitution("ros_specific_arguments['ns']")] self.cmd.extend([normalize_to_list_of_substitutions(x) for x in cmd_extension]) validate_namespace(self.__expanded_node_namespace) except Exception: self.__logger.error( "Error while expanding or validating node name or namespace for '{}':" .format('package={}, executable={}, name={}, namespace={}'.format( self.__package, self.__node_executable, self.__node_name, self.__node_namespace, )) ) raise self.__final_node_name = prefix_namespace( self.__expanded_node_namespace, self.__expanded_node_name) # expand global parameters first, # so they can be overriden with specific parameters of this Node global_params = context.launch_configurations.get('ros_params', None) if global_params is not None or self.__parameters is not None: self.__expanded_parameter_arguments = [] if global_params is not None: param_file_path = self._create_params_file_from_dict(global_params) self.__expanded_parameter_arguments.append((param_file_path, True)) cmd_extension = ['--params-file', f'{param_file_path}'] self.cmd.extend([normalize_to_list_of_substitutions(x) for x in cmd_extension]) assert os.path.isfile(param_file_path) # expand parameters too if self.__parameters is not None: evaluated_parameters = evaluate_parameters(context, self.__parameters) for params in evaluated_parameters: is_file = False if isinstance(params, dict): param_argument = self._create_params_file_from_dict(params) is_file = True assert os.path.isfile(param_argument) elif isinstance(params, pathlib.Path): param_argument = str(params) is_file = True elif isinstance(params, Parameter): param_argument = self._get_parameter_rule(params, context) else: raise RuntimeError('invalid normalized parameters {}'.format(repr(params))) if is_file and not os.path.isfile(param_argument): self.__logger.warning( 'Parameter file path is not a file: {}'.format(param_argument), ) continue self.__expanded_parameter_arguments.append((param_argument, is_file)) cmd_extension = ['--params-file' if is_file else '-p', f'{param_argument}'] self.cmd.extend([normalize_to_list_of_substitutions(x) for x in cmd_extension]) # expand remappings too global_remaps = context.launch_configurations.get('ros_remaps', None) if global_remaps or self.__remappings: self.__expanded_remappings = [] if global_remaps: self.__expanded_remappings.extend(global_remaps) if self.__remappings: self.__expanded_remappings.extend([ (perform_substitutions(context, src), perform_substitutions(context, dst)) for src, dst in self.__remappings ]) if self.__expanded_remappings: cmd_extension = [] for src, dst in self.__expanded_remappings: cmd_extension.extend(['-r', f'{src}:={dst}']) self.cmd.extend([normalize_to_list_of_substitutions(x) for x in cmd_extension])
def test_prefix_namespace(): assert prefix_namespace(None, None) is None assert prefix_namespace('asd', None) == 'asd' assert prefix_namespace('/asd', None) == '/asd' assert prefix_namespace('', None) == '' assert prefix_namespace('/', None) == '/' assert prefix_namespace(None, 'asd') == 'asd' assert prefix_namespace(None, '/asd') == '/asd' assert prefix_namespace(None, '') == '' assert prefix_namespace(None, '/') == '/' assert prefix_namespace('asd', 'bsd') == 'asd/bsd' assert prefix_namespace('asd', '/bsd') == '/bsd' assert prefix_namespace('/asd', 'bsd') == '/asd/bsd' assert prefix_namespace('/asd', '/bsd') == '/bsd' assert prefix_namespace('/', 'bsd') == '/bsd' assert prefix_namespace('', 'bsd') == 'bsd' assert prefix_namespace('asd', '') == 'asd' assert prefix_namespace('asd', 'bsd/') == 'asd/bsd' assert prefix_namespace('asd', '/bsd/') == '/bsd'