def execute(self, context: LaunchContext) -> Optional[List[Action]]:
        """Execute the action."""
        # resolve target container node name

        if is_a_subclass(self.__target_container, ComposableNodeContainer):
            self.__final_target_container_name = self.__target_container.node_name
        elif isinstance(self.__target_container,
                        SomeSubstitutionsType_types_tuple):
            subs = normalize_to_list_of_substitutions(self.__target_container)
            self.__final_target_container_name = perform_substitutions(
                context, subs)
        else:
            self.__logger.error(
                'target container is neither a ComposableNodeContainer nor a SubstitutionType'
            )
            return

        # Create a client to load nodes in the target container.
        self.__rclpy_load_node_client = get_ros_node(context).create_client(
            composition_interfaces.srv.LoadNode,
            '{}/_container/load_node'.format(
                self.__final_target_container_name))

        # Generate load requests before execute() exits to avoid race with context changing
        # due to scope change (e.g. if loading nodes from within a GroupAction).
        load_node_requests = [
            get_composable_node_load_request(node_description, context)
            for node_description in self.__composable_node_descriptions
        ]

        context.add_completion_future(
            context.asyncio_loop.run_in_executor(None, self._load_in_sequence,
                                                 load_node_requests, context))
Example #2
0
    def execute(
        self,
        context: LaunchContext
    ) -> Optional[List[Action]]:
        """Execute the action."""
        # resolve target container node name

        if is_a_subclass(self.__target_container, ComposableNodeContainer):
            self.__final_target_container_name = self.__target_container.node_name
        elif isinstance(self.__target_container, SomeSubstitutionsType_types_tuple):
            subs = normalize_to_list_of_substitutions(self.__target_container)
            self.__final_target_container_name = perform_substitutions(
                context, subs)
        else:
            self.__logger.error(
                'target container is neither a ComposableNodeContainer nor a SubstitutionType')
            return

        # Create a client to load nodes in the target container.
        self.__rclpy_load_node_client = get_ros_node(context).create_client(
            composition_interfaces.srv.LoadNode, '{}/_container/load_node'.format(
                self.__final_target_container_name
            )
        )

        context.add_completion_future(
            context.asyncio_loop.run_in_executor(
                None, self._load_in_sequence, self.__composable_node_descriptions, context
            )
        )
Example #3
0
    def execute(self, context: LaunchContext) -> Optional[List[Action]]:
        """
        Execute the action.

        Delegated to :meth:`launch.actions.ExecuteProcess.execute`.
        """
        self._perform_substitutions(context)
        # Prepare the ros_specific_arguments list and add it to the context so that the
        # LocalSubstitution placeholders added to the the cmd can be expanded using the contents.
        ros_specific_arguments: Dict[str, Union[str, List[str]]] = {}
        if self.__node_name is not None:
            ros_specific_arguments['name'] = '__node:={}'.format(self.__expanded_node_name)
        if self.__expanded_node_namespace != '':
            ros_specific_arguments['ns'] = '__ns:={}'.format(self.__expanded_node_namespace)
        context.extend_locals({'ros_specific_arguments': ros_specific_arguments})
        ret = super().execute(context)

        if self.is_node_name_fully_specified():
            add_node_name(context, self.node_name)
            node_name_count = get_node_name_count(context, self.node_name)
            if node_name_count > 1:
                execute_process_logger = launch.logging.get_logger(self.name)
                execute_process_logger.warning(
                    'there are now at least {} nodes with the name {} created within this '
                    'launch context'.format(node_name_count, self.node_name)
                )

        return ret
Example #4
0
    def execute(self, context: LaunchContext) -> Optional[List[Action]]:
        """
        Execute the action.

        Delegated to :meth:`launch.actions.ExecuteProcess.execute`.
        """
        self._perform_substitutions(context)
        # Prepare the ros_specific_arguments list and add it to the context so that the
        # LocalSubstitution placeholders added to the the cmd can be expanded using the contents.
        ros_specific_arguments: Dict[str, Union[str, List[str]]] = {}
        if self.__node_name is not None:
            ros_specific_arguments['name'] = '__node:={}'.format(
                self.__expanded_node_name)
        if self.__expanded_node_namespace != '':
            ros_specific_arguments['ns'] = '__ns:={}'.format(
                self.__expanded_node_namespace)
        if self.__expanded_parameter_files is not None:
            ros_specific_arguments['params'] = []
            param_arguments = cast(List[str], ros_specific_arguments['params'])
            for param_file_path in self.__expanded_parameter_files:
                param_arguments.append('__params:={}'.format(param_file_path))
        if self.__expanded_remappings is not None:
            ros_specific_arguments['remaps'] = []
            for remapping_from, remapping_to in self.__expanded_remappings:
                remap_arguments = cast(List[str],
                                       ros_specific_arguments['remaps'])
                remap_arguments.append('{}:={}'.format(remapping_from,
                                                       remapping_to))
        context.extend_locals(
            {'ros_specific_arguments': ros_specific_arguments})
        return super().execute(context)
