这个页面描述了用于roslaunch.launch文件的XML格式. 有关roslaunch的背景、功能和相关工具, 请先访问roslaunch页面.

文件解析顺序
置换参数

IF 和 UNLESS 属性

参考标签

launch 文件的例子

文件解析顺序

roslaunch 以单程的方式解析 XML 格式文件, include 是以深度优先的方式解析内容, 而标签Tag以串行的方式处理, 所以一个参数的最后一次设置被认定为有效值. 也就是说在. launch文件中同样的设置可能存在多处, 比如在开头定义了一个变量, 遵循着尽量节省空间的想法, 在后面的定义中又对这个变量进行了重新赋值, 以便重新利用, 在这种情况下, 在整个launch文件解析完成后, 最终进行的那次设置是有效的, 但也并不保证一定有效, 不排除在其它的文件中对变量进行了重命名, 所以推荐使用$(arg)/<arg>的方式进行覆写.

置换参数

roslaunch标签属性可以使用置换参数, roslaunch将在启动节点之前解析这些置换参数. 目前支持的置换参数是:

$(env ENVIRONMENT_VARIABLE)

其中的$是一个置换处理标志, 类似shell中的$. 从当前环境变量替换变量的值. 如果没有设置环境变量, 启动将失败. 该值不能被<env>标签覆盖. –就是说用环境变量ENVIRONMENT_VARIABLE设置的值来替换目标值. 例子:

1
<param name="variable_name" value="$(env NUM_CPUS)" />

paramlaunch文件参数定义的标签, name属性表示定义的变量名称, value属性表示对定义变量进行赋值或替代. 类似于variable_name=$(env NUM_CPUS). 如果没有设置环境变量NUM_CPUS, roslaunch启动时将报错.

$(optenv ENVIRONMENT_VARIABLE)$(optenv ENVIRONMENT_VARIABLE default_value)

和上条的区别在于, optenv表示这是一个可选的环境变量(optional environment). 假如没有设置环境变量ENVIRONMENT_VARIABLE, 若提供了default_value值, 则, 则用default_value替代目标变量, 若没有提供该值, 则用空字符串表示(roslaunch启动时, 不会报错). default_value的值可以是包含被空格分隔的多字符.

1
2
3
4
5
6
<!-- 若设置了环境变量 NUM_CPUS, 则 foo = $NUM_CPUS, 否则 foo = "1". 如果没有默认值 1, 那么 foo = "". -->
<param name="foo" value="$(optenv NUM_CPUS 1)" />
<!-- 若设置了环境变量 CONFIG_PATH, 则 foo = $CONFIG_PATH, 否则 foo = "/home/marvin/ros_workspace". -->
<param name="foo" value="$(optenv CONFIG_PATH /home/marvin/ros_workspace)" />
<!-- 若设置了环境变量 VARIABLE, 则 foo = $VARIABLE, 否则 foo = "ros rocks". 变量可以包含空格字符串. -->
<param name="foo" value="$(optenv VARIABLE ros rocks)" />

$(find pkg)

查找包路径. 例如$(find rospy)/manifest.xml指定包相对路径。包目录的完整文件路径将被内联替换。强烈建议使用包相对路径,因为硬编码路径会限制启动配置的可移植性。前斜杠和后斜杠将按惯例被解析为本地文件系统。

$(anon name)

产生基于名称的匿名 ID, 主要用于节点名称属性中创建匿名节点, 并检查是否有相同的匿名名字, 因为 ROS 中名字作为标识符要求具有唯一性. 其中的 anon 是 anonymous 的简写. 例如:

1
2
<node name="$(anon talk_01)" pkg="rospy_tutorials" type="talker.py" />
<node name="$(anon talk_01)" pkg="rospy_tutorials" type="talker.py" />

则会产生错误, 因为系统检测到了两个节点具有相同的匿名名字.

$(arg varible_name)

解析由<arg>标签指定的变量值. 必须在声明arg的同一启动文件中有对应的<arg>标签。 例如:

1
<param name="foo" value="$(arg my_foo)" />

