visualizer skin updates: broke out traffic visualization from the udgm radio medium skin (the stand-alone traffic skin can be used with any radio medium), added a simple background grid skin and a mote position skin
This commit is contained in:
parent
23f13a2b6f
commit
39aeb2f150
|
@ -26,7 +26,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: AddressVisualizerSkin.java,v 1.1 2009/04/20 16:15:47 fros4943 Exp $
|
* $Id: AddressVisualizerSkin.java,v 1.2 2009/08/27 13:59:47 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.plugins.skins;
|
package se.sics.cooja.plugins.skins;
|
||||||
|
@ -112,8 +112,12 @@ public class AddressVisualizerSkin implements VisualizerSkin {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void paintSkin(Graphics g) {
|
public void paintBeforeMotes(Graphics g) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paintAfterMotes(Graphics g) {
|
||||||
FontMetrics fm = g.getFontMetrics();
|
FontMetrics fm = g.getFontMetrics();
|
||||||
|
g.setColor(Color.BLACK);
|
||||||
|
|
||||||
/* Paint last output below motes */
|
/* Paint last output below motes */
|
||||||
Mote[] allMotes = simulation.getMotes();
|
Mote[] allMotes = simulation.getMotes();
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009, Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the Institute nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* $Id: GridVisualizerSkin.java,v 1.1 2009/08/27 13:59:48 fros4943 Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
package se.sics.cooja.plugins.skins;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import se.sics.cooja.ClassDescription;
|
||||||
|
import se.sics.cooja.Mote;
|
||||||
|
import se.sics.cooja.Simulation;
|
||||||
|
import se.sics.cooja.interfaces.Position;
|
||||||
|
import se.sics.cooja.plugins.Visualizer;
|
||||||
|
import se.sics.cooja.plugins.VisualizerSkin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Background grid visualizer skin.
|
||||||
|
*
|
||||||
|
* @author Fredrik Osterlind
|
||||||
|
*/
|
||||||
|
@ClassDescription("10m background grid")
|
||||||
|
public class GridVisualizerSkin implements VisualizerSkin {
|
||||||
|
private static Logger logger = Logger.getLogger(GridVisualizerSkin.class);
|
||||||
|
|
||||||
|
private Visualizer visualizer = null;
|
||||||
|
|
||||||
|
public void setActive(Simulation simulation, Visualizer vis) {
|
||||||
|
this.visualizer = vis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInactive() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color[] getColorOf(Mote mote) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paintBeforeMotes(Graphics g) {
|
||||||
|
|
||||||
|
/* Background grid every 10 meters */
|
||||||
|
Position upperLeft =
|
||||||
|
visualizer.transformPixelToPosition(-10, -10);
|
||||||
|
upperLeft.setCoordinates(
|
||||||
|
((int)(upperLeft.getXCoordinate()/10))*10,
|
||||||
|
((int)(upperLeft.getYCoordinate()/10))*10,
|
||||||
|
0);
|
||||||
|
Position lowerRight =
|
||||||
|
visualizer.transformPixelToPosition(visualizer.getWidth(), visualizer.getHeight());
|
||||||
|
lowerRight.setCoordinates(
|
||||||
|
((int)(lowerRight.getXCoordinate()/10))*10,
|
||||||
|
((int)(lowerRight.getYCoordinate()/10))*10,
|
||||||
|
0);
|
||||||
|
|
||||||
|
if ((lowerRight.getXCoordinate() - upperLeft.getXCoordinate())/10.0 < 200 &&
|
||||||
|
(lowerRight.getYCoordinate() - upperLeft.getYCoordinate())/10.0 < 200) {
|
||||||
|
/* X axis */
|
||||||
|
for (double x = upperLeft.getXCoordinate(); x <= lowerRight.getXCoordinate(); x += 10.0) {
|
||||||
|
int pixel = visualizer.transformPositionToPixel(x, 0, 0).x;
|
||||||
|
if (x % 100 == 0) {
|
||||||
|
g.setColor(Color.GRAY);
|
||||||
|
} else {
|
||||||
|
g.setColor(Color.LIGHT_GRAY);
|
||||||
|
}
|
||||||
|
g.drawLine(
|
||||||
|
pixel,
|
||||||
|
0,
|
||||||
|
pixel,
|
||||||
|
visualizer.getHeight()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/* Y axis */
|
||||||
|
for (double y = upperLeft.getYCoordinate(); y <= lowerRight.getYCoordinate(); y += 10.0) {
|
||||||
|
int pixel = visualizer.transformPositionToPixel(0, y, 0).y;
|
||||||
|
if (y % 100 == 0) {
|
||||||
|
g.setColor(Color.GRAY);
|
||||||
|
} else {
|
||||||
|
g.setColor(Color.LIGHT_GRAY);
|
||||||
|
}
|
||||||
|
g.drawLine(
|
||||||
|
0,
|
||||||
|
pixel,
|
||||||
|
visualizer.getWidth(),
|
||||||
|
pixel
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paintAfterMotes(Graphics g) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Visualizer getVisualizer() {
|
||||||
|
return visualizer;
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,7 +26,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: IDVisualizerSkin.java,v 1.1 2009/04/14 15:40:26 fros4943 Exp $
|
* $Id: IDVisualizerSkin.java,v 1.2 2009/08/27 13:59:47 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.plugins.skins;
|
package se.sics.cooja.plugins.skins;
|
||||||
|
@ -70,9 +70,13 @@ public class IDVisualizerSkin implements VisualizerSkin {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void paintSkin(Graphics g) {
|
public void paintBeforeMotes(Graphics g) {
|
||||||
FontMetrics fm = g.getFontMetrics();
|
}
|
||||||
|
|
||||||
|
public void paintAfterMotes(Graphics g) {
|
||||||
|
FontMetrics fm = g.getFontMetrics();
|
||||||
|
g.setColor(Color.BLACK);
|
||||||
|
|
||||||
/* Paint ID inside each mote */
|
/* Paint ID inside each mote */
|
||||||
Mote[] allMotes = simulation.getMotes();
|
Mote[] allMotes = simulation.getMotes();
|
||||||
for (Mote mote: allMotes) {
|
for (Mote mote: allMotes) {
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: LEDVisualizerSkin.java,v 1.3 2009/04/20 16:16:25 fros4943 Exp $
|
* $Id: LEDVisualizerSkin.java,v 1.4 2009/08/27 13:59:48 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.plugins.skins;
|
package se.sics.cooja.plugins.skins;
|
||||||
|
@ -103,7 +103,10 @@ public class LEDVisualizerSkin implements VisualizerSkin {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void paintSkin(Graphics g) {
|
public void paintBeforeMotes(Graphics g) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paintAfterMotes(Graphics g) {
|
||||||
/* Paint LEDs left of each mote */
|
/* Paint LEDs left of each mote */
|
||||||
Mote[] allMotes = simulation.getMotes();
|
Mote[] allMotes = simulation.getMotes();
|
||||||
for (Mote mote: allMotes) {
|
for (Mote mote: allMotes) {
|
||||||
|
@ -140,10 +143,7 @@ public class LEDVisualizerSkin implements VisualizerSkin {
|
||||||
} else {
|
} else {
|
||||||
g.drawRect(x, y, 7, 4);
|
g.drawRect(x, y, 7, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g.setColor(Color.BLACK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Visualizer getVisualizer() {
|
public Visualizer getVisualizer() {
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: LogVisualizerSkin.java,v 1.2 2009/04/14 15:40:26 fros4943 Exp $
|
* $Id: LogVisualizerSkin.java,v 1.3 2009/08/27 13:59:47 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.plugins.skins;
|
package se.sics.cooja.plugins.skins;
|
||||||
|
@ -103,8 +103,12 @@ public class LogVisualizerSkin implements VisualizerSkin {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void paintSkin(Graphics g) {
|
public void paintBeforeMotes(Graphics g) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paintAfterMotes(Graphics g) {
|
||||||
FontMetrics fm = g.getFontMetrics();
|
FontMetrics fm = g.getFontMetrics();
|
||||||
|
g.setColor(Color.BLACK);
|
||||||
|
|
||||||
/* Paint last output below motes */
|
/* Paint last output below motes */
|
||||||
Mote[] allMotes = simulation.getMotes();
|
Mote[] allMotes = simulation.getMotes();
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009, Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the Institute nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* $Id: PositionVisualizerSkin.java,v 1.1 2009/08/27 13:59:47 fros4943 Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
package se.sics.cooja.plugins.skins;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.FontMetrics;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.util.Observable;
|
||||||
|
import java.util.Observer;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import se.sics.cooja.ClassDescription;
|
||||||
|
import se.sics.cooja.Mote;
|
||||||
|
import se.sics.cooja.Simulation;
|
||||||
|
import se.sics.cooja.SimEventCentral.MoteCountListener;
|
||||||
|
import se.sics.cooja.interfaces.Position;
|
||||||
|
import se.sics.cooja.plugins.Visualizer;
|
||||||
|
import se.sics.cooja.plugins.VisualizerSkin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visualizer skin for mote positions.
|
||||||
|
*
|
||||||
|
* Paints the three dimensional mote position on the right-hand side of the mote.
|
||||||
|
*
|
||||||
|
* @author Fredrik Osterlind
|
||||||
|
*/
|
||||||
|
@ClassDescription("Positions")
|
||||||
|
public class PositionVisualizerSkin implements VisualizerSkin {
|
||||||
|
private static Logger logger = Logger.getLogger(PositionVisualizerSkin.class);
|
||||||
|
|
||||||
|
private Simulation simulation = null;
|
||||||
|
private Visualizer visualizer = null;
|
||||||
|
|
||||||
|
private Observer positionObserver = new Observer() {
|
||||||
|
public void update(Observable obs, Object obj) {
|
||||||
|
visualizer.repaint();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private MoteCountListener simObserver = new MoteCountListener() {
|
||||||
|
public void moteWasAdded(Mote mote) {
|
||||||
|
Position p = mote.getInterfaces().getPosition();
|
||||||
|
if (p != null) {
|
||||||
|
p.addObserver(positionObserver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void moteWasRemoved(Mote mote) {
|
||||||
|
Position p = mote.getInterfaces().getPosition();
|
||||||
|
if (p != null) {
|
||||||
|
p.deleteObserver(positionObserver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public void setActive(Simulation simulation, Visualizer vis) {
|
||||||
|
this.simulation = simulation;
|
||||||
|
this.visualizer = vis;
|
||||||
|
|
||||||
|
simulation.getEventCentral().addMoteCountListener(simObserver);
|
||||||
|
for (Mote m: simulation.getMotes()) {
|
||||||
|
simObserver.moteWasAdded(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInactive() {
|
||||||
|
simulation.getEventCentral().removeMoteCountListener(simObserver);
|
||||||
|
for (Mote m: simulation.getMotes()) {
|
||||||
|
simObserver.moteWasRemoved(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color[] getColorOf(Mote mote) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paintBeforeMotes(Graphics g) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paintAfterMotes(Graphics g) {
|
||||||
|
FontMetrics fm = g.getFontMetrics();
|
||||||
|
g.setColor(Color.BLACK);
|
||||||
|
|
||||||
|
/* Paint last output below motes */
|
||||||
|
Mote[] allMotes = simulation.getMotes();
|
||||||
|
for (Mote mote: allMotes) {
|
||||||
|
Position pos = mote.getInterfaces().getPosition();
|
||||||
|
Point pixel = visualizer.transformPositionToPixel(pos);
|
||||||
|
|
||||||
|
String msg = "";
|
||||||
|
String[] parts;
|
||||||
|
|
||||||
|
/* X */
|
||||||
|
parts = String.valueOf(pos.getXCoordinate()).split("\\.");
|
||||||
|
if (parts[0].length() >= 4) {
|
||||||
|
msg += parts[0];
|
||||||
|
} else {
|
||||||
|
msg += String.valueOf(pos.getXCoordinate()).substring(0, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Y */
|
||||||
|
msg += ", ";
|
||||||
|
parts = String.valueOf(pos.getYCoordinate()).split("\\.");
|
||||||
|
if (parts[0].length() >= 4) {
|
||||||
|
msg += parts[0];
|
||||||
|
} else {
|
||||||
|
msg += String.valueOf(pos.getYCoordinate()).substring(0, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Z */
|
||||||
|
if (pos.getZCoordinate() != 0) {
|
||||||
|
msg += ", ";
|
||||||
|
parts = String.valueOf(pos.getXCoordinate()).split("\\.");
|
||||||
|
if (parts[0].length() >= 4) {
|
||||||
|
msg += parts[0];
|
||||||
|
} else {
|
||||||
|
msg += String.valueOf(pos.getXCoordinate()).substring(0, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g.drawString(msg, pixel.x + Visualizer.MOTE_RADIUS + 4, pixel.y + 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Visualizer getVisualizer() {
|
||||||
|
return visualizer;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,300 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009, Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the Institute nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* $Id: TrafficVisualizerSkin.java,v 1.1 2009/08/27 13:59:48 fros4943 Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
package se.sics.cooja.plugins.skins;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Observable;
|
||||||
|
import java.util.Observer;
|
||||||
|
|
||||||
|
import javax.swing.Box;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import se.sics.cooja.ClassDescription;
|
||||||
|
import se.sics.cooja.Mote;
|
||||||
|
import se.sics.cooja.RadioConnection;
|
||||||
|
import se.sics.cooja.Simulation;
|
||||||
|
import se.sics.cooja.SimEventCentral.MoteCountListener;
|
||||||
|
import se.sics.cooja.interfaces.Position;
|
||||||
|
import se.sics.cooja.interfaces.Radio;
|
||||||
|
import se.sics.cooja.plugins.Visualizer;
|
||||||
|
import se.sics.cooja.plugins.VisualizerSkin;
|
||||||
|
import se.sics.cooja.plugins.Visualizer.SimulationMenuAction;
|
||||||
|
import se.sics.cooja.radiomediums.AbstractRadioMedium;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Radio traffic visualizer skin.
|
||||||
|
*
|
||||||
|
* Transmitting motes are painted blue. Receiving motes are painted green.
|
||||||
|
* Interfered motes are painted red. Motes without radios are painted gray. All
|
||||||
|
* other motes are painted white.
|
||||||
|
*
|
||||||
|
* In contrast to the {@link UDGMVisualizerSkin}, this skin listens to all mote
|
||||||
|
* radios, not to the radio medium. The radio traffic skin also displays a
|
||||||
|
* history.
|
||||||
|
*
|
||||||
|
* @see UDGMVisualizerSkin
|
||||||
|
* @author Fredrik Osterlind
|
||||||
|
*/
|
||||||
|
@ClassDescription("Radio traffic")
|
||||||
|
public class TrafficVisualizerSkin implements VisualizerSkin {
|
||||||
|
private static Logger logger = Logger.getLogger(TrafficVisualizerSkin.class);
|
||||||
|
|
||||||
|
private static final boolean DRAW_ARROWS = true;
|
||||||
|
private static final Color COLOR_HISTORY = new Color(100, 100, 100, 100);
|
||||||
|
|
||||||
|
private Simulation simulation = null;
|
||||||
|
private Visualizer visualizer = null;
|
||||||
|
|
||||||
|
private Box counters;
|
||||||
|
|
||||||
|
private final static int HISTORY_SIZE = 8;
|
||||||
|
private boolean showHistory = false;
|
||||||
|
private ArrayDeque<RadioConnection> history = new ArrayDeque<RadioConnection>();
|
||||||
|
|
||||||
|
private AbstractRadioMedium radioMedium;
|
||||||
|
private Observer radioObserver, radioMediumObserver;
|
||||||
|
|
||||||
|
public void setActive(Simulation simulation, Visualizer vis) {
|
||||||
|
if (!(simulation.getRadioMedium() instanceof AbstractRadioMedium)) {
|
||||||
|
logger.fatal("Radio medium type not supported: " + simulation.getRadioMedium());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.radioMedium = (AbstractRadioMedium) simulation.getRadioMedium();
|
||||||
|
this.simulation = simulation;
|
||||||
|
this.visualizer = vis;
|
||||||
|
|
||||||
|
final JLabel txCounter = new JLabel("TX: " + radioMedium.COUNTER_TX);
|
||||||
|
final JLabel rxCounter = new JLabel("RX: " + radioMedium.COUNTER_RX);
|
||||||
|
final JLabel interferedCounter = new JLabel("INT: " + radioMedium.COUNTER_INTERFERED);
|
||||||
|
|
||||||
|
counters = Box.createHorizontalBox();
|
||||||
|
counters.add(txCounter);
|
||||||
|
counters.add(Box.createHorizontalStrut(10));
|
||||||
|
counters.add(rxCounter);
|
||||||
|
counters.add(Box.createHorizontalStrut(10));
|
||||||
|
counters.add(interferedCounter);
|
||||||
|
|
||||||
|
visualizer.getCurrentCanvas().add(counters);
|
||||||
|
|
||||||
|
/* Start observing radio medium and radios */
|
||||||
|
radioMedium.addRadioMediumObserver(radioMediumObserver = new Observer() {
|
||||||
|
public void update(Observable obs, Object obj) {
|
||||||
|
txCounter.setText("TX: " + radioMedium.COUNTER_TX);
|
||||||
|
rxCounter.setText("RX: " + radioMedium.COUNTER_RX);
|
||||||
|
interferedCounter.setText("INT: " + + radioMedium.COUNTER_INTERFERED);
|
||||||
|
|
||||||
|
if (showHistory) {
|
||||||
|
RadioConnection[] past = radioMedium.getLastTickConnections();
|
||||||
|
for (RadioConnection con: past) {
|
||||||
|
history.add(con);
|
||||||
|
}
|
||||||
|
while (history.size() > HISTORY_SIZE) {
|
||||||
|
history.removeFirst();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
visualizer.repaint();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
radioObserver = new Observer() {
|
||||||
|
public void update(Observable o, Object arg) {
|
||||||
|
visualizer.repaint();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
simulation.getEventCentral().addMoteCountListener(new MoteCountListener() {
|
||||||
|
public void moteWasAdded(Mote mote) {
|
||||||
|
Radio r = mote.getInterfaces().getRadio();
|
||||||
|
if (r != null) {
|
||||||
|
r.addObserver(radioObserver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void moteWasRemoved(Mote mote) {
|
||||||
|
Radio r = mote.getInterfaces().getRadio();
|
||||||
|
if (r != null) {
|
||||||
|
r.deleteObserver(radioObserver);
|
||||||
|
}
|
||||||
|
history.clear();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
for (Mote mote: simulation.getMotes()) {
|
||||||
|
Radio r = mote.getInterfaces().getRadio();
|
||||||
|
if (r != null) {
|
||||||
|
r.addObserver(radioObserver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Register menu actions */
|
||||||
|
visualizer.registerSimulationMenuAction(ToggleHistoryAction.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInactive() {
|
||||||
|
if (simulation == null) {
|
||||||
|
/* Skin was never activated */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
visualizer.getCurrentCanvas().remove(counters);
|
||||||
|
|
||||||
|
/* Stop observing radio medium and radios */
|
||||||
|
radioMedium.deleteRadioMediumObserver(radioMediumObserver);
|
||||||
|
for (Mote mote: simulation.getMotes()) {
|
||||||
|
Radio r = mote.getInterfaces().getRadio();
|
||||||
|
if (r != null) {
|
||||||
|
r.addObserver(radioObserver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unregister menu actions */
|
||||||
|
visualizer.unregisterSimulationMenuAction(ToggleHistoryAction.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color[] getColorOf(Mote mote) {
|
||||||
|
if (simulation == null) {
|
||||||
|
/* Skin was never activated */
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Radio moteRadio = mote.getInterfaces().getRadio();
|
||||||
|
if (moteRadio == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!moteRadio.isReceiverOn()) {
|
||||||
|
return new Color[] { Color.GRAY };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moteRadio.isTransmitting()) {
|
||||||
|
return new Color[] { Color.BLUE };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moteRadio.isInterfered()) {
|
||||||
|
return new Color[] { Color.RED };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moteRadio.isReceiving()) {
|
||||||
|
return new Color[] { Color.GREEN };
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paintBeforeMotes(Graphics g) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paintAfterMotes(Graphics g) {
|
||||||
|
if (simulation == null) {
|
||||||
|
/* Skin was never activated */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showHistory) {
|
||||||
|
/* Paint history in gray */
|
||||||
|
RadioConnection[] historyArr = history.toArray(new RadioConnection[0]);
|
||||||
|
for (RadioConnection conn : historyArr) {
|
||||||
|
g.setColor(COLOR_HISTORY);
|
||||||
|
Radio source = conn.getSource();
|
||||||
|
Point sourcePoint = visualizer.transformPositionToPixel(source.getPosition());
|
||||||
|
for (Radio destRadio : conn.getDestinations()) {
|
||||||
|
Position destPos = destRadio.getPosition();
|
||||||
|
Point destPoint = visualizer.transformPositionToPixel(destPos);
|
||||||
|
g.drawLine(sourcePoint.x, sourcePoint.y, destPoint.x, destPoint.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Paint active connections in black */
|
||||||
|
RadioConnection[] conns = radioMedium.getActiveConnections();
|
||||||
|
if (conns != null) {
|
||||||
|
g.setColor(Color.BLACK);
|
||||||
|
for (RadioConnection conn : conns) {
|
||||||
|
Radio source = conn.getSource();
|
||||||
|
Point sourcePoint = visualizer.transformPositionToPixel(source.getPosition());
|
||||||
|
for (Radio destRadio : conn.getDestinations()) {
|
||||||
|
if (destRadio == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Position destPos = destRadio.getPosition();
|
||||||
|
Point destPoint = visualizer.transformPositionToPixel(destPos);
|
||||||
|
g.drawLine(sourcePoint.x, sourcePoint.y, destPoint.x, destPoint.y);
|
||||||
|
|
||||||
|
/* Draw arrows */
|
||||||
|
if (DRAW_ARROWS) {
|
||||||
|
Point centerPoint = new Point(
|
||||||
|
destPoint.x/2 + sourcePoint.x/2,
|
||||||
|
destPoint.y/2 + sourcePoint.y/2
|
||||||
|
);
|
||||||
|
int startAngle = (int) (-180 * Math.atan2(destPoint.y - sourcePoint.y, destPoint.x - sourcePoint.x)/Math.PI - 90);
|
||||||
|
g.drawArc(centerPoint.x-5, centerPoint.y-5, 10, 10, startAngle, 180);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ToggleHistoryAction implements SimulationMenuAction {
|
||||||
|
public boolean isEnabled(Visualizer visualizer, Simulation simulation) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription(Visualizer visualizer, Simulation simulation) {
|
||||||
|
VisualizerSkin[] skins = visualizer.getCurrentSkins();
|
||||||
|
boolean showing = false;
|
||||||
|
for (VisualizerSkin skin: skins) {
|
||||||
|
if (skin instanceof TrafficVisualizerSkin) {
|
||||||
|
showing = ((TrafficVisualizerSkin)skin).showHistory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (showing) {
|
||||||
|
return "Hide traffic history";
|
||||||
|
}
|
||||||
|
return "Show traffic history";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doAction(Visualizer visualizer, Simulation simulation) {
|
||||||
|
VisualizerSkin[] skins = visualizer.getCurrentSkins();
|
||||||
|
for (VisualizerSkin skin: skins) {
|
||||||
|
if (skin instanceof TrafficVisualizerSkin) {
|
||||||
|
((TrafficVisualizerSkin)skin).showHistory = !((TrafficVisualizerSkin)skin).showHistory;
|
||||||
|
visualizer.repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public Visualizer getVisualizer() {
|
||||||
|
return visualizer;
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,20 +26,20 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: UDGMVisualizerSkin.java,v 1.6 2009/04/20 18:09:54 fros4943 Exp $
|
* $Id: UDGMVisualizerSkin.java,v 1.7 2009/08/27 13:59:47 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.plugins.skins;
|
package se.sics.cooja.plugins.skins;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.event.MouseListener;
|
import java.awt.event.MouseListener;
|
||||||
import java.util.Observable;
|
|
||||||
import java.util.Observer;
|
|
||||||
|
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.Box;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JSpinner;
|
import javax.swing.JSpinner;
|
||||||
import javax.swing.SpinnerNumberModel;
|
import javax.swing.SpinnerNumberModel;
|
||||||
|
@ -50,7 +50,6 @@ import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import se.sics.cooja.ClassDescription;
|
import se.sics.cooja.ClassDescription;
|
||||||
import se.sics.cooja.Mote;
|
import se.sics.cooja.Mote;
|
||||||
import se.sics.cooja.RadioConnection;
|
|
||||||
import se.sics.cooja.Simulation;
|
import se.sics.cooja.Simulation;
|
||||||
import se.sics.cooja.interfaces.Position;
|
import se.sics.cooja.interfaces.Position;
|
||||||
import se.sics.cooja.interfaces.Radio;
|
import se.sics.cooja.interfaces.Radio;
|
||||||
|
@ -60,17 +59,15 @@ import se.sics.cooja.plugins.Visualizer.SimulationMenuAction;
|
||||||
import se.sics.cooja.radiomediums.UDGM;
|
import se.sics.cooja.radiomediums.UDGM;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visualizer skin for Unit Disk Graph radio medium.
|
* Visualizer skin for configuring the Unit Disk Graph radio medium (UDGM).
|
||||||
*
|
*
|
||||||
* Allows a user to change the collective TX/interference ranges,
|
* Allows a user to change the collective TX/interference ranges, and the TX/RX
|
||||||
* and the TX/RX success ratio.
|
* success ratio.
|
||||||
*
|
*
|
||||||
* Transmitting motes are painted blue. XXXXXXXX
|
* To also see radio traffic, this skin can be combined with {@link
|
||||||
* Receiving motes are painted green.
|
* TrafficVisualizerSkin()}.
|
||||||
* Interfered motes are painted red.
|
*
|
||||||
* Motes without radios are painted gray.
|
* @see TrafficVisualizerSkin
|
||||||
* All other motes are painted white.
|
|
||||||
*
|
|
||||||
* @see UDGM
|
* @see UDGM
|
||||||
* @author Fredrik Osterlind
|
* @author Fredrik Osterlind
|
||||||
*/
|
*/
|
||||||
|
@ -78,38 +75,27 @@ import se.sics.cooja.radiomediums.UDGM;
|
||||||
public class UDGMVisualizerSkin implements VisualizerSkin {
|
public class UDGMVisualizerSkin implements VisualizerSkin {
|
||||||
private static Logger logger = Logger.getLogger(UDGMVisualizerSkin.class);
|
private static Logger logger = Logger.getLogger(UDGMVisualizerSkin.class);
|
||||||
|
|
||||||
private static final boolean DRAW_ARROWS = true;
|
private static Color COLOR_TX = new Color(0, 255, 0, 100);
|
||||||
|
private static Color COLOR_INT = new Color(50, 50, 50, 100);
|
||||||
|
|
||||||
private Simulation simulation = null;
|
private Simulation simulation = null;
|
||||||
private Visualizer visualizer = null;
|
private Visualizer visualizer = null;
|
||||||
private UDGM radioMedium = null;
|
private UDGM radioMedium = null;
|
||||||
private Observer radioMediumObserver;
|
|
||||||
|
|
||||||
private JLabel txCounter = null;
|
|
||||||
private JLabel rxCounter = null;
|
|
||||||
private JLabel interferedCounter = null;
|
|
||||||
|
|
||||||
private JSpinner txRangeSpinner = null;
|
|
||||||
private JSpinner interferenceRangeSpinner = null;
|
|
||||||
private JSpinner successRatioTxSpinner = null;
|
|
||||||
private JSpinner successRatioRxSpinner = null;
|
|
||||||
|
|
||||||
private Mote selectedMote = null;
|
private Mote selectedMote = null;
|
||||||
|
|
||||||
private MouseListener selectMoteMouseListener = new MouseListener() {
|
private Box top, ratioRX, ratioTX, rangeTX, rangeINT;
|
||||||
public void mouseExited(MouseEvent e) { }
|
|
||||||
public void mouseEntered(MouseEvent e) { }
|
|
||||||
public void mouseReleased(MouseEvent e) { }
|
|
||||||
public void mouseClicked(MouseEvent e) { }
|
|
||||||
|
|
||||||
|
private MouseListener selectMoteMouseListener = new MouseAdapter() {
|
||||||
public void mousePressed(MouseEvent e) {
|
public void mousePressed(MouseEvent e) {
|
||||||
Mote[] motes = visualizer.findMotesAtPosition(e.getX(), e.getY());
|
Mote[] motes = visualizer.findMotesAtPosition(e.getX(), e.getY());
|
||||||
if (motes == null || motes.length == 0) {
|
if (motes == null || motes.length == 0) {
|
||||||
selectedMote = null;
|
selectedMote = null;
|
||||||
txRangeSpinner.setVisible(false);
|
rangeTX.setVisible(false);
|
||||||
interferenceRangeSpinner.setVisible(false);
|
rangeINT.setVisible(false);
|
||||||
successRatioTxSpinner.setVisible(false);
|
ratioRX.setVisible(false);
|
||||||
successRatioRxSpinner.setVisible(false);
|
ratioTX.setVisible(false);
|
||||||
|
top.setVisible(false);
|
||||||
visualizer.repaint();
|
visualizer.repaint();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -152,16 +138,16 @@ public class UDGMVisualizerSkin implements VisualizerSkin {
|
||||||
successRatioRxModel.setMaximum(new Double(1.0));
|
successRatioRxModel.setMaximum(new Double(1.0));
|
||||||
|
|
||||||
JSpinner.NumberEditor editor;
|
JSpinner.NumberEditor editor;
|
||||||
txRangeSpinner = new JSpinner(transmissionModel);
|
final JSpinner txRangeSpinner = new JSpinner(transmissionModel);
|
||||||
editor = new JSpinner.NumberEditor(txRangeSpinner, "0m");
|
editor = new JSpinner.NumberEditor(txRangeSpinner, "0m");
|
||||||
txRangeSpinner.setEditor(editor);
|
txRangeSpinner.setEditor(editor);
|
||||||
interferenceRangeSpinner = new JSpinner(interferenceModel);
|
final JSpinner interferenceRangeSpinner = new JSpinner(interferenceModel);
|
||||||
editor = new JSpinner.NumberEditor(interferenceRangeSpinner, "0m");
|
editor = new JSpinner.NumberEditor(interferenceRangeSpinner, "0m");
|
||||||
interferenceRangeSpinner.setEditor(editor);
|
interferenceRangeSpinner.setEditor(editor);
|
||||||
successRatioTxSpinner = new JSpinner(successRatioTxModel);
|
final JSpinner successRatioTxSpinner = new JSpinner(successRatioTxModel);
|
||||||
editor = new JSpinner.NumberEditor(successRatioTxSpinner, "0.0%");
|
editor = new JSpinner.NumberEditor(successRatioTxSpinner, "0.0%");
|
||||||
successRatioTxSpinner.setEditor(editor);
|
successRatioTxSpinner.setEditor(editor);
|
||||||
successRatioRxSpinner = new JSpinner(successRatioRxModel);
|
final JSpinner successRatioRxSpinner = new JSpinner(successRatioRxModel);
|
||||||
editor = new JSpinner.NumberEditor(successRatioRxSpinner, "0.0%");
|
editor = new JSpinner.NumberEditor(successRatioRxSpinner, "0.0%");
|
||||||
successRatioRxSpinner.setEditor(editor);
|
successRatioRxSpinner.setEditor(editor);
|
||||||
|
|
||||||
|
@ -206,11 +192,6 @@ public class UDGMVisualizerSkin implements VisualizerSkin {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
txRangeSpinner.setVisible(false);
|
|
||||||
interferenceRangeSpinner.setVisible(false);
|
|
||||||
successRatioTxSpinner.setVisible(false);
|
|
||||||
successRatioRxSpinner.setVisible(false);
|
|
||||||
|
|
||||||
/* Register mouse listener */
|
/* Register mouse listener */
|
||||||
visualizer.getCurrentCanvas().addMouseListener(selectMoteMouseListener);
|
visualizer.getCurrentCanvas().addMouseListener(selectMoteMouseListener);
|
||||||
|
|
||||||
|
@ -218,35 +199,43 @@ public class UDGMVisualizerSkin implements VisualizerSkin {
|
||||||
visualizer.registerSimulationMenuAction(RangeMenuAction.class);
|
visualizer.registerSimulationMenuAction(RangeMenuAction.class);
|
||||||
visualizer.registerSimulationMenuAction(SuccessRatioMenuAction.class);
|
visualizer.registerSimulationMenuAction(SuccessRatioMenuAction.class);
|
||||||
|
|
||||||
/* Add (currently invisible) spinners */
|
/* UI components */
|
||||||
txCounter = new JLabel("TX: " + radioMedium.COUNTER_TX);
|
top = Box.createVerticalBox();
|
||||||
rxCounter = new JLabel("RX: " + radioMedium.COUNTER_RX);
|
top.setBorder(BorderFactory.createCompoundBorder(
|
||||||
interferedCounter = new JLabel("INT: " + + radioMedium.COUNTER_INTERFERED);
|
BorderFactory.createLineBorder(Color.BLACK),
|
||||||
visualizer.getCurrentCanvas().add(txCounter);
|
BorderFactory.createEmptyBorder(0, 3, 0, 3)));
|
||||||
visualizer.getCurrentCanvas().add(rxCounter);
|
top.setOpaque(true);
|
||||||
visualizer.getCurrentCanvas().add(interferedCounter);
|
top.setBackground(Color.LIGHT_GRAY);
|
||||||
|
|
||||||
visualizer.getCurrentCanvas().add(txRangeSpinner);
|
rangeTX = Box.createHorizontalBox();
|
||||||
visualizer.getCurrentCanvas().add(interferenceRangeSpinner);
|
rangeTX.add(new JLabel("TX range:"));
|
||||||
visualizer.getCurrentCanvas().add(successRatioTxSpinner);
|
rangeTX.add(Box.createHorizontalStrut(5));
|
||||||
visualizer.getCurrentCanvas().add(successRatioRxSpinner);
|
rangeTX.add(txRangeSpinner);
|
||||||
|
rangeINT = Box.createHorizontalBox();
|
||||||
|
rangeINT.add(new JLabel("INT range:"));
|
||||||
|
rangeINT.add(Box.createHorizontalStrut(5));
|
||||||
|
rangeINT.add(interferenceRangeSpinner);
|
||||||
|
ratioTX = Box.createHorizontalBox();
|
||||||
|
ratioTX.add(new JLabel("TX ratio:"));
|
||||||
|
ratioTX.add(Box.createHorizontalStrut(5));
|
||||||
|
ratioTX.add(successRatioTxSpinner);
|
||||||
|
ratioRX = Box.createHorizontalBox();
|
||||||
|
ratioRX.add(new JLabel("RX ratio:"));
|
||||||
|
ratioRX.add(Box.createHorizontalStrut(5));
|
||||||
|
ratioRX.add(successRatioRxSpinner);
|
||||||
|
|
||||||
/* Start observing radio medium */
|
rangeTX.setVisible(false);
|
||||||
radioMedium.addRadioMediumObserver(radioMediumObserver = new Observer() {
|
rangeINT.setVisible(false);
|
||||||
public void update(Observable obs, Object obj) {
|
ratioTX.setVisible(false);
|
||||||
if (txCounter != null) {
|
ratioRX.setVisible(false);
|
||||||
txCounter.setText("TX: " + radioMedium.COUNTER_TX);
|
top.setVisible(false);
|
||||||
}
|
|
||||||
if (rxCounter != null) {
|
|
||||||
rxCounter.setText("RX: " + radioMedium.COUNTER_RX);
|
|
||||||
}
|
|
||||||
if (interferedCounter != null) {
|
|
||||||
interferedCounter.setText("INT: " + + radioMedium.COUNTER_INTERFERED);
|
|
||||||
}
|
|
||||||
|
|
||||||
visualizer.repaint();
|
top.add(rangeTX);
|
||||||
}
|
top.add(rangeINT);
|
||||||
});
|
top.add(ratioTX);
|
||||||
|
top.add(ratioRX);
|
||||||
|
|
||||||
|
visualizer.getCurrentCanvas().add(top);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInactive() {
|
public void setInactive() {
|
||||||
|
@ -258,20 +247,8 @@ public class UDGMVisualizerSkin implements VisualizerSkin {
|
||||||
/* Remove mouse listener */
|
/* Remove mouse listener */
|
||||||
visualizer.getCurrentCanvas().removeMouseListener(selectMoteMouseListener);
|
visualizer.getCurrentCanvas().removeMouseListener(selectMoteMouseListener);
|
||||||
|
|
||||||
/* Stop observing radio medium */
|
/* Remove spinners etc */
|
||||||
radioMedium.deleteRadioMediumObserver(radioMediumObserver);
|
visualizer.getCurrentCanvas().remove(top);
|
||||||
radioMediumObserver = null;
|
|
||||||
radioMedium = null;
|
|
||||||
|
|
||||||
visualizer.getCurrentCanvas().remove(txCounter);
|
|
||||||
visualizer.getCurrentCanvas().remove(rxCounter);
|
|
||||||
visualizer.getCurrentCanvas().remove(interferedCounter);
|
|
||||||
|
|
||||||
/* Remove spinners */
|
|
||||||
visualizer.getCurrentCanvas().remove(txRangeSpinner);
|
|
||||||
visualizer.getCurrentCanvas().remove(interferenceRangeSpinner);
|
|
||||||
visualizer.getCurrentCanvas().remove(successRatioTxSpinner);
|
|
||||||
visualizer.getCurrentCanvas().remove(successRatioRxSpinner);
|
|
||||||
|
|
||||||
/* Unregister menu actions */
|
/* Unregister menu actions */
|
||||||
visualizer.unregisterSimulationMenuAction(RangeMenuAction.class);
|
visualizer.unregisterSimulationMenuAction(RangeMenuAction.class);
|
||||||
|
@ -279,155 +256,72 @@ public class UDGMVisualizerSkin implements VisualizerSkin {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Color[] getColorOf(Mote mote) {
|
public Color[] getColorOf(Mote mote) {
|
||||||
if (simulation == null) {
|
if (mote == selectedMote) {
|
||||||
/* Skin was never activated */
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mote.getState() == Mote.State.DEAD) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Radio moteRadio = mote.getInterfaces().getRadio();
|
|
||||||
if (moteRadio == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selectedMote != null && mote == selectedMote) {
|
|
||||||
return new Color[] { Color.CYAN };
|
return new Color[] { Color.CYAN };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!moteRadio.isReceiverOn()) {
|
|
||||||
return new Color[] { Color.GRAY };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (moteRadio.isTransmitting()) {
|
|
||||||
return new Color[] { Color.BLUE };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (moteRadio.isInterfered()) {
|
|
||||||
return new Color[] { Color.RED };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (moteRadio.isReceiving()) {
|
|
||||||
return new Color[] { Color.GREEN };
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Color COLOR_INTERFERENCE = new Color(
|
public void paintBeforeMotes(Graphics g) {
|
||||||
Color.DARK_GRAY.getRed(),
|
if (simulation == null
|
||||||
Color.DARK_GRAY.getGreen(),
|
|| selectedMote == null
|
||||||
Color.DARK_GRAY.getBlue(),
|
|| selectedMote.getInterfaces().getRadio() == null) {
|
||||||
100
|
|
||||||
);
|
|
||||||
private static Color COLOR_TX = new Color(
|
|
||||||
Color.GREEN.getRed(),
|
|
||||||
Color.GREEN.getGreen(),
|
|
||||||
Color.GREEN.getBlue(),
|
|
||||||
100
|
|
||||||
);
|
|
||||||
public void paintSkin(Graphics g) {
|
|
||||||
if (simulation == null) {
|
|
||||||
/* Skin was never activated */
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Paint transmission and interference range for select mote */
|
/* Paint transmission and interference range for selected mote */
|
||||||
if (selectedMote != null) {
|
Position motePos = selectedMote.getInterfaces().getPosition();
|
||||||
Graphics2D g2 = (Graphics2D) g;
|
|
||||||
Position motePos = selectedMote.getInterfaces().getPosition();
|
|
||||||
|
|
||||||
Point pixelCoord = visualizer.transformPositionToPixel(motePos);
|
Point pixelCoord = visualizer.transformPositionToPixel(motePos);
|
||||||
int x = pixelCoord.x;
|
int x = pixelCoord.x;
|
||||||
int y = pixelCoord.y;
|
int y = pixelCoord.y;
|
||||||
|
|
||||||
// Fetch current output power indicator (scale with as percent)
|
// Fetch current output power indicator (scale with as percent)
|
||||||
if (selectedMote.getInterfaces().getRadio() != null) {
|
Radio selectedRadio = selectedMote.getInterfaces().getRadio();
|
||||||
Radio selectedRadio = selectedMote.getInterfaces().getRadio();
|
double moteInterferenceRange =
|
||||||
double moteInterferenceRange =
|
radioMedium.INTERFERENCE_RANGE
|
||||||
radioMedium.INTERFERENCE_RANGE
|
* ((double) selectedRadio.getCurrentOutputPowerIndicator()
|
||||||
* ((double) selectedRadio.getCurrentOutputPowerIndicator()
|
/ (double) selectedRadio.getOutputPowerIndicatorMax());
|
||||||
/ (double) selectedRadio.getOutputPowerIndicatorMax());
|
double moteTransmissionRange =
|
||||||
double moteTransmissionRange =
|
radioMedium.TRANSMITTING_RANGE
|
||||||
radioMedium.TRANSMITTING_RANGE
|
* ((double) selectedRadio.getCurrentOutputPowerIndicator()
|
||||||
* ((double) selectedRadio.getCurrentOutputPowerIndicator()
|
/ (double) selectedRadio.getOutputPowerIndicatorMax());
|
||||||
/ (double) selectedRadio.getOutputPowerIndicatorMax());
|
|
||||||
|
|
||||||
Point translatedZero = visualizer.transformPositionToPixel(0.0, 0.0, 0.0);
|
Point translatedZero = visualizer.transformPositionToPixel(0.0, 0.0, 0.0);
|
||||||
Point translatedInterference = visualizer.transformPositionToPixel(moteInterferenceRange, moteInterferenceRange, 0.0);
|
Point translatedInterference = visualizer.transformPositionToPixel(moteInterferenceRange, moteInterferenceRange, 0.0);
|
||||||
Point translatedTransmission = visualizer.transformPositionToPixel(moteTransmissionRange, moteTransmissionRange, 0.0);
|
Point translatedTransmission = visualizer.transformPositionToPixel(moteTransmissionRange, moteTransmissionRange, 0.0);
|
||||||
|
|
||||||
translatedInterference.x = Math.abs(translatedInterference.x - translatedZero.x);
|
translatedInterference.x = Math.abs(translatedInterference.x - translatedZero.x);
|
||||||
translatedInterference.y = Math.abs(translatedInterference.y - translatedZero.y);
|
translatedInterference.y = Math.abs(translatedInterference.y - translatedZero.y);
|
||||||
translatedTransmission.x = Math.abs(translatedTransmission.x - translatedZero.x);
|
translatedTransmission.x = Math.abs(translatedTransmission.x - translatedZero.x);
|
||||||
translatedTransmission.y = Math.abs(translatedTransmission.y - translatedZero.y);
|
translatedTransmission.y = Math.abs(translatedTransmission.y - translatedZero.y);
|
||||||
|
|
||||||
/* Interference range */
|
/* Interference range */
|
||||||
g.setColor(COLOR_INTERFERENCE);
|
g.setColor(COLOR_INT);
|
||||||
g.fillOval(
|
g.fillOval(
|
||||||
x - translatedInterference.x,
|
x - translatedInterference.x,
|
||||||
y - translatedInterference.y,
|
y - translatedInterference.y,
|
||||||
2 * translatedInterference.x,
|
2 * translatedInterference.x,
|
||||||
2 * translatedInterference.y);
|
2 * translatedInterference.y);
|
||||||
|
|
||||||
/* Transmission range */
|
/* Transmission range */
|
||||||
g.setColor(COLOR_TX);
|
g.setColor(COLOR_TX);
|
||||||
g.fillOval(
|
g.fillOval(
|
||||||
x - translatedTransmission.x,
|
x - translatedTransmission.x,
|
||||||
y - translatedTransmission.y,
|
y - translatedTransmission.y,
|
||||||
2 * translatedTransmission.x,
|
2 * translatedTransmission.x,
|
||||||
2 * translatedTransmission.y);
|
2 * translatedTransmission.y);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Paint active connections in black */
|
public void paintAfterMotes(Graphics g) {
|
||||||
RadioConnection[] conns = radioMedium.getActiveConnections();
|
|
||||||
if (conns != null) {
|
|
||||||
g.setColor(Color.BLACK);
|
|
||||||
for (RadioConnection conn : conns) {
|
|
||||||
Radio source = conn.getSource();
|
|
||||||
Point sourcePoint = visualizer.transformPositionToPixel(source.getPosition());
|
|
||||||
for (Radio destRadio : conn.getDestinations()) {
|
|
||||||
Position destPos = destRadio.getPosition();
|
|
||||||
Point destPoint = visualizer.transformPositionToPixel(destPos);
|
|
||||||
g.drawLine(sourcePoint.x, sourcePoint.y, destPoint.x, destPoint.y);
|
|
||||||
|
|
||||||
/* Draw arrows */
|
|
||||||
if (DRAW_ARROWS) {
|
|
||||||
Point centerPoint = new Point(
|
|
||||||
destPoint.x/2 + sourcePoint.x/2,
|
|
||||||
destPoint.y/2 + sourcePoint.y/2
|
|
||||||
);
|
|
||||||
int startAngle = (int) (-180 * Math.atan2(destPoint.y - sourcePoint.y, destPoint.x - sourcePoint.x)/Math.PI - 90);
|
|
||||||
g.drawArc(centerPoint.x-5, centerPoint.y-5, 10, 10, startAngle, 180);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Paint past connections in gray */
|
|
||||||
/*conns = radioMedium.getLastTickConnections();
|
|
||||||
if (conns != null) {
|
|
||||||
g.setColor(Color.GRAY);
|
|
||||||
for (RadioConnection conn : conns) {
|
|
||||||
Point sourcePoint = visualizer.transformPositionToPixel(conn.getSource().getPosition());
|
|
||||||
for (Radio dest : conn.getDestinations()) {
|
|
||||||
Position destPos = dest.getPosition();
|
|
||||||
Point destPoint = visualizer.transformPositionToPixel(destPos);
|
|
||||||
g.drawLine(sourcePoint.x, sourcePoint.y, destPoint.x, destPoint.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RangeMenuAction implements SimulationMenuAction {
|
public static class RangeMenuAction implements SimulationMenuAction {
|
||||||
public boolean isEnabled(Simulation simulation) {
|
public boolean isEnabled(Visualizer visualizer, Simulation simulation) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDescription(Simulation simulation) {
|
public String getDescription(Visualizer visualizer, Simulation simulation) {
|
||||||
return "Change transmission ranges";
|
return "Change transmission ranges";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,8 +329,9 @@ public class UDGMVisualizerSkin implements VisualizerSkin {
|
||||||
VisualizerSkin[] skins = visualizer.getCurrentSkins();
|
VisualizerSkin[] skins = visualizer.getCurrentSkins();
|
||||||
for (VisualizerSkin skin: skins) {
|
for (VisualizerSkin skin: skins) {
|
||||||
if (skin instanceof UDGMVisualizerSkin) {
|
if (skin instanceof UDGMVisualizerSkin) {
|
||||||
((UDGMVisualizerSkin)skin).txRangeSpinner.setVisible(true);
|
((UDGMVisualizerSkin)skin).rangeTX.setVisible(true);
|
||||||
((UDGMVisualizerSkin)skin).interferenceRangeSpinner.setVisible(true);
|
((UDGMVisualizerSkin)skin).rangeINT.setVisible(true);
|
||||||
|
((UDGMVisualizerSkin)skin).top.setVisible(true);
|
||||||
visualizer.repaint();
|
visualizer.repaint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -444,11 +339,11 @@ public class UDGMVisualizerSkin implements VisualizerSkin {
|
||||||
};
|
};
|
||||||
|
|
||||||
public static class SuccessRatioMenuAction implements SimulationMenuAction {
|
public static class SuccessRatioMenuAction implements SimulationMenuAction {
|
||||||
public boolean isEnabled(Simulation simulation) {
|
public boolean isEnabled(Visualizer visualizer, Simulation simulation) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDescription(Simulation simulation) {
|
public String getDescription(Visualizer visualizer, Simulation simulation) {
|
||||||
return "Change TX/RX success ratio";
|
return "Change TX/RX success ratio";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,8 +351,9 @@ public class UDGMVisualizerSkin implements VisualizerSkin {
|
||||||
VisualizerSkin[] skins = visualizer.getCurrentSkins();
|
VisualizerSkin[] skins = visualizer.getCurrentSkins();
|
||||||
for (VisualizerSkin skin: skins) {
|
for (VisualizerSkin skin: skins) {
|
||||||
if (skin instanceof UDGMVisualizerSkin) {
|
if (skin instanceof UDGMVisualizerSkin) {
|
||||||
((UDGMVisualizerSkin)skin).successRatioTxSpinner.setVisible(true);
|
((UDGMVisualizerSkin)skin).ratioTX.setVisible(true);
|
||||||
((UDGMVisualizerSkin)skin).successRatioRxSpinner.setVisible(true);
|
((UDGMVisualizerSkin)skin).ratioRX.setVisible(true);
|
||||||
|
((UDGMVisualizerSkin)skin).top.setVisible(true);
|
||||||
visualizer.repaint();
|
visualizer.repaint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue