首页 关于
树枝想去撕裂天空 / 却只戳了几个微小的窟窿 / 它透出天外的光亮 / 人们把它叫做月亮和星星
目录

ROS一个开源的机器人操作系统

Morgan Quigley*, Brian Gerkey, Ken Conley, Josh Faust, Tully Foote,
Jeremy Leibs, Eric Berger, Rob Wheeler, Andrew Ng*

∗ Computer Science Department, Stanford University, Stanford, CA
† Willow Garage, Menlo Park, CA
‡ Computer Science Department, University of Southern California

摘要:

本文介绍一个开源的机器人操作系统ROS。ROS并不是传统意义上用于管理进程和调度的操作系统,它为异构计算机集群(heterogenous compute cluster)的操作系统提供了一个结构化的通信层(a structured communications layer)。在本文中,我们讨论ROS与现有的机器人软件框架之间的关系,简单介绍一些ROS中的应用软件。

1. 引言

为机器人编写软件是很复杂的,尤其是在机器人的规模与范畴不断扩大的今天。不同类型的机器人在硬件上有很大的差别,以至于很多代码难以重用。 因此,大量的代码就称为了一件令人头痛的事情,因为它将是一个很深的技术栈,包括从驱动级的软件到感知,抽象推理,甚至更高级的应用。 现如今广泛的实验需求已经远远超出了任何一个个人研究者的能力,所以机器人软件架构必须能够集成大规模的软件(Since the required bradth of expertise is well beyond the capabilities of any single researcher, robotics software architectures must also support large-scale software integration efforts.)。

面对这些挑战,包括我们在内的很多机器人学者,已经创造了各种不同的框架来完成复杂的任务,简化实验原型机的软件开发过程,也因此在学术界和工业界出现了很多机器人软件系统[1]。 但是这些框架都是为了某个特殊目的而设计的,或者针对设计过程中最重要的部分的增强(or to place emphasis on aspects which wre seen as most important in the design process.)。

本文所描述的框架——ROS,也是在设计过程中经过各种权衡、优化的产物(ROS, the framework described in this paper, is also the product of tradeoffs and prioritizations make during its design cycle)。我们相信它将促进大型集成机器人的研究,在机器人系统更加复杂的未来将发挥广泛的作用。在本文中,我们讨论设计ROS的目标, 我们是如何朝向目标前进的,并举例说明了ROS是如何处理一些在机器人软件开发过程中的常见问题的。

2. 设计目标

我们并没有声称ROS是机器人软件系统中最好的框架。实际上,我们并不相信存在这样的框架。相比于单一的解决方案(a single solution)而言机器人的领域太广泛了。 ROS是面向大型服务机器人(比如说斯坦福大学的STAIR项目[2],Willow Garage的个人机器人项目Personal Robots Program)设计的,但是它不仅仅用于一般服务机器人和移动机器人(mobile manipulation)。

ROS的设计目标可以总结如下:

据我们所知,还不存在一个框架具有这样的设计标准。在本部分,我们将详细阐述这些设计理念并展示他们如何指导设计和实现ROS的。

2.1 点对点(Peer-to-peer)

一个使用ROS的系统是由一系列进程构成的,有可能在几个不同的计算机上,通过点对点协议实时连接着(connected at runtime in a peer-to-peer topology)。 虽然基于中央服务器的框架(比如CARMEN[4])也可以实现多进程和多机(multi-host)的设计,但是如果计算机接入到一个异构的网络中,只有一个数据中心服务器是有问题的。

比如说,ROS面对的大型服务机器人,就有好几个板载的计算机通过以太网相互连接。这个网络通过无线网(wireless LAN)桥接到本体外的一台高性能计算机上完成机器视觉、 语音识别等计算密集型的任务(图1)。无论是在本体上还是本体外运行中央服务器都将导致不必要的慢速网络通信,因为它们都需要大量的消息路由(because many message routes are fully contained in the subnets either onboard or offboard the robot)。相比之下,点对点(peer-to-peer)链接,再组合上缓存(buffering)或者扇出(fanout)软件模块就可以完全避免这个问题。

图1. 一个典型的ROS网络配置

点对点协议需要一种查找表的机制,来指引进程相互找到对方。我们称它为name service或者说是master,将在后续内容中做出更详细的解释。

2.2 多语言(Multi-lingual)

写代码的时候,每个人都有他自己的偏好。这些偏好是个人在开发时间、Debug难度、语法、运行效率等等技术上和文化上的各方面因素权衡的结果。 因此,我们设计的ROS是语言中立的(language-neutral)。目前ROS支持四中不同的语言:C++, Python, Octave和LISP, with other language ports in various states of completion。

