Look, Compute, Move

Look, Compute, Move is a distributed computing paradigm for mobile robots. In every round, each robot performs the following operations:

  1. Look around (e.g. for the position of other robots)
  2. Make some computation (e.g. deciding where to go next)
  3. Move to a new location

This model is often seen as an alternative to message passing, although both could be used in combination. A subtlety is that, in general, this model is synchronous. In particular, it is assumed that, in every round, all LOOK operations are completed before any MOVE operation takes place.

JBotSim offers primitives that allows one to write such algorithms. When extending class Node, in addition to method onClock(), one can also override methods onPreClock() and onPostClock(), with the guarantee that in each round, the methods onPreClock() of all the nodes are executed before the onClock() method of any of them, and the onClock() methods in turn are executed before the onPostClock() methods, thereby guaranteeing a synchronous three-step round process.

Below is an example of a basic algorithm that performs a probabilistic gathering. The LOOK step consists of reading the location of all nodes within sensing range. The COMPUTE step consists of picking a random location among the locations of these nodes. The MOVE step consists of moving towards this location by one unit of distance (at most).

import io.jbotsim.core.Node;
import io.jbotsim.core.Point;

import java.util.ArrayList;
import java.util.Random;

public class LCMNode extends Node{
    ArrayList<Point> locations;
    Point target;

    @Override
    public void onPreClock() {  // LOOK
        locations = new ArrayList<>();
        for (Node node : getSensedNodes())
            locations.add(node.getLocation());
    }
    @Override
    public void onClock(){      // COMPUTE
        if(!locations.isEmpty())
            target = locations.get((new Random()).nextInt(locations.size()));
    }
    @Override
    public void onPostClock(){  // MOVE
        if(target == null)
            return;

        setDirection(target);
        move(Math.min(1, distance(target)));
    }
}

The corresponding main() method is as follows.

public static void main(String[] args) {
    Topology tp = new Topology();
    tp.setDefaultNodeModel(LCMNode.class);
    tp.disableWireless();
    tp.setSensingRange(100);
    tp.setTimeUnit(100);
    for (int i = 0; i<20; i++)
        tp.addNode(-1,-1); // Random location
    new JViewer(tp);
    tp.start();
}

Wireless links are globally disabled because we decided here that robots act based on vision only (here, within a radius of 100). Alternatively, a node may look at all the other nodes through calling getTopology().getNodes() (which is sometimes considered as cheating, but seems OK in this kind of scenario).