def generate_launch_description():
    # Get the launch directory
    bringup_dir = get_package_share_directory('nav2_bringup')
    bringup_launch_dir = os.path.join(bringup_dir, 'launch')
    spawner_dir = get_package_share_directory('robot_spawner_pkg')
    tf_exchange_dir = get_package_share_directory('tf_exchange')

    # Names and poses of the robots
    robots = [{
        'name': 'robot1',
        'x_pose': 0.0,
        'y_pose': 0.5,
        'z_pose': 0.01
    }, {
        'name': 'robot2',
        'x_pose': 0.0,
        'y_pose': -0.5,
        'z_pose': 0.01
    }]

    # On this example all robots are launched with the same settings
    map_yaml_file = LaunchConfiguration('map')

    default_bt_xml_filename = LaunchConfiguration('default_bt_xml_filename')
    autostart = LaunchConfiguration('autostart')
    rviz_config_file = LaunchConfiguration('rviz_config')
    use_robot_state_pub = LaunchConfiguration('use_robot_state_pub')
    use_rviz = LaunchConfiguration('use_rviz')
    log_settings = LaunchConfiguration('log_settings', default='true')

    declare_base_frame = DeclareLaunchArgument('base_frame',
                                               default_value='base_link')

    declare_map_yaml_cmd = DeclareLaunchArgument(
        'map',
        default_value=os.path.join(bringup_dir, 'maps',
                                   'turtlebot3_world.yaml'),
        description='Full path to map file to load')

    declare_robot1_params_file_cmd = DeclareLaunchArgument(
        'robot1_params_file',
        default_value=os.path.join(bringup_dir, 'params',
                                   'nav2_multirobot_params_1.yaml'),
        description=
        'Full path to the ROS2 parameters file to use for robot1 launched nodes'
    )

    declare_robot2_params_file_cmd = DeclareLaunchArgument(
        'robot2_params_file',
        default_value=os.path.join(bringup_dir, 'params',
                                   'nav2_multirobot_params_2.yaml'),
        description=
        'Full path to the ROS2 parameters file to use for robot2 launched nodes'
    )

    declare_bt_xml_cmd = DeclareLaunchArgument(
        'default_bt_xml_filename',
        default_value=os.path.join(
            get_package_share_directory('nav2_bt_navigator'), 'behavior_trees',
            'navigate_w_replanning_and_recovery.xml'),
        description='Full path to the behavior tree xml file to use')

    declare_autostart_cmd = DeclareLaunchArgument(
        'autostart',
        default_value='false',
        description='Automatically startup the stacks')

    declare_rviz_config_file_cmd = DeclareLaunchArgument(
        'rviz_config',
        default_value=os.path.join(
            get_package_share_directory('robot_spawner_pkg'),
            'nav2_namespaced_view.rviz'),
        description='Full path to the RVIZ config file to use.')

    declare_use_robot_state_pub_cmd = DeclareLaunchArgument(
        'use_robot_state_pub',
        default_value='True',
        description='Whether to start the robot state publisher')

    declare_use_rviz_cmd = DeclareLaunchArgument(
        'use_rviz', default_value='True', description='Whether to start RVIZ')

    # Define commands for spawing the robots into Gazebo
    spawn_robots_cmds = []
    for robot in robots:
        spawn_robots_cmds.append(
            IncludeLaunchDescription(
                PythonLaunchDescriptionSource(
                    os.path.join(spawner_dir, 'spawn_tb3.launch.py')),
                launch_arguments={
                    'x_pose': TextSubstitution(text=str(robot['x_pose'])),
                    'y_pose': TextSubstitution(text=str(robot['y_pose'])),
                    'z_pose': TextSubstitution(text=str(robot['z_pose'])),
                    'robot_name': robot['name'],
                    'turtlebot_type': TextSubstitution(text='burger')
                }.items()))

    # Define commands for launching the navigation instances
    nav_instances_cmds = []
    for robot in robots:
        params_file = LaunchConfiguration(robot['name'] + '_params_file')

        group = GroupAction([
            IncludeLaunchDescription(PythonLaunchDescriptionSource(
                os.path.join(bringup_launch_dir, 'rviz_launch.py')),
                                     condition=IfCondition(use_rviz),
                                     launch_arguments={
                                         'namespace':
                                         TextSubstitution(text=robot['name']),
                                         'use_namespace':
                                         'True',
                                         'rviz_config':
                                         rviz_config_file
                                     }.items()),
            IncludeLaunchDescription(PythonLaunchDescriptionSource(
                os.path.join(bringup_dir, 'launch',
                             'tb3_simulation_launch.py')),
                                     launch_arguments={
                                         'namespace': robot['name'],
                                         'use_namespace': 'True',
                                         'map': map_yaml_file,
                                         'use_sim_time': 'True',
                                         'params_file': params_file,
                                         'default_bt_xml_filename':
                                         default_bt_xml_filename,
                                         'autostart': autostart,
                                         'use_rviz': 'False',
                                         'use_simulator': 'False',
                                         'headless': 'False',
                                         'use_robot_state_pub':
                                         use_robot_state_pub
                                     }.items()),
            IncludeLaunchDescription(
                PythonLaunchDescriptionSource(
                    os.path.join(tf_exchange_dir, 'tf_exchange.launch.py')),
                launch_arguments={
                    'namespace': TextSubstitution(text=robot['name']),
                    'robot_name': robot['name'],
                    'base_frame': LaunchConfiguration('base_frame')
                    # 'params_file': params_file
                }.items()),
            LogInfo(condition=IfCondition(log_settings),
                    msg=['Launching ', robot['name']]),
            LogInfo(condition=IfCondition(log_settings),
                    msg=[robot['name'], ' map yaml: ', map_yaml_file]),
            LogInfo(condition=IfCondition(log_settings),
                    msg=[robot['name'], ' params yaml: ', params_file]),
            LogInfo(condition=IfCondition(log_settings),
                    msg=[
                        robot['name'], ' behavior tree xml: ',
                        default_bt_xml_filename
                    ]),
            LogInfo(
                condition=IfCondition(log_settings),
                msg=[robot['name'], ' rviz config file: ', rviz_config_file]),
            LogInfo(condition=IfCondition(log_settings),
                    msg=[
                        robot['name'], ' using robot state pub: ',
                        use_robot_state_pub
                    ]),
            LogInfo(condition=IfCondition(log_settings),
                    msg=[robot['name'], ' autostart: ', autostart])
        ])

        nav_instances_cmds.append(group)

    simulator = IncludeLaunchDescription(PythonLaunchDescriptionSource(
        os.path.join(spawner_dir, 'simulator.launch.py')),
                                         launch_arguments={}.items())

    # Create the launch description and populate
    ld = LaunchDescription()

    # Declare the launch options
    ld.add_action(declare_base_frame)
    ld.add_action(declare_map_yaml_cmd)
    ld.add_action(declare_robot1_params_file_cmd)
    ld.add_action(declare_robot2_params_file_cmd)
    ld.add_action(declare_bt_xml_cmd)
    ld.add_action(declare_use_rviz_cmd)
    ld.add_action(declare_autostart_cmd)
    ld.add_action(declare_rviz_config_file_cmd)
    ld.add_action(declare_use_robot_state_pub_cmd)

    # Add the actions to start gazebo, robots and simulations
    ld.add_action(simulator)

    for spawn_robot_cmd in spawn_robots_cmds:
        ld.add_action(spawn_robot_cmd)

    for simulation_instance_cmd in nav_instances_cmds:
        ld.add_action(simulation_instance_cmd)

    return ld
def generate_launch_description():
    tf_exchange_dir = get_package_share_directory('tf_exchange')
    #rviz_config_file = LaunchConfiguration('rviz_config')
    #map_yaml_file = LaunchConfiguration('map')
    bringup_dir = get_package_share_directory('nav2_bringup')
    slam = LaunchConfiguration('slam')

    declare_map_yaml_cmd = DeclareLaunchArgument(
        'map',
        default_value=os.path.join(bringup_dir, 'maps',
                                   'turtlebot3_world.yaml'),
        description='Full path to map file to load')

    declare_robot_name = DeclareLaunchArgument('robot_name',
                                               default_value='robot1')
    declare_base_frame = DeclareLaunchArgument('base_frame',
                                               default_value='base_link')
    declare_x_pose = DeclareLaunchArgument(
        'x_pose',
        default_value=launch.substitutions.TextSubstitution(text='0.0'))
    declare_y_pose = DeclareLaunchArgument(
        'y_pose',
        default_value=launch.substitutions.TextSubstitution(text='0.0'))
    declare_z_pose = DeclareLaunchArgument(
        'z_pose',
        default_value=launch.substitutions.TextSubstitution(text='0.0'))
    declare_yaw_pose = DeclareLaunchArgument(
        'yaw_pose',
        default_value=launch.substitutions.TextSubstitution(text='0.0'))
    declare_use_rviz_cmd = DeclareLaunchArgument(
        'use_rviz', default_value='True', description='Whether to start RVIZ')

    declare_rviz_config_file_cmd = DeclareLaunchArgument(
        'rviz_config',
        default_value=os.path.join(
            get_package_share_directory('robot_spawner_pkg'), 'custom.rviz'),
        description='Full path to the RVIZ config file to use.')

    declare_slam_cmd = DeclareLaunchArgument('slam',
                                             default_value='False',
                                             description='Whether run a SLAM')

    declare_behaviour_cmd = DeclareLaunchArgument(
        'behaviour',
        default_value='True',
        description='Whether run the default behaviour.')

    tf_exchange = IncludeLaunchDescription(
        PythonLaunchDescriptionSource(
            os.path.join(tf_exchange_dir, 'tf_exchange.launch.py')),
        launch_arguments={
            'namespace': LaunchConfiguration('robot_name'),
            'robot_name': LaunchConfiguration('robot_name'),
            'base_frame': LaunchConfiguration('base_frame')
            #'params_file': [LaunchConfiguration('robot_name'), launch.substitutions.TextSubstitution(text='_params_file')]
        }.items())

    spawner = launch_ros.actions.Node(
        package='robot_spawner_pkg',
        executable='nav2_gazebo_spawner',
        output='screen',
        arguments=[
            '--robot_name',
            LaunchConfiguration('robot_name'),
            '--robot_namespace',
            LaunchConfiguration('robot_name'),
            '--turtlebot_type',
            launch.substitutions.EnvironmentVariable('TURTLEBOT3_MODEL'),
            '-x',
            LaunchConfiguration('x_pose'),
            '-y',
            LaunchConfiguration('y_pose'),
            '-z',
            LaunchConfiguration('z_pose'),
            '-yaw',
            LaunchConfiguration('yaw_pose'),
        ])

    rviz = IncludeLaunchDescription(PythonLaunchDescriptionSource(
        os.path.join(bringup_dir, 'launch', 'rviz_launch.py')),
                                    condition=IfCondition(
                                        LaunchConfiguration('use_rviz')),
                                    launch_arguments={
                                        'namespace':
                                        LaunchConfiguration('robot_name'),
                                        'use_namespace':
                                        'true',
                                        'use_sim_time':
                                        'true'
                                    }.items())  #,
    #'rviz_config': rviz_config_file}.items())

    namespace = LaunchConfiguration('robot_name')
    use_sim_time = TextSubstitution(text='True')
    autostart = 'True'
    params_file = os.path.join(
        get_package_share_directory('robot_spawner_pkg'),
        'nav2_multirobot_params_1.yaml')
    urdf = os.path.join(get_package_share_directory('turtlebot3_description'),
                        'urdf', 'turtlebot3_burger.urdf')

    bringup_cmd_group = GroupAction([
        launch_ros.actions.PushRosNamespace(namespace=namespace),
        launch_ros.actions.Node(
            package='robot_state_publisher',
            executable='robot_state_publisher',
            name='robot_state_publisher',
            #namespace=namespace,
            output='screen',
            parameters=[{
                'use_sim_time': use_sim_time
            }],
            arguments=[urdf],
            remappings=[('/tf', 'tf'), ('/tf_static', 'tf_static')]),
        IncludeLaunchDescription(PythonLaunchDescriptionSource(
            os.path.join(bringup_dir, 'launch', 'slam_launch.py')),
                                 condition=IfCondition(slam),
                                 launch_arguments={
                                     'namespace': namespace,
                                     'use_sim_time': use_sim_time,
                                     'autostart': autostart,
                                     'params_file': params_file
                                 }.items()),
        IncludeLaunchDescription(PythonLaunchDescriptionSource(
            os.path.join(bringup_dir, 'launch', 'localization_launch.py')),
                                 condition=IfCondition(
                                     PythonExpression(['not ', slam])),
                                 launch_arguments={
                                     'namespace': namespace,
                                     'map': LaunchConfiguration('map'),
                                     'use_sim_time': use_sim_time,
                                     'autostart': autostart,
                                     'params_file': params_file,
                                     'use_lifecycle_mgr': 'false'
                                 }.items())
    ])

    drive = launch_ros.actions.Node(
        executable='turtlebot3_drive',
        condition=IfCondition(LaunchConfiguration('behaviour')),
        package='turtlebot3_gazebo',
        namespace=LaunchConfiguration('robot_name'),
    )

    ld = LaunchDescription()
    ld.add_action(declare_map_yaml_cmd)
    ld.add_action(declare_robot_name)
    ld.add_action(declare_base_frame)
    ld.add_action(declare_x_pose)
    ld.add_action(declare_y_pose)
    ld.add_action(declare_z_pose)
    ld.add_action(declare_yaw_pose)
    ld.add_action(declare_use_rviz_cmd)
    ld.add_action(declare_slam_cmd)
    ld.add_action(declare_behaviour_cmd)
    ld.add_action(declare_rviz_config_file_cmd)
    ld.add_action(spawner)
    ld.add_action(rviz)
    ld.add_action(bringup_cmd_group)
    ld.add_action(tf_exchange)
    ld.add_action(drive)
    return ld
