When Robots Go to Law School…

…they learn how to write contracts! Well, I wanted to use something a little different from the typical customers and orders, so I came up with an example from the field of swarm robotics for my upcoming posts on design by contract tools.

Disclaimer: This example is only for illustration and not meant to be useful for any real robotics application.

The following UML class diagram (created with NetBeans) shows a simple object model for robots and swarms. Each Robot may or may not belong to a Swarm, and a swarm can consist of any number of robots. The AbstractRobot class implements some common functionality defined by the Robot interface and serves as the base class for two concrete robot implementations: Navigator and Worker.
Robots class diagram

The Navigator is equipped with a GPS system that enables it to determine its own location. The Worker‘s unique feature is its robot arm that allows it to pick up and manipulate objects. So each of these specialized robots has only limited functionality, but when working together in a swarm they are much more powerful. For example, consider the task of picking up an object from a specific location and dropping it off somewhere else. Neither one of these two robot types could perform this task by itself, because the navigator cannot pick up objects, and the worker does not know how to get to the object’s location. But if they work together, the navigator can lead the way to the object, and the worker can then pick up the object.

Let’s take a look at the source code for the Robot interface.

public interface Robot {

    public static final int FEATURE_GPS = 1;
    public static final int FEATURE_ARM = 2;

    public static final int[] FEATURES = new int[] {
        FEATURE_GPS, FEATURE_ARM
    };

    /**
     * Checks whether this robot has the given
     * feature.
     *
     * @param feature   must be one of the values in
     *                  {@link #FEATURES}
     */
    public boolean hasFeature(int feature);

    /**
     * Gets the swarm to which this robot belongs.
     *
     * @return must be either null or a swarm whose
     *         members (see {@link Swarm#getRobots()})
     *         include this robot
     */
    public Swarm getSwarm();

    /**
     * Sets the swarm to which this robot belongs.
     * This method should only be called from the
     * {@link Swarm} class.
     *
     * @param swarm if this is not null, its
     *              collection of members (see
     *              {@link Swarm#getRobots()})
     *              must already contain this robot
     */
    public void setSwarm(Swarm swarm);

    /**
     * Gets the robot's location. This method may only
     * be called if this robot either has a GPS device
     * (see {@link #FEATURE_GPS}) or belongs to a
     * swarm where at least 3 robots have GPS.
     *
     * @return  the robot's location (not null)
     */
    public Point2D getLocation();
}

The getLocation method deserves an explanation. If the robot is equipped with GPS, it can get its location easily. But even if it doesn’t have GPS, it might be able to determine its location with the help of other robots. It could measure the time it takes for a signal to travel between itself and another robot, and use this information to compute its distance from that robot. If there are at least 3 robots with GPS in the swarm, the robots without GPS can triangulate their positions by measuring their distances from these 3 robots. This is why the getLocation method requires that the robot either has GPS or belongs to a swarm where at least 3 robots have GPS.

The Swarm class is basically just a collection of robots. Here is the source code:


/**
 * Swarm of {@link Robot}s.
 *
 * All member robots (see {@link #getRobots()}) must
 * "know" that they belong to this swarm (that is,
 * their {@link Robot#getSwarm()} method must return
 * this swarm).
 */
public class Swarm {

    private Collection<Robot> robots =
        new ArrayList<Robot>();

    /**
     * Gets the collection of robots that are members
     * of this swarm.
     *
     * @return  not null
     */
    public Collection<Robot> getRobots() {
        return new ArrayList<Robot>(robots);
    }

    /**
     * Adds the given robot to the swarm.
     *
     * @param   robot   the robot to add; must not
     *                  already belong to a swarm
     */
    public void addRobot(Robot robot) {
        robots.add(robot);
        robot.setSwarm(this);
    }

    /**
     * Removes the given robot from the swarm.
     *
     * @param   robot   the robot to remove; must be
     *                  a member of this swarm (see
     *                  {@link #getRobots()})
     */
    public void removeRobot(Robot robot) {
        robots.remove(robot);
        robot.setSwarm(null);
    }
}

The AbstractRobot class contains straightforward implementations of the methods defined by the Robot interface, except for the getLocation method, which is implemented differently in the Navigator and Worker classes (using GPS and triangulation, respectively). You can get the full source code for this example from my Subversion repository or download it as a zip file. All you need to run this example is JDK 5 (or higher) and Ant.

In upcoming posts I will evaluate various tools for creating formal contract specifications to replace the informal contracts that I wrote in the JavaDoc comments above.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: