-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add Parameter substitution Signed-off-by: Kenji Miyake <kenji.miyake@tier4.jp> * Fix bug of set_parameter.py Signed-off-by: Kenji Miyake <kenji.miyake@tier4.jp> * Add a test for SubstitutionFailure Signed-off-by: Kenji Miyake <kenji.miyake@tier4.jp>
- Loading branch information
1 parent
835b40c
commit 0331a2e
Showing
5 changed files
with
175 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# Copyright 2022 Open Source Robotics Foundation, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
"""Module for the Parameter substitution.""" | ||
|
||
from typing import Iterable | ||
from typing import List | ||
from typing import Text | ||
|
||
from launch.frontend import expose_substitution | ||
from launch.launch_context import LaunchContext | ||
from launch.some_substitutions_type import SomeSubstitutionsType | ||
from launch.substitution import Substitution | ||
from launch.substitutions.substitution_failure import SubstitutionFailure | ||
from launch.utilities import normalize_to_list_of_substitutions | ||
from launch.utilities import perform_substitutions | ||
|
||
|
||
@expose_substitution('param') | ||
class Parameter(Substitution): | ||
""" | ||
Substitution that tries to get a parameter that was set by SetParameter. | ||
:raise: SubstitutionFailure when param is not found | ||
""" | ||
|
||
def __init__( | ||
self, | ||
name: SomeSubstitutionsType, | ||
) -> None: | ||
"""Create a Parameter substitution.""" | ||
super().__init__() | ||
self.__name = normalize_to_list_of_substitutions(name) | ||
|
||
@classmethod | ||
def parse(cls, data: Iterable[SomeSubstitutionsType]): | ||
"""Parse a Parameter substitution.""" | ||
if not data or len(data) != 1: | ||
raise AttributeError('param substitutions expect 1 argument') | ||
kwargs = {'name': data[0]} | ||
return cls, kwargs | ||
|
||
@property | ||
def name(self) -> List[Substitution]: | ||
"""Getter for name.""" | ||
return self.__name | ||
|
||
def describe(self) -> Text: | ||
"""Return a description of this substitution as a string.""" | ||
name_str = ' + '.join([sub.describe() for sub in self.name]) | ||
return '{}(name={})'.format(self.__class__.__name__, name_str) | ||
|
||
def perform(self, context: LaunchContext) -> Text: | ||
"""Perform the substitution.""" | ||
name = perform_substitutions(context, self.name) | ||
params_container = context.launch_configurations.get('global_params', None) | ||
for param in params_container: | ||
if isinstance(param, tuple): | ||
if param[0] == name: | ||
return param[1] | ||
raise SubstitutionFailure("parameter '{}' not found".format(name)) |
67 changes: 67 additions & 0 deletions
67
test_launch_ros/test/test_launch_ros/frontend/test_parameter_substitution_frontend.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# Copyright 2022 Open Source Robotics Foundation, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
import io | ||
import textwrap | ||
|
||
from launch import LaunchService | ||
from launch.frontend import Parser | ||
from launch.utilities import perform_substitutions | ||
|
||
|
||
def test_parameter_substitution_yaml(): | ||
yaml_file = textwrap.dedent( | ||
r""" | ||
launch: | ||
- set_parameter: | ||
name: name | ||
value: value | ||
- let: | ||
name: result | ||
value: $(param name) | ||
""" | ||
) | ||
with io.StringIO(yaml_file) as f: | ||
check_parameter_substitution(f) | ||
|
||
|
||
def test_parameter_substitution_xml(): | ||
xml_file = textwrap.dedent( | ||
r""" | ||
<launch> | ||
<set_parameter name="name" value="value" /> | ||
<let name="result" value="$(param name)" /> | ||
</launch> | ||
""" | ||
) | ||
with io.StringIO(xml_file) as f: | ||
check_parameter_substitution(f) | ||
|
||
|
||
def check_parameter_substitution(file): | ||
root_entity, parser = Parser.load(file) | ||
ld = parser.parse_description(root_entity) | ||
ls = LaunchService() | ||
ls.include_launch_description(ld) | ||
assert 0 == ls.run() | ||
|
||
def perform(substitution): | ||
return perform_substitutions(ls.context, substitution) | ||
|
||
set_parameter, let = ld.describe_sub_entities() | ||
assert perform(set_parameter.name) == 'name' | ||
assert perform(set_parameter.value) == 'value' | ||
assert perform(let.name) == 'result' | ||
assert perform(let.value) == 'value' |
32 changes: 32 additions & 0 deletions
32
test_launch_ros/test/test_launch_ros/substitutions/test_parameter_substitution.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# Copyright 2022 Open Source Robotics Foundation, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
"""Test for the Parameter substitutions.""" | ||
|
||
from launch import LaunchContext | ||
|
||
from launch.substitutions.substitution_failure import SubstitutionFailure | ||
|
||
from launch_ros.actions import SetParameter | ||
from launch_ros.substitutions import Parameter | ||
|
||
import pytest | ||
|
||
|
||
def test_parameter_substitution(): | ||
context = LaunchContext() | ||
SetParameter('name', 'value').execute(context) | ||
assert Parameter('name').perform(context) == 'value' | ||
with pytest.raises(SubstitutionFailure): | ||
Parameter('name-invalid').perform(context) |