Пример #1
0
def test_node_name_count():
    lc = LaunchContext()
    add_node_name(lc, 'node_name_1')
    add_node_name(lc, 'node_name_1')
    add_node_name(lc, 'node_name_2')
    assert get_node_name_count(lc, 'node_name_1') == 2
    assert get_node_name_count(lc, 'node_name_2') == 1
    assert get_node_name_count(lc, 'node_name_3') == 0
Пример #2
0
def test_launch_node_with_name_without_namespace():
    node = Node(
        package='demo_nodes_py',
        node_executable='listener_qos',
        node_name=TEST_NODE_NAME,
        output='screen',
    )
    ld = LaunchDescription([node])
    context = _launch(ld)
    assert get_node_name_count(context, f'{TEST_NODE_NAMESPACE}/{TEST_NODE_NAME}') == 0
    assert get_node_name_count(context, f'/{TEST_NODE_NAME}') == 1
Пример #3
0
def test_launch_node_without_name():
    node = Node(
        package='demo_nodes_py',
        node_executable='listener_qos',
        node_namespace=TEST_NODE_NAMESPACE,
        output='screen',
    )
    ld = LaunchDescription([node])
    context = _launch(ld)
    # For Nodes, when node_name is omitted, launch_ros is unable to track it
    assert get_node_name_count(context, f'{TEST_NODE_NAMESPACE}/{TEST_NODE_NAME}') == 0
    assert get_node_name_count(context, f'/{TEST_NODE_NAME}') == 0
def test_composable_node_container_empty_list_of_nodes():
    """Test launching a ComposableNodeContainer with an empty list of nodes."""
    actions = [
        ComposableNodeContainer(package='rclcpp_components',
                                executable='component_container',
                                name=TEST_CONTAINER_NAME,
                                namespace=TEST_CONTAINER_NAMESPACE,
                                composable_node_descriptions=[]),
    ]

    context = _assert_launch_no_errors(actions)
    assert get_node_name_count(
        context, f'/{TEST_CONTAINER_NAMESPACE}/{TEST_CONTAINER_NAME}') == 1
    assert get_node_name_count(context,
                               f'/{TEST_NODE_NAMESPACE}/{TEST_NODE_NAME}') == 0
Пример #5
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
Пример #6
0
def test_load_node_with_namespace_in_group(mock_component_container):
    """Test loading a node with namespace scoped to a group."""
    context = _assert_launch_no_errors([
        GroupAction(
            [
                PushRosNamespace('foo'),
                _load_composable_node(
                    package='foo_package',
                    plugin='bar_plugin',
                    name='test_node_name',
                    namespace='test_node_namespace'
                ),
            ],
            scoped=True,
        ),
    ])

    # Check that launch is aware of loaded component
    assert get_node_name_count(context, '/foo/test_node_namespace/test_node_name') == 1

    # Check that container recieved correct request
    assert len(mock_component_container.requests) == 1
    request = mock_component_container.requests[0]
    assert request.package_name == 'foo_package'
    assert request.plugin_name == 'bar_plugin'
    assert request.node_name == 'test_node_name'
    assert request.node_namespace == '/foo/test_node_namespace'
    assert len(request.remap_rules) == 0
    assert len(request.parameters) == 0
    assert len(request.extra_arguments) == 0
Пример #7
0
def test_load_node_with_params(mock_component_container):
    """Test loading a node with parameters."""
    context = _assert_launch_no_errors([
        _load_composable_node(
            package='foo_package',
            plugin='bar_plugin',
            name='test_node_name',
            namespace='test_node_namespace',
            parameters=[{
                'test_param1': 'test_value_param1',
                'test.param2': 42.0,
            }]
        )
    ])

    # Check that launch is aware of loaded component
    assert get_node_name_count(context, '/test_node_namespace/test_node_name') == 1

    # Check that container recieved correct request
    assert len(mock_component_container.requests) == 1
    request = mock_component_container.requests[0]
    assert request.package_name == 'foo_package'
    assert request.plugin_name == 'bar_plugin'
    assert request.node_name == 'test_node_name'
    assert request.node_namespace == '/test_node_namespace'
    assert len(request.remap_rules) == 0
    assert len(request.parameters) == 2
    assert request.parameters[0].name == 'test_param1'
    assert request.parameters[0].value.type == ParameterType.PARAMETER_STRING
    assert request.parameters[0].value.string_value == 'test_value_param1'
    assert request.parameters[1].name == 'test.param2'
    assert request.parameters[1].value.type == ParameterType.PARAMETER_DOUBLE
    assert request.parameters[1].value.double_value == 42.0
    assert len(request.extra_arguments) == 0
