ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
2

ros2 optionally launch node with no arguments

asked 2019-02-06 15:28:45 -0500

Pete B gravatar image

updated 2019-02-06 16:02:51 -0500

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

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
3

answered 2019-02-06 15:57:56 -0500

William gravatar image

updated 2019-02-06 15:59:17 -0500

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())]
    ),
])
edit flag offensive delete link more

Comments

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[]

mogumbo gravatar image mogumbo  ( 2019-07-16 11:25:32 -0500 )edit

I'm interested in this too. I've opened an issue on ros2/launch. https://github.com/ros2/launch/issues...

newellr gravatar image newellr  ( 2019-07-26 12:03:24 -0500 )edit

Question Tools

5 followers

Stats

Asked: 2019-02-06 15:28:45 -0500

Seen: 2,992 times

Last updated: Feb 06 '19