This tutorial explains some concepts about multi-robot setups. Please refer to the quadrotor simulation tutorial for details about configuring a single-robot setup.
Depending on the available hardware, components of a multi-robot setup may run either on dedicated onboard computers for each robot or a single computer may be shared for all components (e.g. for a multi-robot setup in simulation).
In the former case, components just need to be started as usual, on each host, e.g. like shown in the quadrotor simulation.
In the latter case, when components of different robots need to run on the same
host, similar components instances need to be uniquely identified so that they
each refer to the robot their are controlling. This is achieved by giving them
a new name by using the -i
(or --name
) startup option.
By default, when a component is started, it uses an instance name identical to
its name. For instance, starting rotorcraft-pocolibs
with no option uses the
rotorcraft
instance name:
$ rotorcraft-pocolibs &
rotorcraft: created outport rotorcraft/genom_state
rotorcraft: created outport rotorcraft/genom_metadata
rotorcraft: created inport rotorcraft/rotor_input
rotorcraft: created outport rotorcraft/rotor_measure
rotorcraft: created outport rotorcraft/imu
rotorcraft: created outport rotorcraft/mag
rotorcraft: spawned task main
rotorcraft: spawned task comm
rotorcraft: spawned control task
rotorcraft: setup and running
With -i
or (--name
), a different instance name can be chosen and multiple
instances can be spawned. For instance, here r1_rotorcraft
and r2_rotorcraft
are spawned:
$ rotorcraft-pocolibs -i r1_rotorcraft &
r1_rotorcraft: created outport r1_rotorcraft/genom_state
r1_rotorcraft: created outport r1_rotorcraft/genom_metadata
r1_rotorcraft: created inport r1_rotorcraft/rotor_input
r1_rotorcraft: created outport r1_rotorcraft/rotor_measure
r1_rotorcraft: created outport r1_rotorcraft/imu
r1_rotorcraft: created outport r1_rotorcraft/mag
r1_rotorcraft: spawned task main
r1_rotorcraft: spawned task comm
r1_rotorcraft: spawned control task
r1_rotorcraft: setup and running
$ rotorcraft-pocolibs -i r2_rotorcraft &
r2_rotorcraft: created outport r2_rotorcraft/genom_state
r2_rotorcraft: created outport r2_rotorcraft/genom_metadata
r2_rotorcraft: created inport r2_rotorcraft/rotor_input
r2_rotorcraft: created outport r2_rotorcraft/rotor_measure
r2_rotorcraft: created outport r2_rotorcraft/imu
r2_rotorcraft: created outport r2_rotorcraft/mag
r2_rotorcraft: spawned task main
r2_rotorcraft: spawned task comm
r2_rotorcraft: spawned control task
r2_rotorcraft: setup and running
Each of required component in the setup should be given such a unique name, as soon as multiple instances on the same host are needed.
Similarly, when loading clients in interpreters, two situations can be distinguished: either the same components are running on differents hosts or they are shared on a single host with uniquified instance names.
In the first case, you must open a client connection for each host and load each component on each host separately. Note that to avoid conflicts, you must name each instance differently in the client. Here are a few examples in TCL and python:
eltclsh > set g1 [genomix::connect robot1]
genomix1
eltclsh > $g1 load rotorcraft as r1_rotorcraft ;# change the local name
r1_rotorcraft
eltclsh > set g2 [genomix::connect robot2]
genomix2
eltclsh > $g2 load rotorcraft as r2_rotorcraft ;# change the local name
r2_rotorcraft
>>> g1 = genomix.connect('robot1')
>>> r1_rotorcraft = g1.load('rotorcraft')
>>> g2 = genomix.connect('robot2')
>>> r2_rotorcraft = g2.load('rotorcraft')
In the second scenario, where all components are running on the same host, the
instance name must be specified with the -i
(or --name
) load option when
loading clients in interpreters.
Here are again some examples, in TCL and python:
eltclsh > set g [genomix::localhost]
eltclsh > $g load rotorcraft -i r1_rotorcraft
r1_rotorcraft
eltclsh > $g load rotorcraft -i r2_rotorcraft
r2_rotorcraft
>>> g = genomix.connect()
>>> r1_rotorcraft = g.load('rotorcraft', '-i', 'r1_rotorcraft')
>>> r2_rotorcraft = g.load('rotorcraft', '-i', 'r2_rotorcraft')
Once an instance has been loaded in the client interpreter, it can be used as usual, no matter how it was loaded (e.g. with a specific instance name or not).