ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
3

Can I access the absolute or parent namespace of a node from within a launch file?

asked 2011-11-27 04:36:21 -0500

Hi!

I'm wondering if there is a way to determine a node's absolute or parent namespace from within a launch file at run-time. The reason why I would like to be able to do this is as follows.

First, I use many nested launch files, which contain groups with their own namespaces. For this to work, my launch files need to avoid explicitly setting absolute namespaces, which maximises launch file reuse. (Note that reading absolute or parent namespaces at run-time, on the other hand, would not reduce reuse, so it's not a problem.)

Second, my nodes always read and write parameters and topics within their own private namespaces. This allows intuitive grouping of parameters and topics, and since all nodes always do the same thing it's easy to keep track of things. But most importantly, this avoids polluting the namespace in which the node was started; in particular, this allows multiple nodes to publish identically named topics for the same robot or namespace (without requiring me to look for and remap all potential conflicts).

For example, imagine we have a robot named Marvin, with its own group/namespace "marvin". Now image that marvin uses a robot base controller node called "base_controller", and an IMU-based position estimation node called "imu". The odometry topic produced by the base_driver might be "/marvin/base_controller/odom", and the IMU node might also produce an "odometry" estimate "/marvin/imu/odom". Without the private namespace we'd have to rely on remapping to achieve unique topic names like "base_controller_odom" and "imu_odom", which doesn't scale and gets very messy (what about the second IMU?). Namespaces seem to be a perfect way to avoid this.

The problem arises, of course, when I want to connect two nodes to the same topic. Since both publishers and subscribers will interpret all names as private by default, I can only pass topic names between them if I use absolute paths, or paths which are relative to a common parent node.

For example, if a navigation node, which uses its own "/marvin/navigation/" namespace by default, wants to read from Marvin's base controller's odometry topic "/marvin/base_controller/odom", I either need to tell the navigation node to read "/marvin/base_controller/odom", or I need to tell both to use something like "/marvin/odom". In either case, the desired topic needs to be specified as a global name, or it needs to use a common parent, in order to override the private namespaces used by both nodes.

...

Solution 1. For now I solve this in what I guess is the standard way, by not using private namespaces for topics. I still use the node's name internally to put everything in the private namespace by default anyway, but I can then remap topics relative to the node's parent namespace in the launch file. But this causes a bit more work for each node, and I really like the idea of every node using its own namespace ... (more)

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
2

answered 2011-11-27 11:26:52 -0500

joq gravatar image

The recommended solution is to define parameters in each node's private namespace, but define topics in the relative namespace. While parameters are typically specific to each node, topics are shared between multiple nodes. Publishers and subscribers generally do not need to know who provides or consumes the data, the topic name is sufficient.

So, in your example, /marvin/odom should provide nav_msgs/Odometry for Marvin. Each node will access it using the relative topic name, "odom". This is automatically be resolved in the appropriate namespace without any special handling in the nodes or launch files.

edit flag offensive delete link more

Comments

Thanks for your response. I understand names/namespaces, and I know how they're normally used. But I want to know if roslaunch allows me to do something different. As I mentioned in my question, I believe there are a number of advantages to using private namespaces by default, even for topics.
leblanc_kevin gravatar image leblanc_kevin  ( 2011-11-27 12:15:05 -0500 )edit
I used to believe that, too, but I have since concluded that was wrong. Private namespaces are not a good choice for topics.
joq gravatar image joq  ( 2011-11-27 12:36:08 -0500 )edit
You may be right, especially if (as I suspect) one can't access absolute/parent namespaces. As I said, for now I'm using relative namespaces for topics. But if roslaunch support for namespaces were flexible enough, other approaches (which might even be better in some situations) could be possible.
leblanc_kevin gravatar image leblanc_kevin  ( 2011-11-27 13:32:43 -0500 )edit
1

I do think that OP had a point. Imagine two sub-modules, with their own launch files, that I want to include in separate namespaces into a another module launch file, especially in simulation. Remapping between these sub-namespaces is impossible right now, since the absolute names are not known.

Max Pfingsthorn gravatar image Max Pfingsthorn  ( 2013-07-24 04:41:01 -0500 )edit
1

Thanks for your belated support. ;) Your example is the type of thing I was getting at. Launch file reuse and topic remapping could be much more powerful than they are.

leblanc_kevin gravatar image leblanc_kevin  ( 2013-07-24 05:01:50 -0500 )edit

If you are convinced you need this feature, please open an enhancement request for roslaunch. You can link it to this page to avoid repeating everything.

joq gravatar image joq  ( 2013-07-24 05:56:06 -0500 )edit

This question might be related.

thebyohazard gravatar image thebyohazard  ( 2013-07-24 06:46:49 -0500 )edit
5

answered 2013-07-24 21:59:39 -0500

tfurf gravatar image

updated 2013-07-24 22:01:37 -0500

A current hacked solution we came up with: Keep track of the global namespace by always passing down a <arg name="ns" ...> to every included launch file, and include a <arg name="ns" default=""/>. For example, with a simple two-subnode case, being called from an upper launch file.

The upper level launch:

<launch>
  <arg name="ns" default=""/>
  <remap from="$(arg ns)/node1/chatter" to="$(arg ns)/node2/chatter"/>
  <include file="talk_sub.launch" ns="node1">
    <arg name="ns" value="$(arg ns)/node1"/>
  </include>
  <include file="listen_sub.launch" ns="node2">
    <arg name="ns" value="$(arg ns)/node2"/>
  </include>
</launch>

And then in a lower level launch:

<launch>
  <arg name="ns" default=""/>
  <node name="talker" pkg="play" type="talker.py"/>
</launch>

In this way, you are always using the global-remap method, which always works, and you can reference the global namespace without actually knowing it a priori. This allows you to build up launch files with multi-level includes, and "cleanly" remap at the appropriate points. The best place to remap then is always at the lowest namespace where two topics are common, and no higher.

edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2011-11-27 04:36:21 -0500

Seen: 4,178 times

Last updated: Jul 24 '13