def launch_setup(context, *args, **kwargs):
    # Perform substitutions
    debug = Lc('debug').perform(context)
    namespace = Lc('namespace').perform(context)
    x = Lc('x').perform(context)
    y = Lc('y').perform(context)
    z = Lc('z').perform(context)
    roll = Lc('roll').perform(context)
    pitch = Lc('pitch').perform(context)
    yaw = Lc('yaw').perform(context)
    # use_sim_time = Lc('use_sim_time').perform(context)
    use_world_ned = Lc('use_ned_frame').perform(context)
    is_write_on_disk = Lc('write_file_on_disk').perform(context)

    # Request sim time value to the global node
    res = is_sim_time(return_param=False, use_subprocess=True)

    # Xacro
    #xacro_file = PathJoinSubstitution(get_package_share_directory('uuv_descriptions'),'robots','rexrov_')
    xacro_file = os.path.join(
        get_package_share_directory('uuv_descriptions'), 'robots',
        'rexrov_' + (Lc('mode')).perform(context) + '.xacro')

    # Build the directories, check for existence
    path = os.path.join(
        get_package_share_directory('uuv_descriptions'),
        'robots',
        'generated',
        namespace,
    )

    if not pathlib.Path(path).exists():
        try:
            # Create directory if required and sub-directory
            os.makedirs(path)
        except OSError:
            print("Creation of the directory %s failed" % path)

    output = os.path.join(path, 'robot_description.urdf')

    if not pathlib.Path(xacro_file).exists():
        exc = 'Launch file ' + xacro_file + ' does not exist'
        raise Exception(exc)

    mapping = {}
    if to_bool(use_world_ned):
        mappings = {
            'debug': debug,
            'namespace': namespace,
            'inertial_reference_frame': 'world_ned'
        }
    else:
        mappings = {
            'debug': debug,
            'namespace': namespace,
            'inertial_reference_frame': 'world'
        }

    doc = xacro.process(xacro_file, mappings=mappings)

    if is_write_on_disk:
        with open(output, 'w') as file_out:
            file_out.write(doc)

    # URDF spawner
    args = (
        '-gazebo_namespace /gazebo '
        '-x %s -y %s -z %s -R %s -P %s -Y %s -entity %s -topic robot_description'
        % (x, y, z, roll, pitch, yaw, namespace)).split()

    # Urdf spawner. NB: node namespace does not prefix the spawning service,
    # as using a leading /
    # NB 2: node namespace prefixes the robot_description topic
    urdf_spawner = Node(name='urdf_spawner',
                        package='gazebo_ros',
                        executable='spawn_entity.py',
                        output='screen',
                        parameters=[{
                            'use_sim_time': res
                        }],
                        arguments=args)

    # A joint state publisher plugin already is started with the model, no need to use the default joint state publisher

    # N.B.: alternative way to generate a robot_description string:
    # string = str('ros2 run xacro xacro ' + xacro_file + ' debug:=false namespace:=' + namespace + ' inertial_reference_frame:=world')
    # cmd = Command(string)
    # but it currently yields yaml parsing error due to ":" in the comments of the xacro description files

    robot_state_publisher = Node(
        name='robot_state_publisher',
        package='robot_state_publisher',
        executable='robot_state_publisher',
        output='screen',
        parameters=[{
            'use_sim_time': res
        }, {
            'robot_description': doc
        }],  # Use subst here
    )

    # Message to tf
    message_to_tf_launch = os.path.join(
        get_package_share_directory('uuv_assistants'), 'launch',
        'message_to_tf.launch')

    if not pathlib.Path(message_to_tf_launch).exists():
        exc = 'Launch file ' + message_to_tf_launch + ' does not exist'
        raise Exception(exc)

    launch_args = [
        ('namespace', namespace),
        ('world_frame', 'world'),
        ('child_frame_id', '/' + namespace + '/base_link'),
        ('use_sim_time', str(res).lower()),
    ]
    message_to_tf_launch = IncludeLaunchDescription(
        AnyLaunchDescriptionSource(message_to_tf_launch),
        launch_arguments=launch_args)

    group = GroupAction([
        PushRosNamespace(namespace),
        urdf_spawner,
        robot_state_publisher,
    ])

    return [group, message_to_tf_launch]
Exemple #4
0
def generate_launch_description():
    pkg_bringup = get_package_share_directory('nanosaur_bringup')
    pkg_description = get_package_share_directory('nanosaur_description')
    pkg_control = get_package_share_directory('nanosaur_control')

    # Load nanosaur configuration and check if are included extra parameters
    # This feature is used to avoid pass configuration from docker
    conf = load_config(os.path.join(pkg_bringup, 'param', 'robot.yml'))

    # Load namespace from robot.yml
    namespace_conf = os.getenv("HOSTNAME") if conf.get("multirobot",
                                                       False) else "nanosaur"
    # Load cover_type
    if "cover_type" in conf:
        cover_type_conf = conf.get("cover_type", 'fisheye')
        print(f"Load cover_type from robot.xml: {cover_type_conf}")
    else:
        cover_type_conf = os.getenv("NANOSAUR_COVER_TYPE", 'fisheye')
        print(f"Load cover_type from ENV: {cover_type_conf}")

    config_common_path = LaunchConfiguration('config_common_path')
    namespace = LaunchConfiguration('namespace')
    cover_type = LaunchConfiguration('cover_type')

    declare_config_common_path_cmd = DeclareLaunchArgument(
        'config_common_path',
        default_value=os.path.join(pkg_bringup, 'param', 'nanosaur.yml'),
        description='Path to the `nanosaur.yml` file.')

    declare_namespace_cmd = DeclareLaunchArgument(
        'namespace',
        default_value=namespace_conf,
        description=
        'Enable a namespace for multiple robot. This namespace group all nodes and topics.'
    )

    declare_cover_type_cmd = DeclareLaunchArgument(
        name='cover_type',
        default_value=cover_type_conf,
        description=
        'Cover type to use. Options: pi, fisheye, realsense, zedmini.')

    jtop_node = Node(package='jetson_stats_wrapper',
                     namespace=namespace,
                     executable='jtop',
                     name='jtop',
                     remappings=[('diagnostics', '/diagnostics')])

    # System manager
    system_manager = Node(package='ros2_system_manager',
                          namespace=namespace,
                          executable='system_manager',
                          name='system_manager')

    nanosaur_base_node = Node(package='nanosaur_base',
                              namespace=namespace,
                              executable='nanosaur_base',
                              name='nanosaur_base',
                              respawn=True,
                              respawn_delay=5,
                              parameters=[config_common_path],
                              output='screen')

    # include another launch file in nanosaur namespace
    # https://docs.ros.org/en/foxy/How-To-Guides/Launch-file-different-formats.html
    description_launch = GroupAction(actions=[
        # push-ros-namespace to set namespace of included nodes
        PushRosNamespace(namespace),
        # Nanosaur description
        IncludeLaunchDescription(PythonLaunchDescriptionSource(
            [pkg_description, '/launch/description.launch.py']),
                                 launch_arguments={'cover_type': cover_type
                                                   }.items())
    ])

    # include another launch file in nanosaur namespace
    twist_control_launch = GroupAction(actions=[
        # push-ros-namespace to set namespace of included nodes
        PushRosNamespace(namespace),
        # nanosaur twist launch
        IncludeLaunchDescription(
            PythonLaunchDescriptionSource(
                [pkg_control, '/launch/twist_control.launch.py']))
    ])

    joy2eyes_node = Node(package='nanosaur_base',
                         namespace="teleop",
                         executable='joy2eyes',
                         name='joy2eyes',
                         remappings=[('eyes', f'/{namespace_conf}/eyes')],
                         output='screen')

    system_manager_node = Node(package='ros2_system_manager',
                               namespace="teleop",
                               executable='joy2sm',
                               name='joy2sm',
                               parameters=[config_common_path],
                               remappings=[('shutdown',
                                            f'/{namespace_conf}/shutdown')],
                               output='screen')

    teleop_extra_node_actions = [
        # push-ros-namespace to set namespace of included nodes
        PushRosNamespace(namespace),
        # nanosaur twist launch
        system_manager_node
    ]

    # Extra Debug packages
    # - Eyes bridge
    if conf.get("debug", False):
        print("DEBUG variable exist - Load extra nodes")
        teleop_extra_node_actions += [joy2eyes_node]

    # include another launch file in nanosaur namespace
    teleop_extra_nodes_launch = GroupAction(actions=teleop_extra_node_actions)

    # https://answers.ros.org/question/306935/ros2-include-a-launch-file-from-a-launch-file/
    # include another launch file in the chatter_ns namespace
    teleop_launch = GroupAction(actions=[
        # push-ros-namespace to set namespace of included nodes
        PushRosNamespace(namespace),
        # teleoperation launcher
        IncludeLaunchDescription(PythonLaunchDescriptionSource(
            [pkg_control, '/launch/teleop.launch.py']),
                                 launch_arguments={
                                     'joy_vel':
                                     f"/{namespace_conf}/joy_vel",
                                     'config_filepath':
                                     os.path.join(pkg_control, 'config',
                                                  'ps3.nanosaur.yml')
                                 }.items())
    ])

    print(f"----- cover_type: {cover_type} -----")
    # Define LaunchDescription variable and return it
    ld = LaunchDescription()

    # Namespace nanosaur
    ld.add_action(declare_namespace_cmd)
    # cover_type
    ld.add_action(declare_cover_type_cmd)
    # Nanosaur parameter yml file path
    ld.add_action(declare_config_common_path_cmd)
    # Nanosaur description launch
    ld.add_action(description_launch)
    # jtop node
    ld.add_action(jtop_node)
    # System manager
    ld.add_action(system_manager)
    # Nanusaur driver motors and display
    ld.add_action(nanosaur_base_node)

    # Twist control launcher
    if conf.get("no_twist_mux", False):
        print("Disable twist-mux")
    else:
        ld.add_action(twist_control_launch)

    # teleoperation joystick nanosaur
    # only if joystick is connected
    if os.path.exists("/dev/input/js0"):
        print("Enable Joystick")
        # Teleoperation control
        ld.add_action(teleop_launch)
        # Run Joystick to system_manager node
        ld.add_action(teleop_extra_nodes_launch)

    return ld
