Namespace

In ROS network, it is not recommended to have an overlap in communication names (e.g., name of nodes, topics, and services). Frequently, situations arise in which you are required to designate a "scope" to the names. As an example, this page will show how to run multiple turtlesim applications (the pair of GUI + teleoperation) in a single ROS network using namespace.

Run Node in Namespace

First, rerun our old friend by ros2 run turtlesim turtletele. At this moment, your lists of nodes and topic are as follows:

jbs@jbs:~$ ros2 node list
/turtlesim
jbs@jbs:~$ ros2 topic list
/parameter_events
/rosout
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose

All the names start with a single slash / (e.g., /turtlesim), which corresponds to the global namespace.

Now, try scoping the node /turtlesim by

Running a node with a namespace
ros2 run turtlesim turtlesim_node --ros-args -r __ns:=/my_namespace1

In this command, we used remapping --ros-args -r (r denotes remapping) from the original namespace / to /my_namespace1. This will result in a different set of communication names:

jbs@jbs:~$ ros2 node list
/my_namespace1/turtlesim
jbs@jbs:~$ ros2 topic list
/my_namespace1/turtle1/cmd_vel
/my_namespace1/turtle1/color_sensor
/my_namespace1/turtle1/pose
/parameter_events
/rosout

This time, the names started with /my_namespace1 not /, except parameter_events and /rosout (the latter two are not affected by namespace remapping as they should exist in the global namespace /.) This means all the communication names inside /turtlesim now exist in the namespace /my_namespace1.

Scoping Communication

Can running the executable turtle_teleop_key operate the turtle out-of-box? Our node /my_namespace1/turtlesim is subscribing to /my_namespace1/turtle1/cmd_vel not /turtle1/cmd_vel, as the below outputs show:

jbs@jbs:~$ ros2 node info /my_namespace1/turtlesim
/my_namespace1/turtlesim
  Subscribers:
    /my_namespace1/turtle1/cmd_vel: geometry_msgs/msg/Twist
    /parameter_events: rcl_interfaces/msg/ParameterEvent
  Publishers:
    /my_namespace1/turtle1/color_sensor: turtlesim/msg/Color
    /my_namespace1/turtle1/pose: turtlesim/msg/Pose
    /parameter_events: rcl_interfaces/msg/ParameterEvent
    /rosout: rcl_interfaces/msg/Log
  Service Servers:
    /my_namespace1/clear: std_srvs/srv/Empty
    /my_namespace1/kill: turtlesim/srv/Kill
    /my_namespace1/reset: std_srvs/srv/Empty
    /my_namespace1/spawn: turtlesim/srv/Spawn
    /my_namespace1/turtle1/set_pen: turtlesim/srv/SetPen
    ...

On the other hand, the node teleop_turtle is publishing /turtle1/cmd_vel.

jbs@jbs:~$ ros2 node info /teleop_turtle
/teleop_turtle
  Subscribers:
    /parameter_events: rcl_interfaces/msg/ParameterEvent
  Publishers:
    /parameter_events: rcl_interfaces/msg/ParameterEvent
    /rosout: rcl_interfaces/msg/Log
    /turtle1/cmd_vel: geometry_msgs/msg/Twist
  Service Servers:
    /teleop_turtle/describe_parameters: rcl_interfaces/srv/DescribeParameters
    /teleop_turtle/get_parameter_types: rcl_interfaces/srv/GetParameterTypes
    /teleop_turtle/get_parameters: rcl_interfaces/srv/GetParameters
    /teleop_turtle/list_parameters: rcl_interfaces/srv/ListParameters
    /teleop_turtle/set_parameters: rcl_interfaces/srv/SetParameters
    /teleop_turtle/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomically
  Service Clients:
 
  Action Servers:
 
  Action Clients:
    /turtle1/rotate_absolute: turtlesim/action/RotateAbsolute

Thus, pressing keyboard inputs does not move anymore the turtle in the namespace /my_namespace1

What we resolve this by either of the two:

  1. Topic remapping: make /teleop_turtle publish topic /my_namespace1/turtle1/cmd_vel (we learned this already)
  2. Same namespace: make a new node teleop_turtle in the namespace /my_namespace1.

Option 1: Topic remapping

If you want to go with the first option, run the below command:

ros2 run turtlesim turtle_teleop_key --ros-args -r /turtle1/cmd_vel:=/my_namespace1/turtle1/cmd_vel

This will move the turtle by feeding the topic that /my_namespace1/turtlesim wants. This is a viable solution, but what if you have to deal with multiple topics? Say you have 10 more topics to be remapped. It will be quite a hassle to locate all the topics to be remapped and perform the remapping.

Option 2: Running in the same namespace

Let us try the second approach by

ros2 run turtlesim turtle_teleop_key --ros-args -r __ns:=/my_namespace1

This will remap all the communications to have the namespace /my_namespace1 without needing remapping communications individually. You can check this by:

Communications scoped in /my_namespace1
jbs@jbs:~$ ros2 node info /my_namespace1/teleop_turtle
/my_namespace1/teleop_turtle
  Subscribers:
    /parameter_events: rcl_interfaces/msg/ParameterEvent
  Publishers:
    /my_namespace1/turtle1/cmd_vel: geometry_msgs/msg/Twist
    /parameter_events: rcl_interfaces/msg/ParameterEvent
    /rosout: rcl_interfaces/msg/Log
  Service Servers:
    /my_namespace1/teleop_turtle/describe_parameters: rcl_interfaces/srv/DescribeParameters
    /my_namespace1/teleop_turtle/get_parameter_types: rcl_interfaces/srv/GetParameterTypes
    /my_namespace1/teleop_turtle/get_parameters: rcl_interfaces/srv/GetParameters
    /my_namespace1/teleop_turtle/list_parameters: rcl_interfaces/srv/ListParameters
    /my_namespace1/teleop_turtle/set_parameters: rcl_interfaces/srv/SetParameters
    /my_namespace1/teleop_turtle/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomically
  Service Clients:
 
  Action Servers:
 
  Action Clients:
    /my_namespace1/turtle1/rotate_absolute: turtlesim/action/RotateAbsolute

Following this approach can move the turtle by key-pressing :)

Multi-robot by Namespace

Until now, we have only the single namespace /my_namespace1. We will open a new scope /my_namespace2 and simulate a multi-robot system (although looks very baby-like 😊). Open two new terminals and run the two commands:

ros2 run turtlesim turtle_teleop_key --ros-args -r __ns:=/my_namespace2

and

ros2 run turtlesim turtlesim_node --ros-args -r __ns:=/my_namespace2

Run rqt_graph shows that there are two namespaces: /my_namespace1 and /my_namespace2.

Having two different namespaces, we can communicate one turtlesim program without affecting the other turtlesim in a different namespace. For example, we can kill the turtle of /turtlesim in my_namespace2 by:

ros2 service call /my_namespace2/kill turtlesim/srv/Kill "{name: turtle1}"

As shown in this figure, the turtle name of turtle1 in my_namespace2 was removed, and the turtle in my_namespace1 was not affected.

Summary

As we've observed, manipulating namespaces could scope our communication universe. From this, we can "reuse" an executable for different scopes, without remapping individually.