Пример #8
0
def test_load_node_with_remaps(mock_component_container):
    """Test loading a node with remappings."""
    context = _assert_launch_no_errors([
        _load_composable_node(
            package='foo_package',
            plugin='bar_plugin',
            name='test_node_name',
            namespace='test_node_namespace',
            remappings=[
                ('test_topic1', 'test_remap_topic1'),
                ('test/topic/two', 'test/remap_topic2')
            ]
        )
    ])

    # Check that launch is aware of loaded component
    assert get_node_name_count(context, '/test_node_namespace/test_node_name') == 1

    # Check that container recieved correct request
    assert len(mock_component_container.requests) == 1
    request = mock_component_container.requests[0]
    assert request.package_name == 'foo_package'
    assert request.plugin_name == 'bar_plugin'
    assert request.node_name == 'test_node_name'
    assert request.node_namespace == '/test_node_namespace'
    assert len(request.remap_rules) == 2
    assert request.remap_rules[0] == 'test_topic1:=test_remap_topic1'
    assert request.remap_rules[1] == 'test/topic/two:=test/remap_topic2'
    assert len(request.parameters) == 0
    assert len(request.extra_arguments) == 0
Пример #9
0
def test_launch_composable_node_without_component_name():
    node = ComposableNodeContainer(package='rclcpp_components',
                                   executable='component_container',
                                   node_name=TEST_NODE_NAME,
                                   node_namespace=TEST_NODE_NAMESPACE,
                                   composable_node_descriptions=[
                                       ComposableNode(
                                           package='composition',
                                           node_plugin='composition::Listener',
                                           node_namespace=TEST_NODE_NAMESPACE)
                                   ],
                                   output='screen')
    ld = LaunchDescription([node])
    context = _launch(ld)
    assert get_node_name_count(context,
                               f'{TEST_NODE_NAMESPACE}/{TEST_NODE_NAME}') == 1
    # Unlike for Nodes, launch_ros is able to track component node names even when
    # node_name is not provided for the component
    assert get_node_name_count(context, f'{TEST_NODE_NAMESPACE}/listener') == 1
Пример #10
0
def test_launch_nodes_with_same_names(pytestconfig):
    node1 = Node(
        package='demo_nodes_py',
        node_executable='listener_qos',
        node_name=TEST_NODE_NAME,
        node_namespace=TEST_NODE_NAMESPACE,
        output='screen',
    )

    node2 = LifecycleNode(
        package='lifecycle',
        node_executable='lifecycle_listener',
        node_name=TEST_NODE_NAME,
        node_namespace=TEST_NODE_NAMESPACE,
        output='screen',
    )

    node3 = ComposableNodeContainer(
        package='rclcpp_components',
        node_executable='component_container',
        node_name=TEST_NODE_NAME,
        node_namespace=TEST_NODE_NAMESPACE,
        composable_node_descriptions=[
            ComposableNode(
                package='composition',
                node_plugin='composition::Listener',
                node_name=TEST_NODE_NAME
            )
        ],
        output='screen'
    )

    ld = LaunchDescription([node1, node2, node3])
    context = _launch(ld)
    captured = pytestconfig.pluginmanager.getplugin('capturemanager').read_global_capture()
    assert get_node_name_count(context, f'{TEST_NODE_NAMESPACE}/{TEST_NODE_NAME}') == 3
    expected_line = f'there are now at least 3 nodes with the name {TEST_NODE_NAMESPACE}' \
        f'/{TEST_NODE_NAME} created within this launch context'
    assert expected_line in captured.out
    assert get_node_name_count(context, f'/{TEST_NODE_NAME}') == 1
Пример #11
0
def test_launch_nodes_with_different_names():
    node1 = Node(
        package='demo_nodes_py',
        executable='listener_qos',
        node_name=f'{TEST_NODE_NAME}_1',
        node_namespace=TEST_NODE_NAMESPACE,
        output='screen',
    )

    node2 = LifecycleNode(
        package='lifecycle',
        executable='lifecycle_listener',
        node_name=f'{TEST_NODE_NAME}_2',
        node_namespace=TEST_NODE_NAMESPACE,
        output='screen',
    )

    node3 = ComposableNodeContainer(
        package='rclcpp_components',
        executable='component_container',
        node_name=f'{TEST_NODE_NAME}_3',
        node_namespace=TEST_NODE_NAMESPACE,
        composable_node_descriptions=[
            ComposableNode(
                package='composition',
                node_plugin='composition::Listener',
                node_name=f'{TEST_NODE_NAME}_4',
            )
        ],
        output='screen')

    ld = LaunchDescription([node1, node2, node3])
    context = _launch(ld)
    assert get_node_name_count(
        context, f'{TEST_NODE_NAMESPACE}/{TEST_NODE_NAME}_1') == 1
    assert get_node_name_count(
        context, f'{TEST_NODE_NAMESPACE}/{TEST_NODE_NAME}_2') == 1
    assert get_node_name_count(
        context, f'{TEST_NODE_NAMESPACE}/{TEST_NODE_NAME}_3') == 1
    assert get_node_name_count(context, f'/{TEST_NODE_NAME}_4') == 1
