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

Refactoring due to Location/Attraction API changes

- removed obsolete and duplicate modular movement classes (check your
config-files, you might need to replace "modular" with "modularosm" in
some cases
parent 0d0f5448
...@@ -20,7 +20,10 @@ ...@@ -20,7 +20,10 @@
package de.tud.kom.p2psim.api.topology.movement; package de.tud.kom.p2psim.api.topology.movement;
import java.util.Set;
import de.tud.kom.p2psim.api.topology.TopologyComponent; import de.tud.kom.p2psim.api.topology.TopologyComponent;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint;
/** /**
* A movement model for a group of {@link TopologyComponent}s. The movement * A movement model for a group of {@link TopologyComponent}s. The movement
...@@ -55,11 +58,38 @@ public interface MovementModel { ...@@ -55,11 +58,38 @@ public interface MovementModel {
* view) * view)
* *
* @param actuator * @param actuator
* @param longitude * @param targetAttractionPoint
* @param latitude */
default public void changeTargetLocation(SimLocationActuator actuator,
AttractionPoint targetAttractionPoint)
throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
/**
* OPTIONAL: returns the movement target of the actuator.
*
* OBVIOUSLY, this is not supported by all models (from a semantic point of
* view)
*
* @param actuator
* @return target AttractionPoint
*/
default public AttractionPoint getTargetLocation(
SimLocationActuator actuator) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
/**
* OPTIONAL returns a list of all attraction points
*
* @return
* @throws UnsupportedOperationException
*/ */
public void changeTargetLocation(SimLocationActuator actuator, default public Set<AttractionPoint> getAllAttractionPoints()
double longitude, double latitude); throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
/** /**
* If you want to trigger the movement periodically, set this to a time * If you want to trigger the movement periodically, set this to a time
......
...@@ -38,7 +38,6 @@ import de.tud.kom.p2psim.api.topology.movement.MovementModel; ...@@ -38,7 +38,6 @@ 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.placement.PlacementModel;
import de.tud.kom.p2psim.api.topology.views.TopologyView; import de.tud.kom.p2psim.api.topology.views.TopologyView;
import de.tud.kom.p2psim.impl.simengine.Simulator; import de.tud.kom.p2psim.impl.simengine.Simulator;
import de.tud.kom.p2psim.impl.topology.movement.modular.attraction.AttractionPoint;
import de.tudarmstadt.maki.simonstrator.api.Event; import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler; import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Graphs; import de.tudarmstadt.maki.simonstrator.api.Graphs;
...@@ -53,6 +52,7 @@ import de.tudarmstadt.maki.simonstrator.api.common.graph.INodeID; ...@@ -53,6 +52,7 @@ import de.tudarmstadt.maki.simonstrator.api.common.graph.INodeID;
import de.tudarmstadt.maki.simonstrator.api.component.ComponentNotAvailableException; import de.tudarmstadt.maki.simonstrator.api.component.ComponentNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetInterface; import de.tudarmstadt.maki.simonstrator.api.component.network.NetInterface;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetworkComponent.NetInterfaceName; import de.tudarmstadt.maki.simonstrator.api.component.network.NetworkComponent.NetInterfaceName;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationListener; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationListener;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationRequest; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationRequest;
...@@ -256,17 +256,28 @@ public class DefaultTopologyComponent implements TopologyComponent { ...@@ -256,17 +256,28 @@ public class DefaultTopologyComponent implements TopologyComponent {
} }
@Override @Override
public void updateCurrentLocation(double longitude, double latitude) { public void updateCurrentLocation(Location location) {
position.setEntries(longitude, latitude); position.set(location);
// notify "non-request" listeners // notify "non-request" listeners
for (LocationListener locationListener : listeners) { for (LocationListener locationListener : listeners) {
locationListener.onLocationChanged(getHost(), getLastLocation()); locationListener.onLocationChanged(getHost(), getLastLocation());
} }
} }
@Override
public void setTargetAttractionPoint(AttractionPoint targetAttractionPoint)
throws UnsupportedOperationException {
movementModel.changeTargetLocation(this, targetAttractionPoint);
}
@Override
public AttractionPoint getCurrentTargetAttractionPoint() {
return movementModel.getTargetLocation(this);
}
@Override @Override
public void setNewTargetLocation(double longitude, double latitude) { public Set<AttractionPoint> getAllAttractionPoints() {
movementModel.changeTargetLocation(this, longitude, latitude); return movementModel.getAllAttractionPoints();
} }
@Override @Override
......
...@@ -23,6 +23,8 @@ package de.tud.kom.p2psim.impl.topology; ...@@ -23,6 +23,8 @@ package de.tud.kom.p2psim.impl.topology;
import java.awt.Point; import java.awt.Point;
import java.util.Arrays; import java.util.Arrays;
import org.aopalliance.aop.AspectException;
import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Coordinate;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
...@@ -58,6 +60,8 @@ public class PositionVector implements Location { ...@@ -58,6 +60,8 @@ public class PositionVector implements Location {
* transforms can be performed in the getter-methods. * transforms can be performed in the getter-methods.
*/ */
private double[] values; private double[] values;
private double accuracy = -1;
/** /**
* Create a new Position Vector * Create a new Position Vector
...@@ -96,6 +100,38 @@ public class PositionVector implements Location { ...@@ -96,6 +100,38 @@ public class PositionVector implements Location {
setEntry(i, values[i]); setEntry(i, values[i]);
} }
} }
@Override
public void setLatitude(double latitude)
throws UnsupportedOperationException {
this.setEntry(1, latitude);
}
@Override
public void setLongitude(double longitude)
throws UnsupportedOperationException {
this.setEntry(0, longitude);
}
@Override
public void setAccuracy(double accuracy)
throws UnsupportedOperationException {
if (accuracy < 0) {
throw new AssertionError();
}
this.accuracy = accuracy;
}
@Override
public double getAccuracy() {
assert hasAccuracy() : "should check for hasAccuracy first!";
return accuracy;
}
@Override
public boolean hasAccuracy() {
return accuracy != -1;
}
/** /**
* Number of Dimensions * Number of Dimensions
......
...@@ -36,10 +36,8 @@ import de.tud.kom.p2psim.api.topology.views.TopologyView; ...@@ -36,10 +36,8 @@ import de.tud.kom.p2psim.api.topology.views.TopologyView;
import de.tud.kom.p2psim.api.topology.waypoints.WaypointModel; 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.DBHostListManager;
import de.tud.kom.p2psim.impl.network.modular.db.NetMeasurementDB; 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.AbstractWaypointMovementModel;
import de.tud.kom.p2psim.impl.topology.movement.NoMovement; 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.placement.GNPPlacement;
import de.tud.kom.p2psim.impl.topology.views.latency.GNPLatency; import de.tud.kom.p2psim.impl.topology.views.latency.GNPLatency;
import de.tudarmstadt.maki.simonstrator.api.Binder; import de.tudarmstadt.maki.simonstrator.api.Binder;
...@@ -47,7 +45,6 @@ import de.tudarmstadt.maki.simonstrator.api.Host; ...@@ -47,7 +45,6 @@ import de.tudarmstadt.maki.simonstrator.api.Host;
import de.tudarmstadt.maki.simonstrator.api.Monitor; import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Monitor.Level; import de.tudarmstadt.maki.simonstrator.api.Monitor.Level;
import de.tudarmstadt.maki.simonstrator.api.component.HostComponentFactory; import de.tudarmstadt.maki.simonstrator.api.component.HostComponentFactory;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationRequest;
import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor; import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
/** /**
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
package de.tud.kom.p2psim.impl.topology.movement; package de.tud.kom.p2psim.impl.topology.movement;
import java.nio.channels.UnsupportedAddressTypeException;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
...@@ -40,6 +41,7 @@ import de.tudarmstadt.maki.simonstrator.api.Event; ...@@ -40,6 +41,7 @@ import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler; import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Randoms; import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.Time; import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/** /**
...@@ -69,13 +71,6 @@ public abstract class AbstractMovementModel implements MovementModel { ...@@ -69,13 +71,6 @@ public abstract class AbstractMovementModel implements MovementModel {
public void placeComponent(SimLocationActuator actuator) { public void placeComponent(SimLocationActuator actuator) {
// not supported // not supported
} }
@Override
public void changeTargetLocation(SimLocationActuator actuator,
double longitude, double latitude) throws UnsupportedOperationException {
// not supported by default. Extend this method, if needed.
throw new UnsupportedOperationException();
}
/** /**
* Gets called periodically (after timeBetweenMoveOperations) or by an * Gets called periodically (after timeBetweenMoveOperations) or by an
...@@ -178,19 +173,7 @@ public abstract class AbstractMovementModel implements MovementModel { ...@@ -178,19 +173,7 @@ public abstract class AbstractMovementModel implements MovementModel {
*/ */
protected void updatePosition(SimLocationActuator actuator, protected void updatePosition(SimLocationActuator actuator,
PositionVector newPosition) { PositionVector newPosition) {
this.updatePosition(actuator, newPosition.getLongitude(), actuator.updateCurrentLocation(newPosition);
newPosition.getLatitude());
}
/**
* Call this method to finally update the location of the given component.
*
* @param actuator
* @param newPosition
*/
protected void updatePosition(SimLocationActuator actuator,
double longitude, double latitude) {
actuator.updateCurrentLocation(longitude, latitude);
} }
/** /**
......
...@@ -41,6 +41,7 @@ import de.tudarmstadt.maki.simonstrator.api.Event; ...@@ -41,6 +41,7 @@ import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler; import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Monitor; import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Monitor.Level; import de.tudarmstadt.maki.simonstrator.api.Monitor.Level;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
import de.tudarmstadt.maki.simonstrator.api.Randoms; import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.Time; import de.tudarmstadt.maki.simonstrator.api.Time;
...@@ -78,7 +79,7 @@ public abstract class AbstractWaypointMovementModel implements MovementModel { ...@@ -78,7 +79,7 @@ public abstract class AbstractWaypointMovementModel implements MovementModel {
private double unscaledSpeedLimit = speedLimit; private double unscaledSpeedLimit = speedLimit;
private Random rnd = Randoms.getRandom(AbstractWaypointMovementModel.class); private Random rnd = Randoms.getRandom(AbstractWaypointMovementModel.class);
public AbstractWaypointMovementModel(double worldX, double worldY) { public AbstractWaypointMovementModel(double worldX, double worldY) {
worldDimensions = new PositionVector(worldX, worldY); worldDimensions = new PositionVector(worldX, worldY);
destinations = new WeakHashMap<SimLocationActuator, PositionVector>(); destinations = new WeakHashMap<SimLocationActuator, PositionVector>();
...@@ -97,9 +98,7 @@ public abstract class AbstractWaypointMovementModel implements MovementModel { ...@@ -97,9 +98,7 @@ public abstract class AbstractWaypointMovementModel implements MovementModel {
} }
if (this.waypointModel == null) { if (this.waypointModel == null) {
Monitor.log( Monitor.log(AbstractWaypointMovementModel.class, Level.INFO,
AbstractWaypointMovementModel.class,
Level.INFO,
"No waypoint model has been configured. Thus the movement speed won't be adjusted for the scale of the waypoint model."); "No waypoint model has been configured. Thus the movement speed won't be adjusted for the scale of the waypoint model.");
} }
// //
...@@ -110,7 +109,7 @@ public abstract class AbstractWaypointMovementModel implements MovementModel { ...@@ -110,7 +109,7 @@ public abstract class AbstractWaypointMovementModel implements MovementModel {
return true; return true;
} }
/** /**
* This default implementation relies on {@link PlacementModel}s to be * This default implementation relies on {@link PlacementModel}s to be
* configured in the {@link TopologyFactory} * configured in the {@link TopologyFactory}
...@@ -119,13 +118,6 @@ public abstract class AbstractWaypointMovementModel implements MovementModel { ...@@ -119,13 +118,6 @@ public abstract class AbstractWaypointMovementModel implements MovementModel {
public void placeComponent(SimLocationActuator actuator) { public void placeComponent(SimLocationActuator actuator) {
// not supported // not supported
} }
@Override
public void changeTargetLocation(SimLocationActuator actuator,
double longitude, double latitude) throws UnsupportedOperationException {
// not supported by default. Extend this method, if needed.
throw new UnsupportedOperationException();
}
/** /**
* Gets called periodically (after timeBetweenMoveOperations) or by an * Gets called periodically (after timeBetweenMoveOperations) or by an
...@@ -191,7 +183,7 @@ public abstract class AbstractWaypointMovementModel implements MovementModel { ...@@ -191,7 +183,7 @@ public abstract class AbstractWaypointMovementModel implements MovementModel {
} }
} }
} }
/** /**
* Call this method to finally update the location of the given component. * Call this method to finally update the location of the given component.
* *
...@@ -200,18 +192,7 @@ public abstract class AbstractWaypointMovementModel implements MovementModel { ...@@ -200,18 +192,7 @@ public abstract class AbstractWaypointMovementModel implements MovementModel {
*/ */
protected void updatePosition(SimLocationActuator actuator, protected void updatePosition(SimLocationActuator actuator,
PositionVector newPosition) { PositionVector newPosition) {
this.updatePosition(actuator, newPosition.getLongitude(), newPosition.getLatitude()); actuator.updateCurrentLocation(newPosition);
}
/**
* Call this method to finally update the location of the given component.
*
* @param actuator
* @param newPosition
*/
protected void updatePosition(SimLocationActuator actuator,
double longitude, double latitude) {
actuator.updateCurrentLocation(longitude, latitude);
} }
/** /**
...@@ -243,7 +224,8 @@ public abstract class AbstractWaypointMovementModel implements MovementModel { ...@@ -243,7 +224,8 @@ public abstract class AbstractWaypointMovementModel implements MovementModel {
* @param dst * @param dst
* @return Returns true if the destination was reached * @return Returns true if the destination was reached
*/ */
private boolean reachedPosition(SimLocationActuator comp, PositionVector dst) { private boolean reachedPosition(SimLocationActuator comp,
PositionVector dst) {
PositionVector pos = comp.getRealPosition(); PositionVector pos = comp.getRealPosition();
double distance = pos.distanceTo(dst); double distance = pos.distanceTo(dst);
...@@ -263,10 +245,10 @@ public abstract class AbstractWaypointMovementModel implements MovementModel { ...@@ -263,10 +245,10 @@ public abstract class AbstractWaypointMovementModel implements MovementModel {
private PositionVector getDestination(SimLocationActuator comp) { private PositionVector getDestination(SimLocationActuator comp) {
PositionVector dst = destinations.get(comp); PositionVector dst = destinations.get(comp);
Monitor.log(AbstractWaypointMovementModel.class, Level.DEBUG, "Pos: " Monitor.log(AbstractWaypointMovementModel.class, Level.DEBUG,
+ comp.getRealPosition()); "Pos: " + comp.getRealPosition());
Monitor.log(AbstractWaypointMovementModel.class, Level.DEBUG, "Dst: " Monitor.log(AbstractWaypointMovementModel.class, Level.DEBUG,
+ dst); "Dst: " + dst);
if (dst == null) { if (dst == null) {
Monitor.log(AbstractWaypointMovementModel.class, Level.DEBUG, Monitor.log(AbstractWaypointMovementModel.class, Level.DEBUG,
......
...@@ -33,15 +33,14 @@ import de.tud.kom.p2psim.api.common.SimHost; ...@@ -33,15 +33,14 @@ import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.network.SimNetInterface; import de.tud.kom.p2psim.api.network.SimNetInterface;
import de.tud.kom.p2psim.api.topology.Topology; import de.tud.kom.p2psim.api.topology.Topology;
import de.tud.kom.p2psim.api.topology.movement.MovementInformation; import de.tud.kom.p2psim.api.topology.movement.MovementInformation;
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.movement.SimLocationActuator;
import de.tud.kom.p2psim.impl.simengine.Simulator; import de.tud.kom.p2psim.impl.simengine.Simulator;
import de.tud.kom.p2psim.impl.topology.PositionVector; import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tud.kom.p2psim.impl.topology.movement.modular.ModularMovementModel; import de.tud.kom.p2psim.impl.topology.movement.modularosm.ModularMovementModel;
import de.tud.kom.p2psim.impl.topology.movement.modular.attraction.AttractionPoint; import de.tud.kom.p2psim.impl.topology.movement.modularosm.transition.FixedAssignmentStrategy;
import de.tud.kom.p2psim.impl.topology.movement.modular.transition.FixedAssignmentStrategy;
import de.tudarmstadt.maki.simonstrator.api.Binder; import de.tudarmstadt.maki.simonstrator.api.Binder;
import de.tudarmstadt.maki.simonstrator.api.Time; import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint;
import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor; import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
/** /**
......
...@@ -24,47 +24,25 @@ import java.util.LinkedHashMap; ...@@ -24,47 +24,25 @@ import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.Vector;
import javax.swing.JComponent;
import com.graphhopper.GHRequest;
import com.graphhopper.GHResponse;
import com.graphhopper.util.PointList;
import com.graphhopper.util.shapes.GHPoint;
import com.graphhopper.util.shapes.GHPoint3D;
import de.tud.kom.p2psim.api.scenario.ConfigurationException; import de.tud.kom.p2psim.api.scenario.ConfigurationException;
import de.tud.kom.p2psim.api.topology.Topology; 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.MovementModel;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator; 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.placement.PlacementModel;
import de.tud.kom.p2psim.impl.simengine.Simulator; import de.tud.kom.p2psim.impl.simengine.Simulator;
import de.tud.kom.p2psim.impl.topology.PositionVector; import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tud.kom.p2psim.impl.topology.TopologyFactory; import de.tud.kom.p2psim.impl.topology.TopologyFactory;
import de.tud.kom.p2psim.impl.topology.movement.local.RealWorldMovementPoints;
import de.tud.kom.p2psim.impl.topology.movement.modular.ModularMovementModelViz;
import de.tud.kom.p2psim.impl.topology.movement.modular.transition.TransitionStrategy;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.GPSCalculation; import de.tud.kom.p2psim.impl.topology.movement.modularosm.GPSCalculation;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction.AttractionPoint;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction.IAttractionGenerator;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.mapvisualization.IMapVisualization;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.transition.ITransitionStrategy;
import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.VisualizationInjector;
import de.tud.kom.p2psim.impl.util.Either;
import de.tud.kom.p2psim.impl.util.Left;
import de.tudarmstadt.maki.simonstrator.api.Binder; import de.tudarmstadt.maki.simonstrator.api.Binder;
import de.tudarmstadt.maki.simonstrator.api.Event; import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler; import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Randoms; import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint;
/** /**
* *
...@@ -155,7 +133,7 @@ public class StreetMovement implements MovementModel, EventHandler { ...@@ -155,7 +133,7 @@ public class StreetMovement implements MovementModel, EventHandler {
PositionVector startingPosition = this.returnRandomPositionBetweenPoints(a,b); PositionVector startingPosition = this.returnRandomPositionBetweenPoints(a,b);
ms.updateCurrentLocation(startingPosition.getLongitude(), startingPosition.getLatitude()); ms.updateCurrentLocation(startingPosition);
positions.put(ms, ms.getRealPosition()); positions.put(ms, ms.getRealPosition());
...@@ -173,13 +151,13 @@ public class StreetMovement implements MovementModel, EventHandler { ...@@ -173,13 +151,13 @@ public class StreetMovement implements MovementModel, EventHandler {
double longMin, longMax, latMin, latMax, longNew, latNew; double longMin, longMax, latMin, latMax, longNew, latNew;
// Points have different longitude, so only search for random value for longitude // Points have different longitude, so only search for random value for longitude
if(a.getRealPosition().getLongitude() != b.getRealPosition().getLongitude()) { if(a.getLongitude() != b.getLongitude()) {
if(a.getRealPosition().getLongitude() < b.getRealPosition().getLongitude()) { if(a.getLongitude() < b.getLongitude()) {
longMin = a.getRealPosition().getLongitude(); longMin = a.getLongitude();
longMax = b.getRealPosition().getLongitude(); longMax = b.getLongitude();
} else { } else {
longMin = b.getRealPosition().getLongitude(); longMin = b.getLongitude();
longMax = a.getRealPosition().getLongitude(); longMax = a.getLongitude();
} }
do { do {
...@@ -187,17 +165,17 @@ public class StreetMovement implements MovementModel, EventHandler { ...@@ -187,17 +165,17 @@ public class StreetMovement implements MovementModel, EventHandler {
} while(longNew < longMin); } while(longNew < longMin);
assert longNew > longMin && longNew <= longMax; assert longNew > longMin && longNew <= longMax;
return new PositionVector(longNew, a.getRealPosition().getLatitude()); return new PositionVector(longNew, a.getLatitude());
} }
// Points have different latitude, so only search for random value for latitude // Points have different latitude, so only search for random value for latitude
if(a.getRealPosition().getLatitude() != b.getRealPosition().getLatitude()) { if(a.getLatitude() != b.getLatitude()) {
if(a.getRealPosition().getLatitude() < b.getRealPosition().getLatitude()) { if(a.getLatitude() < b.getLatitude()) {
latMin = a.getRealPosition().getLatitude(); latMin = a.getLatitude();
latMax = b.getRealPosition().getLatitude(); latMax = b.getLatitude();
} else { } else {
latMin = b.getRealPosition().getLatitude(); latMin = b.getLatitude();
latMax = a.getRealPosition().getLatitude(); latMax = a.getLatitude();
} }
do{ do{
...@@ -205,7 +183,7 @@ public class StreetMovement implements MovementModel, EventHandler { ...@@ -205,7 +183,7 @@ public class StreetMovement implements MovementModel, EventHandler {
} while(latNew < latMin); } while(latNew < latMin);
assert latNew > latMin && latNew <= latMax; assert latNew > latMin && latNew <= latMax;
return new PositionVector(a.getRealPosition().getLongitude(), latNew); return new PositionVector(a.getLongitude(), latNew);
} }
return null; return null;
...@@ -221,12 +199,11 @@ public class StreetMovement implements MovementModel, EventHandler { ...@@ -221,12 +199,11 @@ public class StreetMovement implements MovementModel, EventHandler {
} }
@Override @Override
public void changeTargetLocation(SimLocationActuator actuator, public void changeTargetLocation(SimLocationActuator actuator, AttractionPoint ap) {
double longitude, double latitude) {
/* /*
* Set a new target AP for the current actuator * Set a new target AP for the current actuator
*/ */
attractionOfClients.put(actuator, new AttractionPoint((int) longitude, (int) latitude, "")); attractionOfClients.put(actuator, ap);
} }
...@@ -253,13 +230,12 @@ public class StreetMovement implements MovementModel, EventHandler { ...@@ -253,13 +230,12 @@ public class StreetMovement implements MovementModel, EventHandler {
for (Entry<SimLocationActuator, AttractionPoint> entry : attractionOfClients.entrySet()) { for (Entry<SimLocationActuator, AttractionPoint> entry : attractionOfClients.entrySet()) {
SimLocationActuator ms = entry.getKey(); SimLocationActuator ms = entry.getKey();
PositionVector attractionCenter = entry.getValue() PositionVector attractionCenter = (PositionVector) entry.getValue();
.getRealPosition();
PositionVector destination = new PositionVector(attractionCenter); PositionVector destination = new PositionVector(attractionCenter);
if (destination.distanceTo(ms.getRealPosition()) > ms.getMovementSpeed()) { if (destination.distanceTo(ms.getRealPosition()) > ms.getMovementSpeed()) {
PositionVector newPosition = ms.getRealPosition().moveStep(destination, ms.getMovementSpeed()); PositionVector newPosition = ms.getRealPosition().moveStep(destination, ms.getMovementSpeed());
ms.updateCurrentLocation(newPosition.getLongitude(), newPosition.getLatitude()); ms.updateCurrentLocation(newPosition);
positions.put(ms, newPosition); positions.put(ms, newPosition);
} else { } else {
assignNewAttractionPoint(ms); assignNewAttractionPoint(ms);
...@@ -333,7 +309,7 @@ public class StreetMovement implements MovementModel, EventHandler { ...@@ -333,7 +309,7 @@ public class StreetMovement implements MovementModel, EventHandler {
} }
} }
protected List<AttractionPoint> getAttractionPoints() { public List<AttractionPoint> getAttractionPoints() {
return attractionPoints; return attractionPoints;
} }
......
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.topology.movement.modular;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
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;
import de.tud.kom.p2psim.impl.topology.movement.RandomPathMovement;
import de.tud.kom.p2psim.impl.topology.movement.modular.attraction.AttractionGenerator;
import de.tud.kom.p2psim.impl.topology.movement.modular.attraction.AttractionPoint;
import de.tud.kom.p2psim.impl.topology.movement.modular.transition.FixedAssignmentStrategy;
import de.tud.kom.p2psim.impl.topology.movement.modular.transition.TransitionStrategy;
import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.VisualizationInjector;
import de.tud.kom.p2psim.impl.util.Either;
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
* model. In this implementation, it has 4 different models/strategies.
* <p>
* M0: AttractionGenerator -> Generates the {@link AttractionPoint}s and place
* them on the map. The {@link AttractionPoint}s can be moved!
* <p>
* M1: A general {@link MovementModel}, like {@link RandomPathMovement} or
* {@link NoMovement}. It takes the {@link AttractionPoint}s and move them
* around the world.
* <p>
* M2: The {@link TransitionStrategy}! It takes the Hosts, which should be moved
* around, but calculates only the assignment to the {@link AttractionPoint}s.
* It doesn't move the Hosts! It will be only assignment a new AttractionPoint!
*
* <p>
* M3: The {@link LocalMovementStrategy} is responsible for the movement of the
* Hosts. It moves the hosts to the assigned AttractionPoint, and if the
* AttractionPoint has moved, then will be followed. The
* {@link LocalMovementStrategy} will be called from the
* {@link ModularMovementModel} to do a Movement!
* <p>
* This class contains all four components and manage the data exchange.
* Additionally it contains an periodic operation, which handle the movement of
* all hosts. This mean, that it will be call the {@link LocalMovementStrategy}
* with the destination. Please take care, that the handling of the movement of
* the AttractionPoints will be handled by the movement model in M1! <br>
* Further it contains an offset for every Host, which will be added to the
* 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
*/
public class ModularMovementModel implements MovementModel, EventHandler {
private final int EVENT_MOVE = 1;
private final int EVENT_INIT = 2;
protected PositionVector worldDimensions;
protected MovementModel movementModel = new NoMovement();
protected TransitionStrategy transition;
protected AttractionGenerator attractionGenerator;
protected LocalMovementStrategy localMovementStrategy;
private Set<SimLocationActuator> movementListeners = new LinkedHashSet<SimLocationActuator>();
private Set<SimLocationActuator> moveableHosts = new LinkedHashSet<SimLocationActuator>();
private Map<SimLocationActuator, PositionVector> offsetPosition = new LinkedHashMap<SimLocationActuator, PositionVector>();
private boolean initialized = false;
private long timeBetweenMoveOperation = Simulator.SECOND_UNIT;
private Random rand;
public ModularMovementModel() {
this.worldDimensions = Binder.getComponentOrNull(Topology.class)
.getWorldDimensions();
this.rand = Randoms.getRandom(ModularMovementModel.class);
// scheduling initalization!
Event.scheduleImmediately(this, null, EVENT_INIT);
}
/**
* This Method will be not called from the Components. So we call this
* manually!
*/
public void initialize() {
if (!initialized) {
VisualizationInjector.injectComponent("AttractionPoints", -1,
new ModularMovementModelViz(this), false);
checkConfiguration();
// FIXME NR: Special implementation for crater to give movement model
// the mapping of APs to Hosts to enable offline/online going of the
// respective nodes when necessary
if (movementModel.getClass() == CsvMovement.class && transition.getClass() == FixedAssignmentStrategy.class) {
CsvMovement csvMovement = (CsvMovement) movementModel;
FixedAssignmentStrategy transitionStrategy = (FixedAssignmentStrategy) transition;
csvMovement.addTransitionStrategy(transitionStrategy);
}
// setWayPointModel
localMovementStrategy.setObstacleModel(Binder
.getComponentOrNull(Topology.class).getObstacleModel());
localMovementStrategy.setWaypointModel(Binder
.getComponentOrNull(Topology.class).getWaypointModel());
if (movementModel instanceof AbstractWaypointMovementModel) {
AbstractWaypointMovementModel awmm = (AbstractWaypointMovementModel) movementModel;
awmm.setWaypointModel(Binder.getComponentOrNull(Topology.class)
.getWaypointModel());
}
List<AttractionPoint> attractionPoints = attractionGenerator
.getAttractionPoints();
for (AttractionPoint att : attractionPoints) {
movementModel.addComponent(att);
}
transition.setAttractionPoints(attractionPoints);
for (SimLocationActuator ms : moveableHosts) {
transition.addComponent(ms);
}
setTimeBetweenMoveOperations(timeBetweenMoveOperation);
// initial move
move();
initialized = true;
}
}
private void checkConfiguration() {
if (localMovementStrategy == null) {
throw new ConfigurationException(
"LocalMovementStrategy is missing in ModularMovementModel!");
}
if (movementModel == null) {
throw new ConfigurationException(
"MovementModel is missing in ModularMovementModel!");
}
if (transition == null) {
throw new ConfigurationException(
"TransitionStrategy is missing in ModularMovementModel!");
}
if (attractionGenerator == null) {
throw new ConfigurationException(
"AttractionGenerator is missing in ModularMovementModel!");
}
if (movementModel instanceof AbstractWaypointMovementModel
&& Binder.getComponentOrNull(Topology.class)
.getWaypointModel() == null) {
throw new ConfigurationException(
"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 changeTargetLocation(SimLocationActuator actuator,
double longitude, double latitude) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
@Override
public void addComponent(SimLocationActuator comp) {
moveableHosts.add(comp);
offsetPosition.put(comp, randomOffsetVector());
}
@Override
public void setTimeBetweenMoveOperations(long time) {
if (time > 0) {
this.timeBetweenMoveOperation = time;
} else {
throw new ConfigurationException(
"time is negative for the Move Operations");
}
}
private PositionVector randomOffsetVector() {
double x = rand.nextGaussian() * 6;
double y = rand.nextGaussian() * 6;
return new PositionVector(x, y);
}
protected void move() {
Map<SimLocationActuator, AttractionPoint> assigns = transition
.getAssignments();
for (Entry<SimLocationActuator, AttractionPoint> entry : assigns
.entrySet()) {
SimLocationActuator ms = entry.getKey();
PositionVector attractionCenter = entry.getValue()
.getRealPosition();
PositionVector destination = new PositionVector(attractionCenter);
destination.add(offsetPosition.get(ms));
doLocalMovement(ms, destination);
}
Event.scheduleWithDelay(timeBetweenMoveOperation, this, null,
EVENT_MOVE);
}
/**
*
* Ask the local movement strategy for the next position. It may return the
* next position or a boolean with true to notify the movement model that it
* can't get any closer to the current way point.
*
* @param ms
* @param destination
*/
private void doLocalMovement(SimLocationActuator ms,
PositionVector destination) {
Either<PositionVector, Boolean> either = localMovementStrategy
.nextPosition(ms, destination);
if (either.hasLeft()) {
ms.updateCurrentLocation(either.getLeft().getLongitude(), either.getLeft().getLatitude());
}
}
public void setMovementModel(MovementModel mm) {
this.movementModel = mm;
}
public void setAttractionGenerator(AttractionGenerator attractionGenerator) {
this.attractionGenerator = attractionGenerator;
}
public void setLocalMovementStrategy(
LocalMovementStrategy localMovementStrategy) {
this.localMovementStrategy = localMovementStrategy;
}
public void setTransitionStrategy(TransitionStrategy transition) {
this.transition = transition;
}
@Override
public void eventOccurred(Object content, int type) {
if (type == EVENT_INIT) {
initialize();
} else if (type == EVENT_MOVE) {
move();
}
}
/**
* Only for visualization!
*
* @return
*/
protected List<AttractionPoint> getAttractionPoints() {
return new Vector<AttractionPoint>(transition.getAssignments().values());
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.topology.movement.modular;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import javax.swing.JComponent;
import de.tud.kom.p2psim.impl.topology.movement.modular.attraction.AttractionPoint;
import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.VisualizationInjector;
/**
* Visualization Component of the Attraction Points in the Modular Movement
* Model.
*
*
* @author Christoph Muenker
* @version 1.0, 02.07.2013
*/
public class ModularMovementModelViz extends JComponent {
private ModularMovementModel movementModel;
public ModularMovementModelViz(ModularMovementModel model) {
setBounds(0, 0, VisualizationInjector.getWorldX(),
VisualizationInjector.getWorldY());
setOpaque(true);
setVisible(true);
this.movementModel = model;
}
@Override
public void paint(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
for (AttractionPoint aPoint : movementModel.getAttractionPoints()) {
Point point = aPoint.getRealPosition().asPoint();
// draw border
g2.setColor(Color.BLACK);
g2.setStroke(new BasicStroke(1f));
g2.drawOval(VisualizationInjector.scaleValue(point.x) - 15,
VisualizationInjector.scaleValue(point.y) - 15, 30, 30);
g2.setColor(new Color(0.2f, 0.8f, 0.2f, 0.6f));
g2.fillOval(VisualizationInjector.scaleValue(point.x) - 15,
VisualizationInjector.scaleValue(point.y) - 15, 30, 30);
}
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.topology.movement.modular.attraction;
import java.util.List;
/**
* This is the interface for the generator of the {@link AttractionPoint}s. It
* gets the set number of AttractionPoints back. This mean, it will be generate
* them and set the Position of them.
*
* @author Christoph Muenker
* @version 1.0, 02.07.2013
*/
public interface AttractionGenerator {
public void setNumberOfAttractionPoints(int numberOfAttractionPoints);
public List<AttractionPoint> getAttractionPoints();
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.topology.movement.modular.attraction;
import java.util.Random;
import de.tud.kom.p2psim.api.topology.movement.MovementListener;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tudarmstadt.maki.simonstrator.api.Host;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationActuator;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationListener;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationRequest;
/**
* This is the implementation of a AttractionPoint, which implements the
* {@link LocationActuator} interface. So a {@link AttractionPoint} has the
* ability to be moved.
*
* @author Christoph Muenker
* @version 1.0, 02.07.2013
*/
public class AttractionPoint implements SimLocationActuator {
protected static Random rnd = Randoms.getRandom(AttractionPoint.class);
private PositionVector posVec;
private double minSpeed;
private double maxSpeed;
private double currentSpeed = -1;
public AttractionPoint(PositionVector posVec, double minSpeed,
double maxSpeed) {
this.posVec = posVec;
this.minSpeed = minSpeed;
this.maxSpeed = maxSpeed;
}
@Override
public double getMinMovementSpeed() {
return minSpeed;
}
@Override
public double getMaxMovementSpeed() {
return maxSpeed;
}
@Override
public void setMovementSpeed(double speed) {
this.currentSpeed = speed;
}
@Override
public double getMovementSpeed() {
if (currentSpeed == -1) {
double min_speed = getMinMovementSpeed();
double max_speed = getMaxMovementSpeed();
double value = rnd.nextDouble();
this.currentSpeed = (value * (max_speed - min_speed)) + min_speed;
}
return currentSpeed;
}
@Override
public Location getLastLocation() {
return posVec;
}
@Override
public void requestLocationUpdates(LocationRequest request,
LocationListener listener) {
throw new UnsupportedOperationException();
}
@Override
public void removeLocationUpdates(LocationListener listener) {
throw new UnsupportedOperationException();
}
@Override
public LocationRequest getLocationRequest() {
throw new UnsupportedOperationException();
}
@Override
public void initialize() {
throw new UnsupportedOperationException();
}
@Override
public void shutdown() {
throw new UnsupportedOperationException();
}
@Override
public Host getHost() {
throw new UnsupportedOperationException();
}
@Override
public void updateCurrentLocation(double longitude, double latitude) {
posVec.setEntries(longitude, latitude);
}
@Override
public void setNewTargetLocation(double longitude, double latitude)
throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
@Override
public PositionVector getRealPosition() {
return posVec;
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.topology.movement.modular.transition;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.common.SimHostComponent;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tud.kom.p2psim.impl.topology.movement.modular.ModularMovementModel;
import de.tud.kom.p2psim.impl.topology.movement.modular.attraction.AttractionPoint;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
/**
* A {@link TransitionStrategy} for a case in which nodes are affiliated to an
* {@link AttractionPoint} only in the beginning. No further transition will
* take place.
*
* @author Nils Richerzhagen
* @version 1.0, 04.08.2014
*/
public class FixedAssignmentStrategy implements TransitionStrategy {
private Random rnd;
private List<SimLocationActuator> comps = new LinkedList<SimLocationActuator>();
private List<AttractionPoint> aPoints = new LinkedList<AttractionPoint>();
private Map<SimLocationActuator, AttractionPoint> assignments = new LinkedHashMap<SimLocationActuator, AttractionPoint>();
private Map<SimLocationActuator, SimHost> mappingMSHost = new LinkedHashMap<SimLocationActuator, SimHost>();
private Map<SimHost, SimLocationActuator> mappingHostMS = new LinkedHashMap<SimHost, SimLocationActuator>();
private Map<String, AttractionPoint> mappingGroupIdAP = new LinkedHashMap<String, AttractionPoint>();
private Map<AttractionPoint, String> mappingAPGroupId = new LinkedHashMap<AttractionPoint, String>();
public FixedAssignmentStrategy() {
rnd = Randoms.getRandom(FixedAssignmentStrategy.class);
}
@Override
public Map<SimLocationActuator, AttractionPoint> getAssignments() {
return new HashMap<SimLocationActuator, AttractionPoint>(assignments);
}
@Override
public void setAttractionPoints(List<AttractionPoint> attractionPoints) {
aPoints.addAll(attractionPoints);
}
@Override
public void addComponent(SimLocationActuator ms) {
comps.add(ms);
mappingHost(ms);
// No assignments been done before.
if (assignments.isEmpty()) {
AttractionPoint aPoint = aPoints.iterator().next();
assignments.put(ms, aPoint);
mappingGroupId(ms, aPoint);
setStartPosition(ms, aPoint.getRealPosition());
}
// GroupId is not mapped.
else if (!mappingGroupIdAP.containsKey(
mappingMSHost.get(ms).getProperties().getGroupID())) {
for (AttractionPoint actAP : aPoints) {
if (!mappingAPGroupId.containsKey(actAP)) {
assignments.put(ms, actAP);
mappingGroupId(ms, actAP);
setStartPosition(ms, actAP.getRealPosition());
break;
}
}
}
// GroupId is already mapped.
else if (mappingGroupIdAP.containsKey(
mappingMSHost.get(ms).getProperties().getGroupID())) {
AttractionPoint aPoint = mappingGroupIdAP
.get(mappingMSHost.get(ms).getProperties().getGroupID());
assignments.put(ms, aPoint);
setStartPosition(ms, aPoint.getRealPosition());
} else {
throw new Error("Should not happen.");
}
}
private void mappingHost(SimLocationActuator ms) {
SimHostComponent comp = (SimHostComponent) ms;
SimHost host = comp.getHost();
assert host != null;
mappingHostMS.put(host, ms);
mappingMSHost.put(ms, host);
}
private void mappingGroupId(SimLocationActuator ms, AttractionPoint AP) {
SimHostComponent comp = (SimHostComponent) ms;
SimHost host = comp.getHost();
assert host != null;
mappingAPGroupId.put(AP,
mappingMSHost.get(ms).getProperties().getGroupID());
mappingGroupIdAP.put(mappingMSHost.get(ms).getProperties().getGroupID(),
AP);
}
private void setStartPosition(SimLocationActuator ms,
PositionVector aPointReferencePosition) {
double minJitter = 50.0;
double maxJitter = 100.0;
double xJitter = (rnd.nextDouble() * (maxJitter - minJitter))
+ minJitter;
double yJitter = (rnd.nextDouble() * (maxJitter - minJitter))
+ minJitter;
PositionVector jitterVector = new PositionVector(xJitter, yJitter);
PositionVector newPos = aPointReferencePosition.plus(jitterVector);
ms.updateCurrentLocation(newPos.getLongitude(), newPos.getLatitude());
}
/**
* Used by the MobilityModel (M1) of the {@link ModularMovementModel} to get
* the groupId of the affiliated nodes to that {@link AttractionPoint}. Once
* the groupId is known nodes can be set <b>offline</b> or <b>online</b>.
*
* @param attractionPoint
* @return
*/
public String getGroupIdOfAttractionPoint(AttractionPoint attractionPoint) {
return mappingAPGroupId.get(attractionPoint);
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.topology.movement.modular.transition;
import java.util.*;
import java.util.Map.Entry;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.common.SimHostComponent;
import de.tud.kom.p2psim.api.scenario.ConfigurationException;
import de.tud.kom.p2psim.api.topology.Topology;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tud.kom.p2psim.api.topology.social.SocialView;
import de.tud.kom.p2psim.impl.simengine.Simulator;
import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tud.kom.p2psim.impl.topology.movement.modular.attraction.AttractionPoint;
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;
/**
* This is a {@link TransitionStrategy} for the Social Case. It will be try to
* build groups based on the {@link SocialView} information. For this, it tries
* to assignment the given {@link SimLocationActuator} objects to the given
* {@link AttractionPoint}s. For the {@link SocialView}, it is required a
* {@link #socialId}, to find the right {@link SocialView}.
*
* <br>
*
* The Strategy has the parameter of {@link #socialFactor},
* {@link #minPauseTime} and {@link #maxPauseTime}. The socialFactor should be a
* value between 0 and 1. It gives the probability for a social based transition
* or the transition to a random {@link AttractionPoint}. If the social based
* transition is selected, then will be used a scoring to find the right
* {@link AttractionPoint}. For that, it will be used only the AttractionPoints,
* of the hosts, which are in the same SocialCluster or are SocialNeighbors. For
* this AttractionPoints it will be find the highest scoring, which is to found
* in {@link #score(SimLocationActuator, AttractionPoint, List, List, List, List)}
* .
*
* <br>
*
* After the finding of the next {@link AttractionPoint}, it will be scheduled
* an Event, with a delay between min- and maxPauseTime. After this delay, it
* will be tried to assign a new {@link AttractionPoint} like the described
* above.
*
*
* @author Christoph Muenker
* @version 1.0, 02.07.2013
*/
public class SocialTransitionStrategy implements TransitionStrategy,
EventHandler {
private String socialId = null;
private SocialView socialView;
private List<SimLocationActuator> comps = new Vector<SimLocationActuator>();
private List<AttractionPoint> aPoints = new Vector<AttractionPoint>();
private Map<SimLocationActuator, AttractionPoint> assignments = new HashMap<SimLocationActuator, AttractionPoint>();
private Map<SimLocationActuator, Set<AttractionPoint>> favoritePlaces = new HashMap<SimLocationActuator, Set<AttractionPoint>>();
private Map<SimLocationActuator, SimHost> mapMsHost = new HashMap<SimLocationActuator, SimHost>();
private Map<SimHost, SimLocationActuator> mapHostMs = new HashMap<SimHost, SimLocationActuator>();
private double minPauseTime = Simulator.MINUTE_UNIT * 0.5;
private double maxPauseTime = Simulator.MINUTE_UNIT * 100;
private double socialFactor = 0.8;
private long numberOfFavoritePlaces = 4;
private Random rand;
private PositionVector worldDimension;
private boolean init = false;
public SocialTransitionStrategy() {
this.rand = Randoms.getRandom(SocialTransitionStrategy.class);
}
private void init() {
if (!init) {
if (socialId == null) {
throw new ConfigurationException(
"SocialId is not set, to find the needed SocialView!");
}
socialView = Binder.getComponentOrNull(Topology.class)
.getSocialView(socialId);
if (socialView == null) {
throw new ConfigurationException(
"Cannot find the right socialView. Is the socialId correct?");
}
if (minPauseTime > maxPauseTime) {
throw new ConfigurationException(
"MinPauseTime should be smaller then maxPauseTime.");
}
worldDimension = Binder.getComponentOrNull(Topology.class)
.getWorldDimensions();
init = true;
}
}
public void setSocialId(String socialId) {
this.socialId = socialId;
}
@Override
public Map<SimLocationActuator, AttractionPoint> getAssignments() {
return new HashMap<SimLocationActuator, AttractionPoint>(assignments);
}
@Override
public void setAttractionPoints(List<AttractionPoint> attractionPoints) {
init();
aPoints.addAll(attractionPoints);
}
@Override
public void addComponent(SimLocationActuator ms) {
comps.add(ms);
mappingHost(ms);
// assign the ms to an attractionPoint, which is near to the ms
// position.
// TODO: needed? We do Transition as next, and this will delete the
// assignment..
AttractionPoint nearest = aPoints.iterator().next();
for (AttractionPoint aPoint : aPoints) {
if (nearest.getRealPosition()
.distanceTo(ms.getRealPosition()) > aPoint.getRealPosition()
.distanceTo(ms.getRealPosition())) {
nearest = aPoint;
}
}
assignments.put(ms, nearest);
assignFavoritePlaces(ms);
doTransition(ms);
}
public void doTransition(SimLocationActuator ms) {
List<AttractionPoint> apFavorites = getFavoritePlaces(ms);
List<AttractionPoint> apFriends = getFriendsPlaces(ms);
List<AttractionPoint> apClusters = getClusterPlaces(ms);
List<AttractionPoint> apRandom = getRandomPlaces(ms,
(int) Math.max(aPoints.size() * 0.2, 5));
AttractionPoint ap = null;
if (rand.nextDouble() < socialFactor) {
ap = findHighestScore(ms, apFavorites, apFriends, apClusters,
apRandom);
} else {
List<AttractionPoint> aps = new ArrayList<AttractionPoint>();
aps.addAll(apRandom);
aps.addAll(apFavorites);
ap = aps.get(rand.nextInt(apRandom.size()));
}
assignments.put(ms, ap);
Event.scheduleWithDelay(getPauseTime(), this, ms, 0);
}
private AttractionPoint findHighestScore(SimLocationActuator ms,
List<AttractionPoint> apFavorites, List<AttractionPoint> apFriends,
List<AttractionPoint> apClusters, List<AttractionPoint> apRandom) {
Set<AttractionPoint> aps = new LinkedHashSet<AttractionPoint>();
aps.addAll(apFavorites);
aps.addAll(apFriends);
aps.addAll(apClusters);
aps.addAll(apRandom);
double maxScore = 0;
AttractionPoint maxAp = null;
for (AttractionPoint ap : aps) {
double score = score(ms, ap, apFavorites, apFriends, apClusters,
apRandom);
// System.out.println(score);
if (score > maxScore) {
maxScore = score;
maxAp = ap;
}
}
return maxAp;
}
/**
* Score the given AttractionPoint for the given {@link SimLocationActuator}. <br>
* (clusterScore/#NodesInAp + friendsScore + 1/#NodesInAp) * socialFactor +
* (distanceScore + penalty) + (1-socialFactor) <br>
*
* clusterScore = 1 if one is in the same cluster in this AP<br>
* friendsScore = 1 if one friend is in the same AP<br>
* penalty = -1 if AP the actually AP is <br>
* distance = 1 - (distance / maxDistance)
*
* @param ms
* @param ap
* @param apFavorites
* @param apFriends
* @param apClusters
* @param apRandom
* @return
*/
private double score(SimLocationActuator ms, AttractionPoint ap,
List<AttractionPoint> apFavorites, List<AttractionPoint> apFriends,
List<AttractionPoint> apClusters, List<AttractionPoint> apRandom) {
double distance = ms.getRealPosition().distanceTo(ap.getRealPosition());
double distanceScore = 1 - (distance / worldDimension.getLength());
double clusterScore = 0;
double friendsScore = 0;
if (apClusters.contains(ap)) {
if (occurence(ap, apClusters) > 3) {
// occurence give the number of other peers in this AP
clusterScore = 1.0 / (occurence(ap, apClusters) - 1);
} else {
clusterScore = 1.0;
}
}
if (apFriends.contains(ap)) {
if (occurence(ap, apFriends) > 3) {
// occurence give the number of other peers in this AP
friendsScore = 1.0 / (occurence(ap, apFriends) - 1);
} else {
friendsScore = 1.0;
}
}
// penalty for distance
double penalty = 0;
if (ap.equals(assignments.get(ms))) {
penalty = -1;
}
return (clusterScore / assignedToAp(ap) + friendsScore + 1.0 / assignedToAp(ap))
* socialFactor
+ (distanceScore + penalty) * (1 - socialFactor);
}
// counts the number of the AttractionPoint in the list
private int occurence(AttractionPoint ap, List<AttractionPoint> aps) {
int i = 0;
for (AttractionPoint a : aps) {
if (a.equals(ap)) {
i++;
}
}
return i;
}
private int assignedToAp(AttractionPoint ap) {
int i = 1;
for (Entry<SimLocationActuator, AttractionPoint> entry : assignments
.entrySet()) {
if (entry.getValue().equals(ap)) {
i++;
}
}
return i;
}
private List<AttractionPoint> getRandomPlaces(SimLocationActuator ms,
int number) {
Collections.shuffle(aPoints, rand);
List<AttractionPoint> result = new Vector<AttractionPoint>();
Iterator<AttractionPoint> iAP = aPoints.iterator();
for (int i = 0; i < number && iAP.hasNext(); i++) {
result.add(iAP.next());
}
return result;
}
private List<AttractionPoint> getClusterPlaces(SimLocationActuator ms) {
List<AttractionPoint> result = new Vector<AttractionPoint>();
SimHost msHost = mapMsHost.get(ms);
for (SimHost host : socialView.getCluster(msHost)) {
SimLocationActuator temp = mapHostMs.get(host);
if (assignments.get(temp) != null) {
result.add(assignments.get(temp));
}
}
return result;
}
private List<AttractionPoint> getFriendsPlaces(SimLocationActuator ms) {
List<AttractionPoint> result = new Vector<AttractionPoint>();
SimHost msHost = mapMsHost.get(ms);
for (SimHost host : socialView.getNeighbors(msHost)) {
SimLocationActuator temp = mapHostMs.get(host);
if (assignments.get(temp) != null) {
result.add(assignments.get(temp));
}
}
return result;
}
private List<AttractionPoint> getFavoritePlaces(SimLocationActuator ms) {
return new Vector<AttractionPoint>(favoritePlaces.get(ms));
}
private AttractionPoint getRandomPlace(SimLocationActuator ms) {
Collections.shuffle(aPoints, rand);
return aPoints.iterator().next();
}
private AttractionPoint getNearestPlace(SimLocationActuator ms,
List<AttractionPoint> aps) {
if (aps.isEmpty()) {
return null;
}
AttractionPoint nearest = aps.iterator().next();
for (AttractionPoint aPoint : aps) {
if (nearest.getRealPosition()
.distanceTo(ms.getRealPosition()) > aPoint.getRealPosition()
.distanceTo(ms.getRealPosition())
&& !assignments.get(ms).equals(aPoint)) {
nearest = aPoint;
}
}
return nearest;
}
private AttractionPoint getNearestFavoritePlace(SimLocationActuator ms) {
Set<AttractionPoint> fps = favoritePlaces.get(ms);
AttractionPoint nearest = fps.iterator().next();
for (AttractionPoint aPoint : fps) {
if (nearest.getRealPosition()
.distanceTo(ms.getRealPosition()) > aPoint.getRealPosition()
.distanceTo(ms.getRealPosition())
&& !assignments.get(ms).equals(aPoint)) {
nearest = aPoint;
}
}
return nearest;
}
private void assignFavoritePlaces(SimLocationActuator ms) {
Set<AttractionPoint> msFavoritePlaces = new LinkedHashSet<AttractionPoint>();
LinkedList<AttractionPoint> temp = new LinkedList<AttractionPoint>(
aPoints);
Collections.shuffle(temp, rand);
for (int i = 0; i < numberOfFavoritePlaces; i++) {
if (!temp.isEmpty()) {
msFavoritePlaces.add(temp.removeFirst());
}
}
favoritePlaces.put(ms, msFavoritePlaces);
}
private void mappingHost(SimLocationActuator ms) {
SimHostComponent comp = (SimHostComponent) ms;
SimHost host = comp.getHost();
assert host != null;
mapHostMs.put(host, ms);
mapMsHost.put(ms, host);
}
protected long getPauseTime() {
return (long) ((rand.nextDouble() * (maxPauseTime - minPauseTime)) + minPauseTime);
}
public void setMinPauseTime(long minPauseTime) {
if (minPauseTime < 0) {
throw new ConfigurationException(
"MinPauseTime should be bigger then 0!");
}
this.minPauseTime = minPauseTime;
}
public void setMaxPauseTime(long maxPauseTime) {
if (maxPauseTime < 0) {
throw new ConfigurationException(
"MaxPauseTime should be bigger then 0!");
}
this.maxPauseTime = maxPauseTime;
}
@Override
public void eventOccurred(Object se, int type) {
doTransition((SimLocationActuator) se);
}
public void setSocialFactor(double socialFactor) {
if (socialFactor < 0 || socialFactor > 1) {
throw new ConfigurationException(
"socialFactor should be between 0 and 1!");
}
this.socialFactor = socialFactor;
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.topology.movement.modular.transition;
import java.util.List;
import java.util.Map;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tud.kom.p2psim.impl.topology.movement.modular.ModularMovementModel;
import de.tud.kom.p2psim.impl.topology.movement.modular.attraction.AttractionPoint;
/**
* This is the interface for the Transition Strategy.<br>
* It derives automatically the assignments of the added
* {@link SimLocationActuator} to the {@link AttractionPoint}s. This mean, that
* the implementation must handle the new assignments after a certain time. The
* {@link ModularMovementModel}, will be only call the {@link #getAssignments()}
* in every MovementStep, to calculate the movement of the
* {@link SimLocationActuator} Objects, in respect to the Assignment.
*
* @author Christoph Muenker
* @version 1.0, 25.06.2013
*/
public interface TransitionStrategy {
/**
* Returns the assignments of the MovementSupported Objects to the
* AttractionPoints
*
* @return
*/
public Map<SimLocationActuator, AttractionPoint> getAssignments();
/**
* Should be called first, to add the Attraction Points for the assignment!
*
* @param attractionPoints
*/
public void setAttractionPoints(List<AttractionPoint> attractionPoints);
/**
* Add the {@link SimLocationActuator} object and assign the MS to an
* {@link AttractionPoint}.
*
* @param ms
*/
public void addComponent(SimLocationActuator ms);
}
...@@ -31,11 +31,8 @@ import java.util.Vector; ...@@ -31,11 +31,8 @@ import java.util.Vector;
import javax.swing.JComponent; import javax.swing.JComponent;
import org.w3c.dom.Attr;
import de.tud.kom.p2psim.api.scenario.ConfigurationException; import de.tud.kom.p2psim.api.scenario.ConfigurationException;
import de.tud.kom.p2psim.api.topology.Topology; 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.MovementModel;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator; 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.movement.local.LocalMovementStrategy;
...@@ -43,8 +40,6 @@ import de.tud.kom.p2psim.api.topology.placement.PlacementModel; ...@@ -43,8 +40,6 @@ import de.tud.kom.p2psim.api.topology.placement.PlacementModel;
import de.tud.kom.p2psim.impl.simengine.Simulator; import de.tud.kom.p2psim.impl.simengine.Simulator;
import de.tud.kom.p2psim.impl.topology.PositionVector; import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tud.kom.p2psim.impl.topology.TopologyFactory; 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; import de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction.IAttractionGenerator;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.mapvisualization.IMapVisualization; import de.tud.kom.p2psim.impl.topology.movement.modularosm.mapvisualization.IMapVisualization;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.transition.ITransitionStrategy; import de.tud.kom.p2psim.impl.topology.movement.modularosm.transition.ITransitionStrategy;
...@@ -54,7 +49,7 @@ import de.tudarmstadt.maki.simonstrator.api.Binder; ...@@ -54,7 +49,7 @@ import de.tudarmstadt.maki.simonstrator.api.Binder;
import de.tudarmstadt.maki.simonstrator.api.Event; import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler; import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Randoms; import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationActuator; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationActuator;
/** /**
...@@ -90,7 +85,7 @@ import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationAc ...@@ -90,7 +85,7 @@ import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationAc
* *
* *
* *
* @author Martin Hellwig * @author Martin Hellwig, Christoph Muenker
* @version 1.0, 07.07.2015 * @version 1.0, 07.07.2015
*/ */
public class ModularMovementModel implements MovementModel, EventHandler { public class ModularMovementModel implements MovementModel, EventHandler {
...@@ -134,12 +129,11 @@ public class ModularMovementModel implements MovementModel, EventHandler { ...@@ -134,12 +129,11 @@ public class ModularMovementModel implements MovementModel, EventHandler {
*/ */
public void initialize() { public void initialize() {
if (!initialized) { if (!initialized) {
VisualizationInjector.injectComponent("AttractionPoints", -1, VisualizationInjector.injectComponent(new ModularMovementModelViz(this));
new ModularMovementModelViz(this), true, false); if (mapVisualization != null) {
VisualizationInjector.injectComponent(mapVisualization);
VisualizationInjector.injectComponent("Real Map", -2, }
(JComponent) mapVisualization, true, false);
checkConfiguration(); checkConfiguration();
...@@ -178,22 +172,13 @@ public class ModularMovementModel implements MovementModel, EventHandler { ...@@ -178,22 +172,13 @@ public class ModularMovementModel implements MovementModel, EventHandler {
} }
@Override @Override
public void changeTargetLocation(SimLocationActuator actuator, public void changeTargetLocation(SimLocationActuator actuator, AttractionPoint ap) {
double longitude, double latitude) { transition.updateTargetAttractionPoint(actuator, ap);
/* }
* Set a new target AP for the current actuator (or assign to an AP close by)
*/ @Override
AttractionPoint apFound = null; public AttractionPoint getTargetLocation(SimLocationActuator actuator) {
for (AttractionPoint ap : transition.getAllAttractionPoints()) { return transition.getAssignments().get(actuator);
if (ap.getRealPosition().distanceTo(new PositionVector(longitude, latitude)) < 1) {
apFound = ap;
break;
}
}
if (apFound == null) {
apFound = new AttractionPoint((int) longitude, (int) latitude, "");
}
transition.updateTargetAttractionPoint(actuator, apFound);
} }
private void checkConfiguration() { private void checkConfiguration() {
...@@ -240,8 +225,7 @@ public class ModularMovementModel implements MovementModel, EventHandler { ...@@ -240,8 +225,7 @@ public class ModularMovementModel implements MovementModel, EventHandler {
for (Entry<SimLocationActuator, AttractionPoint> entry : assigns for (Entry<SimLocationActuator, AttractionPoint> entry : assigns
.entrySet()) { .entrySet()) {
SimLocationActuator ms = entry.getKey(); SimLocationActuator ms = entry.getKey();
PositionVector attractionCenter = entry.getValue() PositionVector attractionCenter = (PositionVector) entry.getValue();
.getRealPosition();
PositionVector destination = new PositionVector(attractionCenter); PositionVector destination = new PositionVector(attractionCenter);
destination.add(offsetPosition.get(ms)); destination.add(offsetPosition.get(ms));
...@@ -268,8 +252,7 @@ public class ModularMovementModel implements MovementModel, EventHandler { ...@@ -268,8 +252,7 @@ public class ModularMovementModel implements MovementModel, EventHandler {
Either<PositionVector, Boolean> either = localMovementStrategy Either<PositionVector, Boolean> either = localMovementStrategy
.nextPosition(ms, destination); .nextPosition(ms, destination);
if (either.hasLeft()) { if (either.hasLeft()) {
ms.updateCurrentLocation(either.getLeft().getLongitude(), ms.updateCurrentLocation(either.getLeft());
either.getLeft().getLatitude());
/* /*
* Check for negative or out of bound coordinates! * Check for negative or out of bound coordinates!
*/ */
...@@ -321,13 +304,4 @@ public class ModularMovementModel implements MovementModel, EventHandler { ...@@ -321,13 +304,4 @@ public class ModularMovementModel implements MovementModel, EventHandler {
public List<AttractionPoint> getAttractionPoints() { public List<AttractionPoint> getAttractionPoints() {
return new Vector<AttractionPoint>(transition.getAllAttractionPoints()); return new Vector<AttractionPoint>(transition.getAllAttractionPoints());
} }
/**
* Only for visualization
* @param actuator
* @return
*/
public AttractionPoint getCurrentAttractionPoint(LocationActuator actuator) {
return transition.getAssignments().get(actuator);
}
} }
...@@ -27,10 +27,13 @@ import java.awt.Point; ...@@ -27,10 +27,13 @@ import java.awt.Point;
import java.awt.RenderingHints; import java.awt.RenderingHints;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JMenu;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction.AttractionPoint; import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView; import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView;
import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.VisualizationInjector; import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.VisualizationInjector;
import de.tud.kom.p2psim.impl.topology.views.visualization.ui.VisualizationComponent;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint;
/** /**
* Visualization Component of the Attraction Points in the Modular Movement Model. * Visualization Component of the Attraction Points in the Modular Movement Model.
...@@ -39,7 +42,7 @@ import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.Visualiza ...@@ -39,7 +42,7 @@ import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.Visualiza
* @author Martin Hellwig * @author Martin Hellwig
* @version 1.0, 02.07.2015 * @version 1.0, 02.07.2015
*/ */
public class ModularMovementModelViz extends JComponent { public class ModularMovementModelViz extends JComponent implements VisualizationComponent {
private ModularMovementModel movementModel; private ModularMovementModel movementModel;
...@@ -61,7 +64,7 @@ public class ModularMovementModelViz extends JComponent { ...@@ -61,7 +64,7 @@ public class ModularMovementModelViz extends JComponent {
RenderingHints.VALUE_ANTIALIAS_ON); RenderingHints.VALUE_ANTIALIAS_ON);
for (AttractionPoint aPoint : movementModel.getAttractionPoints()) { for (AttractionPoint aPoint : movementModel.getAttractionPoints()) {
Point point = aPoint.getRealPosition().asPoint(); Point point = ((PositionVector) aPoint).asPoint();
// draw border // draw border
g2.setColor(Color.BLACK); g2.setColor(Color.BLACK);
g2.setFont(VisualizationTopologyView.FONT_MEDIUM); g2.setFont(VisualizationTopologyView.FONT_MEDIUM);
...@@ -74,4 +77,24 @@ public class ModularMovementModelViz extends JComponent { ...@@ -74,4 +77,24 @@ public class ModularMovementModelViz extends JComponent {
} }
} }
@Override
public String getDisplayName() {
return "Mobility Model";
}
@Override
public JComponent getComponent() {
return this;
}
@Override
public JMenu getCustomMenu() {
return null;
}
@Override
public boolean isHidden() {
return false;
}
} }
/* /*
* Copyright (c) 2005-2015 KOM – Multimedia Communications Lab * Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
* *
* This file is part of PeerfactSim.KOM. * This file is part of PeerfactSim.KOM.
* *
...@@ -24,38 +24,56 @@ import java.util.Random; ...@@ -24,38 +24,56 @@ import java.util.Random;
import de.tud.kom.p2psim.impl.topology.PositionVector; import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tudarmstadt.maki.simonstrator.api.Randoms; import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint;
/** /**
* This is the implementation of a AttractionPoint. This type of * In the current implementation, {@link AttractionPoint}s cannot move anymore.
* {@link AttractionPoint} has not the ability to be moved. Its data come from
* osm-POIs, which are static locations
* *
* @author Martin Hellwig *
* @version 1.0, 02.07.2015 * @author Christoph Muenker, Bjoern Richerzhagen
* @version 1.0, 02.07.2013
*/ */
public class AttractionPoint { public class AttractionPointImpl extends PositionVector implements AttractionPoint {
protected static Random rnd = Randoms.getRandom(AttractionPoint.class); protected static Random rnd = Randoms.getRandom(AttractionPoint.class);
private PositionVector posVec;
private String name; private String name;
@XMLConfigurableConstructor({ "x", "y", "name" }) public AttractionPointImpl(String name, PositionVector posVec) {
public AttractionPoint(int x, int y, String name) { super(posVec);
this(new PositionVector(x, y), name);
}
public AttractionPoint(PositionVector posVec, String name) {
this.posVec = posVec;
this.name = name; this.name = name;
} }
@Override
public String getName() {
return name;
}
@Override
public AttractionPoint clone(String newName) {
return new AttractionPointImpl(name, this);
}
public PositionVector getRealPosition() { @Override
return posVec; public int hashCode() {
final int prime = 31;
int result = prime * ((name == null) ? 0 : name.hashCode());
return result;
} }
public String getName() { @Override
return name; public boolean equals(Object obj) {
if (this == obj)
return true;
if (getClass() != obj.getClass())
return false;
AttractionPointImpl other = (AttractionPointImpl) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
} }
} }
...@@ -23,6 +23,8 @@ package de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction; ...@@ -23,6 +23,8 @@ package de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint;
/** /**
* For simple scenarios: add attraction points by specifying a coordinate. * For simple scenarios: add attraction points by specifying a coordinate.
* *
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* *
*/ */
package de.tud.kom.p2psim.impl.topology.movement.modular.attraction; package de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.FileReader; import java.io.FileReader;
...@@ -29,6 +29,7 @@ import java.util.List; ...@@ -29,6 +29,7 @@ import java.util.List;
import de.tud.kom.p2psim.api.topology.Topology; import de.tud.kom.p2psim.api.topology.Topology;
import de.tud.kom.p2psim.impl.topology.PositionVector; import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tudarmstadt.maki.simonstrator.api.Binder; import de.tudarmstadt.maki.simonstrator.api.Binder;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint;
import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor; import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
/** /**
...@@ -38,19 +39,15 @@ import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor; ...@@ -38,19 +39,15 @@ import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
* @author Nils Richerzhagen * @author Nils Richerzhagen
* @version 1.0, 16.07.2014 * @version 1.0, 16.07.2014
*/ */
public class CsvAttractionGenerator implements AttractionGenerator { public class CsvAttractionGenerator implements IAttractionGenerator {
private PositionVector worldDimensions; private PositionVector worldDimensions;
private String file; private String file;
private final String SEP = ";"; private final String SEP = ";";
private List<PositionVector> attractionPointsPositions; private List<AttractionPoint> attractionPoints;
private double minSpeed = 2;
private double maxSpeed = 2;
/** /**
* *
...@@ -60,38 +57,27 @@ public class CsvAttractionGenerator implements AttractionGenerator { ...@@ -60,38 +57,27 @@ public class CsvAttractionGenerator implements AttractionGenerator {
public CsvAttractionGenerator(String placementFile) { public CsvAttractionGenerator(String placementFile) {
this.worldDimensions = Binder.getComponentOrNull(Topology.class) this.worldDimensions = Binder.getComponentOrNull(Topology.class)
.getWorldDimensions(); .getWorldDimensions();
attractionPointsPositions = new LinkedList<PositionVector>();
this.file = placementFile; this.file = placementFile;
} }
@Override
public void setNumberOfAttractionPoints(int numberOfAttractionPoints) {
// Number of AttractionPoints is set by the CSV file.
}
@Override @Override
public List<AttractionPoint> getAttractionPoints() { public List<AttractionPoint> getAttractionPoints() {
readData(); if (attractionPoints == null) {
attractionPoints = new LinkedList<>();
List<AttractionPoint> result = new LinkedList<AttractionPoint>(); readData();
for (PositionVector attractionPointPositionVector : attractionPointsPositions) {
AttractionPoint aPoint = new AttractionPoint(
attractionPointPositionVector, minSpeed, maxSpeed);
result.add(aPoint);
} }
return result; return attractionPoints;
} }
private void readData() { private void readData() {
attractionPointsPositions.clear();
boolean entrySuccessfullyRead = false; boolean entrySuccessfullyRead = false;
BufferedReader csv = null; BufferedReader csv = null;
try { try {
csv = new BufferedReader(new FileReader(file)); csv = new BufferedReader(new FileReader(file));
int i = 0;
while (csv.ready()) { while (csv.ready()) {
String line = csv.readLine(); String line = csv.readLine();
if (line.indexOf(SEP) > -1) { if (line.indexOf(SEP) > -1) {
String[] parts = line.split(SEP); String[] parts = line.split(SEP);
...@@ -107,9 +93,9 @@ public class CsvAttractionGenerator implements AttractionGenerator { ...@@ -107,9 +93,9 @@ public class CsvAttractionGenerator implements AttractionGenerator {
+ y); + y);
continue; continue;
} }
attractionPoints.add(new AttractionPointImpl("AP"+i, new PositionVector(x,
attractionPointsPositions.add(new PositionVector(x, y)));
y)); i++;
entrySuccessfullyRead = true; entrySuccessfullyRead = true;
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
// Ignore leading comments // Ignore leading comments
...@@ -122,7 +108,6 @@ public class CsvAttractionGenerator implements AttractionGenerator { ...@@ -122,7 +108,6 @@ public class CsvAttractionGenerator implements AttractionGenerator {
throw new AssertionError("To many columns in CSV."); throw new AssertionError("To many columns in CSV.");
} }
} }
} catch (Exception e) { } catch (Exception e) {
System.err.println(e.toString()); System.err.println(e.toString());
} finally { } finally {
......
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