ROS的声明是在不怎么深的消息层上的(The ROS specification is at the messaging layer, not any deeper.)。由于XML-RPC在很多语言中都有比较成熟的实现, 所以点对点通信协商以及配置信息都是用XML-RPC实现的。与其使用C语言实现内核并针对各种语言提供接口,不如直接就实现各种不同语言版的ROS,这样可以更好的遵循各种语言的约定。 但是在有些情况下,通过封装现有版本的库来实现对新语言的实现也是很方便的,比如Octave客户端就是在C++库的基础上封装实现的。

为了支持跨语言的开发,ROS使用一个简单语言中立接口定义语言(Interface Definition Language, IDL)来描述模块之间传递的消息。IDL使用非常短小的文本文件来描述消息中的每个字段, 并且允许组合各种消息,下面是一个用于点云消息的完整IDL文件内容:

        Header header
        Point32[] pts
        ChannelFloat32[] chan

通过代码生成器生成各种ROS所支持语言的原生对象,以至于不同语言的程序发送和接受的消息,可以在ROS系统中自动的序列化和反序列化。这将有效的节省程序员的时间,减少错误: 刚刚列出的的3行IDL文件江北自动的扩展为137行的C++程序,96行的Python, 81行的Lisp和99行的Octave程序。因为消息是从简单的文本文件中自动生成的,我们就可以容易的枚举新的消息类型。 在写作本文的时候,就已经有超过400种消息用于传递传感器反馈数据、感知的物体、地图等等相关的数据。

这就形成了一种语言中立的消息处理机制,它可以根据需要混合多种语言(The end result is a language-neutral message processing scheme where different languages can be mixed and matched as desired)。

2.3 基于工具的(Tools-based)

为了方便管理ROS系统,我们选择了微内核(microkernel)的设计,提供大量的小工具来编译和运行ROS组件,而不是创建一个巨大的开发和运行环境。

这些工具用于完成各种任务,比如索引源代码,获取或者设置配置参数,点对点链接的可视化,测量带宽的使用情况,消息数据的图形化显示,自动生成文档等等。 尽管我们可以在master模块中实现一个全局时钟和日志系统的服务,我们还是选择把它们作为独立的模块来实现。我们相信性能上的损失相比于稳定性和复杂度收益来说是值得的(We believe the loss in efficiency is more than offset by the gains in stability and complexity management)。

2.4 瘦(Thin)

正如文献[5]中所述的那样,大部分现有的机器人软件工程中所包含的驱动或者算法都可以拿出来用到其它工程上。不幸的是,因为各种原因,这些代码和中间件纠缠在一起很难抽取处它的功能, 并应用到其它环境中。

为了与这种趋势对抗,我们鼓励所有的驱动和算法开发都作为独立的库来实现,而不依赖于ROS。ROS编译系统只是编译源码树中的各个模块(The ROS build system performs modular builds inside the source code tree),并使用CMake使得编译过程相对简单一些(and its use of CMake makes it comparatively easy to follow this "thin" ideology)。 把几乎所有的功能都放到库里,只创建小的可执行文件暴露库的功能到ROS系统中。这样我们就可以方便的抽取出需要的功能用到其它地方里去。此外还有一个附加的好处,就是这样可以方便的进行单元测试, 我们可以写各种独立的测试程序来检验库的各种特性。

ROS也从很多其它开源项目中重用了各种代码,比如来自Player项目[6]的驱动、导航系统、仿真器,OpenCV[7]的视觉算法,OpenRAVE[8]中的规划算法,等等。在这些例子中, ROS只是简单的对这些开源项目做了简单的封装打些补丁,用于各种配置项,引导各个程序之间数据的输入和输出。得益于开源社区的持续维护, ROS编译系统可以自动的从外部仓储()external repositoriess)中更新源文件,打补丁。

2.5 免费且开源(Free and Open-Source)

完整的ROS源代码是公开的。我们相信这是从各个层级上对软件栈debug的关键。虽然像Microsoft Robotics Studio[9]和Webots[10]这样的专利环境也有很多优秀的特性, 我们认为他们都不能替代一个完全开源的平台,尤其是在硬件和各层软件上并行的设计和debuge的时候。

ROS是遵循BSD许可条款的,它允许非商业以及商业行为的开发。ROS使用进程间通信在模块之间传递数据,不要求各个模块链接到一个可执行文件中。这样围绕着ROS创建的系统, 可以在他们的组件上使用更精细的条款:individual modules can incorportate software protected by various licenses ranging from GPL to BSD to proprietary, but license "contamination" ends at the module boundary.

