Robotics StackExchange | Archived questions

Can DeclareLaunchArgument accept dictionaries?

Problem (TL;DR)

ROS2 uses the DeclareLaunchArgument object to create launch parameters that can be overwritten by command line or an including launch file. I know you can use this with parameters that are strings (incl filepaths), bools, integers and floats. But I want to know if it is possible to input dictionaries as well. I haven't yet found a way to do this, and I'm not sure if it's possible.

Problem (in full)

Problem described as above. So far I've tried in ROS2 Foxy, and I haven't yet found anything that would lead me to believe this is explicitly possible in Galactic. The example I'm working with looks something like this:

// In including_launch.py
launch_description = IncludeLaunchDescription(
    PythonLaunchDescriptionSource(["~/some_package/launch/included_launch.py"]),
    launch_arguments={
        params={'num' : 1234, 'bool' : true, 'str' : "hello" },
    }
)

// In included_launch.py
params = LaunchConfiguration('params')  
params_declare = DeclareLaunchArgument('params', default_value={})

node1 = Node(
    package="some_package",
    ...
    parameters=[params]
    ...
)

If I try this example as-is, I get the following warning:

[WARNING] [launch_ros.actions.node]: Parameter file path is not a file: numboolstr

If I try turning the dictionary into a string inside the IncludeLaunchDescription call, the dictionary doesn't get mangled, but DeclareLaunchArgument still doesn't like it:

[WARNING] [launch_ros.actions.node]: Parameter file path is not a file: {'num' : 1234, 'bool' : true, 'str' : "hello" }

I've been reading through examples and source code to see if this can be achieved, but so far haven't found anything that works.

Asked by M@t on 2021-08-23 19:21:08 UTC

Comments

Answers

Looking at the DeclareLaunchArgument constructor: no, it cannot accept dictionaries.

It looks like your intent is to provide a map of argument names (key) and default values (value). If so, may I suggest maintaining a collection of DeclareLaunchArgument actions? That way, you could do:

launch_args = [DeclareLaunchArgument(name, default_value=default_value) for name, default_value in params.items()]

Then, as required, you could do a map(launch_args, LaunchDescription.add_action) - which would add each of your DeclareLaunchArgument actions to the LaunchDescription you are instantiating.

Asked by aprotyas on 2021-08-24 03:26:07 UTC

Comments

Interesting suggestion, but I'm unclear on some of the implementation details - what would that look like as an example similar to the one in my question?

Asked by M@t on 2021-08-24 18:15:00 UTC

Sorry, my suggestion was a bit unclear. I mean something like this:

Instead of the line where you use params_declare = DeclareLaunchArgument('params', default_value={}) , just replace it with launch_args = [DeclareLaunchArgument(name, default_value=default_value) for name, default_value in params.items()]. Also, for the LaunchDescription you generate, you can add the DeclareLaunchArgument actions by performing a map procedure on launch_args (the collection of DeclareLaunchArguments): this can be achieved using map(launch_args, ld.add_action), where ld is the LaunchDescription you initialized beforehand.

Asked by aprotyas on 2021-08-24 18:29:31 UTC

In the launch_ros repo examples there is the following example which I think achieves what you are looking for.

def generate_launch_description():
    """Launch the example.launch.py launch file."""
    return LaunchDescription([
        LogInfo(msg=[
            'Including launch file located at: ', ThisLaunchFileDir(), '/example.launch.py'
        ]),
        IncludeLaunchDescription(
            PythonLaunchDescriptionSource([ThisLaunchFileDir(), '/example.launch.py']),
            launch_arguments={'node_prefix': 'FOO'}.items(),
        ),
    ])

Asked by msmcconnell on 2021-11-24 10:44:30 UTC

Comments