Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support wildcards #369

Open
wants to merge 7 commits into
base: rolling
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions launch_ros/launch_ros/utilities/to_parameters_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"""Module with utility to transform evaluated parameters into parameter lists."""

import pathlib
import re
from typing import List
import warnings

Expand Down Expand Up @@ -74,10 +75,13 @@ def to_parameters_list(
:returns: a list of parameters
"""
parameters = [] # type: List[rclpy.parameter.Parameter]
node_name = node_name.lstrip('/')

if node_name[0] != '/':
node_name = '/' + node_name

if namespace and namespace != '/':
namespace = namespace.strip('/')
node_name = f'{namespace}/{node_name}'
node_name = f'/{namespace}{node_name}'

params_set = {}
warned_once = False
Expand All @@ -89,10 +93,18 @@ def to_parameters_list(

if normalized_param_dict:
param_dict.clear()
if '**' in normalized_param_dict:
param_dict = normalized_param_dict['**']
if node_name in normalized_param_dict:
param_dict.update(normalized_param_dict[node_name])

for key, value in normalized_param_dict.items():
pattern = key if key[0] == '/' else '/' + key
pattern = pattern.replace('/*', '(/\\w+)')
try:
match = re.fullmatch(pattern, node_name)
if match:
param_dict.update(value)
except re.error as e:
raise RuntimeError(
'invalid yaml file {}, error: {}'.format(str(params_set_or_path), e))

if not warned_once and not node_name:
warnings.warn(
'node name not provided to launch; parameter files will not apply',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/***:
ros__parameters:
param: "wildcard"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/*/aa/**/my_node:
ros__parameters:
param: "wildcard"
Original file line number Diff line number Diff line change
Expand Up @@ -396,12 +396,12 @@ def test_load_node_with_param_file(mock_component_container):
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
assert request.parameters[0].name == 'param_1'
assert request.parameters[0].value.integer_value == 1
assert request.parameters[1].name == 'param_2'
assert request.parameters[1].value.integer_value == 22
assert request.parameters[2].name == 'param_3'
assert request.parameters[2].value.integer_value == 33

request = mock_component_container.requests[-1]
assert get_node_name_count(context, '/ns_2/node_2') == 1
Expand Down Expand Up @@ -477,6 +477,26 @@ def test_load_node_with_param_file(mock_component_container):
assert request.node_namespace == '/ns'
assert len(request.parameters) == 0

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

# Namespace not found
context = _assert_launch_no_errors([
_load_composable_node(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from launch_ros.actions.load_composable_nodes import get_composable_node_load_request
from launch_ros.descriptions import ComposableNode

import pytest
import yaml


Expand Down Expand Up @@ -176,3 +177,19 @@ def test_set_param_with_composable_node():
assert parameters[0].value.integer_value == 10
assert parameters[1].name == 'asd'
assert parameters[1].value.string_value == 'bsd'


def test_set_bad_wildcard_param_with_composable_node():
lc = MockContext()
node_description = ComposableNode(
package='asd',
plugin='my_plugin',
name='my_node',
namespace='my_ns'
)
param_file_path = \
os.path.dirname(os.path.abspath(__file__)) + '/example_parameters_bad_wildcard.yaml'
set_param_1 = SetParametersFromFile(param_file_path)
set_param_1.execute(lc)
with pytest.raises(RuntimeError):
get_composable_node_load_request(node_description, lc)