Hey, miles

莫等闲,白了少年头q

0%

ROS基本概念

ROS的概念分为三个层次:文件系统层、计算图层、社区层,还有两个names类型:Package Resource Names和Graph Resource Names

文章参考: http://wiki.ros.org/cn/ROS/Concepts

ROS文件系统层次

文件系统层的概念主要指在硬盘里能看到的ROS目录和文件,例如:

  • Packages: Packages是在ROS中整理及组成软件的主要单元。一个Packages包含节点(ROS runtime processes)、ROS依赖库(ROS-dependent library)、数据集(datasets)、配置文件(configuration files)等等。Package是你在ROS中能建立及分享的最小单元
  • Metapackages: Metapackages是一组具体的服务相关的功能包。大部分metapackages只作为转换rosbuild Stacks的向后兼容的备选。
  • Package Manifests: Manifests(package.xml)描述一个package的元信息,包括了package的名字,版本,功能,证书信息,依赖关系,以及一些其他的被export的package的所有信息。关于package.xml的文件说明,参考REP-0127
  • Repositories: 代码仓库是使用VCS版本控制系统的软件包集合,软件包利用版本控制维持同一版本,它能使用catkin自动发布工具bloom进行发布。这些代码仓库常通过映射来进行转换rosbuild Stacks。仓库可以是只有一个软件包。
  • Message (msg) types: 存储在my_package/msg/MyMessageType.msg的Message文件,主要定义了ROS系统的messages传输的数据结构
  • Service (srv) types: 存储在my_package/srv/MyServiceType.srv的服务services文件,定义了ROS服务通信时的请求(request)和相应(response)的数据结构

ROS计算图层次

**计算图是ROS在点对点网络里整合并处理数据的过程。**基本计算图概念是:节点,主机,参数服务器,消息,服务,话题和数据包,它们通过不同的方式提供数据给图层。

这些概念是在ros_comm库里实现的

  • Nodes: 节点主要执行计算处理。ROS被设计为细粒度的模块化系统;一个机器人控制系统通常有很多节点组成。如:一个节点控制激光测距仪,一个节点控制轮电机,一个节点执行定位,一个节点执行路径规划,一个节点提供图形界面,等等。一个ROS节点通过ROS客户端库client library编写,例如roscpp或rospy
  • Master:ROS主机提供名称注册和查询(lookup to)剩余的计算图。没有主机的话,节点将无法互相寻找、交换信息、或者调用服务。
  • Parameter Server:参数服务器使得数据可以通过key存储在一个中心区域(a center location)。它目前是主机的一部分。
  • Messages: 节点通过消息相互交流。一个信息是一份简单的数据结构,包含着类型域(type fields)。支持标准的原始类型(整形integer,浮点型floating point,布尔型boolean等等),也包括原始类型的数组。消息可以包含任意嵌套的结构和数组(非常类似于C结构)。
  • Topics: 消息通过使用publish/subscribe语义的消息系统进行路由。**一个节点通过把消息发表到指定的话题进行发布消息。话题是一个用来识别消息内容的名字(name)。一个对某一个特定种类的和数据感兴趣的节点将会订阅合适的话题。**一个话题可能有多个并发的publishers和subscribers,一个节点也可能publish或者subscribe多个话题。总得来说,publishers和subscribers觉察不到互相的存在。思想是分离信息的产生与消耗。从逻辑上讲,可以把话题想作强类型的信息总线(strong typed information bus)。每一个总线有一个名字,任何人都可以连接总线发送或者接收信息,只要总线是正确的类型。
  • Services:publish/subscribe模型是非常灵活的交流范式(paradigm),但是它的多对多(many-to-many),单路传输(one-way-transport)对于request/reply的交互是不合适的,这通常需要一个订阅系统。Request/reply通过服务完成,这通过一对信息结构被定义:一个对应于request一个对应于reply。一个providing节点以名称提供服务,客户端通过发送request信息并等待reply使用服务。ROS客户端库通常将此交互呈现给程序员,就好像是远程程序调用一样。
  • Bags:数据包是一种用来保存和回放ROS消息信息的格式。数据包是一种重要的用来存储数据的机理,例如传感器数据,它难以被采集但对于开发和测试算法是非常有必要的。

