0
$\begingroup$

Rosanswers logo

Hello,

I wanted to know if there is a way to create programmatically in Python a ROS Node with a certain namespace decided by me. I know that in ROS 2 this is possible but I can't seem to find anything similar to it on ROS. I'm using ROS Noetic and Python 3.

Thank you!


Originally posted by anonymous53443 on ROS Answers with karma: 63 on 2020-05-29

Post score: 1

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

It looks like the namespace can be set programmatically in ROS 1 by setting ROS_NAMESPACE prior to importing rospy. With the code below, the node will have the namespace /my/custom/namespace unless the user running the node sets ROS_NAMESPACE or passes the command line argument __ns:=/some/other/ns.

import os
import sys

if 'ROS_NAMESPACE' not in os.environ:
    # Default namespace if not set
    # Note, didn't need to check sys.argv for `__ns:=...`,
    # it seems __ns:= takes precidence over ROS_NAMESPACE

    os.environ['ROS_NAMESPACE'] = '/my/custom/namespace'


# Must set `os.environ['ROS_NAMESPACE']` BEFORE importing `rospy`
import rospy

from std_msgs.msg import String

rospy.init_node('listener_default_ns')
rospy.Subscriber("chatter", String, lambda m: rospy.loginfo(m.data))
rospy.spin()

I tested this using ROS Melodic, but I would expect it to work in ROS Noetic as well.


EDIT @gvdhoorn has a good point. While the above answers the literal question, the preferred approach is to set the namespace when starting the nodes. The code of a node should only focus on its purpose; it shouldn't have to be concerned about whether there is one or many robots in different namespaces using that node. The awareness of how the node is integrated into a larger system should only be with the tools that launch the node.

You already discovered it can be set using the ns attribute in launch files. The namespace can be set one node at a time, or on a whole group of nodes at once. I took this example from the ROS wiki and simplified it for this answer.

<launch>
  <!-- Start a single node in the namespace foo -->
  <node ns="foo" name="listener1" pkg="rospy_tutorials" type="listener"/>
  <!-- Start a group of nodes in the namespace bar-->
  <group ns="bar">
    <node pkg="rospy_tutorials" type="listener" name="listener"/>
    <node pkg="rospy_tutorials" type="talker" name="talker"/>
  </group>
</launch>

Originally posted by sloretz with karma: 3061 on 2020-05-29

This answer was ACCEPTED on the original site

Post score: 1


Original comments

Comment by gvdhoorn on 2020-05-29:
It would perhaps also be good to ask why the OP wants to do this, as placing nodes in namespaces (and remapping topics, setting parameters, etc) are typically considered either configuration or deployment time activities.

Comment by anonymous53443 on 2020-05-29:
Thank you! This works yes! Another way I found was to put the namespace on the launch file using the field 'ns'. I want to do this because I want to have a multi-robot system where each robot has the same number of servers and each one accesses their corresponding servers.

Comment by sloretz on 2020-05-29:
Ah got it. Updated answer to describe how to change the namespace using launch files.

Comment by gvdhoorn on 2020-05-29:
@PedroACaldeira: please use the approach shown by @sloretz. Do not put nodes in namespaces by changing os.environ manually inside the nodes themselves.

$\endgroup$

Your Answer

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