3. 命名法(Nomenclature)

ROS系统实现的基础概念是节点(nodes), 消息(messages), 主题(topics)和服务(services)。

节点Nodes是进行运算的进程。ROS是一个模块设计的系统,它是由很多节点构成的。这里的节点与软件模块是同义词,可以相互替换。 当很多节点运行的时候,可以方便地把点对点通信描述成一个图,进程是图的节点,点对点链接是图中的边。

节点之间通过传递消息来通信。严格意义上一个消息就是一个数据结构。支持标准的原生类型(整型、浮点型、布尔型等等),也支持原生类型数组和常数。 消息也可以是由其它类型的消息组合而成的,支持消息的数组,可以任意深度的嵌套。

一个节点发布的消息都是针对某一主题(topic)的,主题仅仅是一个简单的字符串比如"odometry"或者"map"。如果一个节点需要某个特定类型的数据就订阅相关的主题。 针对同一个主题同时可能有多个发布者和订阅者,并且一个节点可能同时发布或者订阅多个主题。一般情况下,发布者和订阅者并不知道对方的存在。

最简单的通信就是一个管道,如右图所示,消息逐次通过各个节点。但是,图通常要复杂的多,有环型、一对多、多对多等各种不同形式的连接。

虽然基于主题的发布订阅模式是一个宽松的通信范式,它的广播路由的方式并不适合同步传输。在ROS系统中,我们实现了一种称为服务(service)的同步通信方式, 它有一个字符串名称和一对消息构成,一个消息用于请求服务,另一个消息用于响应请求,这与通过URI定义的Web服务类似。与主题机制不同的是,只有一个节点可以提供特定名称的服务, 也就是说只能有一个被称作是"classify_image"的服务,就好像是给定一个URI只能有一个Web服务与之对应一样。

4. 使用案例

在本节中,我们将描述一些常见的使用机器人软件框架的场景。ROS的开放结构允许我们创建各种工具。在介绍应用ROS的各种案例中,我们将同时介绍各种为ROS而设计的工具。

4.1 针对某个节点的Debug

在进行机器人研究的时候,尤其是在关注系统中某个特定领域的时候,比如说一个进行计划、推理、感知或者控制的节点。为了让机器人系统运行起来做一些实验, 必须同时运行一个更大的机器人软件环境。比如说,对于一个基于视觉的抓取实验,我们就必须要有一个驱动摄像头和执行器的驱动器, 同时还要运行一系列的中间处理进程(比如,物体识别、姿态检测、轨迹规划)。这就显著增加了机器人研究的难度。

ROS就是为了最小化这种困难而设计的,因为它的模块化结构允许真该开发的节点与已经成熟的节点一起工作。因为在运行的时候界定啊之间相互连接,所以图的结构是可以动态调整的。 实现基于视觉抓取的这一过程中,有可能需要提供一打的节点作为运行的基础设施(infrastruccture)。所谓的基础设施是指在整个实验过程中他们都需要一直运行着。 我们只需要在修改开发中的模块的源码后重新运行它就好了,ROS系统会自动的维护图的结构。这将是生产效率的巨大提升,尤其是当机器人系统越来越复杂的时候。

需要强调的是,修改ROS的运行时图仅仅是开启或者停止一个进程。在debug的设定下,只需要通过命令行或者调试器就可以实现。 方便地从一个运行中的ROS系统中插入和移除一个节点是一个强大的并且基础的特性。

4.2 日志和回放

在机器人感知的研究中通常需要记录下传感器的数据,来简化各种算法的受控对比实验过程。ROS通过提供一般的日志和回放机制来支持这一功能。 任何ROS消息流都可以保存到磁盘上共以后回放。重要的是,我们可以通过命令行来完成所有的操作,它不需要修改图中任何软件的任何代码。

比如说下面左图图所示的网络图可以快速的建立起一个研究视觉里程计的数据包,它保存起来的消息可以回放到另一个包含正在开发的节点(vision research)的图中,如下面右图所示。 正如前面所说的那样,简单的开启一个进程就可以实例化一个节点,而这可以通过命令行、调试器、脚本等各种方式实现。

为了协助日志记录、监视系统,基于Apache项目的log4cxx系统的我们建立了rosconsole库,它提供了一个方便且巨大的日志接口,支持发布printf风格的诊断消息到网络中一个称作rosout的节点中。

4.3 打包子系统(Packaged subsystems)

