ros2 launch 与 roslaunch异同
Kong Liangqian Lv6

原文(https://design.ros2.org/articles/roslaunch.html)

本文描述了ROS 2的launch系统,它可以看作是ROS 1 launch系统的继承者。本文将ROS 1中roslaunch的特性和作用,并将它们与ROS 2launch系统的目的进行比较。

ROS1 的 roslaunch

ROS1的roslaunch主要有以下作用

  • 启动结点
  • 远程通过ssh启动结点
  • 在参数服务器上设置参数
  • 重新启动已经die的进程

roslaunch的设计是为了通过组合来适应复杂的ROS架构:先编写一个简单的系统,然后与其他简单的系统结合,形成更复杂的系统。在roslaunch中,这通过几个机制表现出来:

  • include: 可以引入其他的launch文件,然后给一个namespace
  • group:可以把一些node结点组合在一起,并且给一个一样的name remapping
  • machine:允许为多个机器人使用相同的节点,只要给出不同的名字即可

roslaunch还包括一些工具来帮助你的launch具有可移植性,你可以利用\标签来指定环境变量,$(find pkg)来寻找ROS的包目录,在include标签内使用$(env ENVIRONMENT_VARIABLE)语法

从这一点来看,roslaunch在ROS 1中还有以下的目的:

  • 将系统组合成多个系统来管理复杂性
  • 使用include 来重用片段,而不是从头编写每个片段
  • 使用group将设置应用到节点/进程/include的launch文件集合中
  • 还要使用带有名称空间的组来形成层次结构
  • 通过抽象操作系统概念(例如环境变量)实现可移植性
  • 文件系统的定位(例:使用$(find <package_name>)

这些已经包括了大部分的roslaunch的特点,也差不多就是它的设计目的。下面我们要讨论ROS2的launch系统和ROS1的不同以及改进的地方

ROS2的不同

ROS2的launch系统的其中一个目的是要实现出ROS1的launch系统的特性,但是由于ROS2的架构改变,一些特性、术语需要修改

Nodes 和 进程的关系

在ros1中,每个进程只能有一个节点,因此,它几乎可以互换使用“ROS节点”和“进程”两个名词

即使是“nodelet”(ROS 1特性之一——模拟每个进程有可以包含多个节点),从节点或nodelet到进程的概念映射也由代理进程保留。

由于在ROS 2中每个进程可以有多个节点,因此不再需要合并节点和进程这两个名词。

此外,通过Node的配置(例如parameter和remapping)的方式也需要调整

此外,由于每个进程可以有多个节点,关闭一个节点不再总是意味着向单个进程发送unix信号。可能需要使用其他机制来在多节点进程中进行更细粒度的关闭控制。

远程启动节点(进程)和可移植性

ROS 1中的启动系统只在Linux和其他类unix操作系统(如BSD和macOS)上得到支持。这些机器上都有SSH,这是在远程机器上启动进程时专门调用的机制,它还在定义您指定的内容以及如何从ROS 1配置rosclaunch以能够在远程机器上启动进程方面发挥了作用。

在ROS 2中,Windows已被添加到目标平台的列表中,目前,Windows本身并不支持SSH。因此,除非这种情况发生变化(比听起来更有可能),否则可能需要一种不同的、更可移植的机制来支持该特性。至少,需要在Windows上使用一个替代解决方案,即使SSH仍然在类unix操作系统上使用。

Parameters

在ROS 1中,存在一个全局参数服务器,存储所有参数。节点通过该服务器获取和设置所有参数。参数服务器与来自ROS 1的roslaunch紧密集成,同时也被来自ROS 1的其他类型参数所使用,这些参数被称为“动态重新配置参数”。

在ROS 2中,它不再是一个全局的参数服务器,他们是特定于结点的,并且由结点来管理。不过总的来说,他们的工作方式和ROS 1的“动态重新配置参数”差不多。

进程相关事件和响应

在ROS1中,针对系统的改变而做出响应的方式很少,并且他们都和系统的”die”有关系,

  • 如果系统挂了,再重新孵化一个进程
  • 如果一个required的进程挂了,就关闭整个系统

这是ROS2想要提升的一个地方,它不仅可以通过提供这些常见的反应进程退出,还通过提供更细粒度的信息流程退出(和其他活动),可以让用户指定对这些类型的事件的任意响应。

Deterministic Startup

在ROS1的wiki中,

roslaunch并不保证任何特定的节点启动顺序——尽管这是一个经常被要求的特性,但在ROS体系结构中没有任何特定的含义,因为没有办法知道节点何时初始化。

这也是ROS2的launch系统中希望可以提升的,至少应该有一个生命周期,即节点管理器。

因此,ROS2的launch系统需要分析出各个结点之间的依赖关系,以及依赖的约束。例如,一个用户可能想要启动一个图像处理节点,但是它依赖于相机驱动节点,它不应该直接运行,直到相机驱动节点到达“活跃”状态。这样的约束可以由用户任意定义,也可以由launch系统直接建模。

此外,这些约束不一定与ROS特定事件(如生命周期状态变化)相关。例如,用户可能表示,在另一个进程运行10秒之后,应该启动一个普通进程(在本例中作为子进程执行)。ROS 2中的启动系统可以选择让用户定义满足该约束的谓词,也可以提供一个通用约束,比如:“在另一个进程之后N秒启动”。

结点相关的事件和响应

如果可以的话,利用管理结点,ROS2的launch可以导出,聚合导出,或者对结点的生命周期事件做出反应。

比如:一个结点,注意不是一个进程,的状态到达了”finalized”的状态,就结束launch 系统。

静态描述和编程API

ROS 1的用户都是通过静态描述符来表示要执行的结点和参数,其实这个是有一个API的,但是很少有用户会使用,why? 因为API没有很好的文档说明,在教程和示例中也不普遍。严格遵循XML描述导致两种不同的动态行为/配置方法变得更加流行:

  • 使用XML预处理程序(如xacro或其他通用模板系统)进行预处理
  • 在ROS1 的 roslaunch语法中, 把更复杂的表达式作为XML标签,例如$(eval表达式)(添加在ROS Kinetic)或if=$(arg…)unless=$(arg…)属性

通常当我们讨论这些“动态”特性时,我们会问“为什么roslaunch(来自ROS 1)是静态描述而不是脚本?” 直接的答案是“ 不需要”,但是这个为了实现脚本式编程的API并没有很好的文档,也不容易使用。

静态的启动脚本和脚本式启动各有利弊,这将在本文后进行介绍。即使大伙儿还是偏向使用静态式的启动方式,那ROS 2也依然会把更容易使用的公共API执行静态启动文件作为目标,因此编程式启动的方法永远都将是一个备选项

Locating Files

我们经常需要定位一个文件的位置,无论是可执行文件还是一个需要被传递的文件。ROS2 会支持更多的paths,而不仅仅是share 文件夹。ROS1和ROS2的不同在于,这个package是如何被找到的,一个包可以与哪个文件夹相关联,因此可能还有如何获得相对路径的语法。

ROS2和ROS1 的相同处

前面说了一些和ROS1 launch的不同之处,这个小节将列举和ROS1 launch的相似之处

  • 将常见的ROS概念(如重新映射和更改名称空间)转换为节点的适当命令行参数和配置,这样用户就不必这样做了
  • 通过组合更简单的系统(launch文件)来管理复杂性
  • 允许include其他的launch文件
  • 可以使用group设置一系列的结点集合或者进程
  • 提供操作系统的可移植性

可能还有其他的东西,所有这些都将与ross1中的rosslaunch有共同之处。

 Comments