def test_composable_node_container_in_group_with_launch_configuration_in_description(
):
    """
    Test launch configuration is passed to ComposableNode description inside GroupAction.

    This is a regression test for #114.
    """
    actions = [
        GroupAction([
            DeclareLaunchArgument(name='test_arg', default_value='True'),
            ComposableNodeContainer(
                package='rclcpp_components',
                executable='component_container',
                name=TEST_CONTAINER_NAME,
                namespace=TEST_CONTAINER_NAMESPACE,
                composable_node_descriptions=[
                    ComposableNode(
                        package='composition',
                        plugin='composition::Listener',
                        name=TEST_NODE_NAME,
                        namespace=TEST_NODE_NAMESPACE,
                        parameters=[{
                            'use_sim_time':
                            LaunchConfiguration('test_arg')
                        }],
                    )
                ],
            ),
        ],
                    scoped=True),
    ]

    context = _assert_launch_no_errors(actions)
    assert get_node_name_count(
        context, f'/{TEST_CONTAINER_NAMESPACE}/{TEST_CONTAINER_NAME}') == 1
    assert get_node_name_count(context,
                               f'/{TEST_NODE_NAMESPACE}/{TEST_NODE_NAME}') == 1
def test_composable_node_container():
    """Nominal test for launching a ComposableNodeContainer."""
    actions = [
        ComposableNodeContainer(
            package='rclcpp_components',
            executable='component_container',
            name=TEST_CONTAINER_NAME,
            namespace=TEST_CONTAINER_NAMESPACE,
            composable_node_descriptions=[
                ComposableNode(
                    package='composition',
                    plugin='composition::Listener',
                    name=TEST_NODE_NAME,
                    namespace=TEST_NODE_NAMESPACE,
                )
            ],
        ),
    ]

    context = _assert_launch_no_errors(actions)
    assert get_node_name_count(
        context, f'/{TEST_CONTAINER_NAMESPACE}/{TEST_CONTAINER_NAME}') == 1
    assert get_node_name_count(context,
                               f'/{TEST_NODE_NAMESPACE}/{TEST_NODE_NAME}') == 1
Пример #14
0
def test_load_node(mock_component_container):
    """Test loading a node."""
    context = _assert_launch_no_errors([
        _load_composable_node(package='foo_package',
                              plugin='bar_plugin',
                              name='test_node_name',
                              namespace='test_node_namespace')
    ])

    # Check that launch is aware of loaded component
    assert get_node_name_count(context,
                               '/test_node_namespace/test_node_name') == 1

    # Check that container recieved correct request
    assert len(mock_component_container.requests) == 1
    request = mock_component_container.requests[0]
    assert request.package_name == 'foo_package'
    assert request.plugin_name == 'bar_plugin'
    assert request.node_name == 'test_node_name'
    assert request.node_namespace == '/test_node_namespace'
    assert len(request.remap_rules) == 0
    assert len(request.parameters) == 0
    assert len(request.extra_arguments) == 0