ROS主机在ROS的计算图中扮演着nameservice的角色。它存储了话题和ROS节点的服务注册信息。节点通过与主机交流来报告他们的注册信息。当这些节点与主机交流时,它们会收到其他已注册节点的信息并视情况与其他节点交流。当节点注册信息发生改变时,主机还会回调这些节点,这允许了节点在新的节点运行时动态地创建连接。

节点直接地与其他节点连接;主机仅提供查询信息,更像是一个DNS服务器。订阅了一个话题的节点会与发布话题的节点请求连接,连接将会在一个同意的连接协定(agreed upon connection protocol)上被建立。在ROS中经常被使用的协定被叫做TCPROS,使用了标准的TCP/IP套接字。

这种架构允许了解藕(decoupled)的操作,名样更大更多的复杂系统可以以names为主要手段进行构建。Names在ROS里拥有非常重要的角色:节点,话题,服务和参数都有名字。没有个ROS客户端库都支持命令行的names再分配(remapping),这意味着一个编译的程序可以在运行时被再配置,使得它可以在一个不同的计算图拓扑运行。

例如,控制一个Hokuyo激光测距仪,我们可以启动一个hokuyo_node驱动,驱动将与传感器通信并在一个scan的话题上发布sensor_msgs/LaserScan消息。为了处理这些数据,我们可能会写一个使用laser_filters的节点,节点订阅scan话题上的消息。在订阅之后,我们的滤波器将会自动地开始接收来自传感器的数据。

注意这两端是如何被去偶的。hokuyo_node仅仅会发布扫描结果,而不知道有没有任何节点在订阅。滤波器仅仅是订阅了传感器数据,而不知道是否有任何节点发布它们。这两个节点可以用任何顺序被启动,结束和重启,而不会引起任何的错误情况。

之后我们还可能会增加另外一个激光传感器到我们的机器人上,因此我们需要配置我们的系统。我们需要做的就是再分配被使用的names,当我们启动我们的第一个hokuyo_node,我们可以告诉它将扫描重新映射到base_scan上,然后对滤波器节点做同样的事。现在,所有的这些节点将会使用base_scan话题进行交流,而不会从scan话题上获取消息。然后我们可以为新的测距器启动另外一个hokuyo_node。

ROS开源社区层次

