0
$\begingroup$

Rosanswers logo

I have a node that takes zero or one argument. I want to use ros2 launch arguments to pass either zero or one argument to the the launch file which will then get passed down to the node. I'm having a bit of trouble with the 'zero' argument case.

LaunchDescription([
    launch.actions.DeclareLaunchArgument(
        "my_param",
        default_value=[""],  # default_value=[], has the same problem
        description="optional parameter"
    ),
    launch_ros.actions.Node(
        package="my_package",
        node_executable="my_node",
        arguments=[launch.substitutions.LaunchConfiguration("my_param")]
    ),
])

When I do this, I can run my launch file with my_param:=foo and foo will get passed down to my node. No problem

When I run my launch file without any arguments, my_node still behaves like it got a positional argument - a single empty string. This is not how I intended to launch the node.

What do I need to do to make my_node behave like it got no arguments when I don't pass any arguments to launch?

The current behavior makes sense - the LaunchConfiguration substitution is getting resolved to an empty string and is getting put into the node's arguments array. What I need is a way to substitute the whole 'arguments' list passed to the node instead of substituting a single element in the list, but the Node object really wants a list of substitutions


Originally posted by Pete B on ROS Answers with karma: 43 on 2019-02-06

Post score: 2

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

There's no way to do this (conditionally include a substitution in a list) right now.

You could do something like this:

LaunchDescription([
    launch.actions.DeclareLaunchArgument(
        "my_param",
        default_value=[""],  # default_value=[], has the same problem
        description="optional parameter"
    ),
    launch_ros.actions.Node(
        package="my_package",
        node_executable="my_node",
        arguments=[launch.substitutions.LaunchConfiguration("my_param")],
        condition=launch.conditions.IfCondition(launch.substitutions.LaunchConfiguration("my_param")),
    ),
    launch_ros.actions.Node(
        package="my_package",
        node_executable="my_node",
        arguments=[],
        condition=launch.conditions.UnlessCondition(launch.substitutions.LaunchConfiguration("my_param")),
    ),
])

Which is obviously silly, but it's the only way to express it at the moment.

As a long term solution, I think we either need conditional Substitutions, where maybe they return None if the condition is false, and code that processes lists of substitutions would ignore (just drop) any substitutions that return None, or some way to process lists of substitutions conditionally (not sure how that would work off hand).

Then you'd be able to do something like this:

LaunchDescription([
    launch.actions.DeclareLaunchArgument(
        "my_param",
        default_value=[""],  # default_value=[], has the same problem
        description="optional parameter"
    ),
    launch_ros.actions.Node(
        package="my_package",
        node_executable="my_node",
        arguments=[launch.substitutions.LaunchConfiguration("my_param", condition=launch.conditions.IfCondition(launch.substitutions.LaunchConfiguration("my_param"))]
    ),
])

Or some short hand for self-evaluating the substitution, e.g.:

LaunchDescription([
    launch.actions.DeclareLaunchArgument(
        "my_param",
        default_value=[""],  # default_value=[], has the same problem
        description="optional parameter"
    ),
    launch_ros.actions.Node(
        package="my_package",
        node_executable="my_node",
        arguments=[launch.substitutions.LaunchConfiguration("my_param", condition=launch.conditions.UnlessEmpty())]
    ),
])

Originally posted by William with karma: 17335 on 2019-02-06

This answer was ACCEPTED on the original site

Post score: 3


Original comments

Comment by mogumbo on 2019-07-16:
Has there been any progress on this? I think I'm having the same problem. I have

gzserver = launch.actions.ExecuteProcess(
cmd=['gzserver', '--verbose', '-s', 'libgazebo_ros_init.so',
  LaunchConfiguration('command_arg1'),
  LaunchConfiguration('world_name')],
output='screen'
)

LaunchConfiguration('command_arg1' sometimes evaluates to '' and my launch script fails with [gzserver-1] [Err] [Server.cc:382] Could not open file[]

Comment by newellr on 2019-07-26:
I'm interested in this too. I've opened an issue on ros2/launch. https://github.com/ros2/launch/issues/290

$\endgroup$

Your Answer

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