ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

I have considered this a number of times in the past. Depending on how many parameters you want to change between robots, you may or may not want to consider dynamically modifying yaml files.

My personal preferred approach is to use an OpaqueFunction to create a for-loop in your launch file that uses a LaunchConfiguration to set the loop size. Within that loop, you can then do a number of things like set the namespace, group, the initial position, etc, based on the index.

For more heterogeneous swarms, you could also get creative and dynamically edit and/or make temporary yaml files that can be loaded for each robot.

This could look something like:

def include_swarm_launch_descriptions(context):
    swarm_description = []
    for n in range(int(context.launch_configurations['num_robots'])):
        robot_n_description = GroupAction([
            # *whatever you want to launch here*
        ])
        swarm_descriptions += [robot_n_description]

    return swarm_descriptions 

def generate_launch_description():
    return LaunchDescription([
        DeclareLaunchArgument('num_robots'),
        # ...
        OpaqueFunction(include_swarm_launch_descriptions),
        # ...
    ])

I'd also recommend looking at nav2's multi_tb3_simulation_launch for inspiration on setting different groups/namespaces/arguments for different robots. They use a fixed size loop and a dict to define each robot, but the same principle could be used in a more extensible manner with OpaqueFunction

I have considered this a number of times in the past. Depending on how many parameters you want to change between robots, you may or may not want to consider dynamically modifying yaml files.

My personal preferred approach is to do something similar to your "Option 3" by using an OpaqueFunction. OpaqueFunction lets you evaluate the LaunchConfiguration in context, giving you access to the value set at launch time. You can then use an OpaqueFunction to create that value with a for-loop in your launch file that uses a LaunchConfiguration to set the loop size. Within that loop, you can and then do a number of things like set the namespace, group, the initial position, etc, based on the index.

For more heterogeneous swarms, you could also get creative and dynamically edit and/or make temporary yaml files that can be loaded for each robot.

This could look something like:

def include_swarm_launch_descriptions(context):
    swarm_description = []
    for n in range(int(context.launch_configurations['num_robots'])):
        robot_n_description = GroupAction([
            # *whatever you want to launch here*
        ])
        swarm_descriptions += [robot_n_description]

    return swarm_descriptions 

def generate_launch_description():
    return LaunchDescription([
        DeclareLaunchArgument('num_robots'),
        # ...
        OpaqueFunction(include_swarm_launch_descriptions),
        # ...
    ])

I'd also recommend looking at nav2's multi_tb3_simulation_launch for inspiration on setting different groups/namespaces/arguments for different robots. They use a fixed size loop and a dict to define each robot, but the same principle could be used in a more extensible manner with OpaqueFunction

I have considered this a number of times in the past. Depending on how many parameters you want to change between robots, you may or may not want to consider dynamically modifying yaml files.

My personal preferred approach is to do something similar to your "Option 3" by using an OpaqueFunction. OpaqueFunction lets you evaluate the LaunchConfiguration in context, giving you access to the value set at launch time. You can then use that value with a for-loop and then do a number of things like set the namespace, group, the initial position, etc, based on the index.

For more heterogeneous swarms, you could also get creative and dynamically edit and/or make temporary yaml files that can be loaded for each robot.

This could look something like:

def include_swarm_launch_descriptions(context):
    swarm_description = []
    for n in range(int(context.launch_configurations['num_robots'])):
        robot_n_description = GroupAction([
            # *whatever you want to launch here*
        ])
        swarm_descriptions += [robot_n_description]

    return swarm_descriptions 

def generate_launch_description():
    return LaunchDescription([
        DeclareLaunchArgument('num_robots'),
        # ...
        OpaqueFunction(include_swarm_launch_descriptions),
        # ...
    ])

I'd also recommend looking at nav2's multi_tb3_simulation_launch for inspiration on setting different groups/namespaces/arguments for different robots. They use a fixed size loop and a dict to define each robot, but the same principle could be used in a more extensible manner with OpaqueFunction

.

For some bonus context, there was a small amount of discussion about having a dedicated feature for Launch that would better provide (and describe) this sort of functionality. Never got much traction though so, to my knowledge, OpaqueFunction is still the best option.