Thanks for the feedback. I think that makes a lot of sense; I generalized it into a ForEach action to make it more flexible and much more powerful. It can now iterate over sets of parameters. It’s basically a string list of YAML structures/dictionaries, similar to what Nav2’s ParseMultiRobotPose does.
See the updated PR: Add ForEach action to repeat entities using iteration-specific values by christophebedard · Pull Request #802 · ros2/launch · GitHub.
Examples:
XML
<launch>
<arg name="robots" default="{name: 'robotA', id: 1};{name: 'robotB', id: 2}" />
<for_each values="$(var robots)" >
<log message="'$(for-var name)' id=$(for-var id)" />
</for_each>
</launch>
YAML
launch:
- arg:
name: robots
default: "{name: 'robotA', id: 1};{name: 'robotB', id: 2}"
- for_each:
values: $(var robots)
children:
- log:
message: "'$(for-var name)' id=$(for-var id)"
Python
import launch
def for_each(id: int, name: str):
return [
launch.actions.LogInfo(msg=f"'{name}' id={id}"),
]
def generate_launch_description():
return launch.LaunchDescription([
launch.actions.DeclareLaunchArgument(
'robots', default_value="{name: 'robotA', id: 1};{name: 'robotB', id: 2}"),
launch.actions.ForEach(launch.substitutions.LaunchConfiguration('robots'), function=for_each),
])
Default values are also supported, which I see is useful from looking at ParseMultiRobotPose. In Python, just set a default value for the corresponding callback function parameter. When using one of the frontends, provide an optional default value to the substitution: $(for-var name 'default').