Example #5
0
 def execute(self, context: LaunchContext) -> Optional[List[Action]]:
     # TODO make sure this is done as late as possible
     context.register_event_handler(OnShutdown(on_shutdown=self._destroy))
     # TODO make sure this is done as early as possible
     self._setup()
     if self.__ld_preload_action is not None:
         return [self.__ld_preload_action]
     return None
Example #6
0
 def execute(self, context: LaunchContext) -> Optional[List[Action]]:
     self.__perform_substitutions(context)
     # TODO make sure this is done as early as possible
     if not self._setup():
         # Fail right away if tracing setup fails
         raise RuntimeError('tracing setup failed, see errors above')
     # TODO make sure this is done as late as possible
     context.register_event_handler(OnShutdown(on_shutdown=self._destroy))
     return self.__ld_preload_actions
Example #7
0
def add_node_name(context: LaunchContext, node_name: str) -> None:
    """
    Add a node name to the context, indicating an occurrence of the node name.

    :param context: the context that keeps track of the node names
    :param node_name: the node name to keep track
    """
    try:
        unique_node_names = context.locals.unique_ros_node_names
    except AttributeError:
        context.extend_globals({'unique_ros_node_names': defaultdict(int)})
        unique_node_names = context.locals.unique_ros_node_names
    unique_node_names[node_name] += 1
Example #8
0
 def execute(self, context: LaunchContext):
     """Execute the action."""
     eval_param_dict = evaluate_parameter_dict(context, self.__param_dict)
     global_param_list = context.launch_configurations.get(
         'global_params', [])
     global_param_list.extend(eval_param_dict.items())
     context.launch_configurations['global_params'] = global_param_list
Example #9
0
 def execute(self, context: LaunchContext):
     """Execute the action."""
     src = perform_substitutions(context, self.__src)
     dst = perform_substitutions(context, self.__dst)
     global_remaps = context.launch_configurations.get('ros_remaps', [])
     global_remaps.append((src, dst))
     context.launch_configurations['ros_remaps'] = global_remaps
def test_failing_command_rises(commands):
    """Test that a failing command raises."""
    context = LaunchContext()
    command = Command(commands['failing'])
    with pytest.raises(SubstitutionFailure) as ex:
        command.perform(context)
    ex.match('executed command failed. Command: .*failing_command')
Example #11
0
def test_reset():
    xml_file = \
        """\
        <launch>
            <let name="foo" value="FOO"/>
            <let name="bar" value="BAR"/>
            <reset>
                <keep name="bar" value="$(var bar)"/>
                <keep name="baz" value="BAZ"/>
            </reset>
        </launch>
        """  # noqa: E501
    xml_file = textwrap.dedent(xml_file)
    root_entity, parser = Parser.load(io.StringIO(xml_file))
    ld = parser.parse_description(root_entity)

    assert isinstance(ld.entities[0], SetLaunchConfiguration)
    assert isinstance(ld.entities[1], SetLaunchConfiguration)
    assert isinstance(ld.entities[2], ResetLaunchConfigurations)

    lc = LaunchContext()
    assert len(lc.launch_configurations) == 0
    ld.entities[0].visit(lc)
    ld.entities[1].visit(lc)
    assert len(lc.launch_configurations) == 2
    assert 'foo' in lc.launch_configurations.keys()
    assert lc.launch_configurations['foo'] == 'FOO'
    assert 'bar' in lc.launch_configurations.keys()
    assert lc.launch_configurations['bar'] == 'BAR'
    ld.entities[2].visit(lc)
    assert 'foo' not in lc.launch_configurations.keys()
    assert 'bar' in lc.launch_configurations.keys()
    assert lc.launch_configurations['bar'] == 'BAR'
    assert 'baz' in lc.launch_configurations.keys()
    assert lc.launch_configurations['baz'] == 'BAZ'