def generate_launch_description():
    composable_nodes = [
        ComposableNode(
            package='stereo_image_proc',
            plugin='stereo_image_proc::DisparityNode',
            parameters=[{
                'approximate_sync':
                LaunchConfiguration('approximate_sync'),
                'use_system_default_qos':
                LaunchConfiguration('use_system_default_qos'),
                'stereo_algorithm':
                LaunchConfiguration('stereo_algorithm'),
                'prefilter_size':
                LaunchConfiguration('prefilter_size'),
                'prefilter_cap':
                LaunchConfiguration('prefilter_cap'),
                'correlation_window_size':
                LaunchConfiguration('correlation_window_size'),
                'min_disparity':
                LaunchConfiguration('min_disparity'),
                'disparity_range':
                LaunchConfiguration('disparity_range'),
                'texture_threshold':
                LaunchConfiguration('texture_threshold'),
                'speckle_size':
                LaunchConfiguration('speckle_size'),
                'speckle_range':
                LaunchConfiguration('speckle_range'),
                'disp12_max_diff':
                LaunchConfiguration('disp12_max_diff'),
                'uniqueness_ratio':
                LaunchConfiguration('uniqueness_ratio'),
                'P1':
                LaunchConfiguration('P1'),
                'P2':
                LaunchConfiguration('P2'),
                'full_dp':
                LaunchConfiguration('full_dp'),
            }],
            remappings=[
                ('left/image_rect',
                 [LaunchConfiguration('left_namespace'), '/image_rect']),
                ('left/camera_info',
                 [LaunchConfiguration('left_namespace'), '/camera_info']),
                ('right/image_rect',
                 [LaunchConfiguration('right_namespace'), '/image_rect']),
                ('right/camera_info',
                 [LaunchConfiguration('right_namespace'), '/camera_info']),
            ]),
        ComposableNode(
            package='stereo_image_proc',
            plugin='stereo_image_proc::PointCloudNode',
            parameters=[{
                'approximate_sync':
                LaunchConfiguration('approximate_sync'),
                'avoid_point_cloud_padding':
                LaunchConfiguration('avoid_point_cloud_padding'),
                'use_color':
                LaunchConfiguration('use_color'),
                'use_system_default_qos':
                LaunchConfiguration('use_system_default_qos'),
            }],
            remappings=[
                ('left/camera_info',
                 [LaunchConfiguration('left_namespace'), '/camera_info']),
                ('right/camera_info',
                 [LaunchConfiguration('right_namespace'), '/camera_info']),
                ('left/image_rect_color',
                 [LaunchConfiguration('left_namespace'), '/image_rect_color']),
            ]),
    ]

    return LaunchDescription([
        DeclareLaunchArgument(
            name='approximate_sync',
            default_value='False',
            description=
            'Whether to use approximate synchronization of topics. Set to true if '
            'the left and right cameras do not produce exactly synced timestamps.'
        ),
        DeclareLaunchArgument(
            name='avoid_point_cloud_padding',
            default_value='False',
            description='Avoid alignment padding in the generated point cloud.'
            'This reduces bandwidth requirements, as the point cloud size is halved.'
            'Using point clouds without alignment padding might degrade performance '
            'for some algorithms.'),
        DeclareLaunchArgument(
            name='use_color',
            default_value='True',
            description='Generate point cloud with rgb data.'),
        DeclareLaunchArgument(
            name='use_system_default_qos',
            default_value='False',
            description=
            'Use the RMW QoS settings for the image and camera info subscriptions.'
        ),
        DeclareLaunchArgument(
            name='launch_image_proc',
            default_value='True',
            description=
            'Whether to launch debayer and rectify nodes from image_proc.'),
        DeclareLaunchArgument(name='left_namespace',
                              default_value='left',
                              description='Namespace for the left camera'),
        DeclareLaunchArgument(name='right_namespace',
                              default_value='right',
                              description='Namespace for the right camera'),
        DeclareLaunchArgument(
            name='container',
            default_value='',
            description=
            ('Name of an existing node container to load launched nodes into. '
             'If unset, a new container will be created.')),
        # Stereo algorithm parameters
        DeclareLaunchArgument(
            name='stereo_algorithm',
            default_value='0',
            description=
            'Stereo algorithm: Block Matching (0) or Semi-Global Block Matching (1)'
        ),
        DeclareLaunchArgument(
            name='prefilter_size',
            default_value='9',
            description='Normalization window size in pixels (must be odd)'),
        DeclareLaunchArgument(name='prefilter_cap',
                              default_value='31',
                              description='Bound on normalized pixel values'),
        DeclareLaunchArgument(
            name='correlation_window_size',
            default_value='15',
            description='SAD correlation window width in pixels (must be odd)'
        ),
        DeclareLaunchArgument(
            name='min_disparity',
            default_value='0',
            description='Disparity to begin search at in pixels'),
        DeclareLaunchArgument(
            name='disparity_range',
            default_value='64',
            description=
            'Number of disparities to search in pixels (must be a multiple of 16)'
        ),
        DeclareLaunchArgument(
            name='texture_threshold',
            default_value='10',
            description=
            'Filter out if SAD window response does not exceed texture threshold'
        ),
        DeclareLaunchArgument(
            name='speckle_size',
            default_value='100',
            description='Reject regions smaller than this size in pixels'),
        DeclareLaunchArgument(
            name='speckle_range',
            default_value='4',
            description=
            'Maximum allowed difference between detected disparities'),
        DeclareLaunchArgument(
            name='disp12_max_diff',
            default_value='0',
            description=
            'Maximum allowed difference in the left-right disparity check in pixels '
            '(Semi-Global Block Matching only)'),
        DeclareLaunchArgument(
            name='uniqueness_ratio',
            default_value='15.0',
            description=
            'Filter out if best match does not sufficiently exceed the next-best match'
        ),
        DeclareLaunchArgument(
            name='P1',
            default_value='200.0',
            description=
            'The first parameter ccontrolling the disparity smoothness '
            '(Semi-Global Block Matching only)'),
        DeclareLaunchArgument(
            name='P2',
            default_value='400.0',
            description=
            'The second parameter ccontrolling the disparity smoothness '
            '(Semi-Global Block Matching only)'),
        DeclareLaunchArgument(
            name='full_dp',
            default_value='False',
            description=
            'Run the full variant of the algorithm (Semi-Global Block Matching only)'
        ),
        ComposableNodeContainer(
            condition=LaunchConfigurationEquals('container', ''),
            package='rclcpp_components',
            executable='component_container',
            name='stereo_image_proc_container',
            namespace='',
            composable_node_descriptions=composable_nodes,
        ),
        LoadComposableNodes(
            condition=LaunchConfigurationNotEquals('container', ''),
            composable_node_descriptions=composable_nodes,
            target_container=LaunchConfiguration('container'),
        ),
        # If a container name is not provided,
        # set the name of the container launched above for image_proc nodes
        SetLaunchConfiguration(condition=LaunchConfigurationEquals(
            'container', ''),
                               name='container',
                               value='stereo_image_proc_container'),
        GroupAction(
            [
                PushRosNamespace(LaunchConfiguration('left_namespace')),
                IncludeLaunchDescription(PythonLaunchDescriptionSource([
                    FindPackageShare('image_proc'),
                    '/launch/image_proc.launch.py'
                ]),
                                         launch_arguments={
                                             'container':
                                             LaunchConfiguration('container')
                                         }.items()),
            ],
            condition=IfCondition(LaunchConfiguration('launch_image_proc')),
        ),
        GroupAction(
            [
                PushRosNamespace(LaunchConfiguration('right_namespace')),
                IncludeLaunchDescription(PythonLaunchDescriptionSource([
                    FindPackageShare('image_proc'),
                    '/launch/image_proc.launch.py'
                ]),
                                         launch_arguments={
                                             'container':
                                             LaunchConfiguration('container')
                                         }.items()),
            ],
            condition=IfCondition(LaunchConfiguration('launch_image_proc')),
        )
    ])
Exemple #6
0
def test_group_action_constructors():
    """Test the constructors for the GroupAction class."""
    GroupAction([])
    GroupAction([Action()])
    GroupAction([Action()], scoped=False)
    GroupAction([Action()], scoped=False, launch_configurations={'foo': 'FOO'})
