Ask Your Question
0

Is it possible to have a conditional in a launch file using DeclareLaunchArgument

asked 2021-07-09 15:22:26 -0500

marshallpt gravatar image

updated 2021-07-12 09:35:13 -0500

I have a setup of hierarchical launch files, and I would like to use a launch argument to determine whether or not certain launch actions in them run. I already have a launch argument working via DeclareLaunchArgument that determines the namespace the node launches in, and I was hoping I could use another launch argument to run a simple if statement before adding an action to my launch description, launch_me.

The code below shows my attempt to implement this, but it does not work.

def generate_launch_description():
bridge_topics = join(get_package_share_directory('piracer'),
                     'config', 'ackermann_bridge_topics.yaml')
launch_directory = get_package_share_directory('piracer')

launch_me = LaunchDescription()

car_name_arg = DeclareLaunchArgument('car_name', default_value='car1',
                                    description='Sets the namespace for this car.')

hardware_arg = DeclareLaunchArgument('should_launch_hardware', default_value='true',
                                    description='Determines if hardware_nodes.launch is called.')

hardware_launch = IncludeLaunchDescription(
    PythonLaunchDescriptionSource([launch_directory, '/hardware_nodes.launch.py']),
    launch_arguments={'car_name': LaunchConfiguration('car_name')}.items()
)
ackermann_node = Node(
    package='piracer',
    namespace=[LaunchConfiguration('car_name')],
    executable='ackermann_controller',
    name='ackermann_controller',
    parameters=[bridge_topics]
)
launch_me.add_action(car_name_arg)
launch_me.add_action(hardware_arg)
if LaunchConfiguration('should_launch_hardware') == 'true':
    launch_me.add_action(hardware_launch)
launch_me.add_action(ackermann_node)

return launch_me

Is it possible to use a launch argument as a conditional in a launch file?


EDIT: Solved thanks to djchopp! To properly add the conditional, I had to do four things:

  1. Add an import statement for IfCondition
  2. Add a launch configuration, which I called should_launch_hardware.
  3. Add the condition to the hardware_launch launch action.
  4. Remove the useless if-statement around adding the hardware_launch action to launch_me. It will be added every time, but using the condition should_launch_hardware, ROS will decide if it actually gets executed or not.

A summary of the additions I made to the code are shown below:

from launch.conditions import IfCondition #1
....
should_launch_hardware = LaunchConfiguration('should_launch_hardware') #2
....
hardware_launch = IncludeLaunchDescription(
        PythonLaunchDescriptionSource([launch_directory, '/hardware_nodes.launch.py']),
        launch_arguments={'car_name': LaunchConfiguration('car_name')}.items(),
        condition=IfCondition(should_launch_hardware)   #3
    )

The entire new launch file looks like this:

# Standard library imports
from os.path import join

# Third-party imports
from ament_index_python.packages import get_package_share_directory
from launch_ros.actions import Node
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.actions import IncludeLaunchDescription
from launch.conditions import IfCondition #1
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration


def generate_launch_description():
    bridge_topics = join(get_package_share_directory('piracer'),
                         'config', 'ackermann_bridge_topics.yaml')
    launch_directory = get_package_share_directory('piracer')

    should_launch_hardware = LaunchConfiguration('should_launch_hardware')  #2

    launch_me = LaunchDescription()

    car_name_arg = DeclareLaunchArgument('car_name', default_value='car1',
                                         description='Sets the namespace for this car.')

    hardware_arg = DeclareLaunchArgument('should_launch_hardware', default_value='true',
                                         description='Determines if hardware_nodes.launch is called.')

    hardware_launch = IncludeLaunchDescription(
        PythonLaunchDescriptionSource([launch_directory, '/hardware_nodes.launch.py']),
        launch_arguments={'car_name': LaunchConfiguration('car_name')}.items(),
        condition=IfCondition(should_launch_hardware) #3
    )
    ackermann_node = Node(
        package='piracer',
        namespace=[LaunchConfiguration('car_name')],
        executable='ackermann_controller',
        name='ackermann_controller',
        parameters=[bridge_topics]
    )
    launch_me.add_action(car_name_arg)
    launch_me.add_action(hardware_arg)
    launch_me.add_action(hardware_launch) #4
    launch_me.add_action(ackermann_node)

    return launch_me
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2021-07-12 07:45:26 -0500

djchopp gravatar image

Long answer short, yes it supports conditionals but you have to use the dedicated conditional functionality and not plain python. See this answer I recently wrote that describes how to do what you are asking.

You can see the currently supported conditions in the source code

At time of writing you can use: IfCondition, UnlessCondition, LaunchConfigurationEquals, LaunchConfigurationNotEquals

The IfCondition and UnlessCondition follow these rules:

A string will be considered True if it matches 'true' or '1'.
A string will be considered False if it matches 'false' or '0'.
Any other string content (including empty string) will result in an error.

You can use LaunchConfigurationEquals, LaunchConfigurationNotEquals to cover cases where the launch configuration does not follow the rules above.

Hope this helps!

edit flag offensive delete link more

Comments

This was exactly what I needed! Thank you!

I fully agree with your assessment that ROS2 launch is good, just lacking in documentation. I had no idea the launch.conditions library existed!

marshallpt gravatar image marshallpt  ( 2021-07-12 09:12:44 -0500 )edit

For anyone looking for how to use LaunchConfigurationEquals or LaunchConfigurationNotEquals, I used this question and read the docstring in this bit of the source code. The folder containing that file has all 4 currently available conditions.

marshallpt gravatar image marshallpt  ( 2021-07-27 15:01:17 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 2021-07-09 15:22:26 -0500

Seen: 526 times

Last updated: Jul 12 '21