How do I use launch arguments in the 'arguments' keyword argument of Node in ROS2?

asked 2020-11-26 11:06:19 -0500

galou gravatar image

updated 2020-11-26 23:34:33 -0500

I am able to use a boolean launch argument in IfCondition/UnlessCondition used in the condition keyword argument of a Node or ExecuteProcess. How do I however use it outside of this context?

Here is a launch file that illustrates my question:

#!/usr/bin/env python3

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.actions import ExecuteProcess
from launch.conditions import IfCondition
from launch.conditions import UnlessCondition
from launch.launch_context import LaunchContext
from launch.substitutions import LaunchConfiguration


g_default_true = LaunchConfiguration('default_true', default=True)
g_default_false = LaunchConfiguration('default_false', default=False)


def generate_launch_description():
    context = LaunchContext()

    default_true = IfCondition(g_default_true).evaluate(context)
    default_false = IfCondition(g_default_false).evaluate(context)
    print('\033[1;35m%%%%% default_true outside condition: {}\033[0m'.format(default_true))
    print('\033[1;35m%%%%% default_false outside condition: {}\033[0m'.format(default_false))

    return LaunchDescription([
        DeclareLaunchArgument(
            name=g_default_true.variable_name[0].text,
            default_value=g_default_true),

        DeclareLaunchArgument(
            name=g_default_false.variable_name[0].text,
            default_value=g_default_false),

        ExecuteProcess(
            name='echo_default_true_with_cmd',
            cmd=['echo', '%%%%%', 'default_true_with_cmd: ', 'true' if default_true else 'false'],
            output='screen',
        ),

        ExecuteProcess(
            name='echo_default_false_with_cmd',
            cmd=['echo', '%%%%%', 'default_false_with_cmd: ', 'true' if default_false else 'false'],
            output='screen',
        ),

        ExecuteProcess(
            name='echo_default_true_with_ifcondition',
            cmd=['echo', '%%%%%', 'default_true_with_ifcondition: true'],
            condition=IfCondition(g_default_true),
            output='screen',
        ),

        ExecuteProcess(
            name='echo_default_true_with_unlesscondition',
            cmd=['echo', '%%%%%', 'default_true_with_unlesscondition: false'],
            condition=UnlessCondition(g_default_true),
            output='screen',
        ),

        ExecuteProcess(
            name='echo_default_false_with_ifcondition',
            cmd=['echo', '%%%%%', 'default_false_with_ifcondition: true'],
            condition=IfCondition(g_default_false),
            output='screen',
        ),

        ExecuteProcess(
            name='echo_default_false_with_unlesscondition',
            cmd=['echo', '%%%%%', 'default_false_with_unlesscondition: false'],
            condition=UnlessCondition(g_default_false),
            output='screen',
        ),
    ])

To test it, launch either with ros2 launch ./test.launch.py or ros2 launch ./test.launch.py default_true:=False default_false:=True. In both cases, it shows

%%%%% default_true outside condition: True
%%%%% default_false outside condition: False

How can I use the boolean in the launch file without writing two ExecuteProcess instances?

Thanks a lot, Gaël

edit retag flag offensive close merge delete

Comments

I noticed that the issue is maybe somewhere else because I cannot pass the no_default argument to the following launch file:

#!/usr/bin/env python3
# Try with `ros2 launch ./test2.launch.py no_default:=42`.

import sys

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.launch_context import LaunchContext
from launch.substitutions import LaunchConfiguration


g_no_default = LaunchConfiguration('no_default')


def generate_launch_description():
    context = LaunchContext(argv=sys.argv)

    dla_no_default = DeclareLaunchArgument(
        name=g_no_default.variable_name[0].text,
        description='Argument with no default value',
    )
    dla_no_default.visit(context)

    return LaunchDescription()
galou gravatar image galou  ( 2020-11-27 07:18:36 -0500 )edit

I manage to solve my second example with:

#!/usr/bin/env python3
# Try with `ros2 launch ./test2.launch.py no_default:=42`.

import sys

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.launch_context import LaunchContext
from launch.substitutions import LaunchConfiguration


g_no_default = LaunchConfiguration('no_default')


def generate_launch_description():
    context = LaunchContext(argv=sys.argv)

    dla_no_default = DeclareLaunchArgument(
        name=g_no_default.variable_name[0].text,
        description='Argument with no default value',
    )
    dla_no_default.visit(context)

    return LaunchDescription()

I can now pass the argument to the echo command but I still need to solve how to use it as a bool.

galou gravatar image galou  ( 2020-11-27 09:52:40 -0500 )edit

What also doesn't work is cmd=['echo', '%%%%%', 'default_true_with_cmd: ', 'true' if evaluate_condition_expression(context, [g_default_true]) else 'false'], Interestingly,cmd=['echo', '%%%%%', 'g_default_true: ', g_default_true],shows the correct output (I guess as astr) but comparingg_default_truetoTrueor to the string'True'` also doesn't work.

galou gravatar image galou  ( 2020-11-27 10:20:40 -0500 )edit