Commit fa7e07fc authored by Marc Schiller's avatar Marc Schiller
Browse files

Merge branch 'master' into nr/monitoring-model

parents cbfe8761 21216cd4
......@@ -208,6 +208,10 @@ public class ModularMovementModel implements MovementModel, EventHandler {
offsetPosition.put(comp, randomOffsetVector());
}
public Set<SimLocationActuator> getAllLocationActuators() {
return moveableHosts;
}
@Override
public void setTimeBetweenMoveOperations(long time) {
if (time > 0) {
......
......@@ -20,15 +20,21 @@
package de.tud.kom.p2psim.impl.topology.movement.modularosm;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.geom.Point2D;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
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.VisualizationInjector;
......@@ -36,17 +42,29 @@ import de.tud.kom.p2psim.impl.topology.views.visualization.ui.VisualizationCompo
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.
*
*
* @author Martin Hellwig
* @author Martin Hellwig, Bjoern Richerzhagen
* @version 1.0, 02.07.2015
*/
public class ModularMovementModelViz extends JComponent implements VisualizationComponent {
public class ModularMovementModelViz extends JComponent
implements VisualizationComponent {
private ModularMovementModel movementModel;
private static Color COLOR_ATTR_POINT = new Color(0.2f, 0.2f, 0.2f, 0.4f);
protected boolean showAttractionPoints = true;
protected boolean showNodePositions = true;
private JMenu menu;
private final static int NODE_PAD = 2;
private final static int ATTR_PAD = 10;
private static Color COLOR_ATTR_POINT = Color.decode("#4A7B9D");
public ModularMovementModelViz(ModularMovementModel model) {
setBounds(0, 0, VisualizationInjector.getWorldX(),
......@@ -54,6 +72,36 @@ public class ModularMovementModelViz extends JComponent implements Visualization
setOpaque(true);
setVisible(true);
this.movementModel = model;
menu = new JMenu("Mobility Model");
menu.add(createCheckboxAp());
menu.add(createCheckboxNodePositions());
}
private JCheckBoxMenuItem createCheckboxAp() {
final JCheckBoxMenuItem checkBox = new JCheckBoxMenuItem(
"show attraction points", showAttractionPoints);
checkBox.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
showAttractionPoints = checkBox.isSelected();
VisualizationInjector.invalidate();
}
});
return checkBox;
}
private JCheckBoxMenuItem createCheckboxNodePositions() {
final JCheckBoxMenuItem checkBox = new JCheckBoxMenuItem(
"show node positions", showNodePositions);
checkBox.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
showNodePositions = checkBox.isSelected();
VisualizationInjector.invalidate();
}
});
return checkBox;
}
@Override
......@@ -63,21 +111,37 @@ public class ModularMovementModelViz extends JComponent implements Visualization
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
if (showAttractionPoints) {
for (AttractionPoint aPoint : movementModel.getAttractionPoints()) {
Point point = ((PositionVector) aPoint).asPoint();
// draw border
g2.setColor(Color.BLACK);
g2.setFont(VisualizationTopologyView.FONT_MEDIUM);
g2.drawString(aPoint.getName(),
VisualizationInjector.scaleValue(point.x) - 15,
VisualizationInjector.scaleValue(point.y) - 15);
VisualizationInjector.scaleValue(point.x) - ATTR_PAD,
VisualizationInjector.scaleValue(point.y) - ATTR_PAD);
g2.setColor(COLOR_ATTR_POINT);
g2.fillOval(VisualizationInjector.scaleValue(point.x) - 15,
VisualizationInjector.scaleValue(point.y) - 15, 20, 20);
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
g2.fillOval(
VisualizationInjector.scaleValue(point.x) - ATTR_PAD,
VisualizationInjector.scaleValue(point.y) - ATTR_PAD,
ATTR_PAD * 2 + 1, ATTR_PAD * 2 + 1);
}
}
if (showNodePositions) {
for (SimLocationActuator comp : movementModel
.getAllLocationActuators()) {
Point2D pt = comp.getRealPosition().asPoint();
g2.setColor(Color.GRAY);
g2.fillOval((int) pt.getX() - NODE_PAD,
(int) pt.getY() - NODE_PAD, NODE_PAD * 2 + 1,
NODE_PAD * 2 + 1);
}
}
}
@Override
public String getDisplayName() {
return "Mobility Model";
......@@ -90,7 +154,7 @@ public class ModularMovementModelViz extends JComponent implements Visualization
@Override
public JMenu getCustomMenu() {
return null;
return menu;
}
@Override
......
......@@ -20,6 +20,8 @@
package de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
import de.tud.kom.p2psim.impl.topology.PositionVector;
......@@ -28,20 +30,32 @@ import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Attraction
/**
* In the current implementation, {@link AttractionPoint}s cannot move anymore.
*
* We hold a static list of attraction points to ensure that there exists only
* one instance of each name at a time.
*
* @author Christoph Muenker, Bjoern Richerzhagen
* @version 1.0, 02.07.2013
*/
public class AttractionPointImpl extends PositionVector implements AttractionPoint {
public class AttractionPointImpl extends PositionVector
implements AttractionPoint {
protected static Random rnd = Randoms.getRandom(AttractionPoint.class);
private static Map<String, AttractionPointImpl> instances = new LinkedHashMap<>();
private String name;
private double weight = 0;
private double radius = 0;
public AttractionPointImpl(String name, PositionVector posVec) {
super(posVec);
this.name = name;
if (instances.containsKey(name)) {
throw new AssertionError("Name "+name+" already in use for an attraction point.");
}
instances.put(name, this);
}
@Override
......@@ -49,11 +63,36 @@ public class AttractionPointImpl extends PositionVector implements AttractionPoi
return name;
}
@Override
public double getWeight() {
return weight;
}
@Override
public double getRadius() {
return radius;
}
@Override
public void setWeight(double weight) {
this.weight = weight;
}
@Override
public void setRadius(double radius) {
this.radius = radius;
}
@Override
public AttractionPoint clone(String newName) {
return new AttractionPointImpl(name, this);
}
@Override
public int getTransmissionSize() {
return super.getTransmissionSize() + name.length() + Double.BYTES * 2;
}
@Override
public int hashCode() {
final int prime = 31;
......
......@@ -40,6 +40,7 @@ import de.tud.kom.p2psim.api.topology.views.DropProbabilityDeterminator;
import de.tud.kom.p2psim.api.topology.views.LatencyDeterminator;
import de.tud.kom.p2psim.api.topology.views.TopologyView;
import de.tud.kom.p2psim.impl.topology.PositionVector;
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;
......@@ -130,6 +131,7 @@ public abstract class AbstractTopologyView<L extends DefaultLink> implements
* @param obstaclesSupported
*/
public AbstractTopologyView(PhyType phy, boolean movementSupported) {
Binder.registerComponent(this);
this.phy = phy;
this.movementSupported = movementSupported;
if (movementSupported) {
......
......@@ -314,6 +314,26 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
}
}
/**
* Access to the {@link FiveGTopologyDatabase} that takes care of the
* UMTS-links in the 5G-TopoView.
*
* @return
*/
public FiveGTopologyDatabase getUMTSTopologyDatabase() {
return database;
}
/**
* Access to the {@link FiveGTopologyDatabase} used to determine Wi-Fi AP
* connectivity in the 5G TopoView.
*
* @return
*/
public FiveGTopologyDatabase getAccessPointTopologyDatabase() {
return databaseAccessPoints;
}
/*
* Configuration options
*/
......@@ -453,6 +473,44 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
public void setLinkData(FiveGTopologyDatabase.Entry linkData,
FiveGTopologyDatabase.Entry apLinkData) {
// Initialization
if (this.linkData == null && this.apLinkData == null) {
this.linkData = linkData;
this.apLinkData = apLinkData;
if (apLinkData != null) {
apLinkData.onHostEntersSegment(mobileClient);
} else {
linkData.onHostEntersSegment(mobileClient);
}
// For the first update on link creation.
return;
}
// Update
if (apLinkData != null) {
assert supportsAccessPoints;
if (this.apLinkData != null) {
// was in AP, moves into AP
this.apLinkData.onHostLeavesSegment(mobileClient);
apLinkData.onHostEntersSegment(mobileClient);
} else {
// was NOT in AP, moves into AP
this.linkData.onHostLeavesSegment(mobileClient);
apLinkData.onHostEntersSegment(mobileClient);
}
} else {
if (this.apLinkData != null) {
// was in AP, moves OUT OF AP
this.apLinkData.onHostLeavesSegment(mobileClient);
linkData.onHostEntersSegment(mobileClient);
} else {
// was NOT in AP, moves into NON-AP segment
this.linkData.onHostLeavesSegment(mobileClient);
linkData.onHostEntersSegment(mobileClient);
}
}
this.linkData = linkData;
assert (apLinkData != null && supportsAccessPoints)
|| apLinkData == null;
......@@ -497,10 +555,12 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
@Override
public boolean isConnected() {
if (apLinkData != null)
return apLinkData.getConnectivity();
if (linkData != null)
return linkData.getConnectivity();
if (apLinkData != null) {
return apLinkData.isAvailable();
}
if (linkData != null) {
return linkData.isAvailable();
}
return false;
}
......
......@@ -113,6 +113,8 @@ public class VisualizationTopologyView extends JFrame
protected JSplitPane splitPane;
protected boolean showNodes = true;
public static final Stroke STROKE_BASIC = new BasicStroke(0.8f);
public static final Stroke STROKE_THICK = new BasicStroke(2f);
......@@ -135,6 +137,7 @@ public class VisualizationTopologyView extends JFrame
*
*/
public VisualizationTopologyView() {
Binder.registerComponent(this);
WORLD_X = (int) Binder.getComponentOrNull(Topology.class)
.getWorldDimensions().getX();
WORLD_Y = (int) Binder.getComponentOrNull(Topology.class)
......@@ -334,6 +337,15 @@ public class VisualizationTopologyView extends JFrame
return null;
}
/**
* Set to false to disable default drawing of nodes.
*
* @param showNodes
*/
public void setShowNodes(boolean showNodes) {
this.showNodes = showNodes;
}
/**
* Mini-Container for per-node information
*
......@@ -379,6 +391,8 @@ public class VisualizationTopologyView extends JFrame
protected final static int PADDING = 16;
protected final static int NODE_PAD = 2;
private static final long serialVersionUID = -3023020559483652110L;
public WorldPanel() {
......@@ -443,7 +457,6 @@ public class VisualizationTopologyView extends JFrame
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
//paintPlayingFieldBorder(g2);
paintNodes(g2);
super.paintComponent(g);
}
......@@ -455,19 +468,16 @@ public class VisualizationTopologyView extends JFrame
g2.fillOval((int) node.position.getX() - PADDING,
(int) node.position.getY() - PADDING,
PADDING * 2 + 1, PADDING * 2 + 1);
} else {
if (showNodes) {
// Draw nodes
g2.setColor(Color.DARK_GRAY);
g2.fillOval((int) node.position.getX() - NODE_PAD,
(int) node.position.getY() - NODE_PAD,
NODE_PAD * 2 + 1, NODE_PAD * 2 + 1);
}
}
}
private void paintPlayingFieldBorder(Graphics2D g2) {
g2.setColor(Color.DARK_GRAY);
g2.fillRect(0, 0, getWidth(), getHeight());
g2.setColor(Color.WHITE);
g2.fillRect(0, 0, VisualizationInjector.getWorldX(),
VisualizationInjector.getWorldY());
g2.setPaint(Color.MAGENTA);
g2.setStroke(new BasicStroke(2));
g2.drawLine(0, 0, VisualizationInjector.scaleValue(100), 0);
}
}
......
......@@ -25,6 +25,7 @@ import java.util.Map;
import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.VisualizationInjector;
import de.tud.kom.p2psim.impl.topology.views.visualization.world.FiveGVisualization;
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.Time;
......@@ -58,6 +59,7 @@ public abstract class AbstractGridBasedTopologyDatabase
*/
public AbstractGridBasedTopologyDatabase(int gridSize,
boolean supportCloudlets) {
Binder.registerComponent(this);
this.gridSize = gridSize;
this.cloudEntries = new LinkedHashMap<>();
this.cloudletEntries = new LinkedHashMap<>();
......@@ -149,7 +151,7 @@ public abstract class AbstractGridBasedTopologyDatabase
private final long latencyUp, latencyDown, bandwidthUp, bandwidthDown;
private boolean connectivity = true;
private boolean isAvailable = true;
/**
......@@ -183,7 +185,8 @@ public abstract class AbstractGridBasedTopologyDatabase
@Override
public double getDropProbability(boolean isUpload) {
if(!getConnectivity()){
if(!isAvailable){
// Link is broken.
return 1;
}
return isUpload ? dropUp : dropDown;
......@@ -191,30 +194,26 @@ public abstract class AbstractGridBasedTopologyDatabase
@Override
public long getLatency(boolean isUpload) {
if(!getConnectivity()){
return 9999 * Time.MILLISECOND;
}
return isUpload ? latencyUp : latencyDown;
}
@Override
public long getBandwidth(boolean isUpload) {
if(!getConnectivity()){
if(!isAvailable){
// Link is broken.
return 0;
}
return isUpload ? bandwidthUp : bandwidthDown;
}
@Override
public boolean getConnectivity()
{
return connectivity;
public boolean isAvailable() {
return isAvailable;
}
@Override
public void setConnectivity(boolean connectivity)
{
this.connectivity = connectivity;
public void setAvailability(boolean isAvailable) {
this.isAvailable = isAvailable;
}
}
......
......@@ -20,8 +20,10 @@
package de.tud.kom.p2psim.impl.topology.views.fiveg;
import de.tud.kom.p2psim.api.linklayer.mac.MacAddress;
import de.tud.kom.p2psim.impl.topology.views.FiveGTopologyView;
import de.tud.kom.p2psim.impl.topology.views.FiveGTopologyView.CellLink;
import de.tudarmstadt.maki.simonstrator.api.component.GlobalComponent;
/**
* Database for the {@link FiveGTopologyView} - containing a mapping of position
......@@ -34,7 +36,7 @@ import de.tud.kom.p2psim.impl.topology.views.FiveGTopologyView.CellLink;
* @author Bjoern Richerzhagen
* @version 1.0, Nov 5, 2015
*/
public interface FiveGTopologyDatabase {
public interface FiveGTopologyDatabase extends GlobalComponent {
/**
* Calculation of a segment ID based on a position (usually given in
......@@ -94,6 +96,14 @@ public interface FiveGTopologyDatabase {
*/
public int getSegmentID();
default public void onHostLeavesSegment(MacAddress hostAddr) {
// ignore
}
default public void onHostEntersSegment(MacAddress hostAddr) {
// ignore
}
/**
* Probability of a packet drop on the link - can even be 1, so that the
* link is virtually disconnected.
......@@ -117,22 +127,19 @@ public interface FiveGTopologyDatabase {
public long getBandwidth(boolean isUpload);
/**
* Connectivity of the cell.
* Availability of the cell (false, if the current cell is "broken")
*
* @return <code>false</code> if the cell is broken down/damaged and
* upload/download isn't possible. <code>true</code> otherwise.
* @return
*/
boolean getConnectivity();
boolean isAvailable();
/**
* Set the connectivity of the cell. When set to <code>false</code>, it
* should be impossible to upload or download data via this cell.
* {@link CellLink} refers to this attribute when returning e.g. BW or
* drop rate.
* Set the connectivity of the cell. When set to false, the cell is no
* longer accepting connections and existing connections fail.
*
* @param connectivity
* @param isAvailable
*/
void setConnectivity(boolean connectivity);
void setAvailability(boolean isAvailable);
}
}
......@@ -117,12 +117,6 @@ public class FiveGVisualization extends JComponent implements VisualizationInjec
if (entry == null) {
continue;
}
if (entry.getConnectivity() && entry.getLatency(isUpload) > maxLatency) {
maxLatency = entry.getLatency(isUpload);
}
if (entry.getConnectivity() && entry.getLatency(isUpload) < minLatency) {
minLatency = entry.getLatency(isUpload);
}
}
}
......@@ -140,8 +134,8 @@ public class FiveGVisualization extends JComponent implements VisualizationInjec
// TODO add checkbox for upload/download toggle?
// Latency
double latencyFactor = entry.getConnectivity() ? (entry.getLatency(isUpload) - minLatency)
/ (maxLatency - minLatency) : 4;
double latencyFactor = (entry.getLatency(isUpload) - minLatency)
/ (maxLatency - minLatency);
g2.setColor(
new Color(255, 0, 0, 10 + (int) (40 * latencyFactor)));
g2.fillRect(x, y, stepSize, stepSize);
......@@ -149,7 +143,7 @@ public class FiveGVisualization extends JComponent implements VisualizationInjec
// Drop-Prob
g2.setColor(new Color(255, 0, 0,
10 + (int) (100 * entry.getDropProbability(isUpload))));
float strokeWidth = entry.getConnectivity() ? (float) entry.getDropProbability(isUpload) : 0.2f;
float strokeWidth = (float) entry.getDropProbability(isUpload);
g2.setStroke(new BasicStroke((10 * strokeWidth)));
g2.drawRect(x, y, stepSize, stepSize);
g2.setColor(new Color(255, 255, 255, 255));
......@@ -163,8 +157,7 @@ public class FiveGVisualization extends JComponent implements VisualizationInjec
g2.drawString("BW: "
+ (int) (entry.getBandwidth(isUpload) / Rate.kbit_s)
+ " kBit/s", x + 10, y + 35);
if(!entry.getConnectivity())
{
if(!entry.isAvailable()) {
g2.drawString("!DEAD!", x + 30, y + 70);
}
}
......@@ -180,7 +173,7 @@ public class FiveGVisualization extends JComponent implements VisualizationInjec
{
int segID = database.getSegmentID(x, y);
Entry entry = database.getEntryFor(segID, false);
entry.setConnectivity(!entry.getConnectivity());
entry.setAvailability(!entry.isAvailable());
needsRedraw = true;
}
}
......
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