Commit eff5d429 authored by Julian Zobel's avatar Julian Zobel 🦄
Browse files

Merge branch 'master' into 'cherry-pick-7698d9d7'

# Conflicts:
#   src/de/tud/kom/p2psim/impl/analyzer/metric/output/MetricOutputDAO.java
#   src/de/tud/kom/p2psim/impl/util/db/dao/DAO.java
parents 1c7f20ec 37020b44
......@@ -32,6 +32,7 @@ import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Monitor.Level;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.core.SchedulerComponent;
import de.tudarmstadt.maki.simonstrator.api.component.core.SimulationRuntimeAnalyzer;
import de.tudarmstadt.maki.simonstrator.api.component.core.TimeComponent;
/**
......@@ -57,7 +58,7 @@ SchedulerComponent, TimeComponent {
private long statusInterval = SCHEDULER_WAKEUP_INTERVAL_IN_VIRTUALTIME;
private static final int INITIAL_QUEUE_CAPACITY = 5000;
private static final int INITIAL_QUEUE_CAPACITY = 50000;
private long processedEventCounter;
......@@ -93,6 +94,9 @@ SchedulerComponent, TimeComponent {
protected static final int TYPE_END = 3;
private SimulationRuntimeAnalyzer _simulationRuntimeAnalyzer;
private boolean _simulationRuntimeAnalyzerInit;
/**
* Constructs a new scheduler instance using a calendar queue. If desired,
* status events about the progress of the simulation will be plotted.
......@@ -267,8 +271,14 @@ SchedulerComponent, TimeComponent {
processedEventCounter++;
currentTime = realEvent.getSimulationTime();
if (hasSimulationRuntimeAnalyzer()) {
getSimulationRuntimeAnalyzer().startEventExecution(realEvent.handler, realEvent.type);
}
EventHandler handler = realEvent.handler;
handler.eventOccurred(realEvent.data, realEvent.type);
if (hasSimulationRuntimeAnalyzer()) {
getSimulationRuntimeAnalyzer().endEventExecution(realEvent.handler, realEvent.type);
}
notifyListeners(realEvent, realEvent.handler);
if (realEvent.schedulerType == TYPE_END)
......@@ -298,8 +308,15 @@ SchedulerComponent, TimeComponent {
assert (realEvent.simTime == Long.MIN_VALUE);
realEvent.simTime = currentTime;
if (hasSimulationRuntimeAnalyzer()) {
getSimulationRuntimeAnalyzer().startEventExecution(realEvent.handler, realEvent.type);
}
EventHandler handler = realEvent.handler;
handler.eventOccurred(realEvent.data, realEvent.type);
if (hasSimulationRuntimeAnalyzer()) {
getSimulationRuntimeAnalyzer().endEventExecution(realEvent.handler, realEvent.type);
}
notifyListeners(realEvent, realEvent.handler);
}
......@@ -403,8 +420,14 @@ SchedulerComponent, TimeComponent {
}
currentTime = realEvent.getSimulationTime();
if (hasSimulationRuntimeAnalyzer()) {
getSimulationRuntimeAnalyzer().startEventExecution(realEvent.handler, realEvent.type);
}
EventHandler handler = realEvent.handler;
handler.eventOccurred(realEvent.data, realEvent.type);
if (hasSimulationRuntimeAnalyzer()) {
getSimulationRuntimeAnalyzer().endEventExecution(realEvent.handler, realEvent.type);
}
notifyListeners(realEvent, realEvent.handler);
if (realEvent.schedulerType == TYPE_END) {
......@@ -612,4 +635,16 @@ SchedulerComponent, TimeComponent {
}
}
private SimulationRuntimeAnalyzer getSimulationRuntimeAnalyzer() {
return _simulationRuntimeAnalyzer;
}
private boolean hasSimulationRuntimeAnalyzer() {
if (!_simulationRuntimeAnalyzerInit) {
_simulationRuntimeAnalyzer = Monitor.getOrNull(SimulationRuntimeAnalyzer.class);
_simulationRuntimeAnalyzerInit = true;
}
return _simulationRuntimeAnalyzer != null;
}
}
......@@ -208,7 +208,7 @@ public class Simulator implements RandomGeneratorComponent, GlobalComponent {
/* Real World Starting Time:
* Block till we're allowed to start.
*/
if( realWorldStartTime != null ) {
if(realWorldStartTime != null ) {
try {
......@@ -234,9 +234,13 @@ public class Simulator implements RandomGeneratorComponent, GlobalComponent {
finishedWithoutError = true;
} catch (RuntimeException e) {
finishedWithoutError = false;
reason = e;
throw e;
} finally {
this.running = false;
// After a simulation start the mechanisms, which
// finalize a simulation
......@@ -248,10 +252,18 @@ public class Simulator implements RandomGeneratorComponent, GlobalComponent {
this.running = false;
if (finishedWithoutError) {
Monitor.log(Simulator.class, Level.INFO,
"Simulation successfully finished...");
"Simulation successfully finished :)");
} else {
if(reason == null) {
Monitor.log(Simulator.class, Level.ERROR,
"Simulation finished with errors...\n" + reason);
"Simulation finished with unresolved errors ???");
}
else {
Monitor.log(Simulator.class, Level.ERROR,
"Simulation finished with errors :( \n " +
reason.toString() + " : " + reason.getStackTrace());
}
}
long runTime = System.currentTimeMillis() - startTime;
long minutes = (long) Math.floor((runTime) / 60000);
......@@ -389,8 +401,7 @@ public class Simulator implements RandomGeneratorComponent, GlobalComponent {
if (randomGenerators.containsKey(source)) {
return randomGenerators.get(source);
} else {
long thisSeed = source.toString().hashCode() + 31
* seed;
long thisSeed = source.toString().hashCode() * seed + seed;
Monitor.log(Simulator.class, Level.INFO,
"Created a new Random Source for %s with seed %d", source,
thisSeed);
......@@ -475,7 +486,7 @@ public class Simulator implements RandomGeneratorComponent, GlobalComponent {
*/
@Deprecated
public void setDatabase(String database) {
DAO.database = database;
DAO.setDatabase(database);
}
/**
......
......@@ -32,9 +32,8 @@ import de.tud.kom.p2psim.api.topology.obstacles.ObstacleModel;
import de.tud.kom.p2psim.api.topology.social.SocialView;
import de.tud.kom.p2psim.api.topology.views.TopologyView;
import de.tud.kom.p2psim.api.topology.waypoints.WaypointModel;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.GPSCalculation;
import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.VisualizationInjector;
import de.tud.kom.p2psim.impl.topology.views.visualization.world.SocialViewComponentVis;
import de.tud.kom.p2psim.impl.topology.util.PositionVector;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/**
* Very basic Topology
......@@ -58,7 +57,7 @@ public class DefaultTopology implements Topology {
private List<SocialView> socialViews;
private PositionVector worldDimensions;
private static PositionVector worldDimensions;
private boolean initializedSocial = false;
......@@ -95,6 +94,11 @@ public class DefaultTopology implements Topology {
}
}
@Override
public WaypointModel getWaypointModel() {
return waypointModel;
}
@Override
public void setObstacleModel(ObstacleModel model) {
obstacleModel = model;
......@@ -103,6 +107,11 @@ public class DefaultTopology implements Topology {
}
}
@Override
public ObstacleModel getObstacleModel() {
return obstacleModel;
}
@Override
public void addTopologyListener(TopologyListener listener) {
if (!topoListeners.contains(listener)) {
......@@ -175,13 +184,20 @@ public class DefaultTopology implements Topology {
}
}
@Override
public WaypointModel getWaypointModel() {
return waypointModel;
public static boolean isWithinWorldBoundaries(double x, double y) {
if(x >= 0 && y >= 0
&& x <= worldDimensions.getX() && y <= worldDimensions.getY()) {
return true;
}
else {
return false;
}
@Override
public ObstacleModel getObstacleModel() {
return obstacleModel;
}
public static boolean isWithinWorldBoundaries(Location location) {
return isWithinWorldBoundaries(location.getLongitudeOrX(), location.getLatitudeOrY());
}
}
......@@ -36,14 +36,20 @@ 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.component.BaseTopologyComponent;
import de.tud.kom.p2psim.impl.topology.component.DefaultTopologyComponent;
import de.tud.kom.p2psim.impl.topology.component.TopologyComponentFactory;
import de.tud.kom.p2psim.impl.topology.component.UAVTopologyComponent;
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.placement.GNPPlacement;
import de.tud.kom.p2psim.impl.topology.util.PositionVector;
import de.tud.kom.p2psim.impl.topology.views.latency.GNPLatency;
import de.tudarmstadt.maki.simonstrator.api.Binder;
import de.tudarmstadt.maki.simonstrator.api.Host;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Monitor.Level;
import de.tudarmstadt.maki.simonstrator.api.component.ComponentNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.HostComponentFactory;
import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
......@@ -51,8 +57,8 @@ import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
* This factory is configured with one or more {@link TopologyView}s if the
* {@link LinkLayer} is used.
*
* @author Bjoern Richerzhagen
* @version 1.0, 01.03.2012
* @author Bjoern Richerzhagen, Julian Zobel
* @version 1.1, 06.09.2018
*/
public class TopologyFactory implements HostComponentFactory {
......@@ -72,6 +78,8 @@ public class TopologyFactory implements HostComponentFactory {
private ObstacleModel obstacleModel;
private TopologyComponentFactory topologyComponentFactory = new DefaultTopologyComponent.Factory();
private boolean registerAsInformationProviderInSiS = false;
private static NetMeasurementDB measurementDB = null;
......@@ -126,8 +134,12 @@ public class TopologyFactory implements HostComponentFactory {
* Create a TopologyComponent and register it with the Topology and its
* movement model.
*/
TopologyComponent toCo = new DefaultTopologyComponent(host, topo,
movement, placement, registerAsInformationProviderInSiS);
if(topologyComponentFactory == null) {
throw new UnsupportedOperationException("[TopologyFactory] Cannot create topology component, topology component factory is NULL");
}
TopologyComponent toCo = topologyComponentFactory.createTopologyComponent(host, topo, movement, placement, registerAsInformationProviderInSiS);
/*
* Need to register TopoViews as movement listeners, as they might need
......@@ -231,7 +243,7 @@ public class TopologyFactory implements HostComponentFactory {
}
/**
* Option to disable the default behavior of nodes registering as
* Option to enable the behavior of nodes registering as
* topology providers.
*
* @param registerAsLocationProviderInSiS
......@@ -271,4 +283,9 @@ public class TopologyFactory implements HostComponentFactory {
public ObstacleModel getObstacleModel() {
return obstacleModel;
}
public void setTopologyComponentFactory(TopologyComponentFactory factory) {
this.topologyComponentFactory = factory;
}
}
......@@ -18,90 +18,65 @@
*
*/
package de.tud.kom.p2psim.impl.topology;
package de.tud.kom.p2psim.impl.topology.component;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import de.tud.kom.p2psim.api.common.HostProperties;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.linklayer.mac.MacAddress;
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;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Graphs;
import de.tudarmstadt.maki.simonstrator.api.Host;
import de.tudarmstadt.maki.simonstrator.api.Oracle;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tud.kom.p2psim.impl.topology.util.LocalGraphView;
import de.tud.kom.p2psim.impl.topology.util.LocationRequestImpl;
import de.tud.kom.p2psim.impl.topology.util.PositionVector;
import de.tudarmstadt.maki.simonstrator.api.common.graph.Graph;
import de.tudarmstadt.maki.simonstrator.api.common.graph.IEdge;
import de.tudarmstadt.maki.simonstrator.api.common.graph.INode;
import de.tudarmstadt.maki.simonstrator.api.common.graph.INodeID;
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.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.LocationListener;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationRequest;
import de.tudarmstadt.maki.simonstrator.api.component.sis.SiSComponent;
import de.tudarmstadt.maki.simonstrator.api.component.sis.SiSDataCallback;
import de.tudarmstadt.maki.simonstrator.api.component.sis.SiSInfoProperties;
import de.tudarmstadt.maki.simonstrator.api.component.sis.SiSInformationProvider.SiSProviderHandle;
import de.tudarmstadt.maki.simonstrator.api.component.sis.exception.InformationNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.sis.type.SiSTypes;
import de.tudarmstadt.maki.simonstrator.api.component.sis.SiSInformationProvider.SiSProviderHandle;
import de.tudarmstadt.maki.simonstrator.api.component.sis.SiSInfoProperties;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.component.sis.util.SiSTopologyProvider;
import de.tudarmstadt.maki.simonstrator.api.component.topology.TopologyID;
import de.tudarmstadt.maki.simonstrator.api.component.transport.ConnectivityListener;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetworkComponent.NetInterfaceName;
/**
* Default implementation of a {@link TopologyComponent}.
* Abstract implementation of the topology component interface, to support basic
* functionalities to all topology components.
*
* @author Bjoern Richerzhagen
* @version 1.0, 29.02.2012
* @author Julian Zobel
* @version 1.0, 6 Sep 2018
*/
public class DefaultTopologyComponent implements TopologyComponent {
protected static Random rnd = Randoms.getRandom(AttractionPoint.class);
public abstract class AbstractTopologyComponent implements TopologyComponent {
private SimHost host;
protected SimHost host;
protected final PositionVector position;
protected Topology topology;
private final PositionVector position;
protected MovementModel movementModel;
protected PlacementModel placementModel;
private Topology topology;
private double currentMovementSpeed = -1;
private final boolean registerAsInformationProviderInSiS;
private Map<LocationListener, LocationRequestImpl> openRequests = new LinkedHashMap<LocationListener, LocationRequestImpl>();
private List<LocationListener> listeners = new LinkedList<>();
private MovementModel movementModel;
private PlacementModel placementModel;
private final boolean registerAsInformationProviderInSiS;
/**
* Create a TopologyComponent for the current host.
*
* @param host
* @param topology
* @param movementModel
*/
public DefaultTopologyComponent(SimHost host, Topology topology,
MovementModel movementModel, PlacementModel placementModel, boolean registerAsInformationProviderInSiS) {
//
public AbstractTopologyComponent(SimHost host, Topology topology, MovementModel movementModel, PlacementModel placementModel, boolean registerAsInformationProviderInSiS) {
this.topology = topology;
this.host = host;
this.position = new PositionVector(0, 0);
......@@ -120,17 +95,12 @@ public class DefaultTopologyComponent implements TopologyComponent {
@Override
public void initialize() {
/*
* 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.
*/
// retrieve the initial position of this topology component
position.set(placementModel.place(this));
}
......@@ -201,9 +171,9 @@ public class DefaultTopologyComponent implements TopologyComponent {
if (getHost().getLinkLayer().hasPhy(PhyType.WIFI)) {
new SiSTopologyProvider(sis,
SiSTypes.NEIGHBORS_WIFI,
DefaultTopologyComponent.this,
AbstractTopologyComponent.this,
getTopologyID(NetInterfaceName.WIFI, true),
DefaultTopologyComponent.class);
AbstractTopologyComponent.class);
}
}
}, null, 0);
......@@ -226,11 +196,6 @@ public class DefaultTopologyComponent implements TopologyComponent {
return host;
}
@Override
public PositionVector getRealPosition() {
return position;
}
@Override
public Topology getTopology() {
return topology;
......@@ -244,41 +209,6 @@ public class DefaultTopologyComponent implements TopologyComponent {
return movementModel;
}
@Override
public double getMinMovementSpeed() {
HostProperties properties = getHost().getProperties();
return properties.getMinMovementSpeed();
}
@Override
public double getMaxMovementSpeed() {
HostProperties properties = getHost().getProperties();
return properties.getMaxMovementSpeed();
}
private void calcRandomMovementSpeed() {
double min_speed = getMinMovementSpeed();
double max_speed = getMaxMovementSpeed();
double value = rnd.nextDouble();
this.currentMovementSpeed = (value * (max_speed - min_speed))
+ min_speed;
}
@Override
public double getMovementSpeed() {
if (currentMovementSpeed == -1) {
calcRandomMovementSpeed();
}
return this.currentMovementSpeed;
}
@Override
public void setMovementSpeed(double speed) {
this.currentMovementSpeed = speed;
}
@Override
public Location getLastLocation() {
/*
......@@ -289,41 +219,17 @@ public class DefaultTopologyComponent implements TopologyComponent {
}
@Override
public void updateCurrentLocation(Location location) {
position.set(location);
/*
* FIXME utilization of the NodeDebugMonitor leads to huge performance drop.
*/
// NodeDebugMonitor.update(this.getClass(), getHost().getId(), "Current Location", location);
// try {
// NodeDebugMonitor.update(this.getClass(), getHost().getId(),
// "Distance to target",
// location.distanceTo(movementModel.getTargetLocation(this)));
// } catch (UnsupportedOperationException e) {
// // This is not supported by the movement model (which may happen see
// // MovementModel.java - thus catch and ignore)
// }
// notify "non-request" listeners
for (LocationListener locationListener : listeners) {
locationListener.onLocationChanged(getHost(), getLastLocation());
}
public PositionVector getRealPosition() {
return position; // no copy! See SimLocationActuator Interface Description!
}
@Override
public void setTargetAttractionPoint(AttractionPoint targetAttractionPoint)
throws UnsupportedOperationException {
movementModel.changeTargetLocation(this, targetAttractionPoint);
// NodeDebugMonitor.update(this.getClass(), getHost().getId(), "Target Location", targetAttractionPoint);
}
public void updateCurrentLocation(Location location) {
position.set(location);
@Override
public AttractionPoint getCurrentTargetAttractionPoint() {
return movementModel.getTargetLocation(this);
for (LocationListener locationListener : listeners) {
locationListener.onLocationChanged(getHost(), getLastLocation());
}
@Override
public Set<AttractionPoint> getAllAttractionPoints() {
return movementModel.getAllAttractionPoints();
}
@Override
......@@ -362,92 +268,7 @@ public class DefaultTopologyComponent implements TopologyComponent {
@Override
public LocationRequest getLocationRequest() {
return new LocationRequestImpl();
}
/**
* Update 15.03.16 added support for multiple listeners (however, frequency
* etc. is immune after the first request is registered.)
*
* @author Bjoern Richerzhagen
* @version 1.0, Mar 15, 2016
*/
private class LocationRequestImpl implements LocationRequest, EventHandler {
private boolean immune = false;
private long interval = 1 * Simulator.MINUTE_UNIT;
private int priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY;
private Location lastLocation = null;
private List<LocationListener> listeners = new LinkedList<LocationListener>();
private int eventTypeSeq = 0;
public LocationRequestImpl() {
// nothing to do
}
protected void cancel(LocationListener listener) {
boolean removed = listeners.remove(listener);
if (listeners.isEmpty()) {
// upcoming event is no longer valid!
eventTypeSeq++;
}
assert removed;
}
protected void immunizeAndStart(LocationListener listener) {
immune = true;
assert interval > 0;
if (listeners.isEmpty()) {
// Only start once!
lastLocation = null;
Event.scheduleImmediately(this, null, eventTypeSeq);
} else {
// Fire each new listener at least once
listener.onLocationChanged(getHost(), getLastLocation());
}
listeners.add(listener);
}
@Override
public void setInterval(long interval) {
if (!immune) {
this.interval = interval;
}
}
@Override
public void setPriority(int priority) {
if (!immune) {
this.priority = priority;
}
}
@Override
public void eventOccurred(Object content, int type) {
if (eventTypeSeq != type) {
/*
* Discard invalid events caused when a client cancels updates
* but reactivates the request within the update frequency
* interval. In this case, the old events continue rescheduling
* themselves.
*/
return;
}
if (!listeners.isEmpty()) {
// Only reschedule, if at least one listener is ... listening
Location newLoc = getLastLocation();
listeners.forEach((LocationListener listener) -> listener
.onLocationChanged(getHost(), newLoc));
lastLocation = newLoc;
Event.scheduleWithDelay(interval, this, null, eventTypeSeq);
}
}
return new LocationRequestImpl(getHost(), this);
}
/*
......@@ -467,7 +288,7 @@ public class DefaultTopologyComponent implements TopologyComponent {
netName.toString() + (onlyOnline ? "-online" : "-all"),
DefaultTopologyComponent.class);
if (!this.graphViews.containsKey(id)) {
this.graphViews.put(id, new LocalGraphView(netName, onlyOnline));
this.graphViews.put(id, new LocalGraphView(netName, onlyOnline, topology));
}
return id;
}
......@@ -481,7 +302,7 @@ public class DefaultTopologyComponent implements TopologyComponent {
DefaultTopologyComponent.class);
if (!this.graphViews.containsKey(id)) {
this.graphViews.put(id,
new LocalGraphView(netName, onlyOnline, range));
new LocalGraphView(netName, onlyOnline, range, topology));
}
return id;
}
......@@ -509,222 +330,9 @@ public class DefaultTopologyComponent implements TopologyComponent {
return graphViews.keySet();
}
/**
* This is calculated based on global knowledge. It only registers as
* {@link LocationListener}, if a range is specified by the Provider.
*
* @author Bjoern Richerzhagen
* @version 1.0, May 13, 2015
*/
private class LocalGraphView
implements LocationListener, ConnectivityListener {
/**
* Marker: has there been any movement since the graph view was last
* requested? If so: recalculate! Otherwise, we ignore this object to
* not perform calculations if no one is interested...
*/
private final double distance;
private final boolean isDistanceBased;
private final NetInterfaceName medium;
private final TopologyView topoView;
private final boolean onlyOnline;
private Graph currentView;
private boolean isInvalid = true;
private final PhyType phy;
public LocalGraphView(NetInterfaceName medium, boolean onlyOnline) {
this(medium, onlyOnline, -1);
}
public LocalGraphView(NetInterfaceName medium, boolean onlyOnline,
double distance) {
this.medium = medium;
PhyType localPhy = null;
for (PhyType currPhy : PhyType.values()) {
if (currPhy.getNetInterfaceName() == medium
&& getTopology().getTopologyView(currPhy) != null) {
localPhy = currPhy;
break;
}
}
phy = localPhy;
assert localPhy != null;
this.topoView = getTopology().getTopologyView(localPhy);
this.distance = distance;
this.onlyOnline = onlyOnline;
this.isDistanceBased = (distance > 0);
assert !isDistanceBased || phy.isBroadcastMedium();
if (phy.isBroadcastMedium() || onlyOnline) {
for (Host host : Oracle.getAllHosts()) {
if (phy.isBroadcastMedium()) {
try {
DefaultTopologyComponent dcomp = host.getComponent(
DefaultTopologyComponent.class);
dcomp.requestLocationUpdates(null,
LocalGraphView.this);
} catch (ComponentNotAvailableException e) {
continue;
}
}
if (onlyOnline) {
if (host.getNetworkComponent()
.getByName(medium) != null) {
host.getNetworkComponent().getByName(medium)
.addConnectivityListener(
LocalGraphView.this);
}
}
}
}
}
private void recalculateLocalView() {
if (!isInvalid) {
/*
* Graphs are invalidated (i) based on movement, IFF a range was
* specified, (ii) based on online/offline events, IFF only
* online hosts are to be considered.
*/
return;
}
/*
* Calculate a complete global connectivity graph
*/
// Create new, empty graph
currentView = Graphs.createGraph();
// Add all (online?) nodes
for (MacLayer mac : topoView.getAllMacs()) {
if (!onlyOnline || mac.isOnline()) {
INode node = currentView.createNode(mac.getHost().getId());
node.setProperty(SiSTypes.PHY_LOCATION,
topoView.getPosition(mac.getMacAddress()).clone());
currentView.addElement(node);
}
}
if (isDistanceBased) {
// Build neighbors solely based on an assumed range
for (MacLayer mac : topoView.getAllMacs()) {
// Fix Christoph Storm:
// Do not take offline nodes into account, unless told to do
// so...
if (onlyOnline && !currentView
.containsNode(mac.getHost().getId())) {
continue;
}
// Consider all nodes as potential neighbors
for (MacLayer neighborMac : topoView.getAllMacs()) {
// create, but do NOT add the node object
INode neighbor = currentView
.createNode(neighborMac.getHost().getId());
// only online nodes (already in graph)
if (!onlyOnline
|| currentView.containsNode(neighbor.getId())) {
// Distance?
if (topoView.getDistance(mac.getMacAddress(),
neighborMac.getMacAddress()) <= distance) {
IEdge edge = currentView.createEdge(
mac.getHost().getId(),
neighborMac.getHost().getId());
currentView.addElement(edge);
}
}
}
}
} else {
// Build neighborhoods based on underlay neighbors (1-hop)
for (MacLayer mac : topoView.getAllMacs()) {
// Fix Christoph Storm:
// Do not take offline nodes into account, unless told to do
// so...
if (onlyOnline && !currentView
.containsNode(mac.getHost().getId())) {
continue;
}
// Rely on underlay for neighbors
List<MacAddress> neighbors = topoView
.getNeighbors(mac.getMacAddress());
for (MacAddress neighborMac : neighbors) {
// create, but do NOT add the node object
INode neighbor = currentView.createNode(
topoView.getMac(neighborMac).getHost().getId());
// only online nodes (already in graph)
if (!onlyOnline
|| currentView.containsNode(neighbor.getId())) {
IEdge edge = currentView.createEdge(
mac.getHost().getId(),
topoView.getMac(neighborMac).getHost()
.getId());
currentView.addElement(edge);
edge.setProperty(SiSTypes.PHY_DISTANCE,
topoView.getDistance(mac.getMacAddress(),
neighborMac));
}
}
}
}
isInvalid = false;
}
public INode getOwnNode(SimHost ownHost) {
MacLayer mac = ownHost.getLinkLayer().getMac(phy);
if (!onlyOnline || mac.isOnline()) {
return currentView.createNode(ownHost.getId());
}
return null;
}
public Set<IEdge> getNeighbors(SimHost ownHost) {
recalculateLocalView();
INode ownNode = getOwnNode(ownHost);
return currentView.getOutgoingEdges(ownNode.getId());
}
/**
* This is the global view, therefore we do not distinguish between
* hosts.
*
* @return
*/
public Graph getLocalView() {
recalculateLocalView();
return currentView.clone();
}
@Override
public void onLocationChanged(Host host, Location location) {
this.isInvalid = true;
}
@Override
public void wentOnline(Host host, NetInterface netInterface) {
assert netInterface.getName() == medium;
this.isInvalid = true;
}
@Override
public void wentOffline(Host host, NetInterface netInterface) {
assert netInterface.getName() == medium;
this.isInvalid = true;
}
}
@Override
public String toString() {
return "TopoComp: " + getHost().getId() + " at " + position.toString();
return "Topology Component #" + getHost().getId() + " at pos " + position.toString();
}
}
/*
* 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.component;
import java.util.Set;
import de.tud.kom.p2psim.api.common.SimHost;
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.impl.energy.UAVReplacementCharger;
import de.tudarmstadt.maki.simonstrator.api.component.ComponentNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.overlay.OverlayComponent;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.IAttractionPoint;
import de.tudarmstadt.maki.simonstrator.api.uavsupport.communication.BaseToUAVInterface;
import de.tudarmstadt.maki.simonstrator.api.uavsupport.communication.UAVToBaseInterface;
public class BaseTopologyComponent extends AbstractTopologyComponent {
private OverlayComponent baseOverlayComponent;
private UAVReplacementCharger charger;
private BaseToUAVInterface controllerInterface;
public BaseTopologyComponent(SimHost host, Topology topology,
MovementModel movementModel, PlacementModel placementModel,
boolean registerAsInformationProviderInSiS) {
super(host, topology, movementModel, placementModel,
registerAsInformationProviderInSiS);
// TODO Auto-generated constructor stub
}
@Override
public void initialize() {
super.initialize();
try {
charger = getHost().getComponent(UAVReplacementCharger.class);
} catch (ComponentNotAvailableException e) {
throw new AssertionError("Unable to retrieve Replacement Charger for Base!");
}
}
@Override
public double getMinMovementSpeed() {
throw new UnsupportedOperationException();
}
@Override
public double getMaxMovementSpeed() {
throw new UnsupportedOperationException();
}
@Override
public double getMovementSpeed() {
throw new UnsupportedOperationException();
}
@Override
public void setMovementSpeed(double speed) {
throw new UnsupportedOperationException();
}
@Override
public Set<IAttractionPoint> getAllAttractionPoints() {
throw new UnsupportedOperationException();
}
@Override
public void setTargetAttractionPoint(IAttractionPoint targetAttractionPoint) {
throw new UnsupportedOperationException();
}
@Override
public IAttractionPoint getCurrentTargetAttractionPoint() {
throw new UnsupportedOperationException();
}
public void setOverlayComponent(OverlayComponent component) {
this.baseOverlayComponent = component;
}
public OverlayComponent getBaseComponent() {
return baseOverlayComponent;
}
public UAVReplacementCharger getCharger() {
return charger;
}
public void setControllerInterface(BaseToUAVInterface controllerInterface) {
this.controllerInterface = controllerInterface;
}
public void connectUAVToBase(UAVToBaseInterface uav) {
this.controllerInterface.connectUAVtoBase(uav);
}
public void disconnectUAVFromBase(UAVToBaseInterface uav) {
this.controllerInterface.disconnectUAV(uav);
}
public static class Factory implements TopologyComponentFactory {
@Override
public TopologyComponent createTopologyComponent(SimHost host,
Topology topology, MovementModel movementModel,
PlacementModel placementModel,
boolean registerAsInformationProviderInSiS) {
return new BaseTopologyComponent(host, topology, movementModel, placementModel, registerAsInformationProviderInSiS);
}
}
}
/*
* 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.component;
import java.util.Random;
import java.util.Set;
import de.tud.kom.p2psim.api.common.HostProperties;
import de.tud.kom.p2psim.api.common.SimHost;
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.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.IAttractionPoint;
/**
* Default implementation of a {@link TopologyComponent}.
*
* @author Bjoern Richerzhagen, Julian Zobel
* @version 2.0, 05.09.2018
*/
public class DefaultTopologyComponent extends AbstractTopologyComponent {
protected static Random rnd = Randoms.getRandom(DefaultTopologyComponent.class);
private double currentMovementSpeed = -1;
/**
* Create a TopologyComponent for the current host.
*
* @param host
* @param topology
* @param movementModel
*/
public DefaultTopologyComponent(SimHost host, Topology topology,
MovementModel movementModel, PlacementModel placementModel, boolean registerAsInformationProviderInSiS) {
super(host, topology, movementModel, placementModel, registerAsInformationProviderInSiS);
}
@Override
public void initialize() {
super.initialize();
}
@Override
public double getMinMovementSpeed() {
HostProperties properties = getHost().getProperties();
return properties.getMinMovementSpeed();
}
@Override
public double getMaxMovementSpeed() {
HostProperties properties = getHost().getProperties();
return properties.getMaxMovementSpeed();
}
private void calcRandomMovementSpeed() {
double min_speed = getMinMovementSpeed();
double max_speed = getMaxMovementSpeed();
double value = rnd.nextDouble();
this.currentMovementSpeed = (value * (max_speed - min_speed))
+ min_speed;
}
@Override
public double getMovementSpeed() {
if (currentMovementSpeed == -1) {
calcRandomMovementSpeed();
}
return this.currentMovementSpeed;
}
@Override
public void setMovementSpeed(double speed) {
this.currentMovementSpeed = speed;
}
@Override
public void setTargetAttractionPoint(IAttractionPoint targetAttractionPoint)
throws UnsupportedOperationException {
movementModel.changeTargetLocation(this, targetAttractionPoint);
}
@Override
public IAttractionPoint getCurrentTargetAttractionPoint() {
return movementModel.getTargetLocation(this);
}
@Override
public Set<IAttractionPoint> getAllAttractionPoints() {
return movementModel.getAllAttractionPoints();
}
public static class Factory implements TopologyComponentFactory {
@Override
public TopologyComponent createTopologyComponent(SimHost host,
Topology topology, MovementModel movementModel,
PlacementModel placementModel,
boolean registerAsInformationProviderInSiS) {
return new DefaultTopologyComponent(host, topology, movementModel, placementModel, registerAsInformationProviderInSiS);
}
}
}
/*
* 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.component;
import de.tud.kom.p2psim.api.common.SimHost;
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;
public interface TopologyComponentFactory {
public TopologyComponent createTopologyComponent(SimHost host, Topology topology, MovementModel movementModel, PlacementModel placementModel, boolean registerAsInformationProviderInSiS);
}
/*
* 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.component;
import de.tudarmstadt.maki.simonstrator.api.component.core.MonitorComponent.Analyzer;
public interface UAVStatisticAnalyzer extends Analyzer {
public void uavSwitchedStates(UAVTopologyComponent uav, UAVTopologyComponent.UAVstate newState);
}
......@@ -35,8 +35,8 @@ import java.util.zip.GZIPInputStream;
import de.tud.kom.p2psim.api.topology.movement.MovementSupported;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tud.kom.p2psim.impl.simengine.Simulator;
import de.tud.kom.p2psim.impl.topology.DefaultTopologyComponent;
import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tud.kom.p2psim.impl.topology.component.DefaultTopologyComponent;
import de.tud.kom.p2psim.impl.topology.util.PositionVector;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
......
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