Exemple #7
0
def test_group_action_execute():
    """Test the execute() of the the GroupAction class."""
    lc1 = LaunchContext()

    assert len(lc1.launch_configurations) == 0
    assert len(GroupAction([], scoped=False).visit(lc1)) == 0
    assert len(lc1.launch_configurations) == 0

    assert len(lc1.launch_configurations) == 0
    result = GroupAction([]).visit(lc1)
    assert len(result) == 2  # push and pop actions, due to scope=True
    assert isinstance(result[0], PushLaunchConfigurations)
    assert isinstance(result[1], PopLaunchConfigurations)
    for a in result:
        a.visit(lc1)
    assert len(lc1.launch_configurations) == 0

    assert len(lc1.launch_configurations) == 0
    result = GroupAction([], launch_configurations={'foo': 'FOO'}).visit(lc1)
    assert len(
        result) == 3  # push, set 1 launch_configurations, and pop actions
    assert isinstance(result[0], PushLaunchConfigurations)
    assert isinstance(result[1], SetLaunchConfiguration)
    assert isinstance(result[2], PopLaunchConfigurations)
    for a in result:
        a.visit(lc1)
    assert len(lc1.launch_configurations) == 0

    assert len(lc1.launch_configurations) == 0
    result = GroupAction([],
                         launch_configurations={
                             'foo': 'FOO',
                             'bar': 'BAR'
                         }).visit(lc1)
    assert len(
        result) == 4  # push, set 2 launch_configurations, and pop actions
    assert isinstance(result[0], PushLaunchConfigurations)
    assert isinstance(result[1], SetLaunchConfiguration)
    assert isinstance(result[2], SetLaunchConfiguration)
    assert isinstance(result[3], PopLaunchConfigurations)
    for a in result:
        a.visit(lc1)
    assert len(lc1.launch_configurations) == 0

    assert len(lc1.launch_configurations) == 0
    PushLaunchConfigurations().visit(lc1)
    result = GroupAction([],
                         scoped=False,
                         launch_configurations={
                             'foo': 'FOO'
                         }).visit(lc1)
    assert len(result) == 1  # set 1 launch_configurations
    assert isinstance(result[0], SetLaunchConfiguration)
    for a in result:
        a.visit(lc1)
    assert len(
        lc1.launch_configurations) == 1  # still set after group was included
    PopLaunchConfigurations().visit(lc1)
    assert len(lc1.launch_configurations) == 0

    assert len(lc1.launch_configurations) == 0
    PushLaunchConfigurations().visit(lc1)
    result = GroupAction([Action()],
                         scoped=False,
                         launch_configurations={
                             'foo': 'FOO'
                         }).visit(lc1)
    assert len(
        result
    ) == 2  # set 1 launch_configurations, then the 1 included actions
    assert isinstance(result[0], SetLaunchConfiguration)
    assert isinstance(result[1], Action)
    for a in result:
        a.visit(lc1)
    assert len(
        lc1.launch_configurations) == 1  # still set after group was included
    PopLaunchConfigurations().visit(lc1)
    assert len(lc1.launch_configurations) == 0

    assert len(lc1.launch_configurations) == 0
    result = GroupAction([Action()], launch_configurations={
        'foo': 'FOO'
    }).visit(lc1)
    assert len(
        result
    ) == 4  # push, set 1 launch_configurations, the 1 action, and pop actions
    assert isinstance(result[0], PushLaunchConfigurations)
    assert isinstance(result[1], SetLaunchConfiguration)
    assert isinstance(result[2], Action)
    assert isinstance(result[3], PopLaunchConfigurations)
    for a in result:
        a.visit(lc1)
    assert len(lc1.launch_configurations) == 0
Exemple #8
0
def generate_launch_description():
    # Get the launch directory
    bringup_dir = get_package_share_directory('amazon_robot_bringup')
    launch_dir = os.path.join(bringup_dir, 'launch')

    # Create the launch configuration variables
    namespace = LaunchConfiguration('namespace')
    use_namespace = LaunchConfiguration('use_namespace')
    slam = LaunchConfiguration('slam')
    map_yaml_file = LaunchConfiguration('map')
    use_sim_time = LaunchConfiguration('use_sim_time')
    params_file = LaunchConfiguration('params_file')
    default_bt_xml_filename = LaunchConfiguration('default_bt_xml_filename')
    autostart = LaunchConfiguration('autostart')

    stdout_linebuf_envvar = SetEnvironmentVariable(
        'RCUTILS_LOGGING_BUFFERED_STREAM', '1')

    declare_namespace_cmd = DeclareLaunchArgument(
        'namespace', default_value='', description='Top-level namespace')

    declare_use_namespace_cmd = DeclareLaunchArgument(
        'use_namespace',
        default_value='false',
        description='Whether to apply a namespace to the navigation stack')

    declare_slam_cmd = DeclareLaunchArgument('slam',
                                             default_value='False',
                                             description='Whether run a SLAM')

    declare_map_yaml_cmd = DeclareLaunchArgument(
        'map', description='Full path to map yaml file to load')

    declare_use_sim_time_cmd = DeclareLaunchArgument(
        'use_sim_time',
        default_value='false',
        description='Use simulation (Gazebo) clock if true')

    declare_params_file_cmd = DeclareLaunchArgument(
        'params_file',
        default_value=os.path.join(bringup_dir, 'params', 'nav2_params.yaml'),
        description=
        'Full path to the ROS2 parameters file to use for all launched nodes')

    declare_bt_xml_cmd = DeclareLaunchArgument(
        'default_bt_xml_filename',
        default_value=os.path.join(
            get_package_share_directory('nav2_bt_navigator'), 'behavior_trees',
            'navigate_w_replanning_and_recovery.xml'),
        description='Full path to the behavior tree xml file to use')

    declare_autostart_cmd = DeclareLaunchArgument(
        'autostart',
        default_value='true',
        description='Automatically startup the nav2 stack')

    # Specify the actions
    bringup_cmd_group = GroupAction([
        PushRosNamespace(condition=IfCondition(use_namespace),
                         namespace=namespace),
        IncludeLaunchDescription(PythonLaunchDescriptionSource(
            os.path.join(launch_dir, 'slam_launch.py')),
                                 condition=IfCondition(slam),
                                 launch_arguments={
                                     'namespace': namespace,
                                     'use_sim_time': use_sim_time,
                                     'autostart': autostart,
                                     'params_file': params_file
                                 }.items()),
        IncludeLaunchDescription(PythonLaunchDescriptionSource(
            os.path.join(launch_dir, 'localization_launch.py')),
                                 condition=IfCondition(
                                     PythonExpression(['not ', slam])),
                                 launch_arguments={
                                     'namespace': namespace,
                                     'map': map_yaml_file,
                                     'use_sim_time': use_sim_time,
                                     'autostart': autostart,
                                     'params_file': params_file,
                                     'use_lifecycle_mgr': 'false'
                                 }.items()),
        IncludeLaunchDescription(PythonLaunchDescriptionSource(
            os.path.join(launch_dir, 'navigation_launch.py')),
                                 launch_arguments={
                                     'namespace': namespace,
                                     'use_sim_time': use_sim_time,
                                     'autostart': autostart,
                                     'params_file': params_file,
                                     'default_bt_xml_filename':
                                     default_bt_xml_filename,
                                     'use_lifecycle_mgr': 'false',
                                     'map_subscribe_transient_local': 'true'
                                 }.items()),
    ])

    # Create the launch description and populate
    ld = LaunchDescription()

    # Set environment variables
    ld.add_action(stdout_linebuf_envvar)

    # Declare the launch options
    ld.add_action(declare_namespace_cmd)
    ld.add_action(declare_use_namespace_cmd)
    ld.add_action(declare_slam_cmd)
    ld.add_action(declare_map_yaml_cmd)
    ld.add_action(declare_use_sim_time_cmd)
    ld.add_action(declare_params_file_cmd)
    ld.add_action(declare_autostart_cmd)
    ld.add_action(declare_bt_xml_cmd)

    # Add the actions to launch all of the navigation nodes
    ld.add_action(bringup_cmd_group)

    return ld
def generate_launch_description():
    # Get the launch directory
    bringup_dir = get_package_share_directory('nav2_bringup')
    launch_dir = os.path.join(bringup_dir, 'launch')

    # Create the launch configuration variables
    namespace = LaunchConfiguration('namespace')
    use_namespace = LaunchConfiguration('use_namespace')
    map_yaml_file = LaunchConfiguration('map')
    use_sim_time = LaunchConfiguration('use_sim_time')
    params_file = LaunchConfiguration('params_file')
    bt_xml_file = LaunchConfiguration('bt_xml_file')
    autostart = LaunchConfiguration('autostart')
    use_remappings = LaunchConfiguration('use_remappings')

    stdout_linebuf_envvar = SetEnvironmentVariable(
        'RCUTILS_CONSOLE_STDOUT_LINE_BUFFERED', '1')

    declare_namespace_cmd = DeclareLaunchArgument(
        'namespace',
        default_value='navigation',
        description='Top-level namespace')

    declare_use_namespace_cmd = DeclareLaunchArgument(
        'use_namespace',
        default_value='false',
        description='Whether to apply a namespace to the navigation stack')

    # Declare the launch arguments
    declare_map_yaml_cmd = DeclareLaunchArgument(
        'map',
        description='Full path to map yaml file to load')

    declare_use_sim_time_cmd = DeclareLaunchArgument(
        'use_sim_time',
        default_value='false',
        description='Use simulation (Gazebo) clock if true')

    declare_params_file_cmd = DeclareLaunchArgument(
        'params_file',
        default_value=os.path.join(bringup_dir, 'params', 'nav2_params.yaml'),
        description='Full path to the ROS2 parameters file to use for all launched nodes')

    declare_bt_xml_cmd = DeclareLaunchArgument(
        'bt_xml_file',
        default_value=os.path.join(
            get_package_share_directory('nav2_bt_navigator'),
            'behavior_trees', 'navigate_w_replanning_and_recovery.xml'),
        description='Full path to the behavior tree xml file to use')

    declare_autostart_cmd = DeclareLaunchArgument(
        'autostart', default_value='true',
        description='Automatically startup the nav2 stack')

    declare_use_remappings_cmd = DeclareLaunchArgument(
        'use_remappings', default_value='false',
        description='Arguments to pass to all nodes launched by the file')

    # Specify the actions
    bringup_cmd_group = GroupAction([
        PushRosNamespace(
            condition=IfCondition(use_namespace),
            namespace=namespace),

        IncludeLaunchDescription(
            PythonLaunchDescriptionSource(os.path.join(launch_dir, 'nav2_localization_launch.py')),
            launch_arguments={'namespace': namespace,
                              'map': map_yaml_file,
                              'use_sim_time': use_sim_time,
                              'autostart': autostart,
                              'params_file': params_file,
                              'use_lifecycle_mgr': 'false',
                              'use_remappings': use_remappings}.items()),

        IncludeLaunchDescription(
            PythonLaunchDescriptionSource(os.path.join(launch_dir, 'nav2_navigation_launch.py')),
            launch_arguments={'namespace': namespace,
                              'use_sim_time': use_sim_time,
                              'autostart': autostart,
                              'params_file': params_file,
                              'bt_xml_file': bt_xml_file,
                              'use_lifecycle_mgr': 'false',
                              'use_remappings': use_remappings,
                              'map_subscribe_transient_local': 'true'}.items()),

        Node(
            package='nav2_lifecycle_manager',
            node_executable='lifecycle_manager',
            node_name='lifecycle_manager',
            output='screen',
            parameters=[{'use_sim_time': use_sim_time},
                        {'autostart': autostart},
                        {'node_names': ['map_server',
                                        'amcl',
                                        'controller_server',
                                        'planner_server',
                                        'recoveries_server',
                                        'bt_navigator',
                                        'waypoint_follower']}]),
    ])

    # Create the launch description and populate
    ld = LaunchDescription()

    # Set environment variables
    ld.add_action(stdout_linebuf_envvar)

    # Declare the launch options
    ld.add_action(declare_namespace_cmd)
    ld.add_action(declare_use_namespace_cmd)
    ld.add_action(declare_map_yaml_cmd)
    ld.add_action(declare_use_sim_time_cmd)
    ld.add_action(declare_params_file_cmd)
    ld.add_action(declare_autostart_cmd)
    ld.add_action(declare_bt_xml_cmd)
    ld.add_action(declare_use_remappings_cmd)

    # Add the actions to launch all of the navigation nodes
    ld.add_action(bringup_cmd_group)

    return ld
