0
$\begingroup$

Rosanswers logo

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 by default, for the reasons I mentioned above.

Solution 2. This would be trivial if I had access to the current global namespace of the launch file itself of the current group -- for instance something like "$(ns global)". In this case I could simply tell the navigation node to use "$(ns global)/base_controller/odom".

Solution 3. This would be trivial if I could tell a node to use its parent namespace -- for instance something like "..". In this case I could simply tell the navigation node to use "../base_controller/odom".

...

Is there any way to achieve solutions 2 or 3? Are there any plans to allow this kind of thing?


Originally posted by leblanc_kevin on ROS Answers with karma: 357 on 2011-11-27

Post score: 3

$\endgroup$

2 Answers 2

0
$\begingroup$

Rosanswers logo

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.


Originally posted by joq with karma: 25443 on 2011-11-27

This answer was ACCEPTED on the original site

Post score: 2


Original comments

Comment by leblanc_kevin on 2011-11-27:
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.

Comment by joq on 2011-11-27:
I used to believe that, too, but I have since concluded that was wrong. Private namespaces are not a good choice for topics.

Comment by leblanc_kevin on 2011-11-27:
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.

Comment by Max Pfingsthorn on 2013-07-24:
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.

Comment by leblanc_kevin on 2013-07-24:
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.

Comment by joq on 2013-07-24:
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.

Comment by tfurf on 2013-07-24:
https://github.com/ros/ros_comm/issues/236

Comment by thebyohazard on 2013-07-24:
This question might be related.

Comment by joq on 2016-06-27:
The big advantage of not tying the topic name to the node name is modularity: at some point you may want to use a different node publishing that same topic. That would be transparent to your other nodes.

$\endgroup$
0
$\begingroup$

Rosanswers logo

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.


Originally posted by tfurf with karma: 63 on 2013-07-24

This answer was NOT ACCEPTED on the original site

Post score: 5

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.