ROS2-011-Communication Mechanisms, Wrapping Up: Duplicate Node Names
Introduction
In ROS2, different nodes can share the same node name — for example, you can start several nodes whose name is the turtlesim turtlesim_node node.
Although duplicate node names are allowed, developers should avoid them on their own initiative, because duplicate names can lead to confusion in operation. Take the several turtlesim_node nodes again: when you check how the nodes are running with the node graph (rqt_graph), since those nodes share a name they are drawn as one node on the graph, when in fact there are several. And node names are also tied to topic names, service names, action names, parameters and all sorts of other variables, so that can throw the communication logic into confusion too.
So how do we avoid duplicate node names in ROS2?
The strategies
To avoid name clashes there are generally two common strategies:
- Namespace, i.e. putting a prefix on the node's name; the prefix can be several levels deep, usually in the format of /xxx/yyy/zzz
- Name remapping, giving the node an alias;
How to do it
1. Setting the node name with ros2 run
①. Set the namespace
The syntax is:
ros2 run <package name> <node name> --ros-args --remap __ns:=<namespace>For example:
ros2 run turtlesim turtlesim_node --ros-args --remap __ns:=/t1After running that command in a terminal, checking the node information with ros2 node list shows information containing the following result:
/t1/turtlesim②. Set name remapping
The syntax is:
ros2 run <package name> <node name> --ros-args --remap __name:=<remap name>Or:
ros2 run <package name> <node name> --ros-args --remap __node:=<remap name>For example (taking __name):
ros2 run turtlesim turtlesim_node --ros-args --remap __name:=ts1After running that command in a terminal, checking the node information with ros2 node list shows information containing the following result:
/ts1③. Setting the namespace and name remapping together
Just combine the two commands above. The syntax is:
ros2 run <package name> <node name> --ros-args --remap __ns:=<namespace> --remap __name:=<remap name>For example:
ros2 run turtlesim turtlesim_node --ros-args --remap __ns:=/t1 --remap __name:=ts1After running that command in a terminal, checking the node information with ros2 node list shows information containing the following result:
/t1/ts12. Setting the node name with a launch file
launch files can be written in Python, XML or YAML, and all three can set the namespace and the name remapping.
Before you use it...
When you use a launch file, remember to add the following at the install spot in CMakeLists.txt
install(DIRECTORY launch DESTINATION share/${PROJECT_NAME})Of course, the launch files below cover the configuration for C++ nodes; if you want the configuration for Python nodes, see the launch file notes further on
①. Writing the launch file in Python to set the namespace and name remapping (recommended)
When you write a launch file in Python, you can create the node object to be launched with the Python class launch_ros.actions.Node, and that object's constructor takes two arguments, name and namespace, to set the node's name and namespace. An example:
from launch import LaunchDesciption
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDesciption([
# set the name remapping
Node(package="turtlesim", executable="turtlesim_node", name="ts1"),
# set the namespace
Node(package="turtlesim", executable="turtlesim_node", namespace="t1"),
# set the namespace and name remapping together
Node(package="turtlesim", executable="turtlesim_node", namespace="t1", name="ts1")
])Note
The function name above must be generate_launch_description, otherwise ROS2 won't recognise and run the function.
②. Writing the launch file in XML to set the namespace and name remapping
When you write a launch file in XML, you can set the node's name and namespace through the two arguments name and namespace that node provides. An example:
<launch>
<!-- set the name remapping -->
<node pkg="turtlesim" exec="turtlesim_node" name="ts1"/>
<!-- set the namespace -->
<node pkg="turtlesim" exec="turtlesim_node" namespace="t1"/>
<!-- set the namespace and name remapping together -->
<node pkg="turtlesim" exec="turtlesim_node" namespace="t1" name="ts1"/>
</launch>③. Writing the launch file in YAML to set the namespace and name remapping
When you write a launch file in YAML, you can likewise set the node's name and namespace through the two arguments name and namespace that node provides. An example:
launch:
# set the name remapping
- node:
pkg: "turtlesim"
exec: "turtlesim_node"
name: "ts1"
# set the namespace
- node:
pkg: "turtlesim"
exec: "turtlesim_node"
namespace: "t1"
# set the namespace and name remapping together
- node:
pkg: "turtlesim"
exec: "turtlesim_node"
namespace: "t1"
name: "ts1"3. Setting the node name in code
When we write a node, the node classes provided by rclcpp and rclpy actually each give you arguments in their constructors for setting the node name and namespace.
①. The relevant API in rclcpp
In rclcpp, the node's constructor and some of the arguments it covers look like this:
Node(const std::string &node_name,
const std::string &namespace_,
const NodeOptions &options = NodeOptions())The argument node_name can be used to set the name remapping, and namespace_ can be used to set the namespace. The two can be used together.
②. The relevant API in rclpy
In rclpy, the node's constructor and some of the arguments it covers look like this:
Node(node_name, *,
context=None,
cli_args=None,
namespace=None,
use_global_arguments=True,
enable_rosout=True,
start_parameter_services=True,
parameter_overrides=None,
allow_undeclared_parameters=False,
automatically_declare_parameters_from_overrides=False)The argument node_name can be used to set the name remapping, and namespace can be used to set the namespace. The two can be used together.
What we know so far
Right at the start of our learning we set each node's name through the node_name argument, so setting the node_name argument here is essentially also remapping the node's name. The remapping used here is a little different from the previous two approaches, because the definition happens while the node is being created, rather than remapping or otherwise modifying it from outside before it runs. Do bear that in mind.
Important
This article was translated by Hermes Agent; the original text can be found at here. The translation is for reference only. Translation time: 2026-11-05