my_foo的值赋给参数foo. 这样在解析my_foo的值的时候才能正常进行. 就如同你在表达式中用一个变量进行计算, 你必须在计算之前就已经定义过这个变量才可以. 再如:

1
2
<node name="add_two_ints_server" pkg="beginner_tutorials" type="add_two_ints_server" />
<node name="add_two_ints_client" pkg="beginner_tutorials" type="add_two_ints_client" args="$(arg a) $(arg b)" />

其中的$(arg a)$(arg b)则是对节点所需要的变量进行声明, 这样你在对节点进行参数传递的时候就可以用以下代码进行:
roslaunch beginner_tutorials launch_file.launch a:=1 b:=5

$(eval <expression>) New in Kinetic

允许计算任意复杂的python表达式. 例如:

1
<param name="circumference" value="$(eval 2. * 3. 1415 * arg('radius'))"/>

会根据给定的radius进行计算后将结果赋给circumference. 作为限制, $(eval)的作用范围要跨越表示整个表达式的字符串, 如果在其中插入其它属性是不可行的. 例如:

1
<param name="a_name" value="$(arg r_dis) $(eval 6*7) bar"/>

是不可行的. 为了弥补这个限制,所有的替换命令都可以作为函数在 eval 中使用:

"$(eval arg('sth') + env('PATH') + 'bar' + find('pkg'))"

为了方便起见,参数也是隐式解析的,即以下两个表达式是相同的:

"$(eval arg('foo'))"
"$(eval foo)"

IFUNLESS 属性

所有的标签都支持ifunless属性, 此类属性是基于计算的值包含或是排除一个标签的内容.

if = value (optional)
如果 value 的值为真则包含标签及内容.

unless = value (optional)
如果值为假, 则包括此内容.

1
2
3
4
5
6
<group if="$(arg foo)">
<!-- stuff that will only be evaluated if foo is true -->
</group>

<param name="foo" value="bar" unless="$(arg foo)" />
<!-- This param won't be set when "unless" condition is met -->

参考标签

<launch>

<launch>标签为所有 roslaunch 文件的根标签, 可以将其理解为所有其它标签的容器. 以下为<launch>标签与其它标签的关系:

1
2
3
4
5
6
7
8
9
10
11
12
<launch>
<node/>
<param/>
<remap/>
<machine/>
<rosparam/>
<include/>
<env/>
<test/>
<arg/>
<group/>
</launch>

<node>

用来启动节点, 但不保证节点的启动顺序.

属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
pkg="mypackage"
<!--指定所用的包-->

type="nodetype"
<!--指定对应的可执行程序的名字-->

name="nodename"
<!--指定节点名称, 但不能在这里加入命名空间名称-->

args="arg1 arg2 arg3"
<!--声明或传递参数(optional)-->

machine="machine-name"
<!--在指定的机器上启动节点(optional)-->

respawn="true"
<!--如果节点失败则重新启动(optional)-->

respawn_delay="30"
<!--如果上rospawn属性为真, 则等待一定的时间之后重新启动节点(optional, New in indigo)-->

required="true"
<!--将节点定义为必需节点, 如果本节点失效, 则关闭整个文件(optional)-->

ns="nnss"
<!--在一个命名空间中启动节点(optional)-->

clear_params="true|false"
<!--在节点启动之前是否清空所在命名空间中的变量(optional)-->

output="log|screen"
<!--指定输出的对象(optional)-->

cwd="ROS_HOME|node"
<!--指定node则节点工作路径与其可执行程序路径相同(optional)-->

launch-prefix="prefix arguments"
<!--预先处理指令或参数(optional, 支持多种工具)-->

元素

1
2
3
4
5
6
<node>
<env/>
<remap/>
<rosparam/>
<param/>
</node>

<param>

用于在参数服务器中定义参数. 其属性参数如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
name="namespace/name"
<!-- 参数名称. 在这个名称定义中是可以使用命名空间的, 而在node的名称定义中不能使用命名空间, 这个是有区别的. 但是应该避免指定全局的名称. -->

value="value"
<!-- 定义参数的值, 如果这一属性忽略掉了, 但必须指定 binfile, textfile or command. -->

