added powertracker plugin as default cooja plugin. the powertracker plugin was previously available via contiki projects.
This commit is contained in:
parent
cac4e9a222
commit
6dd1c42e8d
8 changed files with 574 additions and 5 deletions
43
tools/cooja/apps/powertracker/build.xml
Normal file
43
tools/cooja/apps/powertracker/build.xml
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<project name="Cooja: Power Tracker" default="jar" basedir=".">
|
||||||
|
<property name="cooja" location="../.."/>
|
||||||
|
<property name="cooja_jar" value="${cooja}/dist/cooja.jar"/>
|
||||||
|
|
||||||
|
<available file="${cooja_jar}" type="file" property="cooja_jar_exists"/>
|
||||||
|
<fail message="COOJA jar not found at '${cooja_jar}'. Please compile COOJA first." unless="cooja_jar_exists"/>
|
||||||
|
|
||||||
|
<target name="init">
|
||||||
|
<tstamp/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="compile" depends="init">
|
||||||
|
<mkdir dir="build"/>
|
||||||
|
<javac srcdir="java" destdir="build" debug="on" includeantruntime="false">
|
||||||
|
<classpath>
|
||||||
|
<pathelement path="."/>
|
||||||
|
<pathelement location="${cooja_jar}"/>
|
||||||
|
</classpath>
|
||||||
|
</javac>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="clean" depends="init">
|
||||||
|
<delete dir="build"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="jar" depends="clean, init, compile">
|
||||||
|
<mkdir dir="lib"/>
|
||||||
|
<jar destfile="lib/powertracker.jar" basedir="build">
|
||||||
|
<manifest>
|
||||||
|
<attribute name="Class-Path" value="."/>
|
||||||
|
</manifest>
|
||||||
|
</jar>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="jar_and_cooja_run">
|
||||||
|
<ant antfile="build.xml" dir="${cooja}" target="jar" inheritAll="false"/>
|
||||||
|
<ant antfile="build.xml" dir="." target="jar" inheritAll="false"/>
|
||||||
|
<ant antfile="build.xml" dir="${cooja}" target="run" inheritAll="false"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
</project>
|
2
tools/cooja/apps/powertracker/cooja.config
Normal file
2
tools/cooja/apps/powertracker/cooja.config
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
se.sics.cooja.GUI.PLUGINS = + PowerTracker
|
||||||
|
se.sics.cooja.GUI.JARFILES = + powertracker.jar
|
524
tools/cooja/apps/powertracker/java/PowerTracker.java
Normal file
524
tools/cooja/apps/powertracker/java/PowerTracker.java
Normal file
|
@ -0,0 +1,524 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.datatransfer.Clipboard;
|
||||||
|
import java.awt.datatransfer.StringSelection;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Observable;
|
||||||
|
import java.util.Observer;
|
||||||
|
|
||||||
|
import javax.swing.AbstractAction;
|
||||||
|
import javax.swing.Action;
|
||||||
|
import javax.swing.Box;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JTable;
|
||||||
|
import javax.swing.Timer;
|
||||||
|
import javax.swing.table.AbstractTableModel;
|
||||||
|
import javax.swing.table.DefaultTableCellRenderer;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.jdom.Element;
|
||||||
|
|
||||||
|
import se.sics.cooja.ClassDescription;
|
||||||
|
import se.sics.cooja.GUI;
|
||||||
|
import se.sics.cooja.Mote;
|
||||||
|
import se.sics.cooja.PluginType;
|
||||||
|
import se.sics.cooja.SimEventCentral.MoteCountListener;
|
||||||
|
import se.sics.cooja.Simulation;
|
||||||
|
import se.sics.cooja.VisPlugin;
|
||||||
|
import se.sics.cooja.interfaces.Radio;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks radio events to sum up transmission, reception, and radio on times.
|
||||||
|
* This plugin can be run without visualization, i.e. from a Contiki test.
|
||||||
|
*
|
||||||
|
* @author Fredrik Osterlind, Adam Dunkels
|
||||||
|
*/
|
||||||
|
@ClassDescription("PowerTracker")
|
||||||
|
@PluginType(PluginType.SIM_PLUGIN)
|
||||||
|
public class PowerTracker extends VisPlugin {
|
||||||
|
private static Logger logger = Logger.getLogger(PowerTracker.class);
|
||||||
|
|
||||||
|
private static final int POWERTRACKER_UPDATE_INTERVAL = 100; /* ms */
|
||||||
|
|
||||||
|
private static final int COLUMN_MOTE = 0;
|
||||||
|
private static final int COLUMN_RADIOON = 1;
|
||||||
|
private static final int COLUMN_RADIOTX = 2;
|
||||||
|
private static final int COLUMN_RADIORX = 3;
|
||||||
|
|
||||||
|
private Simulation simulation;
|
||||||
|
private MoteCountListener moteCountListener;
|
||||||
|
private ArrayList<MoteTracker> moteTrackers = new ArrayList<MoteTracker>();
|
||||||
|
|
||||||
|
private JTable table;
|
||||||
|
private int tableMaxRadioOnIndex = -1;
|
||||||
|
|
||||||
|
public PowerTracker(final Simulation simulation, final GUI gui) {
|
||||||
|
super("PowerTracker", gui, false);
|
||||||
|
this.simulation = simulation;
|
||||||
|
|
||||||
|
/* Automatically add/delete motes */
|
||||||
|
simulation.getEventCentral().addMoteCountListener(moteCountListener = new MoteCountListener() {
|
||||||
|
public void moteWasAdded(Mote mote) {
|
||||||
|
addMote(mote);
|
||||||
|
table.invalidate();
|
||||||
|
table.repaint();
|
||||||
|
}
|
||||||
|
public void moteWasRemoved(Mote mote) {
|
||||||
|
removeMote(mote);
|
||||||
|
table.invalidate();
|
||||||
|
table.repaint();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
for (Mote m: simulation.getMotes()) {
|
||||||
|
addMote(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GUI.isVisualized()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractTableModel model = new AbstractTableModel() {
|
||||||
|
public int getRowCount() {
|
||||||
|
return moteTrackers.size()+1;
|
||||||
|
}
|
||||||
|
public int getColumnCount() {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
public String getColumnName(int col) {
|
||||||
|
if (col == COLUMN_MOTE) {
|
||||||
|
return "Mote";
|
||||||
|
}
|
||||||
|
if (col == COLUMN_RADIOON) {
|
||||||
|
return "Radio on (%)";
|
||||||
|
}
|
||||||
|
if (col == COLUMN_RADIOTX) {
|
||||||
|
return "Radio TX (%)";
|
||||||
|
}
|
||||||
|
if (col == COLUMN_RADIORX) {
|
||||||
|
return "Radio RX (%)";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public Object getValueAt(int rowIndex, int col) {
|
||||||
|
if (rowIndex < 0 || rowIndex >= moteTrackers.size()+1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rowIndex == moteTrackers.size()) {
|
||||||
|
/* Average */
|
||||||
|
long radioOn = 0;
|
||||||
|
long radioTx = 0;
|
||||||
|
long radioRx = 0;
|
||||||
|
long duration = 0;
|
||||||
|
for (MoteTracker mt: moteTrackers) {
|
||||||
|
radioOn += mt.radioOn;
|
||||||
|
radioTx += mt.radioTx;
|
||||||
|
radioRx += mt.radioRx;
|
||||||
|
|
||||||
|
duration += mt.duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (col == COLUMN_MOTE) {
|
||||||
|
return "AVERAGE";
|
||||||
|
}
|
||||||
|
if (col == COLUMN_RADIOON) {
|
||||||
|
return String.format("%2.2f%%", 100.0*radioOn/duration);
|
||||||
|
}
|
||||||
|
if (col == COLUMN_RADIOTX) {
|
||||||
|
return String.format("%2.2f%%", 100.0*radioTx/duration);
|
||||||
|
}
|
||||||
|
if (col == COLUMN_RADIORX) {
|
||||||
|
return String.format("%2.2f%%", 100.0*radioRx/duration);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
MoteTracker rule = moteTrackers.get(rowIndex);
|
||||||
|
if (col == COLUMN_MOTE) {
|
||||||
|
return rule.mote.toString();
|
||||||
|
}
|
||||||
|
if (col == COLUMN_RADIOON) {
|
||||||
|
return String.format("%2.2f%%", 100.0*rule.getRadioOnRatio());
|
||||||
|
}
|
||||||
|
if (col == COLUMN_RADIOTX) {
|
||||||
|
return String.format("%2.2f%%", 100.0*rule.getRadioTxRatio());
|
||||||
|
}
|
||||||
|
if (col == COLUMN_RADIORX) {
|
||||||
|
return String.format("%2.2f%%", 100.0*rule.getRadioRxRatio());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
table = new JTable(model) {
|
||||||
|
public String getToolTipText(MouseEvent e) {
|
||||||
|
java.awt.Point p = e.getPoint();
|
||||||
|
int rowIndex = table.rowAtPoint(p);
|
||||||
|
if (rowIndex < 0 || rowIndex >= moteTrackers.size()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
MoteTracker mt = moteTrackers.get(rowIndex);
|
||||||
|
return "<html><pre>" + mt.toString() + "</html>";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {
|
||||||
|
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
|
||||||
|
Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
||||||
|
if (row == tableMaxRadioOnIndex) {
|
||||||
|
setBackground(isSelected ? table.getSelectionBackground():Color.RED);
|
||||||
|
setForeground(isSelected ? table.getSelectionForeground():Color.WHITE);
|
||||||
|
} else {
|
||||||
|
setBackground(isSelected ? table.getSelectionBackground():table.getBackground());
|
||||||
|
setForeground(isSelected ? table.getSelectionForeground():table.getForeground());
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Box control = Box.createHorizontalBox();
|
||||||
|
control.add(Box.createHorizontalGlue());
|
||||||
|
control.add(new JButton(printAction));
|
||||||
|
control.add(new JButton(resetAction));
|
||||||
|
|
||||||
|
this.getContentPane().add(BorderLayout.CENTER, new JScrollPane(table));
|
||||||
|
this.getContentPane().add(BorderLayout.SOUTH, control);
|
||||||
|
setSize(400, 400);
|
||||||
|
|
||||||
|
repaintTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Action resetAction = new AbstractAction("Reset") {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
Runnable r = new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (simulation.isRunning()) {
|
||||||
|
simulation.invokeSimulationThread(r);
|
||||||
|
} else {
|
||||||
|
r.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private Action printAction = new AbstractAction("Print to console/Copy to clipboard") {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
String output = radioStatistics(true, true, false);
|
||||||
|
logger.info("PowerTracker output:\n\n" + output);
|
||||||
|
|
||||||
|
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||||
|
StringSelection stringSelection = new StringSelection(output);
|
||||||
|
clipboard.setContents(stringSelection, null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public String radioStatistics() {
|
||||||
|
return radioStatistics(true, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String radioStatistics(boolean radioHW, boolean radioRXTX, boolean onlyAverage) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
/* Average */
|
||||||
|
long radioOn = 0;
|
||||||
|
long radioTx = 0;
|
||||||
|
long radioRx = 0;
|
||||||
|
long radioInterfered = 0;
|
||||||
|
long duration = 0;
|
||||||
|
for (MoteTracker mt: moteTrackers) {
|
||||||
|
radioOn += mt.radioOn;
|
||||||
|
radioTx += mt.radioTx;
|
||||||
|
radioRx += mt.radioRx;
|
||||||
|
radioInterfered += mt.radioInterfered;
|
||||||
|
|
||||||
|
duration += mt.duration;
|
||||||
|
}
|
||||||
|
if (radioHW) {
|
||||||
|
sb.append(String.format("AVG" + " ON " + (radioOn + " us ") + "%2.2f %%", 100.0*radioOn/duration) + "\n");
|
||||||
|
}
|
||||||
|
if (radioRXTX) {
|
||||||
|
sb.append(String.format("AVG" + " TX " + (radioTx + " us ") + "%2.2f %%", 100.0*radioTx/duration) + "\n");
|
||||||
|
sb.append(String.format("AVG" + " RX " + (radioRx + " us ") + "%2.2f %%", 100.0*radioRx/duration) + "\n");
|
||||||
|
sb.append(String.format("AVG" + " INT " + (radioInterfered + " us ") + "%2.2f %%", 100.0*radioInterfered/duration) + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onlyAverage) {
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (MoteTracker mt: moteTrackers) {
|
||||||
|
sb.append(mt.toString(radioHW, radioRXTX));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class MoteTracker implements Observer {
|
||||||
|
/* last radio state */
|
||||||
|
private boolean radioWasOn;
|
||||||
|
private RadioState lastRadioState;
|
||||||
|
private long lastUpdateTime;
|
||||||
|
|
||||||
|
/* accumulating radio state durations */
|
||||||
|
long duration = 0;
|
||||||
|
long radioOn = 0;
|
||||||
|
long radioTx = 0;
|
||||||
|
long radioRx = 0;
|
||||||
|
long radioInterfered = 0;
|
||||||
|
|
||||||
|
private Simulation simulation;
|
||||||
|
private Mote mote;
|
||||||
|
private Radio radio;
|
||||||
|
|
||||||
|
public MoteTracker(Mote mote) {
|
||||||
|
this.simulation = mote.getSimulation();
|
||||||
|
this.mote = mote;
|
||||||
|
this.radio = mote.getInterfaces().getRadio();
|
||||||
|
|
||||||
|
radioWasOn = radio.isReceiverOn();
|
||||||
|
if (radio.isTransmitting()) {
|
||||||
|
lastRadioState = RadioState.TRANSMITTING;
|
||||||
|
} else if (radio.isReceiving()) {
|
||||||
|
lastRadioState = RadioState.RECEIVING;
|
||||||
|
} else if (radio.isInterfered()){
|
||||||
|
lastRadioState = RadioState.INTERFERED;
|
||||||
|
} else {
|
||||||
|
lastRadioState = RadioState.IDLE;
|
||||||
|
}
|
||||||
|
lastUpdateTime = simulation.getSimulationTime();
|
||||||
|
|
||||||
|
radio.addObserver(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(Observable o, Object arg) {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
public void update() {
|
||||||
|
long now = simulation.getSimulationTime();
|
||||||
|
|
||||||
|
accumulateDuration(now - lastUpdateTime);
|
||||||
|
|
||||||
|
/* Radio on/off */
|
||||||
|
if (radioWasOn) {
|
||||||
|
accumulateRadioOn(now - lastUpdateTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Radio tx/rx */
|
||||||
|
if (lastRadioState == RadioState.TRANSMITTING) {
|
||||||
|
accumulateRadioTx(now - lastUpdateTime);
|
||||||
|
} else if (lastRadioState == RadioState.RECEIVING) {
|
||||||
|
accumulateRadioRx(now - lastUpdateTime);
|
||||||
|
} else if (lastRadioState == RadioState.INTERFERED) {
|
||||||
|
accumulateRadioIntefered(now - lastUpdateTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Await next radio event */
|
||||||
|
if (radio.isTransmitting()) {
|
||||||
|
lastRadioState = RadioState.TRANSMITTING;
|
||||||
|
} else if (!radio.isReceiverOn()) {
|
||||||
|
lastRadioState = RadioState.IDLE;
|
||||||
|
} else if (radio.isInterfered()) {
|
||||||
|
lastRadioState = RadioState.INTERFERED;
|
||||||
|
} else if (radio.isReceiving()) {
|
||||||
|
lastRadioState = RadioState.RECEIVING;
|
||||||
|
} else {
|
||||||
|
lastRadioState = RadioState.IDLE;
|
||||||
|
}
|
||||||
|
radioWasOn = radio.isReceiverOn();
|
||||||
|
lastUpdateTime = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void accumulateDuration(long t) {
|
||||||
|
duration += t;
|
||||||
|
}
|
||||||
|
protected void accumulateRadioOn(long t) {
|
||||||
|
radioOn += t;
|
||||||
|
}
|
||||||
|
protected void accumulateRadioTx(long t) {
|
||||||
|
radioTx += t;
|
||||||
|
}
|
||||||
|
protected void accumulateRadioRx(long t) {
|
||||||
|
radioRx += t;
|
||||||
|
}
|
||||||
|
protected void accumulateRadioIntefered(long t) {
|
||||||
|
radioInterfered += t;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected double getRadioOnRatio() {
|
||||||
|
return 1.0*radioOn/duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected double getRadioTxRatio() {
|
||||||
|
return 1.0*radioTx/duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected double getRadioInterferedRatio() {
|
||||||
|
return 1.0*radioInterfered/duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected double getRadioRxRatio() {
|
||||||
|
return 1.0*radioRx/duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mote getMote() {
|
||||||
|
return mote;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dispose() {
|
||||||
|
radio.deleteObserver(this);
|
||||||
|
radio = null;
|
||||||
|
mote = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return toString(true, true);
|
||||||
|
}
|
||||||
|
public String toString(boolean radioHW, boolean radioRXTX) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
String moteString = mote.toString().replace(' ', '_');
|
||||||
|
|
||||||
|
sb.append(moteString + " MONITORED " + duration + " us\n");
|
||||||
|
if (radioHW) {
|
||||||
|
sb.append(String.format(moteString + " ON " + (radioOn + " us ") + "%2.2f %%", 100.0*getRadioOnRatio()) + "\n");
|
||||||
|
}
|
||||||
|
if (radioRXTX) {
|
||||||
|
sb.append(String.format(moteString + " TX " + (radioTx + " us ") + "%2.2f %%", 100.0*getRadioTxRatio()) + "\n");
|
||||||
|
sb.append(String.format(moteString + " RX " + (radioRx + " us ") + "%2.2f %%", 100.0*getRadioRxRatio()) + "\n");
|
||||||
|
sb.append(String.format(moteString + " INT " + (radioInterfered + " us ") + "%2.2f %%", 100.0*getRadioInterferedRatio()) + "\n");
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MoteTracker createMoteTracker(Mote mote) {
|
||||||
|
final Radio moteRadio = mote.getInterfaces().getRadio();
|
||||||
|
if (moteRadio == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Radio observer */
|
||||||
|
MoteTracker tracker = new MoteTracker(mote);
|
||||||
|
tracker.update(null, null);
|
||||||
|
return tracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
while (moteTrackers.size() > 0) {
|
||||||
|
removeMote(moteTrackers.get(0).mote);
|
||||||
|
}
|
||||||
|
for (Mote m: simulation.getMotes()) {
|
||||||
|
addMote(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addMote(Mote mote) {
|
||||||
|
if (mote == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MoteTracker t = createMoteTracker(mote);
|
||||||
|
if (t != null) {
|
||||||
|
moteTrackers.add(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTitle("PowerTracker: " + moteTrackers.size() + " motes");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeMote(Mote mote) {
|
||||||
|
/* Remove mote tracker(s) */
|
||||||
|
MoteTracker[] trackers = moteTrackers.toArray(new MoteTracker[0]);
|
||||||
|
for (MoteTracker t: trackers) {
|
||||||
|
if (t.getMote() == mote) {
|
||||||
|
t.dispose();
|
||||||
|
moteTrackers.remove(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setTitle("PowerTracker: " + moteTrackers.size() + " motes");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closePlugin() {
|
||||||
|
/* Remove repaint timer */
|
||||||
|
repaintTimer.stop();
|
||||||
|
|
||||||
|
simulation.getEventCentral().removeMoteCountListener(moteCountListener);
|
||||||
|
|
||||||
|
/* Remove mote trackers */
|
||||||
|
for (Mote m: simulation.getMotes()) {
|
||||||
|
removeMote(m);
|
||||||
|
}
|
||||||
|
if (!moteTrackers.isEmpty()) {
|
||||||
|
logger.fatal("Mote observers not cleaned up correctly");
|
||||||
|
for (MoteTracker t: moteTrackers.toArray(new MoteTracker[0])) {
|
||||||
|
t.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum RadioState {
|
||||||
|
IDLE, RECEIVING, TRANSMITTING, INTERFERED
|
||||||
|
}
|
||||||
|
|
||||||
|
private Timer repaintTimer = new Timer(POWERTRACKER_UPDATE_INTERVAL, new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
/* Identify max radio on */
|
||||||
|
double maxRadioOn = 0;
|
||||||
|
int maxRadioOnIndex = -1;
|
||||||
|
for (int i=0; i < moteTrackers.size(); i++) {
|
||||||
|
MoteTracker mt = moteTrackers.get(i);
|
||||||
|
if (mt.getRadioOnRatio() > maxRadioOn) {
|
||||||
|
maxRadioOn = mt.getRadioOnRatio();
|
||||||
|
maxRadioOnIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (maxRadioOnIndex >= 0) {
|
||||||
|
tableMaxRadioOnIndex = maxRadioOnIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.repaint();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
public Collection<Element> getConfigXML() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public boolean setConfigXML(Collection<Element> configXML, boolean visAvailable) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -22,7 +22,7 @@ AR_COMMAND_2 =
|
||||||
CONTIKI_STANDARD_PROCESSES = sensors_process;etimer_process
|
CONTIKI_STANDARD_PROCESSES = sensors_process;etimer_process
|
||||||
CORECOMM_TEMPLATE_FILENAME = corecomm_template.java
|
CORECOMM_TEMPLATE_FILENAME = corecomm_template.java
|
||||||
PATH_JAVAC = javac
|
PATH_JAVAC = javac
|
||||||
DEFAULT_PROJECTDIRS = [CONTIKI_DIR]/tools/cooja/apps/mrm;[CONTIKI_DIR]/tools/cooja/apps/mspsim;[CONTIKI_DIR]/tools/cooja/apps/avrora;[CONTIKI_DIR]/tools/cooja/apps/serial_socket;[CONTIKI_DIR]/tools/cooja/apps/collect-view
|
DEFAULT_PROJECTDIRS = [CONTIKI_DIR]/tools/cooja/apps/mrm;[CONTIKI_DIR]/tools/cooja/apps/mspsim;[CONTIKI_DIR]/tools/cooja/apps/avrora;[CONTIKI_DIR]/tools/cooja/apps/serial_socket;[CONTIKI_DIR]/tools/cooja/apps/collect-view;[CONTIKI_DIR]/tools/cooja/apps/powertracker
|
||||||
|
|
||||||
PARSE_WITH_COMMAND=false
|
PARSE_WITH_COMMAND=false
|
||||||
PARSE_COMMAND=nm -a $(LIBFILE)
|
PARSE_COMMAND=nm -a $(LIBFILE)
|
||||||
|
|
|
@ -22,7 +22,7 @@ AR_COMMAND_2 =
|
||||||
CONTIKI_STANDARD_PROCESSES = sensors_process;etimer_process
|
CONTIKI_STANDARD_PROCESSES = sensors_process;etimer_process
|
||||||
CORECOMM_TEMPLATE_FILENAME = corecomm_template.java
|
CORECOMM_TEMPLATE_FILENAME = corecomm_template.java
|
||||||
PATH_JAVAC = javac
|
PATH_JAVAC = javac
|
||||||
DEFAULT_PROJECTDIRS = [CONTIKI_DIR]/tools/cooja/apps/mrm;[CONTIKI_DIR]/tools/cooja/apps/mspsim;[CONTIKI_DIR]/tools/cooja/apps/avrora;[CONTIKI_DIR]/tools/cooja/apps/serial_socket;[CONTIKI_DIR]/tools/cooja/apps/collect-view
|
DEFAULT_PROJECTDIRS = [CONTIKI_DIR]/tools/cooja/apps/mrm;[CONTIKI_DIR]/tools/cooja/apps/mspsim;[CONTIKI_DIR]/tools/cooja/apps/avrora;[CONTIKI_DIR]/tools/cooja/apps/serial_socket;[CONTIKI_DIR]/tools/cooja/apps/collect-view;[CONTIKI_DIR]/tools/cooja/apps/powertracker
|
||||||
|
|
||||||
PARSE_WITH_COMMAND=false
|
PARSE_WITH_COMMAND=false
|
||||||
PARSE_COMMAND=nm -a $(LIBFILE)
|
PARSE_COMMAND=nm -a $(LIBFILE)
|
||||||
|
|
|
@ -22,7 +22,7 @@ AR_COMMAND_2 =
|
||||||
CONTIKI_STANDARD_PROCESSES = sensors_process;etimer_process
|
CONTIKI_STANDARD_PROCESSES = sensors_process;etimer_process
|
||||||
CORECOMM_TEMPLATE_FILENAME = corecomm_template.java
|
CORECOMM_TEMPLATE_FILENAME = corecomm_template.java
|
||||||
PATH_JAVAC = javac
|
PATH_JAVAC = javac
|
||||||
DEFAULT_PROJECTDIRS = [CONTIKI_DIR]/tools/cooja/apps/mrm;[CONTIKI_DIR]/tools/cooja/apps/mspsim;[CONTIKI_DIR]/tools/cooja/apps/avrora;[CONTIKI_DIR]/tools/cooja/apps/serial_socket;[CONTIKI_DIR]/tools/cooja/apps/collect-view
|
DEFAULT_PROJECTDIRS = [CONTIKI_DIR]/tools/cooja/apps/mrm;[CONTIKI_DIR]/tools/cooja/apps/mspsim;[CONTIKI_DIR]/tools/cooja/apps/avrora;[CONTIKI_DIR]/tools/cooja/apps/serial_socket;[CONTIKI_DIR]/tools/cooja/apps/collect-view;[CONTIKI_DIR]/tools/cooja/apps/powertracker
|
||||||
|
|
||||||
PARSE_WITH_COMMAND=false
|
PARSE_WITH_COMMAND=false
|
||||||
PARSE_COMMAND=nm -a $(LIBFILE)
|
PARSE_COMMAND=nm -a $(LIBFILE)
|
||||||
|
|
|
@ -22,7 +22,7 @@ AR_COMMAND_2 =
|
||||||
CONTIKI_STANDARD_PROCESSES = sensors_process;etimer_process
|
CONTIKI_STANDARD_PROCESSES = sensors_process;etimer_process
|
||||||
CORECOMM_TEMPLATE_FILENAME = corecomm_template.java
|
CORECOMM_TEMPLATE_FILENAME = corecomm_template.java
|
||||||
PATH_JAVAC = javac
|
PATH_JAVAC = javac
|
||||||
DEFAULT_PROJECTDIRS = [CONTIKI_DIR]/tools/cooja/apps/mrm;[CONTIKI_DIR]/tools/cooja/apps/mspsim;[CONTIKI_DIR]/tools/cooja/apps/avrora;[CONTIKI_DIR]/tools/cooja/apps/serial_socket;[CONTIKI_DIR]/tools/cooja/apps/collect-view
|
DEFAULT_PROJECTDIRS = [CONTIKI_DIR]/tools/cooja/apps/mrm;[CONTIKI_DIR]/tools/cooja/apps/mspsim;[CONTIKI_DIR]/tools/cooja/apps/avrora;[CONTIKI_DIR]/tools/cooja/apps/serial_socket;[CONTIKI_DIR]/tools/cooja/apps/collect-view;[CONTIKI_DIR]/tools/cooja/apps/powertracker
|
||||||
|
|
||||||
PARSE_WITH_COMMAND = true
|
PARSE_WITH_COMMAND = true
|
||||||
PARSE_COMMAND = /opt/contiki-2.x/tools/cooja/examples/jni_test/mac_users/nmandsize $(LIBFILE)
|
PARSE_COMMAND = /opt/contiki-2.x/tools/cooja/examples/jni_test/mac_users/nmandsize $(LIBFILE)
|
||||||
|
|
|
@ -22,7 +22,7 @@ AR_COMMAND_2 =
|
||||||
CONTIKI_STANDARD_PROCESSES = sensors_process;etimer_process
|
CONTIKI_STANDARD_PROCESSES = sensors_process;etimer_process
|
||||||
CORECOMM_TEMPLATE_FILENAME = corecomm_template.java
|
CORECOMM_TEMPLATE_FILENAME = corecomm_template.java
|
||||||
PATH_JAVAC = javac
|
PATH_JAVAC = javac
|
||||||
DEFAULT_PROJECTDIRS = [CONTIKI_DIR]/tools/cooja/apps/mrm;[CONTIKI_DIR]/tools/cooja/apps/mspsim;[CONTIKI_DIR]/tools/cooja/apps/avrora;[CONTIKI_DIR]/tools/cooja/apps/serial_socket;[CONTIKI_DIR]/tools/cooja/apps/collect-view
|
DEFAULT_PROJECTDIRS = [CONTIKI_DIR]/tools/cooja/apps/mrm;[CONTIKI_DIR]/tools/cooja/apps/mspsim;[CONTIKI_DIR]/tools/cooja/apps/avrora;[CONTIKI_DIR]/tools/cooja/apps/serial_socket;[CONTIKI_DIR]/tools/cooja/apps/collect-view;[CONTIKI_DIR]/tools/cooja/apps/powertracker
|
||||||
|
|
||||||
PARSE_WITH_COMMAND = true
|
PARSE_WITH_COMMAND = true
|
||||||
PARSE_COMMAND=nm -n -C $(LIBFILE)
|
PARSE_COMMAND=nm -n -C $(LIBFILE)
|
||||||
|
|
Loading…
Reference in a new issue