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

Revision history [back]

click to hide/show revision 1
initial version

From @AndyZe 's comment, I took inspiration from the way the UR package defines nodes within an OpaqueFunction. My desire was to pass launch arguments to help define file names assembled as strings for launching gazebo worlds. I convert the LaunchConfiguration object to a string of the value it held with context.perform_substitution, as shown in the first three lines of the launch_setup function:

from launch import LaunchDescription, conditions
from launch.substitutions import LaunchConfiguration, PathJoinSubstitution
from ament_index_python.packages import get_package_share_directory
from launch.actions import IncludeLaunchDescription, DeclareLaunchArgument, OpaqueFunction
from launch.launch_description_sources import AnyLaunchDescriptionSource, PythonLaunchDescriptionSource
import os


def launch_setup(context, *args, **kwargs):
    arg_robot_name = context.perform_substitution(LaunchConfiguration('robot_name'))
    arg_world_name = context.perform_substitution(LaunchConfiguration('world_name'))
    arg_simulated = context.perform_substitution(LaunchConfiguration('simulated'))



    launch_world = IncludeLaunchDescription(
        PythonLaunchDescriptionSource(
            os.path.join(get_package_share_directory(
                'ros_gz_sim'), 'launch/gz_sim.launch.py')
        ),
        launch_arguments={'gz_args': '-r {}'.format(arg_world_name)}.items()
    )

    launch_robot = IncludeLaunchDescription(
        AnyLaunchDescriptionSource(
            PathJoinSubstitution(
                [get_package_share_directory('my_gazebo'), 'launch', '{}_gazebo.launch.xml'.format(arg_robot_name)]
            )
        ),
        condition=conditions.IfCondition(LaunchConfiguration('spawn_robot')),
        launch_arguments={'simulated': '{}'.format(arg_simulated)}.items()
    )

    nodes_to_start = [launch_world, launch_robot]
    return nodes_to_start


def generate_launch_description():
    declared_arguments = []
    declared_arguments.append(
        DeclareLaunchArgument(name='simulated', default_value='true',
                                  description='if time is simulated')
    )
    declared_arguments.append(
        DeclareLaunchArgument(name='world_name', default_value='empty.sdf')        
    )
    declared_arguments.append(
            DeclareLaunchArgument(name='spawn_robot', default_value='true',
                                  description='if agent should be generated, set to false to spawn only world')        
    )
    declared_arguments.append(
            DeclareLaunchArgument(name='robot_name', default_value='my',
                                  description='robot name prefix used to call specific launch file; used with spawn_robot')        
    )            
    return LaunchDescription(declared_arguments + [OpaqueFunction(function=launch_setup)])

I might be missing some helpful methods included in the launch package, but this worked for me.