一些机器人的研究领域,比如说室内机器人导航,已经有一些成熟的算法可以理想的工作了。ROS把这种算法应用到Player项目中提供了一个导航系统,运行时图如右图所示。

虽然每个节点都可以通过命令行运行,但是要输入好几行命令来运行这些进程是一件很麻烦的事。为了方便的运行向导航系统这样的打包功能,ROS提供了一个称作roslaunch的工具, 它解析一个XML描述的运行时图并在计算机上具现它。终端用户就可以只用类似下面的一条指令一键运行整个功能包,并使用Ctrl-C终结掉所有的五个进程。

        $ roslaunch navstack.xml

这一功能也可以有效的提高机器人研究中的一些大型demo的代码重用率和分享效率,因为这样我们可以方便的部署和撤销一个大型的实验系统。

4.4 合作开发

因为机器人和人工智能的范畴太大了,学者之间的合作是必不可少的。为了支持合作开发,ROS软件系统以package的形式组织。我们所定义的package是一种开放形式的:一个ROS package就仅仅是一个目录,它包含了描述这个package以及其相关依赖的XML文件。

A collection of ROS packages is a directory tree with ROS packages at the leaves:一个ROS package repository(仓库)可能包含一个很复杂的子目录。 比如说,在一个ROS仓储的根目录下可能有"nav", "vision"以及"motion planning"的子目录,每一个子目录都可能有很多packages。

ROS提供了一个叫做rospack的工具来查询和审查代码树,搜索依赖关系,根据名称定位package,等各种功能。为了方便,加速命令行引导系统,ROS还提供了一系列的称为rosbash的shell扩展。

rospack工具在多个ROS package仓储同时开发的工作。rospack根据定义本地ROS package仓储根目录的环境变量来遍历pacakge树。rosmake用来递归的编译package仓储,它支持cross-package library dependencies.(译者按,目前ROS采用catkin_make作为编译系统。)

ROS packages的开放特性(open-ended)使得它们的结构和目标有很大的多样性:一些ROS pacakge封装了诸如Player, OpenCV等这样的现有软件,自动化编译过程,暴露这些软件的功能等。 Some packages build nodes for use in ROS graphs, 其它pacakge提供库和唯一的可执行文件,有些则提供的是测试和演示脚本。ROS的这种packaging系统是一种把基于ROS的软件拆分成方便管理的小模块的方式, 每一个小模块都可能有一个独立的团队来维护和开发。

在写作本文的时候,已经在几个公开的仓储中存在了几百个ROS package,还有更多的package在各种组织和公司的私有仓储中。ROS核心则发布在Sourceforge的仓储中http://ros.sourceforge.net(译者按, 现在的ROS系统的官方主页是www.ros.org)。但是这个仓储中只包含基本的ROS通信框架和运行时图管理工具。 用于编译使用ROS的机器人系统的仓储则在另一个Sourceforge中http://personalrobots.sourceforge.net(译者按,现在基本上都在www.ros.org中找到各种工具)。这个仓储包含很多有用的工具和库。

4.5 可视化和监视

在设计和debug机器人软件的时候,常常需要观测一些系统运行状态。在独立的机器上printf虽然使用很好用的debug方式,但是在大型的分布式系统中它就显得有些不好用了。

Instead, ROS can exploit the dynamic nature of the connectivity graph to "tap into" any message stream on the system。 而且,发布者与订阅者之间的解耦关系使得我们可以创建一个通用的监视器(visualizer)。可以写一个简单的程序订阅某一特定的主题,并把特定类型的数据做成图表,比如激光雷达的扫描信息或者图像。 但是,一个更强大的概念是一个支持插件结构的可视化程序:这就是ROS发布的rviz工具。Visualization panels cna be dynamically instantiated to view a large variety of datatypes,比如图像、点云、 几何体(物体识别的结果),渲染机器人姿态和轨迹等。也可以方便地写一些展示其它类型数据的插件。

ROS系统为Python提供了一个原生的接口。我们用Python谢了一个强大的rostopic工具,可以通过命令行过滤消息,resulting in an instantly customizable "message tap" which can convert any portion of any data stream into a text stream. 这些文本流可以通过管道导入到任何其它UNIX命令行工具,比如grep, sed, awk等,不用写任何代码就能创建复杂的监视工具。

类似的,还有一个叫做rxplot的工具提供了一个虚拟示波器,可以绘制运行时的任何变量的时间函数,这也是通过使用Python的introspection和expression evaluation。

4.6 组合功能(Compositoin of functionality)

