1. 前言
在ROS中,节点、话题、服务、参数等都可以有自己的命名空间(namespace)。命名空间是ROS用来组织和隔离不同资源的一种方式,确保了系统中的名字是唯一的,并允许同样的结构在不同的上下文中被重用。这就像在真实世界中的邮政系统,同一个城市里可以有多条同名的“梅花路”,但它们位于不同的区域,比如“东区的梅花路”和“西区的梅花路”。
假设ROS是一个大型的邮局,而这个邮局需要处理来自世界各地的信件。每个信件都有一个地址,告诉邮局如何正确地投递这封信。
在这个比喻中,邮局的“地址系统”就像是ROS的命名空间。
-
全局命名空间: 就像是世界地图上的国家名。例如,当你看到一个以斜杠开头的地址
/china
,你知道这是一个国家的名称,它位于世界地图的全局层面上。 -
相对命名空间: 类似于国家内的城市或小镇。如果你在中国,你可能只需要提到“北京”而不是“/china/beijing”。在ROS中,如果你已经在
robot1
的命名空间下工作,你只需提及相对的主题名“camera”来代表/robot1/camera
。 -
私有命名空间: 像是一个家庭的住址。在一个特定的城市里,家庭的地址是私有的,比如
~/living_room
,在ROS中,如果你有一个节点想要使用它自己专用的主题(比如一个配置参数),它会用~
来指示这是私有命名空间的一部分。
所以,当我们说到ROS的命名空间,我们可以想象为定义一个从全球到本地的详细路径,它告诉ROS系统如何找到特定的“资源”(主题、服务、参数等)。
举一个具体的例子:
假设你有两个机器人,每个都有一个相机。在ROS中,你可能会有如下的主题命名结构:
/robot1/camera/image
:这是第一个机器人相机的图像数据流。/robot2/camera/image
:这是第二个机器人相机的图像数据流。
这里,/robot1
和/robot2
是两个不同的全局命名空间,用来区分不同机器人的资源。camera
和image
表明了资源的种类和类型。
2.节点 Node
在ROS中,节点的名称(name)和节点的命名空间(namespace)是两个用于标识和组织节点的不同概念:
节点名称(Node Name):
- 这是节点的唯一标识符。
- 在一个ROS系统中,每个节点应该有一个独一无二的名字,这样它们可以被单独地识别和引用。
- 节点名称可以在运行时通过
__name:=value
参数动态设置。- 如果没有提供
__name
参数,节点名称将取决于ROS节点初始化代码中指定的名称。节点命名空间(Node Namespace):
- 这是一个逻辑分组,允许你将相关的节点组织在一起。
- 命名空间是话题、服务等的前缀,用于逻辑上分组和隔离这些资源。
- 在命名空间内,可以运行具有相同名称的多个话题或服务,而它们实际上是彼此独立的。
- 命名空间可以在运行时通过
__ns:=value
参数设置。
2.1 创建两个发布到不同命名空间的相同话题的ROS节点
节点1.
#!/usr/bin/env python
# filename: camera1_node.pyimport rospy
from sensor_msgs.msg import Imagedef camera1_publisher():rospy.init_node('camera1_publisher_node', anonymous=True)pub = rospy.Publisher('/camera1/image', Image, queue_size=10)rate = rospy.Rate(10) # 10hzwhile not rospy.is_shutdown():image = Image()# 填充图像数据...pub.publish(image)rate.sleep()if