type="str|int|double|bool|yaml"
<!-- 指定参数的类型(optional), 如果不指定则会自动识别类型, 规则如下:
1. 有“. ”的认为是浮点数, 没有的则认为是整型.
2. ”true” 和 “false” 被认为是逻辑变量 (not case-sensitive).
3. 其它的所有都为string型. -->

textfile="$(find pkg-name)/path/file.txt"
<!-- 文件的内容被存储为string类型用以替代目标变量(optional). 该文件必须是本地可访问的, 但是强烈建议使用包相对路径$(find)/file.txt的语法来指定位置。 -->

binfile="$(find pkg-name)/path/file"
<!-- 内容将被存储为 base64-encoded XML-RPC 二进制对象用以替代目标变量(optional). 同上建议相对路径指定位置 -->

command="$(find pkg-name)/exe '$(find pkg-name)/arg. txt'"(optional)
<!-- 执行某项命令, 命令的输出将被存储为一个string类型以替代目标变量. 文件的路径变量需要用单引号包括. -->

例子

1
2
<!-- 在参数服务器中定义名称为:publish_frequency, 类型为:double, 值为:10.0 的变量.  -->
<param name="publish_frequency" type="double" value="10.0" />
1
2
<!-- 如果是加载 YAML 文件可以用以下代码,其中的 file 属性要指定路径和文件名.  -->
<rosparam command="load" file="FILENAME" />

<rosparam>

支持从YAML文件读取与卸载参数.

属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- rosparam的命令, 可以指定 加载|卸载|删除 对应的参数.  -->
command="load|dump|delete" (optional, default=load)

<!-- 指定文件所要求的路径. -->
file="$(find pkg-name)/path/my. yaml" (load or dump commands)

<!-- 参数名称 -->
param="param-name"

<!-- 设定参数给指定的命名空间(设定参数的作用域) -->
ns="namespace" (optional)

<!-- 是否运允许使用YAML文件中置换参数 -->
subst_value=true|false (optional)

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- 加载.yaml文件 -->
<rosparam command="load" file="$(find rosparam)/example.yaml" />

<!-- 卸载.yaml文件 -->
<rosparam command="delete" param="my/param" />

<!-- 定义一个变量 a_list, 而变量的值即为标签之间的所有内容, 即 a_list = [1, 2, 3, 4, 5] -->
<rosparam param="a_list">[1, 2, 3, 4]</rosparam>

<rosparam>
a: 1
b: 2
</rosparam>

<!-- 参数置换允许您使用 roslaunch args 来表示一个 YAML 字符串的全部或部分 -->
<!-- 如果subst_value为false, 表示不允许使用替代标签, 则输出的blacklist只是一个字符串$(arg whitelist); 但如果为true则表示允许使用替代标签, 则blacklist输出的值为[3, 2]. -->
<arg name="whitelist" default="[3, 2]"/>
<rosparam param="whitelist" subst_value="True">$(arg whitelist)</rosparam>
<!-- 它们对于在yaml字符串中嵌入$(find…)和其他替换模式也很有用。 -->

<remap>

用来通过名称进行参数之间的映射. 其属性如下:

属性

1
2
3
4
5
from="original-name"
<!-- 指定节点原来要监听的话题的名称. -->

to="new-name"
<!-- 指定节点实际要监听的话题的名称. -->

例子

1
2
<remap from="chatter" to="hello"/>
<!-- 此行代码表明要将原来应监听chatter话题的节点改到监听hello话题. -->

<machine>

<machine>标签声明一台可以运行ROS节点的机器。如果在本地启动所有节点,则不需要此标签。它主要用于声明远程机器的SSHROS环境变量设置,不过您也可以使用它来声明关于本地机器的信息。

属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
name="machine-name"
<!-- 要分配给机器的名称。这对应于<node>标记的machine属性的名称。 -->

address="blah.willowgarage.com"
<!-- 机器的远程地址或主机名 -->

env-loader="/opt/ros/fuerte/env.sh"