def test_missing_command_raises(commands):
    """Test that a command that doesn't exist raises."""
    context = LaunchContext()
    command = Command('ros2_launch_test_command_i_m_not_a_command')
    with pytest.raises(SubstitutionFailure) as ex:
        command.perform(context)
    ex.match('file not found:')
Example #13
0
def test_group():
    yaml_file = \
        """\
        launch:
            - let:
                name: 'foo'
                value: 'FOO'
            - let:
                name: 'bar'
                value: 'BAR'
            - group:
                scoped: True
                forwarding: False
                keep:
                    -   name: 'bar'
                        value: $(var bar)
                    -   name: 'baz'
                        value: 'BAZ'
                children:
                    - let:
                        name: 'var1'
                        value: 'asd'
                    - let:
                        name: 'var2'
                        value: 'asd'
        """  # noqa: E501
    yaml_file = textwrap.dedent(yaml_file)
    root_entity, parser = Parser.load(io.StringIO(yaml_file))
    ld = parser.parse_description(root_entity)

    assert isinstance(ld.entities[0], SetLaunchConfiguration)
    assert isinstance(ld.entities[1], SetLaunchConfiguration)
    assert isinstance(ld.entities[2], GroupAction)

    lc = LaunchContext()
    assert 0 == len(lc.launch_configurations)
    ld.entities[0].visit(lc)
    ld.entities[1].visit(lc)
    assert 2 == len(lc.launch_configurations)
    assert 'foo' in lc.launch_configurations.keys()
    assert 'FOO' == lc.launch_configurations['foo']
    assert 'bar' in lc.launch_configurations.keys()
    assert 'BAR' == lc.launch_configurations['bar']
    actions = ld.entities[2].execute(lc)
    assert 5 == len(actions)
    assert isinstance(actions[0], PushLaunchConfigurations)
    assert isinstance(actions[1], ResetLaunchConfigurations)
    assert isinstance(actions[2], SetLaunchConfiguration)
    assert isinstance(actions[3], SetLaunchConfiguration)
    assert isinstance(actions[4], PopLaunchConfigurations)
    actions[0].visit(lc)
    actions[1].visit(lc)
    assert 'foo' not in lc.launch_configurations.keys()
    assert 'bar' in lc.launch_configurations.keys()
    assert 'BAR' == lc.launch_configurations['bar']
    assert 'baz' in lc.launch_configurations.keys()
    assert 'BAZ' == lc.launch_configurations['baz']
    actions[2].visit(lc)
    actions[3].visit(lc)
    actions[4].visit(lc)
 def execute(self, context: LaunchContext):
     """Execute the action."""
     filename = perform_substitutions(context, self._input_file)
     global_param_list = context.launch_configurations.get(
         'global_params', [])
     global_param_list.append(filename)
     context.launch_configurations['global_params'] = global_param_list
Example #15
0
    def _load_in_sequence(self,
                          composable_node_descriptions: List[ComposableNode],
                          context: LaunchContext) -> None:
        """
        Load composable nodes sequentially.

        :param composable_node_descriptions: descriptions of composable nodes to be loaded
        :param context: current launch context
        """
        next_composable_node_description = composable_node_descriptions[0]
        composable_node_descriptions = composable_node_descriptions[1:]
        self._load_node(next_composable_node_description, context)
        if len(composable_node_descriptions) > 0:
            context.add_completion_future(
                context.asyncio_loop.run_in_executor(
                    None, self._load_in_sequence, composable_node_descriptions,
                    context))
    def _load_in_sequence(self, load_node_requests: List[
        composition_interfaces.srv.LoadNode.Request],
                          context: LaunchContext) -> None:
        """
        Load composable nodes sequentially.

        :param composable_node_descriptions: descriptions of composable nodes to be loaded
        :param context: current launch context
        """
        next_load_node_request = load_node_requests[0]
        load_node_requests = load_node_requests[1:]
        self._load_node(next_load_node_request, context)
        if len(load_node_requests) > 0:
            context.add_completion_future(
                context.asyncio_loop.run_in_executor(None,
                                                     self._load_in_sequence,
                                                     load_node_requests,
                                                     context))