def generate_launch_description():
    map_yaml_file = os.getenv('TEST_MAP')
    world = os.getenv('TEST_WORLD')
    urdf = os.getenv('TEST_URDF')
    sdf = os.getenv('TEST_SDF')

    bt_xml_file = os.path.join(
        get_package_share_directory('nav2_bt_navigator'), 'behavior_trees',
        os.getenv('BT_NAVIGATOR_XML'))

    bringup_dir = get_package_share_directory('nav2_bringup')
    robot1_params_file = os.path.join(
        bringup_dir,  # noqa: F841
        'params/nav2_multirobot_params_1.yaml')
    robot2_params_file = os.path.join(
        bringup_dir,  # noqa: F841
        'params/nav2_multirobot_params_2.yaml')

    # Names and poses of the robots
    robots = [{
        'name': 'robot1',
        'x_pose': 0.0,
        'y_pose': 0.5,
        'z_pose': 0.01
    }, {
        'name': 'robot2',
        'x_pose': 0.0,
        'y_pose': -0.5,
        'z_pose': 0.01
    }]

    # Launch Gazebo server for simulation
    start_gazebo_cmd = ExecuteProcess(cmd=[
        'gzserver', '-s', 'libgazebo_ros_factory.so', '--minimal_comms', world
    ],
                                      output='screen')

    # Define commands for spawing the robots into Gazebo
    spawn_robots_cmds = []
    for robot in robots:
        spawn_robots_cmds.append(
            Node(package='nav2_gazebo_spawner',
                 node_executable='nav2_gazebo_spawner',
                 output='screen',
                 arguments=[
                     '--robot_name',
                     TextSubstitution(text=robot['name']), '--robot_namespace',
                     TextSubstitution(text=robot['name']), '--sdf',
                     TextSubstitution(text=sdf), '-x',
                     TextSubstitution(text=str(robot['x_pose'])), '-y',
                     TextSubstitution(text=str(robot['y_pose'])), '-z',
                     TextSubstitution(text=str(robot['z_pose']))
                 ]))

    # Define commands for launching the robot state publishers
    robot_state_pubs_cmds = []
    for robot in robots:
        robot_state_pubs_cmds.append(
            Node(package='robot_state_publisher',
                 node_executable='robot_state_publisher',
                 node_namespace=TextSubstitution(text=robot['name']),
                 output='screen',
                 parameters=[{
                     'use_sim_time': 'True'
                 }],
                 remappings=[('/tf', 'tf'), ('/tf_static', 'tf_static')],
                 arguments=[urdf]))

    # Define commands for launching the navigation instances
    nav_instances_cmds = []
    for robot in robots:
        params_file = eval(robot['name'] + '_params_file')

        group = GroupAction([
            # Instances use the robot's name for namespace
            PushRosNamespace(robot['name']),
            IncludeLaunchDescription(PythonLaunchDescriptionSource(
                os.path.join(bringup_dir, 'launch', 'nav2_bringup_launch.py')),
                                     launch_arguments={
                                         'namespace': robot['name'],
                                         'map': map_yaml_file,
                                         'use_sim_time': 'True',
                                         'params_file': params_file,
                                         'bt_xml_file': bt_xml_file,
                                         'autostart': 'True',
                                         'use_remappings': 'True'
                                     }.items())
        ])
        nav_instances_cmds.append(group)

    ld = LaunchDescription()
    ld.add_action(
        SetEnvironmentVariable('RCUTILS_CONSOLE_STDOUT_LINE_BUFFERED', '1'), )
    ld.add_action(start_gazebo_cmd)
    for spawn_robot in spawn_robots_cmds:
        ld.add_action(spawn_robot)
    for state_pub in robot_state_pubs_cmds:
        ld.add_action(state_pub)
    for nav_instance in nav_instances_cmds:
        ld.add_action(nav_instance)

    return ld
Exemple #11
0
def generate_launch_description():
    # Get the launch directory
    bringup_dir = get_package_share_directory('nav2_bringup')

    # Names and poses of the robots
    robots = [{
        'name': 'robot1',
        'x_pose': 0.0,
        'y_pose': 0.5,
        'z_pose': 0.01
    }, {
        'name': 'robot2',
        'x_pose': 0.0,
        'y_pose': -0.5,
        'z_pose': 0.01
    }]

    # Simulation settings
    world = LaunchConfiguration('world')
    simulator = LaunchConfiguration('simulator')

    # On this example all robots are launched with the same settings
    map_yaml_file = LaunchConfiguration('map')
    params_file = LaunchConfiguration('params_file')
    bt_xml_file = LaunchConfiguration('bt_xml_file')
    autostart = LaunchConfiguration('autostart')
    rviz_config_file = LaunchConfiguration('rviz_config')
    use_robot_state_pub = LaunchConfiguration('use_robot_state_pub')
    use_rviz = LaunchConfiguration('use_rviz')
    log_settings = LaunchConfiguration('log_settings', default='true')

    # Declare the launch arguments
    declare_world_cmd = DeclareLaunchArgument(
        'world',
        default_value=os.path.join(bringup_dir, 'worlds', 'world_only.model'),
        description='Full path to world file to load')

    declare_simulator_cmd = DeclareLaunchArgument(
        'simulator',
        default_value='gazebo',
        description='The simulator to use (gazebo or gzserver)')

    declare_map_yaml_cmd = DeclareLaunchArgument(
        'map',
        default_value=os.path.join(bringup_dir, 'maps',
                                   'turtlebot3_world.yaml'),
        description='Full path to map file to load')

    declare_params_file_cmd = DeclareLaunchArgument(
        'params_file',
        default_value=os.path.join(bringup_dir, 'params', 'nav2_params.yaml'),
        description=
        'Full path to the ROS2 parameters file to use for all launched nodes')

    declare_bt_xml_cmd = DeclareLaunchArgument(
        'bt_xml_file',
        default_value=os.path.join(
            get_package_share_directory('nav2_bt_navigator'), 'behavior_trees',
            'navigate_w_replanning_and_recovery.xml'),
        description='Full path to the behavior tree xml file to use')

    declare_autostart_cmd = DeclareLaunchArgument(
        'autostart',
        default_value='false',
        description='Automatically startup the stacks')

    declare_rviz_config_file_cmd = DeclareLaunchArgument(
        'rviz_config',
        default_value=os.path.join(bringup_dir, 'rviz',
                                   'nav2_namespaced_view.rviz'),
        description='Full path to the RVIZ config file to use')

    declare_use_robot_state_pub_cmd = DeclareLaunchArgument(
        'use_robot_state_pub',
        default_value='True',
        description='Whether to start the robot state publisher')

    declare_use_rviz_cmd = DeclareLaunchArgument(
        'use_rviz', default_value='True', description='Whether to start RVIZ')

    # Start Gazebo with plugin providing the robot spawing service
    start_gazebo_cmd = ExecuteProcess(
        cmd=[simulator, '--verbose', '-s', 'libgazebo_ros_factory.so', world],
        output='screen')

    # Define commands for spawing the robots into Gazebo
    spawn_robots_cmds = []
    for robot in robots:
        spawn_robots_cmds.append(
            IncludeLaunchDescription(
                PythonLaunchDescriptionSource(
                    os.path.join(bringup_dir, 'launch',
                                 'spawn_tb3_launch.py')),
                launch_arguments={
                    'x_pose': TextSubstitution(text=str(robot['x_pose'])),
                    'y_pose': TextSubstitution(text=str(robot['y_pose'])),
                    'z_pose': TextSubstitution(text=str(robot['z_pose'])),
                    'robot_name': robot['name'],
                    'turtlebot_type': TextSubstitution(text='waffle')
                }.items()))

    # Define commands for launching the navigation instances
    nav_instances_cmds = []
    for robot in robots:
        namespaced_rviz_config_file = ReplaceString(
            source_file=rviz_config_file,
            replacements={'<robot_namespace>': ('/' + robot['name'])})

        group = GroupAction([
            # TODO(orduno)
            # Each `action.Node` within the `localization` and `navigation` launch
            # files has two versions, one with the required remaps and another without.
            # The `use_remappings` flag specifies which runs.
            # A better mechanism would be to have a PushNodeRemapping() action:
            # https://github.com/ros2/launch_ros/issues/56
            # For more on why we're remapping topics, see the note below

            # PushNodeRemapping(remappings)

            # Instances use the robot's name for namespace
            PushRosNamespace(robot['name']),
            IncludeLaunchDescription(
                PythonLaunchDescriptionSource(
                    os.path.join(bringup_dir, 'launch',
                                 'nav2_tb3_simulation_launch.py')),
                launch_arguments={
                    # TODO(orduno) might not be necessary to pass the robot name
                    'namespace': robot['name'],
                    'map_yaml_file': map_yaml_file,
                    'use_sim_time': 'True',
                    'params_file': params_file,
                    'bt_xml_file': bt_xml_file,
                    'autostart': autostart,
                    'use_remappings': 'True',
                    'rviz_config_file': namespaced_rviz_config_file,
                    'use_rviz': use_rviz,
                    'use_simulator': 'False',
                    'use_robot_state_pub': use_robot_state_pub
                }.items()),
            LogInfo(condition=IfCondition(log_settings),
                    msg=['Launching ', robot['name']]),
            LogInfo(condition=IfCondition(log_settings),
                    msg=[robot['name'], ' map yaml: ', map_yaml_file]),
            LogInfo(condition=IfCondition(log_settings),
                    msg=[robot['name'], ' params yaml: ', params_file]),
            LogInfo(condition=IfCondition(log_settings),
                    msg=[robot['name'], ' behavior tree xml: ', bt_xml_file]),
            LogInfo(condition=IfCondition(log_settings),
                    msg=[
                        robot['name'], ' rviz config file: ',
                        namespaced_rviz_config_file
                    ]),
            LogInfo(condition=IfCondition(log_settings),
                    msg=[
                        robot['name'], ' using robot state pub: ',
                        use_robot_state_pub
                    ]),
            LogInfo(condition=IfCondition(log_settings),
                    msg=[robot['name'], ' autostart: ', autostart])
        ])

        nav_instances_cmds.append(group)

    # A note on the `remappings` variable defined above and the fact it's passed as a node arg.
    # A few topics have fully qualified names (have a leading '/'), these need to be remapped
    # to relative ones so the node's namespace can be prepended.
    # In case of the transforms (tf), currently, there doesn't seem to be a better alternative
    # for multi-robot transforms:
    # https://github.com/ros/geometry2/issues/32
    # https://github.com/ros/robot_state_publisher/pull/30

    # Create the launch description and populate
    ld = LaunchDescription()

    # Declare the launch options
    ld.add_action(declare_simulator_cmd)
    ld.add_action(declare_world_cmd)
    ld.add_action(declare_map_yaml_cmd)
    ld.add_action(declare_params_file_cmd)
    ld.add_action(declare_bt_xml_cmd)
    ld.add_action(declare_use_rviz_cmd)
    ld.add_action(declare_autostart_cmd)
    ld.add_action(declare_rviz_config_file_cmd)
    ld.add_action(declare_use_robot_state_pub_cmd)

    # Add the actions to start gazebo, robots and simulations
    ld.add_action(start_gazebo_cmd)

    for spawn_robot_cmd in spawn_robots_cmds:
        ld.add_action(spawn_robot_cmd)

    for simulation_instance_cmd in nav_instances_cmds:
        ld.add_action(simulation_instance_cmd)

    return ld
