Is it possible to have a conditional in a launch file using DeclareLaunchArgument
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:
- Add an import statement for
IfCondition
- Add a launch configuration, which I called
should_launch_hardware
. - Add the condition to the
hardware_launch
launch action. - Remove the useless if-statement around adding the
hardware_launch
action tolaunch_me
. It will be added every time, but using the conditionshould_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