def test_command_with_stderr_raises(commands):
    """Test that a command that produces stderr raises."""
    context = LaunchContext()
    command = Command(commands['with_stderr'])
    with pytest.raises(SubstitutionFailure) as ex:
        command.perform(context)
    ex.match(
        'executed command showed stderr output. Command: .*command_with_stderr'
        r'[\w\W]*asd bsd')
Example #18
0
def test_passthrough_properties():
    name = 'name'
    cwd = 'cwd'
    env = {'a': '1'}
    exe = Executable(cmd=['test'], name=name, cwd=cwd, env=env)
    exe.prepare(LaunchContext(), None)
    assert exe.final_name.startswith(name)
    assert exe.final_cwd == cwd
    assert exe.final_env == env
def generate_launch_description():
    map_yaml_file = os.getenv('TEST_MAP')
    world = os.getenv('TEST_WORLD')

    bt_navigator_xml = 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')
    params_file = os.path.join(bringup_dir, 'params', 'nav2_params.yaml')

    # Replace the `use_astar` setting on the params file
    param_substitutions = {
        'planner_server.ros__parameters.GridBased.use_astar': 'False'}
    configured_params = RewrittenYaml(
        source_file=params_file,
        root_key='',
        param_rewrites=param_substitutions,
        convert_types=True)

    context = LaunchContext()
    new_yaml = configured_params.perform(context)
    return LaunchDescription([
        SetEnvironmentVariable('RCUTILS_LOGGING_BUFFERED_STREAM', '1'),
        SetEnvironmentVariable('RCUTILS_LOGGING_USE_STDOUT', '1'),

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

        # TODO(orduno) Launch the robot state publisher instead
        #              using a local copy of TB3 urdf file
        Node(
            package='tf2_ros',
            executable='static_transform_publisher',
            output='screen',
            arguments=['0', '0', '0', '0', '0', '0', 'base_footprint', 'base_link']),

        Node(
            package='tf2_ros',
            executable='static_transform_publisher',
            output='screen',
            arguments=['0', '0', '0', '0', '0', '0', 'base_link', 'base_scan']),

        IncludeLaunchDescription(
            PythonLaunchDescriptionSource(
                os.path.join(bringup_dir, 'launch', 'bringup_launch.py')),
            launch_arguments={'namespace': '',
                              'use_namespace': 'False',
                              'map': map_yaml_file,
                              'use_sim_time': 'True',
                              'params_file': new_yaml,
                              'bt_xml_file': bt_navigator_xml,
                              'autostart': 'True'}.items()),
    ])
Example #20
0
File: node.py Project: hfz-Nick/ROS
    def execute(self, context: LaunchContext) -> Optional[List[Action]]:
        """
        Execute the action.

        Delegated to :meth:`launch.actions.ExecuteProcess.execute`.
        """
        self._perform_substitutions(context)
        # Prepare the ros_specific_arguments list and add it to the context so that the
        # LocalSubstitution placeholders added to the the cmd can be expanded using the contents.
        ros_specific_arguments = []  # type: List[Text]
        if self.__node_name is not None:
            ros_specific_arguments.append('__node:={}'.format(
                self.__expanded_node_name))
        if self.__node_namespace is not None:
            ros_specific_arguments.append('__ns:={}'.format(
                self.__expanded_node_namespace))
        if self.__expanded_remappings is not None:
            for remapping_from, remapping_to in self.__remappings:
                ros_specific_arguments.append('{}:={}'.format(
                    remapping_from, remapping_to))
        context.extend_locals(
            {'ros_specific_arguments': ros_specific_arguments})
        return super().execute(context)
Example #21
0
 def execute(self, context: LaunchContext):
     """Execute the action."""
     pushed_namespace = perform_substitutions(context, self.namespace)
     previous_namespace = context.launch_configurations.get(
         'ros_namespace', None)
     namespace = make_namespace_absolute(
         prefix_namespace(previous_namespace, pushed_namespace))
     try:
         validate_namespace(namespace)
     except Exception:
         raise SubstitutionFailure(
             'The resulting namespace is invalid:'
             " [previous_namespace='{}', pushed_namespace='{}']".format(
                 previous_namespace, pushed_namespace))
     context.launch_configurations['ros_namespace'] = namespace
