@@ -74,17 +74,14 @@ def __init__(
7474 self , * ,
7575 node_name : Optional [SomeSubstitutionsType ] = None ,
7676 node_namespace : Optional [SomeSubstitutionsType ] = None ,
77+ original_node_name : Optional [SomeSubstitutionsType ] = None ,
7778 parameters : Optional [SomeParameters ] = None ,
7879 remappings : Optional [SomeRemapRules ] = None ,
7980 traits : Optional [Iterable [NodeTrait ]] = None ,
8081 ** kwargs
8182 ) -> None :
8283 """
83- Construct an Node description.
84-
85- Many arguments are passed eventually to
86- :class:`launch.actions.ExecuteProcess`, so see the documentation of
87- that class for additional details.
84+ Construct a Node description.
8885
8986 If the node name is not given (or is None) then no name is passed to
9087 the node on creation and instead the default name specified within the
@@ -117,6 +114,9 @@ def __init__(
117114
118115 :param: node_name the name of the node
119116 :param: node_namespace the ROS namespace for this Node
117+ :param: original_node_name the name of the node before remapping; if not specified,
118+ remappings/parameters (including node name/namespace changes) may be applied
119+ to all nodes which share a command line executable with this one
120120 :param: parameters list of names of yaml files with parameter rules,
121121 or dictionaries of parameters.
122122 :param: remappings ordered list of 'to' and 'from' string pairs to be
@@ -131,12 +131,14 @@ def __init__(
131131
132132 self .__node_name = node_name
133133 self .__node_namespace = node_namespace
134+ self .__original_node_name = original_node_name
134135 self .__parameters = [] if parameters is None else normalized_params
135136 self .__remappings = [] if remappings is None else list (normalize_remap_rules (remappings ))
136137 self .__traits = traits
137138
138139 self .__expanded_node_name = self .UNSPECIFIED_NODE_NAME
139140 self .__expanded_node_namespace = self .UNSPECIFIED_NODE_NAMESPACE
141+ self .__expanded_original_node_name = self .UNSPECIFIED_NODE_NAME
140142 self .__expanded_parameter_arguments = None # type: Optional[List[Tuple[Text, bool]]]
141143 self .__final_node_name = None # type: Optional[Text]
142144 self .__expanded_remappings = None # type: Optional[List[Tuple[Text, Text]]]
@@ -157,6 +159,11 @@ def node_namespace(self):
157159 """Getter for node_namespace."""
158160 return self .__node_namespace
159161
162+ @property
163+ def original_node_name (self ):
164+ """Getter for original_node_name."""
165+ return self .__original_node_name
166+
160167 @property
161168 def parameters (self ):
162169 """Getter for parameters."""
@@ -245,6 +252,10 @@ def _perform_substitutions(self, context: LaunchContext, cmd: List) -> None:
245252 cmd_ext = ['-r' , LocalSubstitution ("ros_specific_arguments['ns']" )]
246253 cmd .extend ([normalize_to_list_of_substitutions (x ) for x in cmd_ext ])
247254 validate_namespace (self .__expanded_node_namespace )
255+ if self .__original_node_name is not None :
256+ self .__expanded_original_node_name = perform_substitutions (
257+ context , normalize_to_list_of_substitutions (self .__original_node_name ))
258+ self .__expanded_node_name .lstrip ('/' )
248259 except Exception :
249260 self .__logger .error (
250261 "Error while expanding or validating node name or namespace for '{}':"
@@ -310,10 +321,17 @@ def _perform_substitutions(self, context: LaunchContext, cmd: List) -> None:
310321 # Prepare the ros_specific_arguments list and add it to the context so that the
311322 # LocalSubstitution placeholders added to the the cmd can be expanded using the contents.
312323 ros_specific_arguments : Dict [str , Union [str , List [str ]]] = {}
324+ original_name_prefix = ""
325+ if self .__expanded_original_node_name is not self .UNSPECIFIED_NODE_NAME :
326+ original_name_prefix = '{}:' .format (self .__expanded_original_node_name )
313327 if self .__node_name is not None :
314- ros_specific_arguments ['name' ] = '__node:={}' .format (self .__expanded_node_name )
328+ ros_specific_arguments ['name' ] = '{}__node:={}' .format (
329+ original_name_prefix , self .__expanded_node_name
330+ )
315331 if self .__expanded_node_namespace != '' :
316- ros_specific_arguments ['ns' ] = '__ns:={}' .format (self .__expanded_node_namespace )
332+ ros_specific_arguments ['ns' ] = '{}__ns:={}' .format (
333+ original_name_prefix , self .__expanded_node_namespace
334+ )
317335 context .extend_locals ({'ros_specific_arguments' : ros_specific_arguments })
318336
319337 if self .is_node_name_fully_specified ():
@@ -324,4 +342,4 @@ def _perform_substitutions(self, context: LaunchContext, cmd: List) -> None:
324342 execute_process_logger .warning (
325343 'there are now at least {} nodes with the name {} created within this '
326344 'launch context' .format (node_name_count , self .node_name )
327- )
345+ )
0 commit comments