def generate_launch_description():
    # Get the launch directory
    bringup_dir = get_package_share_directory('nav2_bringup')
    launch_dir = os.path.join(bringup_dir, 'launch')

    # Names and poses of the robots
    robots = [{
        'name': 'robot1',
        'x_pose': 0.0,
        'y_pose': 0.5,
        'z_pose': 0.01
    }, {
        'name': 'robot2',
        'x_pose': 0.0,
        'y_pose': -0.5,
        'z_pose': 0.01
    }]

    # Simulation settings
    world = LaunchConfiguration('world')
    simulator = LaunchConfiguration('simulator')

    # On this example all robots are launched with the same settings
    map_yaml_file = LaunchConfiguration('map')

    autostart = LaunchConfiguration('autostart')
    rviz_config_file = LaunchConfiguration('rviz_config')
    use_robot_state_pub = LaunchConfiguration('use_robot_state_pub')
    use_rviz = LaunchConfiguration('use_rviz')
    log_settings = LaunchConfiguration('log_settings', default='true')

    # Declare the launch arguments
    declare_world_cmd = DeclareLaunchArgument(
        'world',
        default_value=os.path.join(bringup_dir, 'worlds', 'world_only.model'),
        description='Full path to world file to load')

    declare_simulator_cmd = DeclareLaunchArgument(
        'simulator',
        default_value='gazebo',
        description='The simulator to use (gazebo or gzserver)')

    declare_map_yaml_cmd = DeclareLaunchArgument(
        'map',
        default_value=os.path.join(bringup_dir, 'maps',
                                   'turtlebot3_world.yaml'),
        description='Full path to map file to load')

    declare_robot1_params_file_cmd = DeclareLaunchArgument(
        'robot1_params_file',
        default_value=os.path.join(bringup_dir, 'params',
                                   'nav2_multirobot_params_1.yaml'),
        description=
        'Full path to the ROS2 parameters file to use for robot1 launched nodes'
    )

    declare_robot2_params_file_cmd = DeclareLaunchArgument(
        'robot2_params_file',
        default_value=os.path.join(bringup_dir, 'params',
                                   'nav2_multirobot_params_2.yaml'),
        description=
        'Full path to the ROS2 parameters file to use for robot2 launched nodes'
    )

    declare_autostart_cmd = DeclareLaunchArgument(
        'autostart',
        default_value='false',
        description='Automatically startup the stacks')

    declare_rviz_config_file_cmd = DeclareLaunchArgument(
        'rviz_config',
        default_value=os.path.join(bringup_dir, 'rviz',
                                   'nav2_namespaced_view.rviz'),
        description='Full path to the RVIZ config file to use.')

    declare_use_robot_state_pub_cmd = DeclareLaunchArgument(
        'use_robot_state_pub',
        default_value='True',
        description='Whether to start the robot state publisher')

    declare_use_rviz_cmd = DeclareLaunchArgument(
        'use_rviz', default_value='True', description='Whether to start RVIZ')

    # Start Gazebo with plugin providing the robot spawing service
    start_gazebo_cmd = ExecuteProcess(cmd=[
        simulator, '--verbose', '-s', 'libgazebo_ros_init.so', '-s',
        'libgazebo_ros_factory.so', world
    ],
                                      output='screen')

    # Define commands for spawing the robots into Gazebo
    spawn_robots_cmds = []
    for robot in robots:
        spawn_robots_cmds.append(
            IncludeLaunchDescription(
                PythonLaunchDescriptionSource(
                    os.path.join(bringup_dir, 'launch',
                                 'spawn_tb3_launch.py')),
                launch_arguments={
                    'x_pose': TextSubstitution(text=str(robot['x_pose'])),
                    'y_pose': TextSubstitution(text=str(robot['y_pose'])),
                    'z_pose': TextSubstitution(text=str(robot['z_pose'])),
                    'robot_name': robot['name'],
                    'turtlebot_type': TextSubstitution(text='waffle')
                }.items()))

    # Define commands for launching the navigation instances
    nav_instances_cmds = []
    for robot in robots:
        params_file = LaunchConfiguration(f"{robot['name']}_params_file")

        group = GroupAction([
            IncludeLaunchDescription(PythonLaunchDescriptionSource(
                os.path.join(launch_dir, 'rviz_launch.py')),
                                     condition=IfCondition(use_rviz),
                                     launch_arguments={
                                         'namespace':
                                         TextSubstitution(text=robot['name']),
                                         'use_namespace':
                                         'True',
                                         'rviz_config':
                                         rviz_config_file
                                     }.items()),
            IncludeLaunchDescription(PythonLaunchDescriptionSource(
                os.path.join(bringup_dir, 'launch',
                             'tb3_simulation_launch.py')),
                                     launch_arguments={
                                         'namespace': robot['name'],
                                         'use_namespace': 'True',
                                         'map': map_yaml_file,
                                         'use_sim_time': 'True',
                                         'params_file': params_file,
                                         'autostart': autostart,
                                         'use_rviz': 'False',
                                         'use_simulator': 'False',
                                         'headless': 'False',
                                         'use_robot_state_pub':
                                         use_robot_state_pub
                                     }.items()),
            LogInfo(condition=IfCondition(log_settings),
                    msg=['Launching ', robot['name']]),
            LogInfo(condition=IfCondition(log_settings),
                    msg=[robot['name'], ' map yaml: ', map_yaml_file]),
            LogInfo(condition=IfCondition(log_settings),
                    msg=[robot['name'], ' params yaml: ', params_file]),
            LogInfo(
                condition=IfCondition(log_settings),
                msg=[robot['name'], ' rviz config file: ', rviz_config_file]),
            LogInfo(condition=IfCondition(log_settings),
                    msg=[
                        robot['name'], ' using robot state pub: ',
                        use_robot_state_pub
                    ]),
            LogInfo(condition=IfCondition(log_settings),
                    msg=[robot['name'], ' autostart: ', autostart])
        ])

        nav_instances_cmds.append(group)

    # Create the launch description and populate
    ld = LaunchDescription()

    # Declare the launch options
    ld.add_action(declare_simulator_cmd)
    ld.add_action(declare_world_cmd)
    ld.add_action(declare_map_yaml_cmd)
    ld.add_action(declare_robot1_params_file_cmd)
    ld.add_action(declare_robot2_params_file_cmd)
    ld.add_action(declare_use_rviz_cmd)
    ld.add_action(declare_autostart_cmd)
    ld.add_action(declare_rviz_config_file_cmd)
    ld.add_action(declare_use_robot_state_pub_cmd)

    # Add the actions to start gazebo, robots and simulations
    ld.add_action(start_gazebo_cmd)

    for spawn_robot_cmd in spawn_robots_cmds:
        ld.add_action(spawn_robot_cmd)

    for simulation_instance_cmd in nav_instances_cmds:
        ld.add_action(simulation_instance_cmd)

    return ld
def generate_launch_description():
    # Get the launch directory
    bringup_dir = get_package_share_directory('nav2_bringup')
    launch_dir = os.path.join(bringup_dir, 'launch')

    # Create the launch configuration variables
    namespace = LaunchConfiguration('namespace')
    use_namespace = LaunchConfiguration('use_namespace')
    slam = LaunchConfiguration('slam')
    map_yaml_file = LaunchConfiguration('map')
    use_sim_time = LaunchConfiguration('use_sim_time')
    params_file = LaunchConfiguration('params_file')
    autostart = LaunchConfiguration('autostart')
    use_composition = LaunchConfiguration('use_composition')

    # Map fully qualified names to relative ones so the node's namespace can be prepended.
    # In case of the transforms (tf), currently, there doesn't seem to be a better alternative
    # https://github.com/ros/geometry2/issues/32
    # https://github.com/ros/robot_state_publisher/pull/30
    # TODO(orduno) Substitute with `PushNodeRemapping`
    #              https://github.com/ros2/launch_ros/issues/56
    remappings = [('/tf', 'tf'), ('/tf_static', 'tf_static')]

    # Create our own temporary YAML files that include substitutions
    param_substitutions = {
        'use_sim_time': use_sim_time,
        'yaml_filename': map_yaml_file
    }

    configured_params = RewrittenYaml(source_file=params_file,
                                      root_key=namespace,
                                      param_rewrites=param_substitutions,
                                      convert_types=True)

    stdout_linebuf_envvar = SetEnvironmentVariable(
        'RCUTILS_LOGGING_BUFFERED_STREAM', '1')

    declare_namespace_cmd = DeclareLaunchArgument(
        'namespace', default_value='', description='Top-level namespace')

    declare_use_namespace_cmd = DeclareLaunchArgument(
        'use_namespace',
        default_value='false',
        description='Whether to apply a namespace to the navigation stack')

    declare_slam_cmd = DeclareLaunchArgument('slam',
                                             default_value='False',
                                             description='Whether run a SLAM')

    declare_map_yaml_cmd = DeclareLaunchArgument(
        'map', description='Full path to map yaml file to load')

    declare_use_sim_time_cmd = DeclareLaunchArgument(
        'use_sim_time',
        default_value='false',
        description='Use simulation (Gazebo) clock if true')

    declare_params_file_cmd = DeclareLaunchArgument(
        'params_file',
        default_value=os.path.join(bringup_dir, 'params', 'nav2_params.yaml'),
        description=
        'Full path to the ROS2 parameters file to use for all launched nodes')

    declare_autostart_cmd = DeclareLaunchArgument(
        'autostart',
        default_value='true',
        description='Automatically startup the nav2 stack')

    declare_use_composition_cmd = DeclareLaunchArgument(
        'use_composition',
        default_value='True',
        description='Whether to use composed bringup')

    # Specify the actions
    bringup_cmd_group = GroupAction([
        PushRosNamespace(condition=IfCondition(use_namespace),
                         namespace=namespace),
        Node(condition=IfCondition(use_composition),
             name='nav2_container',
             package='rclcpp_components',
             executable='component_container_isolated',
             parameters=[configured_params, {
                 'autostart': autostart
             }],
             remappings=remappings,
             output='screen'),
        IncludeLaunchDescription(PythonLaunchDescriptionSource(
            os.path.join(launch_dir, 'slam_launch.py')),
                                 condition=IfCondition(slam),
                                 launch_arguments={
                                     'namespace': namespace,
                                     'use_sim_time': use_sim_time,
                                     'autostart': autostart,
                                     'params_file': params_file
                                 }.items()),
        IncludeLaunchDescription(PythonLaunchDescriptionSource(
            os.path.join(launch_dir, 'localization_launch.py')),
                                 condition=IfCondition(
                                     PythonExpression(['not ', slam])),
                                 launch_arguments={
                                     'namespace': namespace,
                                     'map': map_yaml_file,
                                     'use_sim_time': use_sim_time,
                                     'autostart': autostart,
                                     'params_file': params_file,
                                     'use_composition': use_composition,
                                     'container_name': 'nav2_container'
                                 }.items()),
        IncludeLaunchDescription(PythonLaunchDescriptionSource(
            os.path.join(launch_dir, 'navigation_launch.py')),
                                 launch_arguments={
                                     'namespace': namespace,
                                     'use_sim_time': use_sim_time,
                                     'autostart': autostart,
                                     'params_file': params_file,
                                     'use_composition': use_composition,
                                     'container_name': 'nav2_container'
                                 }.items()),
    ])

    # Create the launch description and populate
    ld = LaunchDescription()

    # Set environment variables
    ld.add_action(stdout_linebuf_envvar)

    # Declare the launch options
    ld.add_action(declare_namespace_cmd)
    ld.add_action(declare_use_namespace_cmd)
    ld.add_action(declare_slam_cmd)
    ld.add_action(declare_map_yaml_cmd)
    ld.add_action(declare_use_sim_time_cmd)
    ld.add_action(declare_params_file_cmd)
    ld.add_action(declare_autostart_cmd)
    ld.add_action(declare_use_composition_cmd)

    # Add the actions to launch all of the navigation nodes
    ld.add_action(bringup_cmd_group)

    return ld
