Commit d88a552d authored by Björn Richerzhagen's avatar Björn Richerzhagen
Browse files

MovementModel refactoring (non-breaking changes)

- support for in-model placement of nodes
parent 288e94c4
......@@ -42,7 +42,9 @@ public interface TopologyComponent extends SimHostComponent,
* Binder-class.
*
* @return
* @deprecated use Binder.getComponent(Topology.class) instead!
*/
@Deprecated
public Topology getTopology();
}
......@@ -40,6 +40,12 @@ public interface MovementModel {
*/
public void addComponent(SimLocationActuator actuator);
/**
* Called for each component once during initialization, after all
* components have been added.
*/
public void placeComponent(SimLocationActuator actuator);
/**
* If you want to trigger the movement periodically, set this to a time
*
......
......@@ -34,6 +34,7 @@ import de.tud.kom.p2psim.api.linklayer.mac.MacLayer;
import de.tud.kom.p2psim.api.linklayer.mac.PhyType;
import de.tud.kom.p2psim.api.topology.Topology;
import de.tud.kom.p2psim.api.topology.TopologyComponent;
import de.tud.kom.p2psim.api.topology.movement.MovementModel;
import de.tud.kom.p2psim.api.topology.placement.PlacementModel;
import de.tud.kom.p2psim.api.topology.views.TopologyView;
import de.tud.kom.p2psim.impl.simengine.Simulator;
......@@ -75,37 +76,60 @@ public class DefaultTopologyComponent implements TopologyComponent {
private SimHost host;
private PositionVector position;
private final PositionVector position;
private Topology topology;
private double currentMovementSpeed = -1;
private Map<LocationListener, LocationRequestImpl> openRequests = new LinkedHashMap<LocationListener, LocationRequestImpl>();
private List<LocationListener> listeners = new LinkedList<>();
private MovementModel movementModel;
private PlacementModel placementModel;
/**
* This reference is nulled after placement, as the process is only done
* once.
* Create a TopologyComponent for the current host.
*
* @param host
* @param topology
* @param movementModel
*/
private PlacementModel placement;
public DefaultTopologyComponent(SimHost host, Topology topology,
PlacementModel placement) {
MovementModel movementModel, PlacementModel placementModel) {
this.topology = topology;
this.placement = placement;
this.host = host;
// TODO maybe we need to do this in the initialize-method
placement.addComponent(this);
this.position = new PositionVector(0, 0);
this.movementModel = movementModel;
if (this.movementModel != null) {
this.movementModel.addComponent(this);
}
this.placementModel = placementModel;
if (this.placementModel != null) {
this.placementModel.addComponent(this);
}
}
@Override
public void initialize() {
position = placement.place(this);
placement = null;
/*
* Set the component's initial position and notify listeners of the
* Topology that this component is initialized.
*/
topology.addComponent(this);
movementModel.placeComponent(this);
if (placementModel != null) {
/*
* Legacy support for placement models.
*/
position.set(placementModel.place(this));
}
try {
final SiSComponent sis = host.getComponent(SiSComponent.class);
sis.provide().nodeState(SiSTypes.PHY_LOCATION,
......@@ -159,6 +183,7 @@ public class DefaultTopologyComponent implements TopologyComponent {
public void shutdown() {
topology = null;
host = null;
movementModel = null;
}
@Override
......@@ -268,7 +293,6 @@ public class DefaultTopologyComponent implements TopologyComponent {
return new LocationRequestImpl();
}
/**
* Update 15.03.16 added support for multiple listeners (however, frequency
* etc. is immune after the first request is registered.)
......@@ -403,7 +427,7 @@ public class DefaultTopologyComponent implements TopologyComponent {
/**
* This is calculated based on global knowledge. It only registers as
* {@link MovementListener}, if a range is specified by the Provider.
* {@link LocationListener}, if a range is specified by the Provider.
*
* @author Bjoern Richerzhagen
* @version 1.0, May 13, 2015
......@@ -587,4 +611,9 @@ public class DefaultTopologyComponent implements TopologyComponent {
}
@Override
public String toString() {
return "TopoComp: " + getHost().getId() + " at " + position.toString();
}
}
......@@ -36,7 +36,10 @@ import de.tud.kom.p2psim.api.topology.views.TopologyView;
import de.tud.kom.p2psim.api.topology.waypoints.WaypointModel;
import de.tud.kom.p2psim.impl.network.modular.DBHostListManager;
import de.tud.kom.p2psim.impl.network.modular.db.NetMeasurementDB;
import de.tud.kom.p2psim.impl.topology.movement.AbstractMovementModel;
import de.tud.kom.p2psim.impl.topology.movement.AbstractWaypointMovementModel;
import de.tud.kom.p2psim.impl.topology.movement.NoMovement;
import de.tud.kom.p2psim.impl.topology.movement.modular.ModularMovementModel;
import de.tud.kom.p2psim.impl.topology.placement.GNPPlacement;
import de.tud.kom.p2psim.impl.topology.views.latency.GNPLatency;
import de.tudarmstadt.maki.simonstrator.api.Binder;
......@@ -66,7 +69,7 @@ public class TopologyFactory implements HostComponentFactory {
/**
* Movement model for the current group of hosts
*/
private MovementModel movement;
private MovementModel movement = new NoMovement();
private WaypointModel waypointModel;
......@@ -120,25 +123,24 @@ public class TopologyFactory implements HostComponentFactory {
measurementDBHosts.put(host, hostMeta);
}
/*
* Create a TopologyComponent and register it with the Topology and its
* movement model.
*/
TopologyComponent toCo = new DefaultTopologyComponent(host, topo,
placement);
if (movement != null) {
/*
* Movement models influence a node's current position via the
* SimLocationActuator-Interface.
*/
movement.addComponent(toCo);
/*
* Need to register TopoViews as movement listeners, as they might
* need to update topologies after each movement.
*/
for (PhyType phy : PhyType.values()) {
TopologyView view = topo.getTopologyView(phy);
if (view != null) {
toCo.requestLocationUpdates(null, view);
}
movement, placement);
/*
* Need to register TopoViews as movement listeners, as they might need
* to update topologies after each movement.
*/
for (PhyType phy : PhyType.values()) {
TopologyView view = topo.getTopologyView(phy);
if (view != null) {
toCo.requestLocationUpdates(null, view);
}
}
Monitor.log(TopologyFactory.class, Level.INFO,
"Topology Component for Host %s created. Placement: %s, Movement: %s",
host.getHostId(), placement, movement);
......
......@@ -27,16 +27,20 @@ import java.util.Random;
import java.util.Set;
import de.tud.kom.p2psim.api.topology.Topology;
import de.tud.kom.p2psim.api.topology.TopologyComponent;
import de.tud.kom.p2psim.api.topology.movement.MovementListener;
import de.tud.kom.p2psim.api.topology.movement.MovementModel;
import de.tud.kom.p2psim.api.topology.movement.MovementSupported;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tud.kom.p2psim.api.topology.placement.PlacementModel;
import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tud.kom.p2psim.impl.topology.TopologyFactory;
import de.tudarmstadt.maki.simonstrator.api.Binder;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/**
* Unified movement Models. Can be used inside an Application (virtual Position)
......@@ -57,6 +61,15 @@ public abstract class AbstractMovementModel implements MovementModel {
private Random random = Randoms.getRandom(AbstractMovementModel.class);
/**
* This default implementation relies on {@link PlacementModel}s to be
* configured in the {@link TopologyFactory}
*/
@Override
public void placeComponent(SimLocationActuator actuator) {
// not supported
}
/**
* Gets called periodically (after timeBetweenMoveOperations) or by an
* application and should be used to recalculate positions
......@@ -158,9 +171,10 @@ public abstract class AbstractMovementModel implements MovementModel {
*/
protected void updatePosition(SimLocationActuator actuator,
PositionVector newPosition) {
this.updatePosition(actuator, newPosition.getLongitude(), newPosition.getLatitude());
this.updatePosition(actuator, newPosition.getLongitude(),
newPosition.getLatitude());
}
/**
* Call this method to finally update the location of the given component.
*
......
......@@ -25,19 +25,23 @@ import java.util.Random;
import java.util.Set;
import java.util.WeakHashMap;
import de.tud.kom.p2psim.api.topology.TopologyComponent;
import de.tud.kom.p2psim.api.topology.movement.MovementModel;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tud.kom.p2psim.api.topology.movement.local.LocalMovementStrategy;
import de.tud.kom.p2psim.api.topology.placement.PlacementModel;
import de.tud.kom.p2psim.api.topology.waypoints.WaypointModel;
import de.tud.kom.p2psim.impl.scenario.simcfg2.annotations.After;
import de.tud.kom.p2psim.impl.scenario.simcfg2.annotations.Configure;
import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tud.kom.p2psim.impl.topology.TopologyFactory;
import de.tud.kom.p2psim.impl.util.Either;
import de.tud.kom.p2psim.impl.util.geo.maps.MapLoader;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Monitor.Level;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.Time;
......@@ -74,7 +78,7 @@ public abstract class AbstractWaypointMovementModel implements MovementModel {
private double unscaledSpeedLimit = speedLimit;
private Random rnd = Randoms.getRandom(AbstractWaypointMovementModel.class);
public AbstractWaypointMovementModel(double worldX, double worldY) {
worldDimensions = new PositionVector(worldX, worldY);
destinations = new WeakHashMap<SimLocationActuator, PositionVector>();
......@@ -106,6 +110,15 @@ public abstract class AbstractWaypointMovementModel implements MovementModel {
return true;
}
/**
* This default implementation relies on {@link PlacementModel}s to be
* configured in the {@link TopologyFactory}
*/
@Override
public void placeComponent(SimLocationActuator actuator) {
// not supported
}
/**
* Gets called periodically (after timeBetweenMoveOperations) or by an
......
......@@ -31,11 +31,14 @@ import java.util.Vector;
import de.tud.kom.p2psim.api.scenario.ConfigurationException;
import de.tud.kom.p2psim.api.topology.Topology;
import de.tud.kom.p2psim.api.topology.TopologyComponent;
import de.tud.kom.p2psim.api.topology.movement.MovementModel;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tud.kom.p2psim.api.topology.movement.local.LocalMovementStrategy;
import de.tud.kom.p2psim.api.topology.placement.PlacementModel;
import de.tud.kom.p2psim.impl.simengine.Simulator;
import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tud.kom.p2psim.impl.topology.TopologyFactory;
import de.tud.kom.p2psim.impl.topology.movement.AbstractWaypointMovementModel;
import de.tud.kom.p2psim.impl.topology.movement.CsvMovement;
import de.tud.kom.p2psim.impl.topology.movement.NoMovement;
......@@ -50,6 +53,7 @@ import de.tudarmstadt.maki.simonstrator.api.Binder;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/**
* Modular Movement Model uses different models/strategies to create a movement
......@@ -82,8 +86,6 @@ import de.tudarmstadt.maki.simonstrator.api.Randoms;
* destination point (AttractionPoint), so that not all hosts, which are
* assigned to one {@link AttractionPoint}, lies on the same point.<br>
*
*
*
* @author Christoph Muenker
* @version 1.0, 02.07.2013
*/
......@@ -200,6 +202,15 @@ public class ModularMovementModel implements MovementModel, EventHandler {
"Missing WaypointModel for the ModuloarMovementModel.movementModel");
}
}
/**
* This default implementation relies on {@link PlacementModel}s to be
* configured in the {@link TopologyFactory}
*/
@Override
public void placeComponent(SimLocationActuator actuator) {
// not supported
}
@Override
public void addComponent(SimLocationActuator comp) {
......
......@@ -33,11 +33,14 @@ import javax.swing.JComponent;
import de.tud.kom.p2psim.api.scenario.ConfigurationException;
import de.tud.kom.p2psim.api.topology.Topology;
import de.tud.kom.p2psim.api.topology.TopologyComponent;
import de.tud.kom.p2psim.api.topology.movement.MovementModel;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tud.kom.p2psim.api.topology.movement.local.LocalMovementStrategy;
import de.tud.kom.p2psim.api.topology.placement.PlacementModel;
import de.tud.kom.p2psim.impl.simengine.Simulator;
import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tud.kom.p2psim.impl.topology.TopologyFactory;
import de.tud.kom.p2psim.impl.topology.movement.modular.transition.TransitionStrategy;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction.AttractionPoint;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction.IAttractionGenerator;
......@@ -49,6 +52,7 @@ import de.tudarmstadt.maki.simonstrator.api.Binder;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/**
* Modular Movement Model uses different models/strategies to create a movement
......@@ -157,6 +161,15 @@ public class ModularMovementModel implements MovementModel, EventHandler {
initialized = true;
}
}
/**
* This default implementation relies on {@link PlacementModel}s to be
* configured in the {@link TopologyFactory}
*/
@Override
public void placeComponent(SimLocationActuator actuator) {
// not supported
}
private void checkConfiguration() {
if (localMovementStrategy == null) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment