1
$\begingroup$

Rosanswers logo

The tldr is can you scope launch arguments in the python launch system when using IncludeLaunchDescription?

Assume we have a base python launch file (base_launch.py, referred to as base) that includes another python launch file (ext_launch.py, referred to as ext). The base has an argument arg1 that it may use and pass on to one or more included launch files. Ext also has an argument of the same name. I print the base argument, include ext which also print its argument, and then again print the argument in base. The output from this shows that changes to the arguments value in ext also changes the arguments value in base.

Is there any way to not overwrite arguments of the same name (i.e. assign arguments with scope)? Or is there a different design pattern that should be followed?

base_launch.py

#!/usr/bin/env python3
from launch import LaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.actions import DeclareLaunchArgument, LogInfo, IncludeLaunchDescription
from launch.substitutions import LaunchConfiguration, ThisLaunchFileDir

def generate_launch_description():
  arg1 = LaunchConfiguration('arg1')

  return LaunchDescription([
    DeclareLaunchArgument(
      'arg1',
      default_value='Internal_Arg',
      description='Argument'
    ),

    LogInfo(msg=['Internal Arg (before): ', arg1]),

    IncludeLaunchDescription(
      PythonLaunchDescriptionSource([ThisLaunchFileDir(),'/ext_launch.py']),
      launch_arguments={
        'arg1': 'External_Arg_Mod'
      }.items()
    ),

    LogInfo(msg=['Internal Arg (after): ', arg1]),

  ])

ext_launch.py

#!/usr/bin/env python3

from launch import LaunchDescription
from launch.actions import LogInfo, DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration

def generate_launch_description():
  arg1 = LaunchConfiguration('arg1')

  return LaunchDescription([
    DeclareLaunchArgument(
      'arg1',
      default_value='External_Arg',
      description='Argument'
    ),

    LogInfo(msg=['External Arg: ', arg1])
  ])

Output:

[INFO] [launch.user]: Internal Arg (before): Internal_Arg
[INFO] [launch.user]: External Arg: External_Arg_Mod
[INFO] [launch.user]: Internal Arg (after): External_Arg_Mod

Originally posted by djchopp on ROS Answers with karma: 328 on 2021-05-05

Post score: 0

$\endgroup$

1 Answer 1

1
$\begingroup$

Rosanswers logo

You can use the GroupAction action. From its docstring:

Action that yields other actions, optionally scoping launch configurations.

This action is used to nest other actions without including a separate launch description, while also optionally having a condition (like all other actions), scoping launch configurations, and/or declaring launch configurations for just the group and its yielded actions.

You can wrap the inclusion of ext in a group action to achieve the scoping you want:

GroupAction([
    IncludeLaunchDescription(
        PythonLaunchDescriptionSource([ThisLaunchFileDir(),'/ext_launch.py']),
        launch_arguments={
            'arg1': 'External_Arg_Mod'
        }.items()
    )
]),

With that, running ros2 launch launch_test base_launch.py gives:

[INFO] [launch.user]: Internal Arg (before): Internal_Arg
[INFO] [launch.user]: External Arg: External_Arg_Mod
[INFO] [launch.user]: Internal Arg (after): Internal_Arg

Internally the scoping works by using the PushLaunchConfigurations and PopLaunchConfigurations actions:

        if self.__scoped:
            self.__actions_to_return = [
                PushLaunchConfigurations(),
                *self.__actions_to_return,
                PopLaunchConfigurations()
            ]

So you may also be able to surround the include with those in your own launch file if you feel that using GroupAction around a single action is less nice.


Originally posted by sgvandijk with karma: 649 on 2021-05-07

This answer was ACCEPTED on the original site

Post score: 2

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.