A Python library for the design and control of artificial swarms.
This package includes tools to either control or simulate specific hardware parts of a robot capable of (i) locomotion, (ii) sensing, and (iii) communication with the aim of performing experimental research in artificial swarming. It also includes some models of swarming behavior built using these tools. For more information see http://journal.frontiersin.org/article/10.3389/frobt.2017.00012/
The design of robots using this library consists of three main pieces:
The marabunta library follows this structure and provides the following classes:
Body
with the required methods to use as a body of a robot. Any body models should inherit from this class to be accepted by BaseRobot
.
Body
implementation to simulate a robot body. Does not require any hardware to use. A file with a list of coordinates can be loaded to include obstacles in the simulation.Body
implementation to control an eBot. Requires bluetooth connection, an eBot, and the appropiate eBot-API installed.Network
with the required methods to use as a network of a robot. Any network models should inherit from this class to be accepted by BaseRobot.
Network
implementation to simulate the communication using regular files (assumes the different robots are in the same computer, or at least can access the same files). Does not require any hardware to use.Network
implementation using a series 1 XBee. Requires an XBee connected through a serial port.BaseBody
and a network instance that inherits from BaseNetwork
.
MockBody
. The obstacles are loaded from a file and stored in a grid using "Verlet lists" for fast access to local obstacle data.To install the module, type:
python setup.py install
(may require sudo
depending on your system). This will install the marabunta
module and its
marabunta.models
submodule.
To control eBots through eBotBody
one needs to have the eBot-API installed. The official version can be found at https://github.com/EdgeBotix/eBot-API.
A fork of this API that uses the host CPU to compute the localization of the robot by implementing a Kalman filter instead of relying on the eBot localization can be found at https://github.com/david-mateo/eBot-API.
To design a robot behavior, one should define a new class that inherits from BaseRobot
. The initialization of BaseRobot
requires of a body, implemented as a class inheriting from BaseBody
, and a network, a class inheriting from BaseNetwork
.
To add support for new hardware, one should implement classes inheriting from BaseBody
or BaseNetwork
. These classes contain the minimal list of methods than any body or network should implement.
To use the provided methods to make the robot move following a particular behavior, say heading consensus, one has to define the body, the network, the robot, turn it on, and iteratively call its update
method. A minimal example code is:
from marabunta import eBotBody, XBeeNetwork
from marabunta.models import HeadingConsensusRobot
total_time = 60
ID = "Walle"
init_pos = [0., 0.]
init_heading = 0.
communication_slot = 0.1
body = ebotBody( init_pos , init_heading)
network = XBeeNetwork(communication_slot, communication_slot + 0.1, 1, ID)
robot = HeadingConsensusRobot(body, network)
robot.turn_on()
# MAIN LOOP
end_time = time() + total_time
while time() < end_time:
robot.update(dt, speed)
sleep(dt)
robot.turn_off()
Any robot inherting from BaseRobot
has __enter__
and __exit__
methods that allow to use the robot with the with
statement instead of explicitly turning it on and off. This option provides a cleaner way to operate the robot in the face of potential hardware failures.
A minimal example code following this approach is:
from marabunta import eBotBody, XBeeNetwork
from marabunta.models import HeadingConsensusRobot
total_time = 60
ID = "Walle"
init_pos = [0., 0.]
init_heading = 0.
communication_slot = 0.1
body = ebotBody(init_pos, init_heading)
network = XBeeNetwork(communication_slot, communication_slot + 0.1, 1, ID)
with HeadingConsensusRobot(body, network) as robot:
# MAIN LOOP
end_time = time() + total_time
while time() < end_time:
robot.update(dt, speed)
sleep(dt)
One can find several ways to operate the robots in the scripts contained in examples/
.