Look, Compute, Move

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

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 enable the execution of such synchronous 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, all onPreClock() network-wide are executed before any onClock(), and all onClock() network-wide are executed before any onPostClock().

Below is an example of algorithm that performs a probabilistic gathering. The LOOK step consists of reading the location of all nodes within sensing range. Note that we might have considered all of the nodes in the network, if we wanted to, rather than only those within sensing range, by using the getTopology().getNodes() method. 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 (or by the missing amount, if smaller than one unit).

import jbotsim.Node;

import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Random;

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

    @Override
    public void onPreClock() {  // LOOK
        locations = new ArrayList<Point2D>();
        for (Node node : getSensedNodes())
            locations.add(node.getLocation());
    }
    @Override
    public void onClock(){      // COMPUTE
        target = locations.get((new Random()).nextInt(locations.size()));
    }
    @Override
    public void onPostClock(){  // MOVE
        setDirection(target);
        move(Math.min(1, distance(target)));
    }
}    

The corresponding main() is as follows.

public static void main(String[] args) {
    Topology tp = new Topology(false);
    tp.setDefaultNodeModel(LCMNode.class);
    tp.disableWireless();
    tp.setSensingRange(100);
    tp.setClockSpeed(100);
    for (int i = 0; i<20; i++)
        tp.addNode(-1,-1);
    new JViewer(tp);
    tp.start();
}    
Here, the topology is created in a stopped state (false argument) and only started at the end of the initialization. The reason is that nodes are added by program and their execution must not interfere. Wireless links are globally disabled because robots act based on vision (here, within a radius of 100). Finally, the duration of a round is set to 100ms and twenty nodes are added at random locations.