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.