迁移启动文件

虽然 ROS 1 中的启动文件始终使用 .xml 文件指定,但 ROS 2 支持 Python 脚本以实现更大的灵活性(请参阅 launch package)以及 XML 和 YAML 文件。

本指南介绍如何编写 ROS 2 XML 启动文件以便从 ROS 1 轻松迁移。

背景

ROS 2 启动系统及其 Python API 的描述可在 启动系统教程 中找到。

迁移标签

launch

节点

  • Available in ROS 1.

  • Launches a new node.

  • Differences from ROS 1:

    • type attribute is now exec.

    • ns attribute is now namespace.

    • 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>

参数

因此,它只能嵌套在 node 标签中使用。 ROS 2 不支持某些属性:typetextfilebinfileexecutable。 * 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

  • Available in ROS 1.

  • Loads parameters from a yaml file.

  • It has been replaced with a from attribute in param tags.

例子

<node pkg="my_package" exec="my_executable" name="my_node" ns="/an_absoulute_ns">
   <param from="/path/to/file"/>
</node>

remap

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_envunset_env 代替。 * 不支持 clear_paramspass_all_args 属性。

例子

See `Replacing an include tag`_.

arg

  • Available in ROS 1.

  • arg is used for declaring a launch argument, or to pass an argument when using include tags.

  • Differences from ROS 1:

    • value attribute is not allowed. Use let tag for this.

    • doc is now description.

    • When nested within an include tag, if, unless, and description 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

不支持 ifunless 标签。 * set_env 可以嵌套在根标签 launchgroup 标签中。 它接受与 env 相同的属性,也接受 ifunless 标签。 * 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

通常与 letincludepush_ros_namespace 标签一起使用。 * 与 ROS 1 的区别:

  • 没有 ns 属性。

请参阅新的 push_ros_namespace 标签作为解决方法。 * clear_params 属性不可用。 * 它不接受 remapparam 标签作为子标签。

例子

launch-prefix 配置会影响 executablenode 标签的操作。 如果 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

includegroup 标签不接受 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 相比有一些变化:

  • envoptenv 标签已被 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”)。