i-score @ FOSDEM 2016

During the 2016 edition of FOSDEM,  the Free and Open-Source Software Developers’ European Meeting, i-score was present in the Open Media Room for a 20 minutes-presentation, interoperating with Processing via a patch made by Théo de la Hogue :

Link to the presentation page.

Controlling Metabots with i-score

This article explains how to control the Metabot robots with i-score.
The goal is to create a full interactive robot choreography.

The Metabots are small, open-source, 3D-printable robots built in France by Rhoban.
They can be bought in http://metabot.fr/

1. Presentation

i-score can control some parameters of the metabots in real-time.
The metabots can be connected in Bluetooth, or with an USB cable (but this
is less practical for shows !).

This technology currently only works in Linux, however.

Requirements :

  • A Metabot.
  • A Linux system with development packages, SDL, i-score and Bluetooth support with bluetoothctl.
  • A build of this repository : https://github.com/iscore-metabots/minuit-controller

The tutorial uses the command-line to connect to the metabots but graphical managers can also be used.

i-score communicates via the Minuit protocol with an intermediary program, named “linker”.
Linker then converts the Minuit messages into serial-port commands adapted for the Metabot.

2. Connecting the metabots.

First, ensure that the metabot is correctly charged and turn it on.
Then, run bluetoothctl.
Bluetoothctl is a shell of its own. Inside it, follow this procedure :

$ bluetoothctl
[bluetooth]# agent KeyboardOnly
[bluetooth]# default-agent
[bluetooth]# power on
[bluetooth]# scan on
[NEW] Device B8:63:BC:00:46:ED ROBOTIS BT-210 
[bluetooth]# pair B8:63:BC:00:46:ED
[agent] Enter PIN code: 1234
[bluetooth]# trust B8:63:BC:00:46:ED
Connection with the Metabot

The MAC address of the Metabot will be different for each Metabot.

Once this is done, open a standard shell and run :

sudo modprobe rfcomm
sudo rfcomm bind rfcomm0 B8:63:BC:00:46:ED
Enabling serial port connection to the metabot.

This will open a virtual file that allows “reading” and “writing” to the Metabot.
To test if it works, you can try to write the start message to the bot :

$ sudo su
# echo start > /dev/rfcomm0
Starting the metabot

The metabot should then wake up.

To keep the Bluetooth connection alive, the safest bet is to open a shell via minicom or cu inside the metabot.
For instance :

sudo minicom -s

Edit the settings by going to “Serial port configuration”, setting the port to /dev/rfcomm0 and going to “Leave”.
This drops yourself to a shell where commands can be sent to the metabot.

e.g. : dx 10   => the metabot moves laterally at 10 centimeter per second
The command “help” lists the metabot options.

3. Set-up the Minuit controller

We have to launch the linker software with correct parameters for the Metabot.
The linker translates Minuit (OSC) messages to serial messages, with a configuration file :

Metabot = {objectType={Container}, subnodes={moves, sys, modes}, description={"Metabot, un robot très sympatique"}}
moves = {objectType={Container}, subnodes={h, dx, dy, turn}, description={"Fonctions de mouvement"}}
sys = {objectType={Container}, subnodes={start, stop, quit}, description={"Fonctions"}}
modes = {objectType={Container}, subnodes={alt, crab, backleg, back, freq, gait}, description={"Fonctions changeant la pose que prend le robot"}}
h = {objectType={Data}, type={decimal}, rangeBounds={-30,-120}, description={"Change la hauteur du metabot"}}
dx = {objectType={Data}, type={decimal}, rangeBounds={-300,300}, description={"Le robot avance d'autant de centimetres par pas dans la direction x"}}
dy = {objectType={Data}, type={decimal}, rangeBounds={-300,300}, description={"Le robot avance d'autant de centimetres par pas dans la direction y"}}
turn = {objectType={Data}, type={decimal}, rangeBounds={-300,300}, description={"Le robot effectue une rotation d'autant de centimetres par pas"}}
start = {objectType={Data}, type={integer}, rangeBounds={0,1}, description={"Activer les moteurs"}}
stop = {objectType={Data}, type={integer}, rangeBounds={0,1}, description={"Désactiver les moteurs"}}
alt = {objectType={Data}, type={integer}, rangeBounds={0,10}, description={"Change l'altitude du robot"}}
crab = {objectType={Data}, type={decimal}, rangeBounds={0,10}, description={"Taux de crabe"}}
backleg = {objectType={Data}, type={decimal}, rangeBounds={0,10}, description={"Change la hauteur des pattes arrières"}}
back = {objectType={Data}, type={integer}, rangeBounds={0,1}, description={"Retourner les pattes"}}
freq = {objectType={Data}, type={decimal}, rangeBounds={0,3}, description={"Change la fréquence du robot"}}
gait = {objectType={Data}, type={integer}, rangeBounds={0,1}, description={"gait"}}
quit = {objectType={Data}, type={integer}, rangeBounds={0,1}, description={"Ordonne au serveur de s'arreter"}}

The first line is the name of the Minuit device that has to be put in i-score.
Launch the linker like this : it will open a port and wait for i-score.

sudo ./linker /dev/rfcomm0 9998 ../minuit_controller/metabot.cfg
Command to launch the linker

4. Set-up i-score

The Linker exposes by default the device named “Metabot” to i-score.
Once loaded (this takes time), you can score the Metabot parameters.

Process overview : Loop


The loop is somewhat similar to the scenario.
It is a process that allows to loop other processes.
However no new structures can be created or removed in it.

It is built of :

  • A first sync, event, and state.
  • A time constraint.
  • A last sync, event, and state.

When created, it looks like this :



The last event can be resized :


Processes can of course be added to the interval, as well as data to the states.


The loop process, as its name tells, loops :

To make an infinite loop, one can for instance remove the maximum of its parent interval :


To make an interactive loop, a trigger can instead be added at the first or last trigger of the loop :

Process overview : Scenario


The scenario process is the heart of score, its raison d’être.
It allows to sequence the various objects presented before in a non-linear timeline.

When opening score for the first time, the blank document is a root Time interval, the blue line at the top, which
contains a single scenario.



The various edition features of a scenario are detailed in the tutorials.

Sub-scenarios can of course be added :

Full-view and hierarchy

One can go inside sub-scenarios by using the Full-view feature of the interval.

By double-clicking on a interval name, it switches to the main view.

Process overview : Mapping


The mapping process allows to map  input parameters to output parameters in real-time.
It is a simple transfer function.
It is based on a curve, just like the automation.
However, it is a time-independent process : instead of mapping the time to a value, it maps an input value to an output value.
Its curve is purple.


From an edition point of view, a mapping is identical to an automation : it is just a curve.
However, since it is not temporal, growing the process with the Grow mode has no effect : it will always be rescaled.


The mapping inspector is very simple :


The parameters are :

  • Source address : its value will be fetched at each tick. Like elsewhere in the software, accessing a single value of an array is supported, as well as unit conversions.
  • Source min / max : the values in which the input is assumed to be.
  • Target address : the address that will be written to.
  • Target min / max : the output range.


The mapping behaves as follows at each tick :

  1. The current value of the source address is fetched.
  2. It is mapped to the X axis of the curve according to the source min-max.
  3. The corresponding point is taken on the Y axis.
  4. This point is scaled according to the target min-max.
  5. The resulting value is sent to the target address.

For instance, the following curve with identical min-max for the source and target would just
copy its input to its output at each tick :


If the target max is set to twice the source max (for instance from (0, 1) to (0, 2)), all the input values will be multiplied by two.

The following curve will invert the input values.


More complex curves will of course have more complex effects.