def generate_launch_description():
    # Get the launch directory
    bringup_dir = get_package_share_directory('nav2_bringup')
    mod_bringup_dir = get_package_share_directory('rsb_nav2')
    launch_dir = os.path.join(bringup_dir, 'launch')

    # Names and poses of the robots
    robots = [
        {'name': 'robot1', 'x_pose': 0.0, 'y_pose': 0.5, 'z_pose': 0.01},
        {'name': 'robot2', 'x_pose': 0.0, 'y_pose': -0.5, 'z_pose': 0.01}
        ]

    # Create the launch configuration variables
    slam = LaunchConfiguration('slam')
    namespace = LaunchConfiguration('namespace')
    use_namespace = LaunchConfiguration('use_namespace')
    map_yaml_file = LaunchConfiguration('map')
    use_sim_time = LaunchConfiguration('use_sim_time')
    params_file = LaunchConfiguration('params_file')
    default_bt_xml_filename = LaunchConfiguration('default_bt_xml_filename')
    autostart = LaunchConfiguration('autostart')

    # Launch configuration variables specific to simulation
    rviz_config_file = LaunchConfiguration('rviz_config_file')
    use_simulator = LaunchConfiguration('use_simulator')
    use_robot_state_pub = LaunchConfiguration('use_robot_state_pub')
    use_rviz = LaunchConfiguration('use_rviz')
    headless = LaunchConfiguration('headless')
    world = LaunchConfiguration('world')

    # Map fully qualified names to relative ones so the node's namespace can be prepended.
    # In case of the transforms (tf), currently, there doesn't seem to be a better alternative
    # https://github.com/ros/geometry2/issues/32
    # https://github.com/ros/robot_state_publisher/pull/30
    # TODO(orduno) Substitute with `PushNodeRemapping`
    #              https://github.com/ros2/launch_ros/issues/56
    remappings = [('/tf', 'tf'),
                  ('/tf_static', 'tf_static')]

    # Declare the launch arguments
    declare_namespace_cmd = DeclareLaunchArgument(
        'namespace',
        default_value='',
        description='Top-level namespace')

    declare_use_namespace_cmd = DeclareLaunchArgument(
        'use_namespace',
        default_value='true',
        description='Whether to apply a namespace to the navigation stack')

    declare_slam_cmd = DeclareLaunchArgument(
        'slam',
        default_value='False',
        description='Whether run a SLAM')

    declare_map_yaml_cmd = DeclareLaunchArgument(
        'map',
        default_value=os.path.join(bringup_dir, 'maps', 'turtlebot3_world.yaml'),
        description='Full path to map file to load')

    declare_use_sim_time_cmd = DeclareLaunchArgument(
        'use_sim_time',
        default_value='true',
        description='Use simulation (Gazebo) clock if true')

    declare_robot1_params_file_cmd = DeclareLaunchArgument(
        'robot1_params_file',
        default_value=os.path.join(mod_bringup_dir, 'params', 'nav2_multirobot_params_1.yaml'), #MOD
        description='Full path to the ROS2 parameters file to use for robot1 launched nodes')

    declare_robot2_params_file_cmd = DeclareLaunchArgument(
        'robot2_params_file',
        default_value=os.path.join(mod_bringup_dir, 'params', 'nav2_multirobot_params_2.yaml'), #MOD
        description='Full path to the ROS2 parameters file to use for robot2 launched nodes')

    declare_bt_xml_cmd = DeclareLaunchArgument(
        'default_bt_xml_filename',
        default_value=os.path.join(
            get_package_share_directory('nav2_bt_navigator'),
            'behavior_trees', 'navigate_w_replanning_and_recovery.xml'),
        description='Full path to the behavior tree xml file to use')

    declare_autostart_cmd = DeclareLaunchArgument(
        'autostart', default_value='true',
        description='Automatically startup the nav2 stack')

    declare_rviz_config_file_cmd = DeclareLaunchArgument(
        'rviz_config_file',
        default_value=os.path.join(bringup_dir, 'rviz', 'nav2_default_view.rviz'),
        description='Full path to the RVIZ config file to use')

    declare_use_simulator_cmd = DeclareLaunchArgument(
        'use_simulator',
        default_value='True',
        description='Whether to start the simulator')

    declare_use_robot_state_pub_cmd = DeclareLaunchArgument(
        'use_robot_state_pub',
        default_value='True',
        description='Whether to start the robot state publisher')

    declare_use_rviz_cmd = DeclareLaunchArgument(
        'use_rviz',
        default_value='True',
        description='Whether to start RVIZ')

    declare_simulator_cmd = DeclareLaunchArgument(
        'headless',
        default_value='False',
        description='Whether to execute gzclient)')

    declare_world_cmd = DeclareLaunchArgument(
        'world',
        # TODO(orduno) Switch back once ROS argument passing has been fixed upstream
        #              https://github.com/ROBOTIS-GIT/turtlebot3_simulations/issues/91
        # default_value=os.path.join(get_package_share_directory('turtlebot3_gazebo'),
        #                            'worlds/turtlebot3_worlds/waffle.model'),
        default_value=os.path.join(mod_bringup_dir, 'worlds', 'double_tb3_world.model'),
        description='Full path to world model file to load')

    # Specify the actions
    start_gazebo_server_cmd = ExecuteProcess(
        condition=IfCondition(use_simulator),
        cmd=['gzserver', '-s', 'libgazebo_ros_init.so', world],
        cwd=[launch_dir], output='screen')

    start_gazebo_client_cmd = ExecuteProcess(
        condition=IfCondition(PythonExpression([use_simulator, ' and not ', headless])),
        cmd=['gzclient'],
        cwd=[launch_dir], output='screen')

    urdf = os.path.join(bringup_dir, 'urdf', 'turtlebot3_waffle.urdf')

    start_robot_state_publisher_cmd = Node(
        condition=IfCondition(use_robot_state_pub),
        package='robot_state_publisher',
        executable='robot_state_publisher',
        name='robot_state_publisher',
        namespace=namespace,
        output='screen',
        parameters=[{'use_sim_time': use_sim_time}],
        remappings=remappings,
        arguments=[urdf])

    rviz_cmd = IncludeLaunchDescription(
        PythonLaunchDescriptionSource(os.path.join(launch_dir, 'rviz_launch.py')),
        condition=IfCondition(use_rviz),
        launch_arguments={'namespace': '',
                          'use_namespace': 'True',
                          'rviz_config': rviz_config_file}.items())

    bringup_cmd = IncludeLaunchDescription(
        PythonLaunchDescriptionSource(os.path.join(launch_dir, 'bringup_launch.py')),
        launch_arguments={'namespace': namespace,
                          'use_namespace': use_namespace,
                          'slam': slam,
                          'map': map_yaml_file,
                          'use_sim_time': use_sim_time,
                          'params_file': params_file,
                          'default_bt_xml_filename': default_bt_xml_filename,
                          'autostart': autostart}.items())


    # Define commands for launching the navigation instances
    nav_instances_cmds = []
    for robot in robots:
        group = GroupAction([
            IncludeLaunchDescription(
                PythonLaunchDescriptionSource(
                        os.path.join(launch_dir, 'rviz_launch.py')),
                condition=IfCondition(use_rviz),
                launch_arguments={
                                  'namespace': TextSubstitution(text=robot['name']),
                                  'use_namespace': 'True',
                                  'rviz_config': rviz_config_file}.items()),
        ])

        nav_instances_cmds.append(group)

    # Create the launch description and populate
    ld = LaunchDescription()

    # Declare the launch options
    ld.add_action(declare_namespace_cmd)
    ld.add_action(declare_use_namespace_cmd)
    ld.add_action(declare_slam_cmd)
    ld.add_action(declare_map_yaml_cmd)
    ld.add_action(declare_use_sim_time_cmd)
    ld.add_action(declare_robot1_params_file_cmd)
    ld.add_action(declare_robot2_params_file_cmd)
    ld.add_action(declare_bt_xml_cmd)
    ld.add_action(declare_autostart_cmd)

    ld.add_action(declare_rviz_config_file_cmd)
    ld.add_action(declare_use_simulator_cmd)
    ld.add_action(declare_use_robot_state_pub_cmd)
    ld.add_action(declare_use_rviz_cmd)
    ld.add_action(declare_simulator_cmd)
    ld.add_action(declare_world_cmd)

    # Add any conditioned actions
    ld.add_action(start_gazebo_server_cmd)
    ld.add_action(start_gazebo_client_cmd)

    # Add the actions to launch all of the navigation nodes
    ld.add_action(start_robot_state_publisher_cmd)
    ld.add_action(rviz_cmd)
    ld.add_action(bringup_cmd)


    for simulation_instance_cmd in nav_instances_cmds:
        ld.add_action(simulation_instance_cmd)

    return ld