<!-- New in Fuerte. 指定远程计算机上的环境文件。环境文件必须是一个设置了所有需要环境变量的shell脚本,并提供参数执行exec -->

default="true|false|never" (optional)
<!-- 将此机器设置为节点的默认分配机器。默认设置只适用于后续在同一范围内定义的节点。注意:如果没有默认机器,则使用本地机器。可以通过设置default="never"来阻止机器被选中,在这种情况下,只能显式地分配机器。 -->

user="username" (optional)
<!-- 登录机器的ssh用户名, 如果不需要可以忽略 -->

password="passwhat"(strongly discouraged)
<!-- ssh登录密码。强烈建议您配置SSH密钥和SSH代理,这样您就可以使用证书登录了 -->

timeout="10.0" (optional)
<!-- 登录超时检测时间,默认设置为10秒。虽然您可以使用此设置来允许较慢的连接,但需要更改此参数通常是您的整个ROS图将出现通信问题的症状(While you can use this setting to allow for slower connections, needing to change this parameter is generally a symptom that your overall ROS graph will have communication issues.) -->

例子

下面的示例显示如何配置节点“footalker”来运行另一台机器。它使用 Fuerte 附带的默认的 env-loader 文件。注:**Basic (ROS Fuerte and later) using env-loader**

1
2
3
4
<launch>
<machine name="foo" address="foo-address" env-loader="/opt/ros/fuerte/env.sh" user="someone"/>
<node machine="foo" name="footalker" pkg="test_ros" type="talker.py" />
</launch>

下面是一个 ev -loader 脚本示例。如果你想使用不同的环境配置, 将/opt/ros/fuerte/setup.sh 替换为另外的安装文件:

1
2
3
4
#!/bin/sh

./opt/ros/fuerte/setup.sh
exec "$@"

此外,如果要从rosws工作空间中加载源:

1
2
3
4
#!/usr/bin/env bash

source /home/username/path/to/workspace/setup.bash
exec "$@"

<include>

<include>标记允许您将另一个roslaunch XML文件导入当前文件。它将被导入到当前的文档范围,包括<group><remap>标签。除了<master>标记外,include文件中的所有内容都将被导入。<master>标签仅在顶级文件中被遵守。

属性

1
2
3
4
5
6
7
8
9
10
11
file="$(find pkg-name)/path/filename.xml"
<!-- 指定要包含的文件路径. -->

ns="namespace_name" (optional)
<!-- 指定要导入文件的命名空间. -->

clear_params="true|false" (optional Default: false)
<!-- 在文件加载之前删除<include>的命名空间中的所有参数, 缺省为false, 此参数要谨慎使用, 用之前要核对好命名空间名称. -->

pass_all_args="true|false" (optional Default: false)
<!-- 如果为true,所有当前上下文的args将被加入到在处理<include>文件时创建的子上下文中. -->

元素

1
2
3
4
<include>
<env>
<arg>
</include>

<env>

此标签用来设置将要启动的节点的环境变量, 其可以在<launch>, <include>, <node><machine>标签中使用. 当在<launch>中使用时, <env>标签作用于其后声明的所有节点. 但是用此标签声明的环境变量对于$(env …)不可见, 所以并不能用$(env …)对其它变量的值进行置换, 所以<env>标签不能用来参数化 launch 文件.

属性

1
2
3
4
5
name="environment-variable-name"
<!-- 此属性用来设置环境变量名称. -->

value="environment-variable-value"
<!-- 此属性用来设置环境变量值. -->

<test>

<test>标签在语法上类似于<node>标签, 都是指定一个ROS节点运行, 但是<test>标签表明当前要运行的节点是一个测试节点.

<test><node>具有大部分相同的属性, 但以下内容是不同的:

  • 没有 respawn 属性 (测试节点必须要被终止, 所以它们没有重启属性)
  • 没有输出属性, 因为测试节点有其输出记录机制.
  • Machine 属性被忽略.

属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
pkg="mypackage"
<!-- 这一属性是必需的属性, 指定节点的包名称. -->

test-name="test_name"
<!-- 必须的属性, 指定测试节点的名称. -->

