启动文件roslaunch
一.使用启动文件
执行启动文件 想要运行一个启动文件,可以像下面这样使用
roslaunch命令 2:
roslaunch package-name launch-file-name
在启动任意节点之前,roslaunch 首先会判断 roscore 是否正在运行;如果没有,则自动
启动 roscore。
关于 roslaucn 工具一个重要但容易忘记的事实是,文件内所有的节点几乎都在同一时刻启动。因此,事实上你无法确定各个节点的启动顺序。不过这并没有什么影响,设计良好的 ROS 节点是不关心各个节点的启动顺序的。
二.启动文件的基本元素
最简单的启动文件由一个包含若干节点元素(node elements)的根元素(root element)组成。
(1)插入根元素
启动文件是 XML 文件,每个 XML 文件都必须要包插入根元素含一个根元素。对于 ROS 启动文件,根元素由一对 launch 标签定义:
<launch>
...
<launch>
(2)启动节点
任何启动文件的核心都是一系列的节点元素,每个节点元素指向一个需要启动的节点 。节点元素的形式为:
<node
pkg=”package-name”
type=”executable-name”
name=”node-name”
/>
在节点标签末尾的斜杠“/”是很容易忘记的,但是它很重要。它表明不必再等待结束标签(“”),并且该节点元素是完整的。
pkg 和 type 属性定义了 ROS 应该运行哪个程序来启动这个节点。这些和 rosrun 的两个命令行参数的作用是一致的,即给出功能包名和可执行文件的名称。
name 属性给节点指派了名称,它将覆盖任何通过调用 ros::int来赋予节点的名称。
(3)请求复位
在启动了启动文件中所有的请求节点之后,roslaunch会监视每一个节点,记录哪一个节点是活跃的。对于每个节点,我们可以设置 respawn 属性为真,这样当节点停止的时候,roslaunch 会重新启动该节点。
respawn=”true”
(4)为节点维护独立的窗口
使用 roslaunch 的一个缺点是所有的节点共享一个终端,而使用 rosrun 的时候,每个节点都有一个独立的终端。这对于不接收控制台输入,只生成日志消息的节点是可行的(通常也是有帮助的),但是对于依赖控制台输入的节点来说,例如 turtle_teleop_key,更倾向于为节点保留独立的终端。
幸运的是,roslaunch 提供了一个实现该目的的简洁方法——对节点元素使用启动前缀(launch-prefix)属性:
Launch-prefix=“command-prefix”
事实上,roslaunch 在启动节点时的内部工作原理是调用相应的命令行工具,即 rosrun。启动前缀的主要思想是在其命令行前面添加给出的命令行前缀。
三.重映射
重映射是基于替换的思想:每个重映射包含一个原始名称和一个新名称。每当节点使用重映射中的原始名称时,ROS客户端库就会将它默默地替换成其对应的新名称。
1.创建重映射
方法一
当使用命令行启动节点时,分别给出原始名称和新名称,中间由一个:=分开,如下所示:
original-name := new-name
例如,运行一个 turtlesime 的实例,如果想要把海龟的姿态
数据发布到话题/tim 而不是/turtle1/pose,就可以使用如下命
令:
rosrun turtlesim turtlesim_node turtle1/pose:=tim
方法二
通过启动文件的方式,只需在启动文件内使用重映射(remap)
元素即可 7 :
<remap from=”original-name”to ”new-name”/>
如果该属性在顶层,即作为 launch 元素的子元素出现,重映
射将会应用到所有的后续节点。这些重映射元素也可以作为
一个节点元素的子元素,如:
<node node-attributes>
<remap from=”original-name”to ”new-name”/>
</node>
在这种情况下,给出的重映射只应用于其所在的节点。例如,上面的命令行本质上等价于如下结构的启动文件:
<node pkg=”turtlesim” type=”turtlesim_node”
name=”turtlesim_node”>
<remap from=”turtle1/pose”to ”tim”/>
</node>
关于重映射的使用,有一点需要牢记:在 ROS 应用任何重映射之前,所有的名称都要先解析为全局名称,包括重映射中的原始名称和新名称。因此,虽然在重映射中出现的名称通常是相对名称,但当名称解析完成后,重映射就可以通过直接的字符串比较来实现,即在所有重映射中查找某个节点使用的原始名称。
ADD
1.包含其他文件
如果想在启动文件中包含其他启动文件的内容(包括所有的节点和参数),可以使用包含(include)元素 :
<include file=”path-to-launch-file”>
此处 file 属性的值应该是我们想包含的文件的完整路径。由于直接输入路径信息很繁琐且容易出错,大多数包含元素都使用查找(find)命令搜索功能包的位置来替代直接输入路径:
<include file=”$(find package-name)/launch-file-name”>
包含元素同样支持命名空间属性,可以将内容压入一个指定的命名空间中去:
<include file=”...” ns=”namespace”/>
是当被包含进来的启动文件属于另一个功能包的时候,设置的操作应当独立于其他节点。
2.启动参数
为了使启动文件便于配置,roslaunch还支持启动参数,有时也简称为参数甚至args,其功能有点像可执行程序中的局部变量。这样做的优点是通过设置参数来描述节点在不同ROS会话中运行时可能需要改变的一小部分,从而避免代码重复。
声明参数
为了声明一个参数,可以使用 arg 元素。
<arg name=”agr-name”>
参数赋值
启动文件中的每一个参数都要进行赋值。赋值有很多种方法,例如可以像下面在 roslaunch 命令行中提供该值:
roslaunch package-name launch-file-name arg-name:=arg-value
除此之外,你也可以使用以下两种语法,将参数值作为 arg声明的一部分:
<arg name=”arg-name” default=”arg-value”/>
<arg name=”arg-name” value=”arg-value”/>
两者的唯一区别在于命令行参数可以覆盖默认值 default,但是不能覆盖参数值 value。
获取参数值
一旦参数值被声明并且被赋值,你就可以利用下面的arg 替换(arg substitution)语法来使用该参数值了:
$(arg arg-name)
每个该替换出现的地方,roslaunch 都将它替换成参数值
向包括的启动文件中发送参数值
目前已介绍的参数设定技巧的局限在于,它并未提供任何方法将参数传递到通过包含元素导入
的次级启动文件中去。这一点很重要,因为像局部变量一样,参数仅定义在对其进行声明的启动文件中,而不能被包含的启动文件“继承”。
该问题的解决方案就是将 arg 元素作为一个包含元素的子元素,如下所示:
<incluce file=”path–to-launch-file”>
<arg name=”arg-name” value=”arg-value”/>
...
</include>
请注意,该 arg 元素的用法和之前我们看到的 arg 声明是不同的。在 include 标签之间的参数是属于被包含文件的,而不是它们出现的启动文件。因为目的是为被包括的启动文件设置响应的参数值,所以该处需要使用 value 属性。一种常见的情况是两个启动文件(包含文件和被包含文件)有一些共同的参数,在这种情况下,我们希望参数在传递的时候不会改变。这样的元素在两个地方使用相同的参数名:
<arg name=”arg-name” value=”$(arg arg-name)”>
在该例子中,第一个参数名字通常是指被包含文件中的参数,第二个参数名是指当前文件中的参数。这样做之后,给定参数在两个启动文件中有相同的值。