Migrating Launch Files
While launch files in ROS 1 are always specified using .xml files, ROS 2 supports Python scripts to enable more flexibility (see launch package) as well as XML and YAML files.
This guide describes how to write ROS 2 XML launch files for an easy migration from ROS 1.
Background
A description of the ROS 2 launch system and its Python API can be found in Launch System tutorial.
Replacing an include tag
In order to include a launch file under a namespace as in ROS 1 then the include
tags must be nested in a group
tag.
<group>
<include file="another_launch_file"/>
</group>
Then, instead of using the ns
attribute, add the push_ros_namespace
action tag to specify the namespace:
<group>
<push_ros_namespace namespace="my_ns"/>
<include file="another_launch_file"/>
</group>
Nesting include
tags under a group
tag is only required when specifying a namespace
Substitutions
Documentation about ROS 1’s substitutions can be found in roslaunch XML wiki.
Substitutions syntax hasn’t changed, i.e. it still follows the $(substitution-name arg1 arg2 ...)
pattern.
There are, however, some changes w.r.t. ROS 1:
env
andoptenv
tags have been replaced by theenv
tag.$(env <NAME>)
will fail if the environment variable doesn’t exist.$(env <NAME> '')
does the same as ROS 1’s$(optenv <NAME>)
.$(env <NAME> <DEFAULT>)
does the same as ROS 1’s$(env <NAME> <DEFAULT>)
or$(optenv <NAME> <DEFAULT>)
.find
has been replaced withfind-pkg-share
(substituting the share directory of an installed package). Alternativelyfind-pkg-prefix
will return the root of an installed package.There is a new
exec-in-pkg
substitution. e.g.:$(exec-in-pkg <package_name> <exec_name>)
.There is a new
find-exec
substitution.arg
has been replaced withvar
. It looks at configurations defined either witharg
orlet
tag.eval
anddirname
substitutions require escape characters for string values, e.g.if="$(eval '\'$(var variable)\' == \'val1\'')"
.anon
substitution is not supported.
Type inference rules
The rules that were shown in Type inference rules
subsection of param
tag applies to any attribute.
For example:
<!--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"/>
Some attributes accept more than a single type, for example value
attribute of param
tag.
It’s usual that parameters that are of type int
(or float
) also accept an str
, that will be later substituted and tried to convert to an int
(or float
) by the action.