在ROS系统中,一个软件栈就是一堆为实现某种有用功能的node,比如之前举的导航系统的栗子。正如前文所说的那样,只需要在一个XML文档中描述了node的运行方式,ROS就可以只使用一个命令具现一堆nodes。 举个栗子,在一个多机器人的环境中,一个导航栈在每个机器人上都会用到,而且仿人的机器人可能需要实现两个独立的手臂的控制器。ROS通过把node和整个roslaunch的描述文件都包含到一个子名字空间下, 来实现这一功能,这样是为了防止名字冲突。本质上是在所有的node、topic、和service的名字上都添加一个字符串(就是那个名字空间),而不需要修改任何节点或者集群的代码。 下图就展示了一个多机器人控制系统的层级结构,它们只是在自己的名字空间下简单的具现了多个导航栈。

这幅图是由rxgraph工具自动生成的,它可以监控任何ROS运行时图。在图中椭圆表示node,topic是方框,链接关系是边。

4.7 坐标变换

机器人系统经常因为各种原因需要跟踪特殊的关系,比如移动机器人与固定坐标系之间的位置关系,各种传感器坐标和执行器的坐标,或者目标物体的坐标。

为了简化和统一处理坐标关系,ROS系统提供了一个称为tf的坐标变换系统。这个tf系统构建了一个动态的变换树,描述了系统中所有坐标系的相对关系。 随着机器人中各个子系统采集的信息流(关机编码器、定位算法等),ty system can produce streams of transformations between nodes on the tree by constructing a path between the desired ndoes and performing the necessary calculations.

比如说,tf系统可以用于根据激光雷达的扫描数据生成点云。再比如一个双臂机器人,tf system can stream the transformation from a wrist camera on one robotic arm to the moving tool tip of the second arm of the robot.如果通过手算,这个过程将是很枯燥的,而且很容出错不容易debug,但用用tf工具再组合上ROS的动态消息框架,就可以自动的系统的完成这些操作。

5. 总结

我们本着模块化、基于工具的软件开发思想设计了ROS系统。我们期望它是一个开放的设计,可扩展,在各种不同的硬件平台、研究设定、以及运行环境约束下能有用。

致谢

我们感谢孵化ROS的用户社区的反馈和贡献,尤其是Rosen Diankov(ROS Octave库的作者)和Bhaskara Marthi(ROS LISP库的作者)。

参考资料

[1] J. Kramer and M. Scheutz, “Development environments for autonomous mobile robots: A survey,” Autonomous Robots, vol. 22, no. 2, pp. 101–132, 2007.

[2] M. Quigley, E. Berger, and A. Y. Ng, “STAIR: Hardware and Software Architecture,” in AAAI 2007 Robotics Workshop, Vancouver, B.C, August, 2007.

[3] K. Wyobek, E. Berger, H. V. der Loos, and K. Salisbury, “Towards a personal robotics development platform: Rationale and design of an intrinsically safe personal robot,” in Proc. of the IEEE Intl. Conf. on Robotics and Automation (ICRA), 2008.

[4] M. Montemerlo, N. Roy, and S. Thrun, “Perspectives on standardization in mobile robot programming: The Carnegie Mellon Navigation (CARMEN) Toolkit,” in Proc. of the IEEE/RSJ Intl. Conf. on Intelligent Robots and Systems (IROS), Las Vegas, Nevada, Oct. 2003, pp.2436–2441.

[5] A. Makarenko, A. Brooks, and T. Kaupp, in Proc. of the IEEE/RSJ Intl. Conf. on Intelligent Robots and Systems (IROS), Nov. 2007.

[6] R. T. Vaughan and B. P. Gerkey, “Reusable robot code and the Player/Stage Project,” in Software Engineering for Experimental Robotics, ser. Springer Tracts on Advanced Robotics, D. Brugali, Ed. Springer, 2007, pp. 267–289.

[7] G. Bradski and A. Kaehler, Learning OpenCV, Sep. 2008.

[8] R. Diankov and J. Kuffner, “The robotic busboy: Steps towards developing a mobile robotic home assistant,” in Intelligent Autonomous Systems, vol. 10, 2008.

[9] J. Jackson, “Microsoft robotics studio: A technical introduction,” in IEEE Robotics and Automation Magazine, Dec. 2007, http://msdn.microsoft.com/en-us/robotics.

[10] O. Michel, “Webots: a powerful realistic mobile robots simulator,” in Proc. of the Second Intl. Workshop on RoboCup. Springer-Verlag, 1998.




Copyright @ 高乙超. All Rights Reserved. 京ICP备16033081号-1