Example #22
0
def test_group():
    xml_file = \
        """\
        <launch>
            <let name="foo" value="FOO"/>
            <let name="bar" value="BAR"/>
            <group scoped="True" forwarding="False">
                <keep name="bar" value="$(var bar)"/>
                <keep name="baz" value="BAZ"/>
                <let name="var1" value="asd"/>
                <let name="var2" value="asd"/>
            </group>
        </launch>
        """  # noqa: E501
    xml_file = textwrap.dedent(xml_file)
    root_entity, parser = Parser.load(io.StringIO(xml_file))
    ld = parser.parse_description(root_entity)

    assert isinstance(ld.entities[0], SetLaunchConfiguration)
    assert isinstance(ld.entities[1], SetLaunchConfiguration)
    assert isinstance(ld.entities[2], GroupAction)

    lc = LaunchContext()
    assert 0 == len(lc.launch_configurations)
    ld.entities[0].visit(lc)
    ld.entities[1].visit(lc)
    assert 2 == len(lc.launch_configurations)
    assert 'foo' in lc.launch_configurations.keys()
    assert 'FOO' == lc.launch_configurations['foo']
    assert 'bar' in lc.launch_configurations.keys()
    assert 'BAR' == lc.launch_configurations['bar']
    actions = ld.entities[2].execute(lc)
    assert 5 == len(actions)
    assert isinstance(actions[0], PushLaunchConfigurations)
    assert isinstance(actions[1], ResetLaunchConfigurations)
    assert isinstance(actions[2], SetLaunchConfiguration)
    assert isinstance(actions[3], SetLaunchConfiguration)
    assert isinstance(actions[4], PopLaunchConfigurations)
    actions[0].visit(lc)
    actions[1].visit(lc)
    assert 'foo' not in lc.launch_configurations.keys()
    assert 'bar' in lc.launch_configurations.keys()
    assert 'BAR' == lc.launch_configurations['bar']
    assert 'baz' in lc.launch_configurations.keys()
    assert 'BAZ' == lc.launch_configurations['baz']
    actions[2].visit(lc)
    actions[3].visit(lc)
    actions[4].visit(lc)
Example #23
0
    def execute(self, context: LaunchContext):
        """Execute the action."""
        with open(str(self.__param_file.evaluate(context)), 'r') as f:
            eval_param_dict = yaml.safe_load(f)['/**']['ros__parameters']

        vehicle_info_keys = {
            'wheel_radius', 'wheel_width', 'wheel_base', 'wheel_tread',
            'front_overhang', 'rear_overhang', 'left_overhang',
            'right_overhang', 'vehicle_height'
        }

        if vehicle_info_keys <= eval_param_dict.keys():
            eval_param_dict['ready_vehicle_info_param'] = True
            global_params = context.launch_configurations.get('ros_params', {})
            global_params.update(eval_param_dict)
            context.launch_configurations['ros_params'] = global_params
        else:
            raise RuntimeError('vehicle info param file is invalid.')
 def execute(self, context: LaunchContext):
     """Execute the action."""
     pushed_namespace = perform_substitutions(context, self.namespace)
     previous_namespace = context.launch_configurations.get(
         'ros_namespace', '')
     namespace = pushed_namespace
     if not pushed_namespace.startswith('/'):
         namespace = previous_namespace + '/' + pushed_namespace
     namespace = namespace.rstrip('/')
     if namespace != '':
         try:
             validate_namespace(namespace)
         except Exception:
             raise SubstitutionFailure(
                 'The resulting namespace is invalid:'
                 " [previous_namespace='{}', pushed_namespace='{}']".format(
                     previous_namespace, pushed_namespace))
     context.launch_configurations['ros_namespace'] = namespace
Example #25
0
def test_reset():
    yaml_file = \
        """\
        launch:
            - let:
                name: 'foo'
                value: 'FOO'
            - let:
                name: 'bar'
                value: 'BAR'
            - reset:
                keep:
                    -   name: 'bar'
                        value: $(var bar)
                    -   name: 'baz'
                        value: 'BAZ'
        """  # noqa: E501
    print('Load YAML')
    yaml_file = textwrap.dedent(yaml_file)
    print('Load Parser')
    root_entity, parser = Parser.load(io.StringIO(yaml_file))
    print('Parse Description')
    ld = parser.parse_description(root_entity)

    assert isinstance(ld.entities[0], SetLaunchConfiguration)
    assert isinstance(ld.entities[1], SetLaunchConfiguration)
    assert isinstance(ld.entities[2], ResetLaunchConfigurations)

    lc = LaunchContext()
    assert len(lc.launch_configurations) == 0
    ld.entities[0].visit(lc)
    ld.entities[1].visit(lc)
    assert len(lc.launch_configurations) == 2
    assert 'foo' in lc.launch_configurations.keys()
    assert lc.launch_configurations['foo'] == 'FOO'
    assert 'bar' in lc.launch_configurations.keys()
    assert lc.launch_configurations['bar'] == 'BAR'
    ld.entities[2].visit(lc)
    assert 'foo' not in lc.launch_configurations.keys()
    assert 'bar' in lc.launch_configurations.keys()
    assert lc.launch_configurations['bar'] == 'BAR'
    assert 'baz' in lc.launch_configurations.keys()
    assert lc.launch_configurations['baz'] == 'BAZ'
