✅博客主页:爆打维c-CSDN博客 🐾
🔹分享自己学习AI/编程知识的过程 🐾
🔹我的GitHub代码仓库 https://github.com/lyy-0118

该文章是对手把手教你学ROS(万字详解)这篇博客的续写,将补全之前没讲到的知识,想系统了解ROS知识的可以去看我的ROS学习专栏,持续更新中~~~

Let's go~
2 .6 计算图源命名( Graph Resource Names)
本部分,将学习ROS如何为其各类计算图资源(如节点、话题、参数和服务等)命名和解析。
节点、话题、服务和参数统称为计算图源( Graph Resource) ,而每个计算图源由一个叫****计算图源名称(graph resource name)****的短字符串标识。事实上,计算图源名称在ROS命令行和代码中是广泛存在的,前面我们已经多次接触它们。
在上面,我们用字符串(例如"turtlesim")来给节点命名,用"turtle1/cmd_vel"和"turtle1/pose"等字符串作为话题的名称。这些都是计算图源名称的例子。ROS具有一个能够接受几种不同类型名(全局名称、相对名称和私有名称)的命名系统,上述字符串均是相对名称。
有效名称具有以下特征:
- 第一个字符是字母字符([az | AZ]),代字号(〜)或正斜杠(/)
- 后续字符可以是字母数字([0-9 | az | AZ]),下划线(_)或正斜杠(/)
- 例外:基本名称(如下所述)不能包含正斜杠(/)或波浪号(〜)。
2 .6.1 全局名称( Global names)
以前斜杠"/"开始的名称为全局名称,如下面的计算图源名称:
- /teleop_turtle
- /turtlesim
- /turtle1/cmd_vel
全局名称可以在任何地方都可以使用,如命令行工具或源代码中,都有明确的含义,不会产生二义性,也无需额外的上下文信息来决定名称指的哪个资源。
一个全局名称的几个组成部分:
- 前斜杠"/"表明这个名称为全局名称。
- 由斜杠分开的一系列命名空间(namespace),每个斜杠代表一级命名空间。命名空间用于将相关的计算图源归类在一起。ROS允许多层次的命名空间。
- 描述资源本身的基本名称(base name)
/turtle1/cmd_vel
2 .6.2 相对名称( Relative names)
1 . 相对名称的概念
使用全局名称时,为了指明一个计算图源,需要完整列出其所属的命名空间,尤其是有时候命名空间层次比较多,使用不方便。
这时,一个主要替代方案是让ROS为计算图源提供一个默认的命名空间 ,具有此特征的名称叫做相对计算图源名称(ralative graph resource name),或简称为相对名称(relative name)。
相对名称的典型特征是它缺少全局名称带有的前斜杠"/"。
2 . 解析相对名称
将相对名称转化为全局名称,是将当前默认的命名空间的名称加在相对名称的前面,从而将相对名解析为全局名称。
比如,如果我们在默认命名空间为/turtle1 的地方使用相对名称cmd_vel,那么ROS通过下面的组合方法得到全局名称:
得到的全局名称就可以用于确定一个特定的计算图源,就像前面介绍全局名称的使用时一样。

3 . 设置默认命名空间
默认的命名空间是单独地为每个节点设置的 ,而不是在系统范围进行。ROS默认使用全局命名空间(/)作为此节点的默认命名空间。ROS提供如下两种方面设计默认的命名空间:
- 大部分ROS程序,包括调用ros::init的所有C++程序,接受叫做__ns的命令行参数,此参数将为程序指定一个默认命名空间。
_ _ns:=default-namespace
- 还可以利用环境变量为在shell内执行的ROS程序设置默认命名空间。
Export ROS_NAMESPACE=default-namespace
请注意:只有当没有其他由_ _ns参数指定的默认命名空间时,这个环境变量才有效。
4 . 理解相对名称的目的
有人可能会问另一个问题:我为什么要使用相对名称?提出相对名称这个概念的真正意义在于它使得在小系统基础上实现复杂系统变得更加容易。
当一个节点内的计算图源全部使用相对名称时,这本质上给用户提供了一种非常简单的移植手段,即用户能方便地将此节点和话题移植到其他的(比如用户自己程序的)命名空间,而节点的原设计者并不一定参与这个过程。这种灵活性可以使得一个系统的组织结构更清晰,更重要的是能够防止在整合来自不同来源的节点发生名称冲突。
作为对比,如果所有节点都使用全局名称命名自己的计算图源,就很难实现这种高效资源整合。所以,除非一些特殊情况有特殊要求,否则编写节点时并不推荐使用全局名称。
2 .6.3 私有名称( Private names )
1 . 私有名称的概念
这种命名方式基于如下事实:每个节点内部都有这样一些资源,这些资源只与本节点有关,而不会与其他节点打交道。
私有名称仅仅表示其他节点不会使用它们所在的命名空间,也就是仅在命名空间层面上有意义。对于其他节点来讲,只要知道私有名称解析后的全局名称,都可以通过其全局名称访问这些计算图源。
2 . 私有名称的定义与解析
以一个波浪字符(~)开始 名称是私有名称。与相对名称的主要差别在于,私有名称不是用当前默认命名空间,而是用的它们节点名称作为命名空间。
例如,有一个节点,它的全局名称是 /sim1/pubvel,ROS将其私有名称∼max_vel转换至如下全局名称:

2 .6.4 匿名名称(Anonymous names)
1 . 匿名名称的概念
除了以上三种基本的命名类型,ROS还提供了另一种被称为匿名名称的命名机制,一般用于为节点进行自动、唯一性的命名(匿名并不是指没有名字,而是指非用户指定、没有语义信息的名字)。匿名名称的目的是使节点的命名更容易遵守唯一性的规则。
2. 匿名名称的定义
其思路是,当节点调用ros::init方法时可以请求一个自动分配的唯一名称。
为了请求一个匿名名称,节点需要将ros::init_options::Anonymous-Name作为第四个参数传递给ros::init方法:
ros::init(argc, argv, base_name, ros::init_options::AnonymousName);
这个附加选项的作用是在节点的基本名称后面追加某个额外的文本,以确保节点的名字是唯一的。
这个程序的行为本身并没有什么特别。但是,正因为它请求了一个匿名名称,所以我们可以同时运行任意多的以上程序的副本。这很容易理解,每个程序开始运行时,它就会得到一个具备唯一性的名字。