Пример #15
0
def test_load_node_with_param_file(mock_component_container):
    """Test loading a node with with parameters specified in yaml files."""
    parameters_file_dir = pathlib.Path(__file__).resolve().parent

    # Case 1: no node name in yaml file
    context = _assert_launch_no_errors([
        _load_composable_node(
            package='foo_package',
            plugin='bar_plugin',
            name='test_node_name',
            namespace='test_node_namespace',
            parameters=[
                parameters_file_dir / 'example_parameters_no_name.yaml'
            ],
        )
    ])
    request = mock_component_container.requests[0]
    assert get_node_name_count(context, '/test_node_namespace/test_node_name') == 1
    assert request.node_name == 'test_node_name'
    assert request.node_namespace == '/test_node_namespace'
    assert len(request.parameters) == 2
    assert request.parameters[0].name == 'some_int'
    assert request.parameters[0].value.integer_value == 42
    assert request.parameters[1].name == 'a_string'
    assert request.parameters[1].value.string_value == 'Hello world'

    # Case 2: node name with namespace
    context = _assert_launch_no_errors([
        _load_composable_node(
            package='foo_package',
            plugin='bar_plugin',
            name='test_node_name',
            namespace='ns',
            parameters=[
                parameters_file_dir / 'example_parameters_namespace.yaml'
            ],
        )
    ])
    request = mock_component_container.requests[1]
    assert get_node_name_count(context, '/ns/test_node_name') == 1
    assert request.node_name == 'test_node_name'
    assert request.node_namespace == '/ns'
    assert len(request.parameters) == 1
    assert request.parameters[0].name == 'param'
    assert request.parameters[0].value.integer_value == 1

    # Case 3: nested node name with namespace
    context = _assert_launch_no_errors([
        _load_composable_node(
            package='foo_package',
            plugin='bar_plugin',
            name='my_node',
            namespace='my_ns',
            parameters=[
                parameters_file_dir / 'example_parameters_nested_namespace.yaml'
            ],
        )
    ])
    request = mock_component_container.requests[2]
    assert get_node_name_count(context, '/my_ns/my_node') == 1
    assert request.node_name == 'my_node'
    assert request.node_namespace == '/my_ns'
    assert len(request.parameters) == 5
    assert request.parameters[0].name == 'some_int'
    assert request.parameters[0].value.integer_value == 42
    assert request.parameters[1].name == 'a_string'
    assert request.parameters[1].value.string_value == 'Hello world'
    assert request.parameters[2].value.string_value == ''

    # Case 4: node name without namespace
    context = _assert_launch_no_errors([
        _load_composable_node(
            package='foo_package',
            plugin='bar_plugin',
            name='test_node_name',
            namespace='',
            parameters=[
                parameters_file_dir / 'example_parameters_no_namespace.yaml'
            ],
        )
    ])
    request = mock_component_container.requests[3]
    assert get_node_name_count(context, '//test_node_name') == 1
    assert request.node_name == 'test_node_name'
    assert request.node_namespace == '/'
    assert len(request.parameters) == 1
    assert request.parameters[0].name == 'param'
    assert request.parameters[0].value.integer_value == 2

    # Case 5: wildcard
    context = _assert_launch_no_errors([
        _load_composable_node(
            package='foo_package',
            plugin='bar_plugin',
            name='my_node',
            namespace='wildcard_ns',
            parameters=[
                parameters_file_dir / 'example_parameters_wildcard.yaml'
            ],
        )
    ])
    request = mock_component_container.requests[4]
    assert get_node_name_count(context, '/wildcard_ns/my_node') == 1
    assert request.node_name == 'my_node'
    assert request.node_namespace == '/wildcard_ns'
    assert len(request.parameters) == 1
    assert request.parameters[0].name == 'param'
    assert request.parameters[0].value.string_value == 'wildcard'

    # Case 6: multiple entries (params with node name should take precedence over wildcard params)
    context = _assert_launch_no_errors([
        _load_composable_node(
            package='foo_package',
            plugin='bar_plugin',
            name='node_1',
            namespace='ns_1',
            parameters=[
                parameters_file_dir / 'example_parameters_multiple_entries.yaml'
            ],
        ),
        _load_composable_node(
            package='foo_package',
            plugin='bar_plugin',
            name='node_2',
            namespace='ns_2',
            parameters=[
                parameters_file_dir / 'example_parameters_multiple_entries.yaml'
            ],
        )
    ])
    request = mock_component_container.requests[5]
    assert get_node_name_count(context, '/ns_1/node_1') == 1
    assert request.node_name == 'node_1'
    assert request.node_namespace == '/ns_1'
    assert len(request.parameters) == 3
    assert request.parameters[0].name == 'param_2'
    assert request.parameters[0].value.integer_value == 2
    assert request.parameters[1].name == 'param_3'
    assert request.parameters[1].value.integer_value == 33
    assert request.parameters[2].name == 'param_1'
    assert request.parameters[2].value.integer_value == 1

    request = mock_component_container.requests[6]
    assert get_node_name_count(context, '/ns_2/node_2') == 1
    assert request.node_name == 'node_2'
    assert request.node_namespace == '/ns_2'
    assert len(request.parameters) == 2
    assert request.parameters[0].name == 'param_2'
    assert request.parameters[0].value.integer_value == 22
    assert request.parameters[1].name == 'param_3'
    assert request.parameters[1].value.integer_value == 3

    # Case 7: node name not found
    context = _assert_launch_no_errors([
        _load_composable_node(
            package='foo_package',
            plugin='bar_plugin',
            name='wrong_node_name',
            namespace='ns',
            parameters=[
                parameters_file_dir / 'example_parameters_no_namespace.yaml'
            ],
        )
    ])
    request = mock_component_container.requests[7]
    assert get_node_name_count(context, '/ns/wrong_node_name') == 1
    assert request.node_name == 'wrong_node_name'
    assert request.node_namespace == '/ns'
    assert len(request.parameters) == 0