0
$\begingroup$

Rosanswers logo

Hello,

I am currently working on a multi-robot simulation package and I would like to spawn multiple robots with different parameters using launch files.

In general, I have a few ideas to implement this, but don't know if it is even possible to implement them currently.

1.Use a .yaml file to specify the scenario, so for example

 robot1:
     name: robot0
     x_pose: 0.0
     y_pose: 0.0
 robot2:
     name: robot1
     x_pose: 1.0
     y_pose: 1.0

You would then need to load this in the launch file and for each entry you create a corresponding action in the launch description.

2.Specify the number of robots as an os environment variable or as argv in the command line and accessing it in the launch file. However I think this is not modular enough for larger simulations.

3.Access the launch configuration of the launch file (for example "LaunchConfiguration('robot_number')") and create a array with an entry for each robot:

for num in range(int(robot_number.perform(LaunchContext()))):
    robots.append({'name': 'robot'+str(num), 'namespace': 'robot'+str(num), 'x_pose': num*-1.0, 'y_pose': 0.0, 'z_pose': 0.01},)

However, when I tried to implement the third approach, it was not possible to access the LaunchConfiguration when there is no default value set. Additionally, if you call this launch file with a different number of robots, the default value is still used, as the LaunchContext is local.

4.It could be possible to combine the ideas, so that you access a LaunchConfiguration to get the number of robots and then modify a template .yaml file with a $namespace$ parameter, which gets replaced by a script in the launch file. This temporary parameter file could then be forwarded to the other launch files to spawn the robots and start the navigation nodes (inspired by the RewrittenYaml script of Nav2).

My questions would be:

  1. Is it somehow possible to access the non-default LaunchConfiguration value in a launch file?
  2. Is it possible to access a .yaml file in a launch file and add actions for each listed robot?

Best Regards

Harun Teper


Originally posted by HarunTeper on ROS Answers with karma: 13 on 2021-11-12

Post score: 0

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

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.


Originally posted by shonigmann with karma: 1567 on 2021-11-12

This answer was ACCEPTED on the original site

Post score: 2


Original comments

Comment by HarunTeper on 2021-11-15:
I think I will then do a combination of both, dynamically creating yaml files (as there are many parameters) and using the OpaqueFunction to launch the modules for each robot. Thank you for pointing out this method, as I did not know how to access the LaunchConfiguration like this.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.