Example #26
0
def test_substituted_properties():
    os.environ['EXECUTABLE_NAME'] = 'name'
    os.environ['EXECUTABLE_CWD'] = 'cwd'
    os.environ['EXECUTABLE_ENVVAR'] = 'var'
    os.environ['EXECUTABLE_ENVVAL'] = 'value'
    name = EnvironmentVariable('EXECUTABLE_NAME')
    cwd = EnvironmentVariable('EXECUTABLE_CWD')
    env = {
        EnvironmentVariable('EXECUTABLE_ENVVAR'):
        EnvironmentVariable('EXECUTABLE_ENVVAL')
    }
    exe = Executable(cmd=['test'], name=name, cwd=cwd, env=env)
    exe.prepare(LaunchContext(), None)
    assert exe.final_name.startswith('name')
    assert exe.final_cwd == 'cwd'
    assert exe.final_env == {'var': 'value'}
    del os.environ['EXECUTABLE_NAME']
    del os.environ['EXECUTABLE_CWD']
    del os.environ['EXECUTABLE_ENVVAR']
    del os.environ['EXECUTABLE_ENVVAL']
Example #27
0
    else:
        raise RuntimeError('No launch file supplied')

    launch_arguments.extend(args.launch_arguments)
    parsed_launch_arguments = parse_launch_arguments(launch_arguments)

    launch_description = launch.LaunchDescription([
        launch.actions.IncludeLaunchDescription(
            launch.launch_description_sources.AnyLaunchDescriptionSource(path),
            launch_arguments=parsed_launch_arguments,
        ),
    ])
    walker = []
    walker.append(launch_description)
    ros_specific_arguments: Dict[str, Union[str, List[str]]] = {}
    context = LaunchContext(argv=launch_arguments)
    context._set_asyncio_loop(asyncio.get_event_loop())

    try:
        # * Here we mimic the run loop inside launch_service,
        #   but without actually kicking off the processes.
        # * Traverse the sub entities by DFS.
        # * Shadow the stdout to avoid random print outputs.
        mystring = StringIO()
        sys.stdout = mystring
        while walker:
            entity = walker.pop()
            visit_future = entity.visit(context)
            if visit_future is not None:
                visit_future.reverse()
                walker.extend(visit_future)
                          default_value='127.0.0.1',
                          description='ROBOT_IP'),
    DeclareLaunchArgument('port',
                          default_value='12345',
                          description='ROBOT_PORT'),
    DeclareLaunchArgument('mode',
                          default_value='virtual',
                          description='OPERATION MODE'),
    DeclareLaunchArgument('model',
                          default_value='m1013',
                          description='ROBOT_MODEL'),
    DeclareLaunchArgument('color',
                          default_value='white',
                          description='ROBOT_COLOR'),
]
context = LaunchContext()


def load_file(package_name, file_path):
    package_path = get_package_share_directory(package_name)
    absolute_file_path = os.path.join(package_path, file_path)

    try:
        with open(absolute_file_path, 'r') as file:
            return file.read()
    except EnvironmentError:  # parent of IOError, OSError *and* WindowsError where available
        return None


def load_yaml(package_name, file_path):
    package_path = get_package_share_directory(package_name)
def test_command_with_stderr_warn(commands):
    """Test `Command` substitution with `on_stderr='warn'`."""
    context = LaunchContext()
    command = Command(commands['with_stderr'], on_stderr='warn')
    output = command.perform(context)
    assert output == ''
def test_command_with_stderr_capture(commands):
    """Test `Command` substitution with `on_stderr='capture'`."""
    context = LaunchContext()
    command = Command(commands['with_stderr'], on_stderr='capture')
    output = command.perform(context)
    assert output == 'asd bsd\n'