迁移启动文件
虽然在ROS 1中,启动文件总是使用 .xml 文件指定的,但ROS 2支持使用Python脚本以提供更大的灵活性(参见 launch 包 ),同时还支持XML和YAML文件。
本指南描述了如何编写ROS 2 XML启动文件,以便轻松从ROS 1迁移。
迁移标签
节点
启动一个新的节点。
与ROS 1的不同之处:
type
属性现在为exec
。ns
属性现在为namespace
。以下属性不可用:
machine
,respawn_delay
,clear_params
。
示例
<launch>
<node pkg="demo_nodes_cpp" exec="talker"/>
<node pkg="demo_nodes_cpp" exec="listener"/>
</launch>
param
用于将参数传递给节点。
在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``托管。
节点
/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
在 ROS 1 中可用 <https://wiki.ros.org/roslaunch/XML/rosparam>`__。
从yaml文件中加载参数。
已被``param``标签中的``from``属性替代。
示例
<node pkg="my_package" exec="my_executable" name="my_node" ns="/an_absoulute_ns">
<param from="/path/to/file"/>
</node>
remap
用于将重新映射规则传递给节点。
它只能在``node``标签内使用。
示例
<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 2中,它没有作用域。使用``group``标签来嵌套包含文件以进行作用域控制。
不支持``ns``属性。参考``push_ros_namespace``标签的示例以获取解决方法。
在
include
标签中嵌套的arg
标签不支持条件(if
、unless
)或description
属性。不支持嵌套``env``标签。可以使用``set_env``和``unset_env``代替。
不支持``clear_params``和``pass_all_args``属性。
示例
请参阅`替换 include 标签`_。
arg
arg
用于声明一个启动参数,或者在使用include
标签时传递参数。与ROS 1的不同之处:
不允许使用
value
属性。请使用let
标签代替。现在,
doc
变为description
。在
include
标签内嵌套时,不允许使用if
、unless
和description
属性。
示例
<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>
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>
组
允许限制启动配置的范围。通常与``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>
machine
目前不支持。
测试
目前不支持。
ROS 2中的新标签
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-->
替换了`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相比,有一些变化:
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``标签的``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)``。