迁移启动文件
虽然 ROS 1 中的启动文件始终使用 .xml 文件指定,但 ROS 2 支持 Python 脚本以实现更大的灵活性(请参阅 launch package)以及 XML 和 YAML 文件。
本指南介绍如何编写 ROS 2 XML 启动文件以便从 ROS 1 轻松迁移。
背景
ROS 2 启动系统及其 Python API 的描述可在 启动系统教程 中找到。
迁移标签
launch
launch
is the root element of any ROS 2 launch XML file.
节点
Launches a new node.
Differences from ROS 1:
type
attribute is nowexec
.ns
attribute is nownamespace
.The following attributes aren’t available:
machine
,respawn_delay
,clear_params
.
例子
<launch>
<node pkg="demo_nodes_cpp" exec="talker"/>
<node pkg="demo_nodes_cpp" exec="listener"/>
</launch>
参数
用于将参数传递给节点。
ROS 2 中没有全局参数概念。
因此,它只能嵌套在 node
标签中使用。
ROS 2 不支持某些属性:type
、textfile
、binfile
、executable
。
* command
属性现在是 value="$(command '...' )"
。
例子
<launch>
<node pkg="demo_nodes_cpp" exec="parameter_event">
<param name="foo" value="5"/>
</node>
</launch>
类型推断规则
以下是一些如何编写参数的示例:
<node pkg="my_package" exec="my_executable" name="my_node">
<!--A string parameter with value "1"-->
<param name="a_string" value="'1'"/>
<!--A integer parameter with value 1-->
<param name="an_int" value="1"/>
<!--A float parameter with value 1.0-->
<param name="a_float" value="1.0"/>
<!--A string parameter with value "asd"-->
<param name="another_string" value="asd"/>
<!--Another string parameter, with value "asd"-->
<param name="string_with_same_value_as_above" value="'asd'"/>
<!--Another string parameter, with value "'asd'"-->
<param name="quoted_string" value="\'asd\'"/>
<!--A list of strings, with value ["asd", "bsd", "csd"]-->
<param name="list_of_strings" value="asd, bsd, csd" value-sep=", "/>
<!--A list of ints, with value [1, 2, 3]-->
<param name="list_of_ints" value="1,2,3" value-sep=","/>
<!--Another list of strings, with value ["1", "2", "3"]-->
<param name="another_list_of_strings" value="'1';'2';'3'" value-sep=";"/>
<!--A list of strings using an strange separator, with value ["1", "2", "3"]-->
<param name="strange_separator" value="'1'//'2'//'3'" value-sep="//"/>
</node>
参数分组
在 ROS 2 中,param
标签允许嵌套。
例如:
<node pkg="my_package" exec="my_executable" name="my_node" ns="/an_absoulute_ns">
<param name="group1">
<param name="group2">
<param name="my_param" value="1"/>
</param>
<param name="another_param" value="2"/>
</param>
</node>
这将创建两个参数:
值为“1”的“group1.group2.my_param”,由节点“/an_absolute_ns/my_node”托管。
值为“2”的“group1.another_param”,由节点“/an_absolute_ns/my_node”托管。
也可以使用完整的参数名称:
<node pkg="my_package" exec="my_executable" name="my_node" ns="/an_absoulute_ns">
<param name="group1.group2.my_param" value="1"/>
<param name="group1.another_param" value="2"/>
</node>
rosparam
Loads parameters from a yaml file.
It has been replaced with a
from
attribute inparam
tags.
例子
<node pkg="my_package" exec="my_executable" name="my_node" ns="/an_absoulute_ns">
<param from="/path/to/file"/>
</node>
remap
用于将重映射规则传递给节点。
它只能在
node
标签内使用。
Example
<launch>
<node pkg="demo_nodes_cpp" exec="talker">
<remap from="chatter" to="my_topic"/>
</node>
<node pkg="demo_nodes_cpp" exec="listener">
<remap from="chatter" to="my_topic"/>
</node>
</launch>
include
`在 ROS 1 <https://wiki.ros.org/roslaunch/XML/include> 中可用`__。
允许包含另一个启动文件。
与 ROS 1 的区别:
在 ROS 1 中可用,包含的内容是有范围的。
在 ROS 2 中,不是。 在
group
标签中嵌套包含以限定其范围。 * 不支持ns
属性。 有关解决方法,请参阅push_ros_namespace
标签示例。 * 嵌套在include
标签中的arg
标签不支持条件 (if
,unless
) 或description
属性。 * 不支持嵌套的env
标签。 可以使用set_env
和unset_env
代替。 * 不支持clear_params
和pass_all_args
属性。
例子
arg
arg
is used for declaring a launch argument, or to pass an argument when usinginclude
tags.Differences from ROS 1:
value
attribute is not allowed. Uselet
tag for this.doc
is nowdescription
.When nested within an
include
tag,if
,unless
, anddescription
attributes aren’t allowed.
例子
<launch>
<arg name="topic_name" default="chatter"/>
<node pkg="demo_nodes_cpp" exec="talker">
<remap from="chatter" to="$(var topic_name)"/>
</node>
<node pkg="demo_nodes_cpp" exec="listener">
<remap from="chatter" to="$(var topic_name)"/>
</node>
</launch>
将参数传递给启动文件
在上面的 XML 启动文件中,“topic_name”默认为名称“chatter”,但可以在命令行上进行配置。 假设上述启动配置位于名为“mylaunch.xml”的文件中,可以通过以下方式启动它来使用不同的主题名称:
ros2 launch mylaunch.xml topic_name:=custom_topic_name
在:doc:使用替换 中有一些关于传递命令行参数的附加信息。
env
设置环境变量。
它已被
env
、set_env
和unset_env
取代:env
只能嵌套在node
或executable
标签中使用。
不支持 if
和 unless
标签。
* set_env
可以嵌套在根标签 launch
或 group
标签中。
它接受与 env
相同的属性,也接受 if
和 unless
标签。
* unset_env
取消设置环境变量。
它接受 name
属性和条件。
例子
<launch>
<set_env name="MY_ENV_VAR" value="MY_VALUE" if="CONDITION_A"/>
<set_env name="ANOTHER_ENV_VAR" value="ANOTHER_VALUE" unless="CONDITION_B"/>
<set_env name="SOME_ENV_VAR" value="SOME_VALUE"/>
<node pkg="MY_PACKAGE" exec="MY_EXECUTABLE" name="MY_NODE">
<env name="NODE_ENV_VAR" value="SOME_VALUE"/>
</node>
<unset_env name="MY_ENV_VAR" if="CONDITION_A"/>
<node pkg="ANOTHER_PACKAGE" exec="ANOTHER_EXECUTABLE" name="ANOTHER_NODE"/>
<unset_env name="ANOTHER_ENV_VAR" unless="CONDITION_B"/>
<unset_env name="SOME_ENV_VAR"/>
</launch>
group
通常与 let
、include
和 push_ros_namespace
标签一起使用。
* 与 ROS 1 的区别:
没有
ns
属性。
请参阅新的 push_ros_namespace
标签作为解决方法。
* clear_params
属性不可用。
* 它不接受 remap
或 param
标签作为子标签。
例子
launch-prefix
配置会影响 executable
和 node
标签的操作。
如果 use_time_prefix_in_talker
参数为 1
,此示例将使用 time
作为前缀,仅适用于 talker。
<launch>
<arg name="use_time_prefix_in_talker" default="0"/>
<group>
<let name="launch-prefix" value="time" if="$(var use_time_prefix_in_talker)"/>
<node pkg="demo_nodes_cpp" exec="talker"/>
</group>
<node pkg="demo_nodes_cpp" exec="listener"/>
</launch>
机器
目前不支持。
测试
目前不支持。
ROS 2 中的新标签
set_env 和 unset_env
参见 env 标签描述。
push_ros_namespace
include
和 group
标签不接受 ns
属性。
此操作可用作解决方法:
<!-Other tags-->
<group>
<push_ros_namespace namespace="my_ns"/>
<!--Nodes here are namespaced with "my_ns".-->
<!--If there is an include action here, its nodes will also be namespaced.-->
<push_ros_namespace namespace="another_ns"/>
<!--Nodes here are namespaced with "another_ns/my_ns".-->
<push_ros_namespace namespace="/absolute_ns"/>
<!--Nodes here are namespaced with "/absolute_ns".-->
<!--The following node receives an absolute namespace, so it will ignore the others previously pushed.-->
<!--The full path of the node will be /asd/my_node.-->
<node pkg="my_pkg" exec="my_executable" name="my_node" ns="/asd"/>
</group>
<!--Nodes outside the group action won't be namespaced.-->
<!-Other tags-->
let
它是用值属性替换“arg”标签。
<let name="foo" value="asd"/>
可执行文件
它允许运行任何可执行文件。
例子
<executable cmd="ls -las" cwd="/var/log" name="my_exec" launch-prefix="something" output="screen" shell="true">
<env name="LD_LIBRARY" value="/lib/some.so"/>
</executable>
替换包含标签
为了像在 ROS 1 中一样在 命名空间 下包含启动文件,必须将“include”标签嵌套在“group”标签中。
<group>
<include file="another_launch_file"/>
</group>
然后,不要使用“ns”属性,而是添加“push_ros_namespace”操作标签来指定命名空间:
<group>
<push_ros_namespace namespace="my_ns"/>
<include file="another_launch_file"/>
</group>
仅在指定命名空间时才需要在“group”标记下嵌套“include”标记
替换
有关 ROS 1 替换的文档可在“roslaunch XML wiki <https://wiki.ros.org/roslaunch/XML>”中找到。 替换语法没有改变,即它仍然遵循“$(substitution-name arg1 arg2 …)”模式。 但是,与 ROS 1 相比有一些变化:
env
和optenv
标签已被env
标签取代。
如果环境变量不存在,$(env <NAME>)
将失败。
$(env <NAME> '')
与 ROS 1 的 $(optenv <NAME>)
作用相同。
$(env <NAME> <DEFAULT>)
与 ROS 1 的 $(env <NAME> <DEFAULT>)
或 $(optenv <NAME> <DEFAULT>)
作用相同。
find
已被find-pkg-share
取代(替换已安装软件包的共享目录)。
或者,find-pkg-prefix
将返回已安装软件包的根目录。
有一个新的
exec-in-pkg
替换。
例如:“$(exec-in-pkg <package_name> <exec_name>)”。 * 有一个新的“find-exec”替换。 * “arg”已被“var”替换。 它查看用“arg”或“let”标签定义的配置。 * “eval”和“dirname”替换需要字符串值的转义字符,例如“if=”$(eval ‘'$(var variable)' == 'val1'’)””。 * 不支持“anon”替换。
类型推断规则
“param”标签的“类型推断规则”小节中显示的规则适用于任何属性。 例如:
<!--Setting a string value to an attribute expecting an int will raise an error.-->
<tag1 attr-expecting-an-int="'1'"/>
<!--Correct version.-->
<tag1 attr-expecting-an-int="1"/>
<!--Setting an integer in an attribute expecting a string will raise an error.-->
<tag2 attr-expecting-a-str="1"/>
<!--Correct version.-->
<tag2 attr-expecting-a-str="'1'"/>
<!--Setting a list of strings in an attribute expecting a string will raise an error.-->
<tag3 attr-expecting-a-str="asd, bsd" str-attr-sep=", "/>
<!--Correct version.-->
<tag3 attr-expecting-a-str="don't use a separator"/>
某些属性接受多种类型,例如“param”标签的“value”属性。 通常,类型为“int”(或“float”)的参数也接受“str”,稍后将由操作替换并尝试将其转换为“int”(或“float”)。