ROS开源社区层次是使得不同的社区可以交换软件和知识的资源。这些资源包括:

  • Distributions:ROS发布版是你可以安装的被细分版本的栈列(stacks)。发布版和Linux发布版扮演了相似的角色:他们使得安装一批软件更加简单,他们也在一系列软件中保持一致的版本(and they also maintain consistent versions across a set of software.)。
  • Repositories: ROS依赖于代码仓库的联合网络,在这里不同的机构可以开发并发行(release)他们自己的机器人软件组件。
  • The ROS Wiki:ROS社区Wiki是关于ROS的文件信息的主要讨论区。任何人可以注册帐号并贡献他们自己的文档,提供更正或者更新,撰写指南等等。
  • Bug Ticket System:Please see Tickets for information about file tickets
  • Mailing List: [ros-users mailing list](http://wiki.ros.org/Mailing Lists)是ROS更新的主要的交流渠道,同样是一个询问关于ROS软件问题的论坛。
  • ROS Answers:一个回答你的ROS相关问题的Q&A网站
  • BlogWillow Garage Blog提供定期的更新,包括图片以及视频。

Names

图资源名(Graph Resource Names)

图资源名称提供了一个分层的命名结构,它被用在所有的ROS计算图中的资源。例如节点,参数,话题和服务。这些名称在ROS中非常有力并且是组成ROS中更大更复杂系统的中枢,因此理解这些names如何工作和如何去操作他们是十分关键的。

在我们叙述names之前,这里是一些name的例子:

  • /(the global namespace)
  • /foo
  • /stanford/robot/name
  • /wg/node1

图资源名是一种ROS中提供封装的重要的机制。每一个资源都被定义在一个namespace中,namespace可能会被分享在很多其他的资源中。总得来说,资源可以在他们的namespace中创建资源,他们也可以通过在namespace里或者上面访问资源(they can access resources within or above their own namespace)。在不同的namespace中也可以建立连接,但是这通常被集成在两个namespaces上的代码完成。这种封装避免了系统的不同部分意外地抓取了错误命名的资源或者全局劫持的名字。

names是相对解析的,因此resources不需要知道他们在哪一个namespace中。这简化了编程过程,因为工作在一起的节点可以被写作好像他们都在namespace的最高层。当这些节点被集成到更大的系统中时,他们可以被下推入一个定义他们代码集合的namespace。例如,一个人可以使用一个Stanford demo和一个Willow Garage,并把他们融合到一个新的有stanford和wg的子图的demo中。如果两个demos都有一个节点名较’camera’,他们不会造成冲突。需要对整个图可视的工具(e.g. graph visualization) 或参数(e.g. demo_name)可以被顶层节点创建。

有效名(Valid Names)

一个valid name有如下特点:

  1. 首字母是字母([a-z|A-Z]),波浪线(~)或者左斜杠(/)
  2. 后续字符可以是字母或者数字(0-9|a-z|A-Z),下划线(_)或者左斜杠(/)

特例:base names(在后面叙述)不能有左斜杠(/)或者波浪线(~)。

解析(Resolving)

在ROS中有四种图资源名:base,relative,global和private,他们有如下语法:

  • base
  • relative/name
  • /global/name
  • ~private/name

默认地,resolution是在节点的namespace中相对完成的。例如,节点/wg/node1有namespace /wg,因此名字node2将会解析到/wg/node2。

没有namespace修饰的名字无论怎样都是base names。Base names实际上是relative names的子类,并且拥有同样地resolution规则。Base names最经常被用作初始化节点名字。

以"/"为开头的名字是global的,他们被认为是完全解析的。Global names应该尽量地被避免因为它限制了代码的移植能力。

以"~"开头的名字是private的。他们将节点的名字转换为一个namespace。例如,在namespace /wg/的node1有private的namespace /wg/node1。Private names在通过参数服务器向一个特定的节点传递参数时是有用的。

这里有一些name resolution的例子:

Node Relative(default) Global Private
/node1 bar -> / bar /bar -> /bar ~bar -> /node1/bar
/wg/node2 bar -> /wg/bar /bar -> /bar ~bar -> /wg/node2/bar
/wg/node3 foo/bar -> /wg/foo/bar /foo/var -> /foo/bar ~foo/bar -> /wg/node3/foo/bar

再映射(Remapping)

在ROS节点内部的任何名字都可以在节点在命令行被启动时被再映射。更多信息可以看Remapping Arguments

包资源名(Package Resource Names)

包资源名使用文件系统层次的观念被用在ROS中,来简化查询硬盘上的文件和数据类型的流程。包资源名非常简单:他们只是资源所在包的名字+资源名。例如,名字“std_msgs/String”指的是在"std_msgs"包中的String"消息类型。

一些可能会被查阅的ROS相关的文件使用包资源名,包括:

包资源名和文件路径是非常相似的,除了包资源名会更短。这是由于ROS在硬盘上定位包并对其内容进行附加架设的能力。例如,消息描述总是被存储在msg的子路径下,并且有.msg的扩展名,因此std_msgs/String是路径/to/std_msgs/msg/String.msg的速写。类似的,节点类型foo/bar与用可执行许可在包foo中搜索一个叫做bar的名字是等效的。

有效名(Valid Names)

包资源名有严格的命名规则,因为他们经常被用在自动生成的代码。正因为如此,一个ROS包不能有除了下划线的特殊字符(a ROS package cannot have special characters other than an underscore),并且名字必须以字母开头。一个有效的名字有如下特点:

  1. 首字符是字母 ([a-z|A-Z])
  2. 后续的字符可以是字母或者数字([0-9|a-z|A-Z]),下划线(_)或者左斜杠(/)
  3. 至多能有一个左斜杠(/)

代码API

roscpp::names API reference (ROS Indigo)

下一步

[高级概念](http://wiki.ros.org/cn/ROS/Higher-Level Concepts)