ros2 / launch

Tools for launching multiple processes and for writing tests involving multiple processes.
Apache License 2.0
124 stars 139 forks source link

XML launch `<include>` can pass implicit arguments #689

Open VRichardJP opened 1 year ago

VRichardJP commented 1 year ago

The ROS2 launch XML format documentation (http://design.ros2.org/articles/roslaunch_xml.html) states that:

<arg> Tag The tag allows for launch file configuration via the command-line or when including it via an tag. Arguments are launch configuration variables just like the ones defined by tags. Arguments are limited to the scope of their definition and thus have to be explictly passed to included files if any.

If I understand the documentation correctly, if a launch file includes another with the <include> tag, the <arg> parameters are not passed to the other launch file implicitly.

So for example, with these 2 files:

<!-- parent.launch.xml -->
<launch>
  <arg name="foo" default="there!"/>
  <include file="child.launch.xml"/>
</launch>
<!-- child.launch.xml -->
<launch>
  <arg name="foo"/>
  <executable cmd="echo Hello $(var foo)" output="screen" shell="true" />
</launch>

We get an error if we try to launch the parent.launch.xml, because foo is not set for the included file:

$ ros2 launch parent.launch.xml
[INFO] [launch]: All log files can be found below /home/sig/.ros/log/2023-01-20-01-08-28-929056-vr-desktop-1016
[INFO] [launch]: Default logging verbosity is set to INFO
[ERROR] [launch]: Caught exception in launch (see debug for traceback): Included launch description missing required argument 'foo' (description: 'no description given'), given: []

So far so good.

However, if we change the child launch file to:

<!-- child.launch.xml -->
<launch>
  <!-- <arg name="foo"/> -->
  <executable cmd="echo Hello $(var foo)" output="screen" shell="true" />
</launch>

Then, not only no error occurs, but the argument is passed to the child launch file:

$ ros2 launch parent.launch.xml
[INFO] [launch]: All log files can be found below /home/sig/.ros/log/2023-01-20-01-08-16-842624-vr-desktop-961
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [echo-1]: process started with pid [972]
[INFO] [echo-1]: process has finished cleanly [pid 972]
[echo-1] Hello there!

Is it a bug? an undocumented feature?

Bug report

Required Info:

Run ros2 launch parent.launch.xml with:

<!-- parent.launch.xml -->
<launch>
  <arg name="foo" default="there!"/>
  <include file="child.launch.xml"/>
</launch>
<!-- child.launch.xml -->
<launch>
  <!-- <arg name="foo"/> -->
  <executable cmd="echo Hello $(var foo)" output="screen" shell="true" />
</launch>

Expected behavior

Error because foo is undefined?

Actual behavior

The command outputs [echo-1] Hello there!, so not only foo is defined, but it is also passed implicitely from the parent file.

Additional information

xperroni commented 11 months ago

I have found a variation of this problem: if the included launch file specifies a default for the argument, it gets overwritten even if the argument is not being explicitly passed along. Building on the above example, if we had:

<!-- parent.launch.xml -->
<launch>
  <arg name="foo" default="there!"/>
  <include file="child.launch.xml"/>
</launch>
<!-- child.launch.xml -->
<launch>
  <arg name="foo" default="elsewhere!"/>
  <executable cmd="echo Hello $(var foo)" output="screen" shell="true" />
</launch>

The output would still be [echo-1] Hello there!, even though you'd expect it to be [echo-1] Hello elsewhere!.

I believe this is a subtle side-effect of <include> being not-scoped, that is, it's expected to work as if the contents of the included file were copy-pasted into the including file. Apparently the first <arg> tag in the file takes precedence over any subsequent re-definitions of a given argument, instead of being overwritten by them.

However, even fixing this precedence order still wouldn't fix the implicit argument passing issue — without scoping, the argument that was undefined in the included file will be defined by the time it's reached during the processing of the including file.