Link them together and run the simulation
Example with a Netlogo random walk model
The model used is a simple random
walk where, for each simulation step,
agents (so-called walkers) choose a random direction and step forward.
The Netlogo model specification is available
here.
The exchanged data will be here the walkers positions (x,y) the same
for input and output. In this simplistic case, the model exchange
theses
data with itself (i.e. its input port correspond to its output port).
Since not very useful for simulation results, this
example allows to introduce the very first concepts and their
implementation
In this tutorial, we present the operation we take on the positions in
order for the walkers not go outside the boundaries of the model.
An operation to filter the positions
In our example, we want that, when a
walker reaches the boundaries of the model, its position is
automatically set to (0,0). Although this operation is quite simple, it
is the basis to more evolved ones (see link2models).
In order to implement an operation, you need to extend the
Operation
interface. The apply method is used to implement the core of the
operation. In our example, for each positions, we check that it is
inside the boundaries. If not, we set the position to (0,0).
/**
* This class represents an operation which goal is to change the positions
* (x,y) of the Netlogo turtles when they reach the borders (defined by
* environment width and height)
*
* @author Julien Siebert
*/
public class PositionsLimitOp implements Operation {
/**
* Environment width (in order to replace the agents when they are out).
*/
private int environmentWidth;
/**
* Environment height (in order to replace the agents when they are out).
*/
private int environmentHeight;
/**
* Constructor
* @param width
* @param height
*/
public PositionsLimitOp(int width, int height) {
environmentHeight = height;
environmentWidth = width;
}
public SimulData apply(SimulData someKindOfData) {
// the list of new positions to return
HashMap<Double, Point2D.Double> newPositionList = new HashMap<Double, Point2D.Double>();
// check if the class of the simulData is correct (i.e. correspond to
// the TurtlePosition Class)
if (someKindOfData.getClass().equals(TurtlePositions.class)) {
// get the initial list of positions
TurtlePositions pos = (TurtlePositions) someKindOfData;
HashMap<Double, Point2D.Double> oldPositionList = pos
.getTurtlePositions();
// limit the turtle positions
for (Double turtleID : oldPositionList.keySet()) {
// get the initial positions
Point2D.Double aPosition = oldPositionList.get(turtleID);
// limit the initial position (if needed)
aPosition = operation(aPosition);
// fill the resulting hashMap (I.e. the new list of new
// positions)
newPositionList.put(turtleID, aPosition);
}
} else {
// exit.
System.err
.println("trying to take an operation on a non turtle position data");
System.exit(666);
}
// the simulData to return
SimulData res = new TurtlePositions(newPositionList);
return res;
}
/**
* This is an example of operation we can take on the set of input data. In
* this example when an agent is outside the environment boundaries (width
* and height), then its position is set to the origin (0,0).
*
* @param aPosition
* @return
*/
private Point2D.Double operation(Point2D.Double aPosition) {
Point2D.Double newPosToReturn = aPosition;
if ((aPosition.getX() < (-environmentWidth / 2))
|| (aPosition.getX() > (environmentWidth / 2))
|| (aPosition.getY() < (-environmentHeight / 2))
|| (aPosition.getY() > (environmentHeight / 2))) {
newPosToReturn.y = 0;
newPosToReturn.x = 0;
}
return newPosToReturn;
}
public int getEnvironmentWidth() {
return environmentWidth;
}
public int getEnvironmentHeight() {
return environmentHeight;
}
}