ROS 核心概念
作者:Gaurav Gupta
编译:McGL
在上一篇文章中,我们介绍了 ROS 的概况,希望你的安装已经完成了。在本文中,我们将介绍 ROS 的一些核心概念,熟悉所谓的行话。其目的是做一个简短的概念介绍,这些概念你可能会在浏览 ROS 教程或其他地方遇到。如果你按教程安装和配置,那么文件系统中应该有一个名为 catkin_ws 的目录(这取决于你如何设置配置文件)。那么,这个目录是什么,为什么它很重要呢?
Catkin 工作空间(Workspace)
等等,catkin 是什么?它是应用程序的编译系统。可以把它看作是 CMake 或 GNU Make 的更“高级”版本。由于你的 ROS 应用程序可能包括一系列的软件,从 .cpp 到 .py 文件和大量的依赖,ROS 开发人员认为编译问题的最佳现成解决方案是 catkin。你可以在这里(http://wiki.ros.org/catkin/conceptual_overview) 阅读更多关于它的信息。Catkin 工作空间(workspace)是你的 ROS 应用程序的 home 目录。这是开发、编译和安装代码的地方。你可以在桌面上拥有任意多的工作空间。它们不需要命名为 catkin_ws,它可以是任何有效的目录名。
那么,如何决定何时创建一个新的工作空间呢?这要看情况。对于所有项目只使用一个工作空间,或者采用另一种极端的方式,为每个包使用一个工作空间(下面将对此进行解释) ,并没有硬性规定,但是这两种方式都是不明智的。可以将工作空间看作你的应用程序,因此所有代码和相关文件都应该放在那里。例如,如果你正在开发两个项目: 一个是移动机器人项目,另一个是机械手操控项目,那么将相关的“包”放到单独的工作空间中是有意义的,这样可以方便地进行代码编译、共享和管理。
你可能会想,你实际上会在哪里写代码? 在 catkin 工作空间的某个地方。
ROS 包(Packages)
这是你实际放置代码的地方。它可以被认为是一个最小的独立用户开发实体,可以编译,安装和运行。可以这样想: 开发一个驱动自主移动机器人(或者说无人驾驶汽车)的项目时,将会有几个较小的应用程序一起工作以实现最终目标。例如,其中一项任务是与摄像头对接并提供视觉数据,另一项任务是解释这些数据以识别车道线、障碍物、交通标志。还有一个任务是进行路径规划,这样的任务还有很多。这些任务中的每一项都需要开发人员不同的专业知识,并且它们在整个应用程序中的角色也大不相同。
ROS 包是保存每个任务的所有源代码、脚本、 CMakeLists、启动文件、消息文件、服务文件和其他文件的地方。再次强调,对于 ROS 包来说,并没有硬性规定只能关注应用程序的一个特定方面,但是以这种方式维护它是明智的。如果你想更多地了解 ROS 包的设计和组件,请参阅这里(http://wiki.ros.org/Packages)以更深入的理解。
到目前为止,我已经使用了“进程(processes)”这个词来指代所执行的任何应用程序代码。在 ROS 生态系统中,这样的可执行文件称为 ROS 节点(Node)。它只不过是一个使用 ROS 框架与其他这样的可执行程序通信的程序。它提供了使用发布者、订阅者、服务或动作服务器客户机进行通信的方法。
发布者(Publisher)和订阅者(Subscriber)
考虑移动机器人开发中的一个典型情况,需要定位模块连续提供机器人在世界坐标参考帧中的姿态。控制算法需要使用这个姿态来跟踪给定的路径,这个控制器节点然后将速度命令发送给电机驱动程序。请注意,所有时间里机器人的姿态和速度命令都必须提供,没有例外。为了实现这一功能,ROS 提供了发布者和订阅者。在我们讨论的例子中,你的定位节点将“发布(publishing)”机器人的姿态,您的控制节点将“订阅(subscribing)”这些信息,然后“发布”运动命令。这里有一个问题,“如果他们都在发送和接收数据,他们如何知道使用哪些数据以及用于什么目的”。
这就是ROS 主题(Topics)起作用的地方。ROS 节点本质上广播(发布)特定主题上的数据(消息) ,一个或多个节点可以接收(订阅)该信息。每个主题都惟一地标识这些消息。事情是这样的,定义机器人姿态所需的数据类型与描述摄像头流的数据类型有很大的不同。ROS 提供了一些针对大多数常用信息的内置消息类型,它允许用户根据应用程序的需要定义自己的消息类型。
下面显示了一个有代表性的图,其中发布者发送数据,一个或多个节点可以订阅该信息。
ROS 服务
发布者-订阅者机制适合于更连续的通信,通常还有一种需求是进行远程过程调用(Remote procedure Call/RPC)。它只不过是一个相当于函数调用的进程间调用,包括客户机的请求和服务器的响应。它通常适用于更为离散的事件,如打开/关闭 LED,设置或获取参数或任何其他合适的函数评估。与发布者-订阅者一样,服务也有一个唯一的服务名称,并且在服务类型中定义了请求和响应对。此外,与消息类似,ROS 带有一些预先构建的服务,并允许用户根据需求进行开发。
从上面的图中可以看到,每个服务主机可以响应几个请求,但这些请求并不是并发的,即每次处理一个请求,其余的查询要排队(队列的长度可以由用户指定)。
ROS ActionLib
想象下面一个场景。假设某种情况要求启动一个特定的行动,提供反馈,然后在成功、失败或抢占后终止。举个例子,物流作业中的机器人顶部有一个传送带,当你停靠在那个精确的位置时,你想启动传送带运动,当装载作业完成时终止运动。进行这个操作的一个懒惰的方法是从任务管理器发起一个服务调用到传送控制器,等待并希望在进程完成时得到响应,在这个操作进行期间阻塞你的整个代码。如果驱动装置出了问题,而它根本不动了怎么办?很明显,你将被留在一个无人区,你的代码被困在服务中没有出路。ROS actionlib 构建在 ROS 消息之上,为这种情况提供现成的功能。动作客户端通过目标请求发起调用,具有抢占目标的能力,动作服务器在活动时提供持续的反馈,在终止时根据用户定义的标准反馈成功/失败。它可以理解为一个有一定自由度的服务调用的混合,用类似订阅者的功能启动一个特定的操作,听取反馈,最终接受来自服务器的响应。与消息和服务类似,动作(action)文件可用于定义交换的数据的操作类型和要标识的主题名称。一如既往,ROS 具有一些内置的操作类型,同时向用户提供创建自定义动作文件的能力。
基于 actionlib 的通信的示意图如下所示。虽然动作服务器可以回答多个客户机的请求,但是对服务器的每个目标请求都会抢占先前的计算。这意味着每次只有一个客户机能够与动作服务器进行有意义的通信。
就是这样!
希望这个由两部分组成的系列文章能让你对 ROS 及其一些核心组件有一个基本的了解。其目的实际上是提供一个启动平台,以启动你的开发旅程。ROS tutorials(http://wiki.ros.org/ROS/Tutorials) 是你学习的好地方,ROS answers(https://answers.ros.org/questions/) 是提正确问题的好地方,但是动手做项目是真正掌握任何东西的最好方法。学习愉快。干杯!
来源:
https://medium.com/black-coffee-robotics/ros-core-concepts-24972a2743cf