type="nodetype"
<!-- 必须的属性, 指定测试节点所对应的可执行程序名称. -->

<!-- 标签可选择的属性如下: -->
name="nodename"
<!-- 节点名称. PS:名称中不能包含命名空间, 如果要指定要使用ns属性, 如果此属性未指定, 则test-name将被作为节点名称. -->

args="arg1 arg2 arg3"
<!-- 用测试节点传递参数. -->

clear_params="true|false"
<!-- 如果是true, 则在启动之前清空当前节点私有命名空间中的全部参数. -->

cwd="ROS_HOME|node"
<!-- 指定工作路径. 如果是node则节点的工作目录与节点的可执行程序目录相同. -->

launch-prefix="prefix arguments"
<!-- 节点启动之前的预置参数或命令. -->

ns="namespace_name"
<!-- 在指定的命名空间中启动节点. -->

retry="0"
<!-- 用于有时可能失效的随机过程, 设置重新尝试的次数. -->

time-limit="60. 0"
<!-- 认定节点启动失败之前要经历的时间, 缺省为60s. -->

例子

1
2
<test test-name="test" pkg="mypkg" type="test. py" time-limit="10. 0" args="--test1 --test2" />
<!-- 上行代码指定要测试的节点的名称, 包名称, 可执行程序名称, 测试时间跨度和要传递的参数 -->

元素

1
2
3
4
5
6
<test>
<env/>
<remap/>
<rosparam/>
<param/>
</test>

<arg>

<arg>标签允许通过命令行、<include>标签或者更上层的文件传递指定的值,用来创建可以重用或者可配置的的launch文件. 但<arg>标签是非全局的, 一个声明只针对一个launch文件, 如同局部变量一样。如果要在一个包含文件include file中使用, 则必须要显式的值传递.

<arg>可以通过以下三种方式使用:

1
2
3
4
5
6
7
8
<arg name="foo" />
<!-- 声明了一个foo变量。foo必须通过命令行传递或通过<include>标签进行传递. -->

<arg name="foo" default="1" />
<!-- 声明变量foo, 并赋予一个缺省值1. foo可以通过命令行覆写或<include>标签进行值传递使用. -->

<arg name="foo" value="bar" />
<!-- 声明了一个值为bar的常量foo。foo的值不能被覆写。此用法支持启动文件的内部参数化,而无需在更高级别暴露该参数。 -->

属性

1
2
3
4
5
6
7
8
9
10
11
name="arg_name"
<!-- 指定变量名. -->

default="default value" (optional)
<!-- 指定变量缺省值, 不能与value属性一起使用. -->

value="value" (optional)
<!-- 指定变量值, 不能与default属性一起使用. -->

doc="description for this arg" (optional) New in Indigo
<!-- 变量描述. -->

例子

  • 传递一个参数到包含文件中

my_file.launch:

1
2
3
4
<include file="included.launch">
<!-- all vars that included.launch requires must be set -->
<arg name="hoge" value="fuga" />
</include>

included.launch:

1
2
3
4
5
6
7
<launch>
<!-- declare arg to be passed in -->
<arg name="hoge" />

<!-- read value of arg -->
<param name="param" value="$(arg hoge)"/>
</launch>

则当运行my_file.launch文件时, hoge参数会从my_file.launch<include>标签中传递进入included.launch文件中, 产生一个变量名为param, 值为fuga的变量. 但是由于<arg>定义的为一个文件内部的局部变量(类似于类内的私有变量), 无法从更高一级或外部进行访问, 即不能通过命令行进行赋值, 所以, 当运行:

roslaunch %YOUR_ROS_PKG% my_file.launch hoge:=my_value

时, hoge的值还是原来设定的fuga值, 而不管你在局部的<arg>属性中是用value属性还是default属性. 如果想用自己的定义值在命令行中进行覆盖, 则<arg>标签要使用更高一层级的default属性指定my_file.launch如下所示:

1
2
3
4
5
6
7
<!-- 即定义一个更高一层次的<arg>标签来执行值传递, 从更高一层级传递到局部再传递到included.launch文件中.  -->
<launch>
<arg name="temp" default="fuga"/>
<include file="$(find your_pkg)/launch/included.launch">
<arg name="param" value="$(arg temp)" />
</include>
</launch>
  • 通过命令行传递变量
    roslaunch使用与ROS映射参数相同的语法来指定arg
1
2
3
$ roslaunch my_file.launch hoge:=my_value  (.launch file is available at the current dir)

$ roslaunch %YOUR_ROS_PKG% my_file.launch hoge:=my_value

<group>

可以对一组节点进行设置, 并且可以通过 ns 属性将一组节点放到一个隔离开的命名空间中.

属性

1
2
3
4
5
6
ns="namespace" (optional)
<!-- 将一组节点指定到一个特定的命名空间中, 命名空间可以是全局的或是局部的, 但并有推荐使用全局的命名空间. -->

clear_params="true|false" (optional)
在节点启动之前清空<group>命名空间中的所有参数, 谨慎使用.
<!-- 内部可使用的标签如下所示: -->

元素

1
2
3
4
5
6
7
8
9
10
11
<group>
<node>
<param>
<remap>
<machine>
<rosparam>
<include>
<env>
<test>
<arg>
<group/>

launch 文件的例子

一个简单的例子

1
2
3
4
<launch>
<node name="talker" pkg="rospy_tutorials" type="talker" />
</launch>
<!-- 在本地使用当前ros环境启动rospy_tutorials包中的可执行程序为talker的节点, 节点名称定义为talker. -->

一个复杂一点的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<launch>

<machine name="local_alt" address="localhost" default="true" ros-root="/u/user/ros/ros/" ros-package-path="/u/user/ros/ros-pkg" />
<!-- 本地的机器已经进行了缺省定义, 这个标签的作用是用指定的ROS_ROOT和ROS_PACKAGE_PATH值对其重新赋值-->

<node name="listener-1" pkg="rospy_tutorials" type="listener" />
<!-- 启动一个收听节点 -->

<node name="listener-2" pkg="rospy_tutorials" type="listener" args="-foo arg2" />
<!-- 向监听节点中传递参数 -->

<node name="listener-3" pkg="rospy_tutorials" type="listener" respawn="true" />
<!-- 一个可以重新启动的节点 -->

<node ns="wg1" name="listener-wg1" pkg="rospy_tutorials" type="listener" respawn="true" />
<!-- 在 'wg1' 命名空间中启动一个节点 -->

<group ns="wg2">
<!-- 在 'wg2' 命名空间中启动一组节点 -->

<remap from="chatter" to="hello"/>
<!-- remap在group范围内作用于在其后声明的所有节点 -->

<node pkg="rospy_tutorials" type="listener" name="listener" args="--test" respawn="true" />
<node pkg="rospy_tutorials" type="talker" name="talker">
<param name="talker_1_param" value="a value" />
<!-- 设置局部变量 -->

<remap from="chatter" to="hello-1"/>
<!-- 节点可以有其自己私有的remap指令 -->

<env name="ENV_EXAMPLE" value="some value" />
<!-- 为节点设置环境变量 -->
</node>

</group>

</launch>

设置参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<launch>

<param name="somestring1" value="bar" />
<!-- 值类型为string类型 -->

<param name="somestring2" value="10" type="str" />
<!-- 强制使用string类型而不是整型定义参数 -->

<param name="someinteger1" value="1" type="int" />
<!-- 指定为整型 -->
<param name="someinteger2" value="2" />
<!-- 自动识别为整型 -->

<param name="somefloat1" value="3. 14159" type="double" />
<!-- 指定为浮点型数据 -->
<param name="somefloat2" value="3. 0" />
<!-- 自动识别为浮点型数据 -->

<param name="wg/childparam" value="a child namespace parameter" />
<!-- 在子命名空间中设置参数 -->

<param name="configfile" textfile="$(find roslaunch)/example. xml" />
<!-- 向参数服务器中加载文本文件内容 -->

<param name="binaryfile" binfile="$(find roslaunch)/example. xml" />
<!-- 向参数服务器中加载二进制文件内容 -->

</launch>

参考链接: