迁移启动文件

虽然在ROS 1中,启动文件总是使用 .xml 文件指定的,但ROS 2支持使用Python脚本以提供更大的灵活性(参见 launch 包 ),同时还支持XML和YAML文件。

本指南描述了如何编写ROS 2 XML启动文件,以便轻松从ROS 1迁移。

背景

关于ROS 2启动系统及其Python API的详细信息,请参阅 启动系统教程

迁移标签

启动

节点

  • 在ROS 1中可用

  • 启动一个新的节点。

  • 与ROS 1的不同之处:

    • type 属性现在为 exec

    • ns 属性现在为 namespace

    • 以下属性不可用:machinerespawn_delayclear_params

示例

<launch>
   <node pkg="demo_nodes_cpp" exec="talker"/>
   <node pkg="demo_nodes_cpp" exec="listener"/>
</launch>

param

  • 在 ROS 1 中可用.

  • 用于将参数传递给节点。

  • 在ROS 2中没有全局参数的概念。因此,它只能在 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``托管。

  • 节点 /an_absolute_ns/my_node 托管的 group1.another_param 的值为 2

也可以使用完整的参数名称:

<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

示例

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

remap

示例

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

包括

  • 在ROS 1中可用

  • 允许包含另一个启动文件。

  • 与ROS 1的不同之处:

    • 在ROS 1中可用,所包含的内容是有作用域的。在ROS 2中,它没有作用域。使用``group``标签来嵌套包含文件以进行作用域控制。

    • 不支持``ns``属性。参考``push_ros_namespace``标签的示例以获取解决方法。

    • include 标签中嵌套的 arg 标签不支持条件(ifunless)或 description 属性。

    • 不支持嵌套``env``标签。可以使用``set_env``和``unset_env``代替。

    • 不支持``clear_params``和``pass_all_args``属性。

示例

请参阅`替换 include 标签`_。

arg

  • 在ROS 1中可用

  • arg 用于声明一个启动参数,或者在使用 include 标签时传递参数。

  • 与ROS 1的不同之处:

    • 不允许使用 value 属性。请使用 let 标签代替。

    • 现在,doc 变为 description

    • include 标签内嵌套时,不允许使用 ifunlessdescription 属性。

示例

<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

有关如何传递命令行参数的其他信息,请参阅 使用替换

env

  • 在 ROS 1 中可用

  • 设置环境变量。

  • 已被替换为 envset_envunset_env

    • env 只能嵌套在 nodeexecutable 标签中。不支持 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>

  • 在ROS 1中可用

  • 允许限制启动配置的范围。通常与``let``、``include``和``push_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>

machine

目前不支持。

测试

目前不支持。

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

使用`value`属性替代了``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>

替换了`include`标签

为了在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>

只有在指定命名空间时才需要将``include``标签嵌套在``group``标签下。

替换

关于ROS 1的替代方案的文档可以在 roslaunch XML wiki 中找到。替代语法没有改变,仍然遵循 $(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>) 功能相同。

  • findfind-pkg-share 替代(用于替代已安装包的共享目录)。或者,find-pkg-prefix 将返回已安装包的根目录。

  • 新增了一个 exec-in-pkg 替代。例如:$(exec-in-pkg <package_name> <exec_name>)

  • 有一个新的 find-exec 替代方式。

  • arg 已被替换为 var。它查看使用 arglet 标签定义的配置。

  • evaldirname 替换需要为字符串值使用转义字符,例如 if="$(eval '\'$(var variable)\' == \'val1\'')"

  • 不支持 anon 替代方式。

类型推断规则

在``param``标签的``Type inference rules``子节中显示的规则适用于任何属性。例如:

<!--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)``。