ROS中的节点、参数、话题和服务统称为计算图源,其命名方式采用灵活的分层结构,便于在复杂的系统中集成和复用。以下是一些命名的示例:
·/foo
·/stanford/robot/name
·/wg/node1
计算图源命名是ROS封装的一种重要机制。每个资源都定义在一个命名空间内,该命名空间内还可以创建更多资源。
但是处于不同命名空间内的资源不仅可以在所处命名空间内使用,
还可以在全局范围内访问,这与C++中的private有所不同。这种命名机制可以有效避免不同命名空间内的命名冲突。
有效的命名
一个有效的命名应该具备以下特点:
1)首字符必须是字母([a-z|A-Z])、波浪线(~)或者左斜杠(/)。
2)后续字符可以是字母或数字([0-9|a-z|A-Z])、下划线(_)或者左斜杠(/)。
命名解析
计算图源的名称可以分为以下四种:
1)基础(base)名称,例如:base。
2)全局(global)名称,例如:/global/name。
3)相对(relative)名称,例如:relative/name。
4)私有(private)名称,例如:~private/name。
基础名称用来描述资源本身,可以看作相对名称的一个子类,上述示例中的name就是一个基础名称。
首字符是左斜杠(/)的名称是全局名称,由左斜杠分开一系列命名空间,示例中的命名空间为global。全局名称之所以称为全局,是因为它的解析度最高,可以在全局范围内直接访问。
但是在系统中全局名称越少越好
,因为过多的全局名称会直接影响功能包的可移植性。
全局名称需要列出所有命名空间,在命名空间繁多的复杂系统中使用较为不便,所以可以使用相对名称代替
。相对名称由ROS提供默认的命名空间,不需要带有开头的左斜杠。
例如在默认命名空间/relative内使用相对名称name,解析到全局名称为/relative/name。可见,相对名称的重点是如何确定默认的命名空间,ROS为我们提供了以下三种方式。
1)通过命令参数设置。调用ros::init()的ROS程序会接收名为__ns的命令行参数,可以为程序设置默认的命名空间,赋值的方式为__ns:=default-namespace。
2)在launch文件中设置。在launch文件中可通过设置ns参数来确定默认命名空间:
<node name="turtlesim_node" pkg="turtlesim " type="turtlesim_node" ns="sim1" />
3)使用环境变量设置。也可以在执行ROS程序的终端中设置默认命名空间的环境变量:
export ROS_NAMESPACE=default-namespace
相比全局名称,相对名称具备良好的移植性,用户可以直接将一个相对命名的节点移植到其他命名空间内,有效防止命名冲突。
顾名思义,私有名称是一个节点内部私有的资源名称,只会在节点内部使用。私有名称以波浪线“~”开始
,与相对名称一样,其并不包含本身所在的命名空间,需要ROS为其解析;但不同的是,私有名称并不使用当前默认命名空间,而是用节点的全局名称作为命名空间。
例如有一个节点的全局名称是/sim1/pubvel,其中的私有名称~max_vel解析成全局名称即为/sim1/pubvel/max_vel。
综上所述,我们可以将其中三种名称的解析方式归纳如表所示。
命名重映射
所有ROS节点内的资源名称都可以在节点启动时进行重映射。ROS这一强大的特性甚至可
以支持我们同时打开多个相同的节点,而不会发生命名冲突。
命名重映射采用如下语法:
name:=new_name
例如将chatter重映射为/wg/chatter,在节点启动时可以使用如下方式重映射命名:
rosrun rospy_tutorials talker chatter:=/wg/chatter
ROS的命名解析是在命名重映射之前发生的。所以当我们需要“foo:=bar”时,会将节点内的所有foo命名映射为bar,而如果我们重映射“/foo:=bar”时,ROS只会将全局解析为/foo的名称重映射为bar。
命名重映射与命名解析之间关系