Skip to content

Commit 3711692

Browse files
Fix SetUseSimTime for launch frontends (#488)
1. Fix parsing of action for frontends. 2. Make the Python action handle & normalize substitutions and then perform them. And add frontend tests. Signed-off-by: Christophe Bedard <[email protected]>
1 parent ba3073b commit 3711692

File tree

2 files changed

+76
-5
lines changed

2 files changed

+76
-5
lines changed

launch_ros/launch_ros/actions/set_use_sim_time.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,18 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
from typing import List
16+
from typing import Union
1517

1618
from launch import Action
1719
from launch.frontend import Entity
1820
from launch.frontend import expose_action
1921
from launch.frontend import Parser
2022
from launch.launch_context import LaunchContext
23+
from launch.some_substitutions_type import SomeSubstitutionsType
24+
from launch.substitution import Substitution
25+
from launch.utilities.type_utils import normalize_typed_substitution
26+
from launch.utilities.type_utils import perform_typed_substitution
2127

2228
from launch_ros.ros_adapters import get_ros_node
2329

@@ -30,32 +36,33 @@ class SetUseSimTime(Action):
3036

3137
def __init__(
3238
self,
33-
value: bool,
39+
value: Union[bool, SomeSubstitutionsType],
3440
**kwargs
3541
) -> None:
3642
"""Create a SetUseSimTime action."""
3743
super().__init__(**kwargs)
38-
self.__value = value
44+
self.__value = normalize_typed_substitution(value, bool)
3945

4046
@classmethod
4147
def parse(cls, entity: Entity, parser: Parser):
4248
"""Return `SetUseSimTime` action and kwargs for constructing it."""
4349
_, kwargs = super().parse(entity, parser)
44-
kwargs['value'] = parser.parse_substitution(entity.get_attr('value'))
50+
kwargs['value'] = parser.parse_if_substitutions(entity.get_attr('value', data_type=bool))
4551
return cls, kwargs
4652

4753
@property
48-
def value(self) -> bool:
54+
def value(self) -> List[Substitution]:
4955
"""Getter for value."""
5056
return self.__value
5157

5258
def execute(self, context: LaunchContext):
5359
"""Execute the action."""
60+
value = perform_typed_substitution(context, self.value, bool)
5461
node = get_ros_node(context)
5562
param = Parameter(
5663
'use_sim_time',
5764
Parameter.Type.BOOL,
58-
self.value
65+
value,
5966
)
6067
node.set_parameters([param])
6168
if not node.get_parameter('use_sim_time').get_parameter_value().bool_value:
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Copyright 2025 Open Source Robotics Foundation, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import io
16+
import textwrap
17+
18+
from launch import LaunchService
19+
from launch.frontend import Parser
20+
from launch.utilities.type_utils import perform_typed_substitution
21+
from launch_ros.actions import SetUseSimTime
22+
import pytest
23+
24+
25+
yaml_file = textwrap.dedent(
26+
r"""
27+
launch:
28+
- let:
29+
name: sim_time
30+
value: '1'
31+
- set_use_sim_time:
32+
value: $(var sim_time)
33+
"""
34+
)
35+
36+
37+
xml_file = textwrap.dedent(
38+
r"""
39+
<launch>
40+
<let name="sim_time" value="1" />
41+
<set_use_sim_time value="$(var sim_time)" />
42+
</launch>
43+
"""
44+
)
45+
46+
47+
@pytest.mark.parametrize(
48+
'file',
49+
[
50+
pytest.param(yaml_file, id='YAML'),
51+
pytest.param(xml_file, id='XML'),
52+
],
53+
)
54+
def test_set_use_sim_timer(file):
55+
root_entity, parser = Parser.load(io.StringIO(file))
56+
ld = parser.parse_description(root_entity)
57+
ls = LaunchService()
58+
ls.include_launch_description(ld)
59+
assert 0 == ls.run()
60+
61+
lc = ls.context
62+
assert len(ld.entities) == 2
63+
assert isinstance(ld.entities[1], SetUseSimTime)
64+
assert perform_typed_substitution(lc, ld.entities[1].value, bool) is True

0 commit comments

Comments
 (0)