def generate_launch_description():
    base_driver = LaunchConfiguration('base_driver')
    use_sim_time = LaunchConfiguration('use_sim_time')
    standard_params = {'use_sim_time': LaunchConfiguration('use_sim_time')}

    return LaunchDescription([
        DeclareLaunchArgument('base_driver', default_value='true'),
        DeclareLaunchArgument('slam', default_value='false'),
        DeclareLaunchArgument('nav', default_value='false'),
        DeclareLaunchArgument('use_sim_time', default_value='false'),
        DeclareLaunchArgument('map_path'),
        # Base
        # -- Kobuki Base
        include_launch(
            'hls_lfcd_lds_driver', 'hlds_laser.launch.py', cond='base_driver',
            launch_arguments={
                'port': '/dev/lds01',
                'frame_id': 'laser_link',
                'use_sim_time': use_sim_time,
            }.items()),
        include_launch(
            'robot_runtime', 'description.launch.py', cond=None,
            launch_arguments={
                **standard_params,
                'joint_states': base_driver,
            }.items()),
        include_launch(
            'robot_runtime', 'teleop.launch.py',
            launch_arguments={
                'base_driver': base_driver,
                'use_sim_time': use_sim_time,
            }.items()),
        Node(
            package='prometheus_exporter',
            node_executable='prometheus_exporter',
            node_name='prometheus_exporter',
            parameters=[standard_params],
            output='screen',
        ),

        GroupAction([
            PushRosNamespace('parking'),
            include_launch(
                'parking', 'parking.launch.py',
                launch_arguments={
                    'map': LaunchConfiguration('map_path'),
                    'use_sim_time': use_sim_time,
                }.items()),
        ]),

        include_launch(
            'robot_runtime', 'cartographer.launch.py', cond='slam',
            launch_arguments={
                'use_sim_sime': use_sim_time,
                'configuration_basename': 'kobuki_lds_2d.lua',
            }.items()),
        include_launch(
            'robot_runtime', 'nav.launch.py', cond='nav',
            launch_arguments={
                'use_sim_time': use_sim_time,
                'map': LaunchConfiguration('map_path'),
            }.items()),
    ])
def test_group_action_execute():
    """Test the execute() of the the GroupAction class."""
    lc1 = LaunchContext()

    assert len(lc1.launch_configurations) == 0
    assert len(GroupAction([], scoped=False).visit(lc1)) == 0
    assert len(lc1.launch_configurations) == 0

    assert len(lc1.launch_configurations) == 0
    result = GroupAction([], forwarding=True).visit(lc1)
    assert len(
        result) == 2  # push and pop actions, due to scope=True, forwarded=True
    assert isinstance(result[0], PushLaunchConfigurations)
    assert isinstance(result[1], PopLaunchConfigurations)
    for a in result:
        a.visit(lc1)
    assert len(lc1.launch_configurations) == 0

    assert len(lc1.launch_configurations) == 0
    result = GroupAction([], forwarding=False).visit(lc1)
    assert len(
        result
    ) == 3  # push, reset, pop actions, due to scope=True, forwarded=False
    assert isinstance(result[0], PushLaunchConfigurations)
    assert isinstance(result[1], ResetLaunchConfigurations)
    assert isinstance(result[2], PopLaunchConfigurations)
    for a in result:
        a.visit(lc1)
    assert len(lc1.launch_configurations) == 0

    assert len(lc1.launch_configurations) == 0
    result = GroupAction([],
                         forwarding=True,
                         launch_configurations={
                             'foo': 'FOO'
                         }).visit(lc1)
    assert len(
        result) == 3  # push, set 1 launch_configurations, and pop actions
    assert isinstance(result[0], PushLaunchConfigurations)
    assert isinstance(result[1], SetLaunchConfiguration)
    assert isinstance(result[2], PopLaunchConfigurations)
    for a in result:
        a.visit(lc1)
    assert len(lc1.launch_configurations) == 0

    assert len(lc1.launch_configurations) == 0
    result = GroupAction([],
                         forwarding=True,
                         launch_configurations={
                             'foo': 'FOO',
                             'bar': 'BAR'
                         }).visit(lc1)
    assert len(
        result) == 4  # push, set 2 launch_configurations, and pop actions
    assert isinstance(result[0], PushLaunchConfigurations)
    assert isinstance(result[1], SetLaunchConfiguration)
    assert isinstance(result[2], SetLaunchConfiguration)
    assert isinstance(result[3], PopLaunchConfigurations)
    for a in result:
        a.visit(lc1)
    assert len(lc1.launch_configurations) == 0

    assert len(lc1.launch_configurations) == 0
    result = GroupAction([],
                         forwarding=False,
                         launch_configurations={
                             'foo': 'FOO',
                             'bar': 'BAR'
                         }).visit(lc1)
    assert len(
        result
    ) == 3  # push, reset (which will set launch_configurations), and pop actions
    assert isinstance(result[0], PushLaunchConfigurations)
    assert isinstance(result[1], ResetLaunchConfigurations)
    assert isinstance(result[2], PopLaunchConfigurations)
    for a in result:
        a.visit(lc1)
    assert len(lc1.launch_configurations) == 0

    assert len(lc1.launch_configurations) == 0
    PushLaunchConfigurations().visit(lc1)
    result = GroupAction([],
                         scoped=False,
                         launch_configurations={
                             'foo': 'FOO'
                         }).visit(lc1)
    assert len(result) == 1  # set 1 launch_configurations
    assert isinstance(result[0], SetLaunchConfiguration)
    for a in result:
        a.visit(lc1)
    assert len(
        lc1.launch_configurations) == 1  # still set after group was included
    PopLaunchConfigurations().visit(lc1)
    assert len(lc1.launch_configurations) == 0

    assert len(lc1.launch_configurations) == 0
    PushLaunchConfigurations().visit(lc1)
    result = GroupAction([Action()],
                         scoped=False,
                         launch_configurations={
                             'foo': 'FOO'
                         }).visit(lc1)
    assert len(
        result
    ) == 2  # set 1 launch_configurations, then the 1 included actions
    assert isinstance(result[0], SetLaunchConfiguration)
    assert isinstance(result[1], Action)
    for a in result:
        a.visit(lc1)
    assert len(
        lc1.launch_configurations) == 1  # still set after group was included
    PopLaunchConfigurations().visit(lc1)
    assert len(lc1.launch_configurations) == 0

    assert len(lc1.launch_configurations) == 0
    result = GroupAction([Action()],
                         forwarding=True,
                         launch_configurations={
                             'foo': 'FOO'
                         }).visit(lc1)
    assert len(
        result
    ) == 4  # push, set 1 launch_configurations, the 1 action, and pop actions
    assert isinstance(result[0], PushLaunchConfigurations)
    assert isinstance(result[1], SetLaunchConfiguration)
    assert isinstance(result[2], Action)
    assert isinstance(result[3], PopLaunchConfigurations)
    for a in result:
        a.visit(lc1)
    assert len(lc1.launch_configurations) == 0

    assert len(lc1.launch_configurations) == 0
    lc1.launch_configurations['foo'] = 'FOO'
    lc1.launch_configurations['bar'] = 'BAR'
    result = GroupAction([Action()],
                         forwarding=False,
                         launch_configurations={
                             'bar': LaunchConfiguration('bar'),
                             'baz': 'BAZ'
                         }).visit(lc1)
    # push, reset (which will set launch_configurations), 1 action, and pop actions
    assert len(result) == 4
    assert isinstance(result[0], PushLaunchConfigurations)
    assert isinstance(result[1], ResetLaunchConfigurations)
    assert isinstance(result[2], Action)
    assert isinstance(result[3], PopLaunchConfigurations)
    result[0].visit(lc1)  # Push
    assert 'foo' in lc1.launch_configurations.keys(
    )  # Copied to new scope, before Reset
    assert lc1.launch_configurations['foo'] == 'FOO'
    assert 'bar' in lc1.launch_configurations.keys(
    )  # Copied to new scope, before Reset
    assert lc1.launch_configurations['bar'] == 'BAR'
    result[1].visit(lc1)  # Reset
    assert 'foo' not in lc1.launch_configurations.keys(
    )  # Cleared from scope in Reset
    assert 'bar' in lc1.launch_configurations.keys(
    )  # Evaluated and forwarded in Reset
    assert lc1.launch_configurations['bar'] == 'BAR'
    assert 'baz' in lc1.launch_configurations.keys(
    )  # Evaluated and added in Reset
    assert lc1.launch_configurations['baz'] == 'BAZ'
    result[2].visit(lc1)  # Action
    result[3].visit(lc1)  # Pop
    assert 'foo' in lc1.launch_configurations.keys()  # Still in original scope
    assert lc1.launch_configurations['foo'] == 'FOO'
    assert 'bar' in lc1.launch_configurations.keys()  # Still in original scope
    assert lc1.launch_configurations['bar'] == 'BAR'
    assert 'baz' not in lc1.launch_configurations.keys(
    )  # Out of scope from pop, no longer exists
    assert len(lc1.launch_configurations) == 2
    lc1.launch_configurations.clear()

    assert len(lc1.launch_configurations) == 0
    lc1.launch_configurations['foo'] = 'FOO'
    lc1.launch_configurations['bar'] = 'BAR'
    result = GroupAction([Action()],
                         forwarding=True,
                         launch_configurations={
                             'foo': 'OOF'
                         }).visit(lc1)
    # push, 1 set (overwrite), 1 action, and pop actions
    assert len(result) == 4
    assert isinstance(result[0], PushLaunchConfigurations)
    assert isinstance(result[1], SetLaunchConfiguration)
    assert isinstance(result[2], Action)
    assert isinstance(result[3], PopLaunchConfigurations)
    result[0].visit(lc1)  # Push
    assert 'foo' in lc1.launch_configurations.keys(
    )  # Copied to new scope, before Set
    assert lc1.launch_configurations['foo'] == 'FOO'
    assert 'bar' in lc1.launch_configurations.keys()  # Copied to new scope
    assert lc1.launch_configurations['bar'] == 'BAR'
    result[1].visit(lc1)  # Set
    assert 'foo' in lc1.launch_configurations.keys()  # Overwritten in Set
    assert lc1.launch_configurations['foo'] == 'OOF'
    assert 'bar' in lc1.launch_configurations.keys()  # Untouched
    assert lc1.launch_configurations['bar'] == 'BAR'
    result[2].visit(lc1)  # Action
    result[3].visit(lc1)  # Pop
    assert 'foo' in lc1.launch_configurations.keys(
    )  # Still in original scope with original value
    assert lc1.launch_configurations['foo'] == 'FOO'
    assert 'bar' in lc1.launch_configurations.keys(
    )  # Still in original scope with original value
    assert lc1.launch_configurations['bar'] == 'BAR'
    lc1.launch_configurations.clear()