Merge pull request #979 from TheGeorge/drifting-motes
Time Drifting Motes
This commit is contained in:
commit
9261ff5d13
|
@ -44,6 +44,7 @@ import org.contikios.cooja.MoteType;
|
|||
import org.contikios.cooja.Simulation;
|
||||
import org.contikios.cooja.mote.memory.MemoryInterface;
|
||||
import org.contikios.cooja.motes.AbstractEmulatedMote;
|
||||
|
||||
import avrora.arch.avr.AVRProperties;
|
||||
import avrora.core.LoadableProgram;
|
||||
import avrora.sim.AtmelInterpreter;
|
||||
|
@ -54,6 +55,8 @@ import avrora.sim.mcu.EEPROM;
|
|||
import avrora.sim.platform.MicaZ;
|
||||
import avrora.sim.platform.PlatformFactory;
|
||||
|
||||
import org.contikios.cooja.avrmote.interfaces.MicaClock;
|
||||
|
||||
/**
|
||||
* @author Joakim Eriksson, Fredrik Osterlind
|
||||
*/
|
||||
|
@ -74,6 +77,10 @@ public class MicaZMote extends AbstractEmulatedMote implements Mote {
|
|||
|
||||
private EEPROM eeprom = null;
|
||||
|
||||
private long executed = 0;
|
||||
private long skipped = 0;
|
||||
|
||||
|
||||
/* Stack monitoring variables */
|
||||
private boolean stopNextInstruction = false;
|
||||
|
||||
|
@ -184,6 +191,10 @@ public class MicaZMote extends AbstractEmulatedMote implements Mote {
|
|||
private long cyclesExecuted = 0;
|
||||
private long cyclesUntil = 0;
|
||||
public void execute(long t) {
|
||||
MicaClock clock = ((MicaClock) (myMoteInterfaceHandler.getClock()));
|
||||
double deviation = clock.getDeviation();
|
||||
long drift = clock.getDrift();
|
||||
|
||||
/* Wait until mote boots */
|
||||
if (myMoteInterfaceHandler.getClock().getTime() < 0) {
|
||||
scheduleNextWakeup(t - myMoteInterfaceHandler.getClock().getTime());
|
||||
|
@ -197,12 +208,21 @@ public class MicaZMote extends AbstractEmulatedMote implements Mote {
|
|||
|
||||
/* TODO Poll mote interfaces? */
|
||||
|
||||
/* skip if necessary */
|
||||
if (((1-deviation) * executed) > skipped) {
|
||||
skipped += 1;
|
||||
scheduleNextWakeup(t + Simulation.MILLISECOND);
|
||||
}
|
||||
|
||||
/* Execute one millisecond */
|
||||
cyclesUntil += NR_CYCLES_PER_MSEC;
|
||||
while (cyclesExecuted < cyclesUntil) {
|
||||
cyclesExecuted += interpreter.step();
|
||||
}
|
||||
|
||||
/* book keeping */
|
||||
executed += 1;
|
||||
|
||||
/* TODO Poll mote interfaces? */
|
||||
|
||||
/* Schedule wakeup every millisecond */
|
||||
|
|
|
@ -54,10 +54,12 @@ public class MicaClock extends Clock {
|
|||
private MicaZMote myMote;
|
||||
|
||||
private long timeDrift; /* Microseconds */
|
||||
private double deviation;
|
||||
|
||||
public MicaClock(Mote mote) {
|
||||
simulation = mote.getSimulation();
|
||||
myMote = (MicaZMote) mote;
|
||||
deviation = 1.0;
|
||||
}
|
||||
|
||||
public void setTime(long newTime) {
|
||||
|
@ -68,6 +70,15 @@ public class MicaClock extends Clock {
|
|||
return simulation.getSimulationTime() + timeDrift;
|
||||
}
|
||||
|
||||
public double getDeviation() {
|
||||
return deviation;
|
||||
}
|
||||
|
||||
public void setDeviation(double deviation) {
|
||||
assert (deviation>0.0) && (deviation<=1.0);
|
||||
this.deviation = deviation;
|
||||
}
|
||||
|
||||
public void setDrift(long drift) {
|
||||
timeDrift = drift;
|
||||
}
|
||||
|
@ -75,19 +86,4 @@ public class MicaClock extends Clock {
|
|||
public long getDrift() {
|
||||
return timeDrift;
|
||||
}
|
||||
|
||||
public JPanel getInterfaceVisualizer() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void releaseInterfaceVisualizer(JPanel panel) {
|
||||
}
|
||||
|
||||
public Collection<Element> getConfigXML() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setConfigXML(Collection<Element> configXML, boolean visAvailable) {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -78,6 +78,8 @@ import se.sics.mspsim.util.MapEntry;
|
|||
import se.sics.mspsim.util.MapTable;
|
||||
import se.sics.mspsim.profiler.SimpleProfiler;
|
||||
|
||||
import org.contikios.cooja.mspmote.interfaces.MspClock;
|
||||
|
||||
/**
|
||||
* @author Fredrik Osterlind
|
||||
*/
|
||||
|
@ -288,13 +290,22 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
|
|||
|
||||
private long lastExecute = -1; /* Last time mote executed */
|
||||
private long nextExecute;
|
||||
|
||||
private long executed = 0;
|
||||
private long skipped = 0;
|
||||
|
||||
public void execute(long time) {
|
||||
execute(time, EXECUTE_DURATION_US);
|
||||
}
|
||||
|
||||
public void execute(long t, int duration) {
|
||||
MspClock clock = ((MspClock) (myMoteInterfaceHandler.getClock()));
|
||||
double deviation = clock.getDeviation();
|
||||
long drift = clock.getDrift();
|
||||
|
||||
/* Wait until mote boots */
|
||||
if (!booted && myMoteInterfaceHandler.getClock().getTime() < 0) {
|
||||
scheduleNextWakeup(t - myMoteInterfaceHandler.getClock().getTime());
|
||||
if (!booted && clock.getTime() < 0) {
|
||||
scheduleNextWakeup(t - clock.getTime());
|
||||
return;
|
||||
}
|
||||
booted = true;
|
||||
|
@ -313,12 +324,17 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
|
|||
throw new RuntimeException("Bad event ordering: " + lastExecute + " < " + t);
|
||||
}
|
||||
|
||||
if (((1-deviation) * executed) > skipped) {
|
||||
lastExecute = lastExecute + duration; // (t+duration) - (t-lastExecute);
|
||||
nextExecute = t+duration;
|
||||
skipped += duration;
|
||||
scheduleNextWakeup(nextExecute);
|
||||
}
|
||||
|
||||
/* Execute MSPSim-based mote */
|
||||
/* TODO Try-catch overhead */
|
||||
try {
|
||||
nextExecute =
|
||||
t + duration +
|
||||
myCpu.stepMicros(t - lastExecute, duration);
|
||||
nextExecute = myCpu.stepMicros(Math.max(0, t-lastExecute), duration) + t + duration;
|
||||
lastExecute = t;
|
||||
} catch (EmulationException e) {
|
||||
String trace = e.getMessage() + "\n\n" + getStackTrace();
|
||||
|
@ -330,7 +346,9 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
|
|||
if (nextExecute < t) {
|
||||
throw new RuntimeException(t + ": MSPSim requested early wakeup: " + nextExecute);
|
||||
}
|
||||
|
||||
/*logger.debug(t + ": Schedule next wakeup at " + nextExecute);*/
|
||||
executed += duration;
|
||||
scheduleNextWakeup(nextExecute);
|
||||
|
||||
if (stopNextInstruction) {
|
||||
|
|
|
@ -52,9 +52,11 @@ public class MspClock extends Clock {
|
|||
private Simulation simulation;
|
||||
|
||||
private long timeDrift; /* Microseconds */
|
||||
private double deviation;
|
||||
|
||||
public MspClock(Mote mote) {
|
||||
simulation = mote.getSimulation();
|
||||
deviation = 1.0;
|
||||
}
|
||||
|
||||
public void setTime(long newTime) {
|
||||
|
@ -73,19 +75,12 @@ public class MspClock extends Clock {
|
|||
return timeDrift;
|
||||
}
|
||||
|
||||
public JPanel getInterfaceVisualizer() {
|
||||
/* TODO Show current CPU speed */
|
||||
return null;
|
||||
public void setDeviation(double deviation) {
|
||||
assert (deviation>0.0) && (deviation<=1.0);
|
||||
this.deviation = deviation;
|
||||
}
|
||||
|
||||
public void releaseInterfaceVisualizer(JPanel panel) {
|
||||
public double getDeviation() {
|
||||
return deviation;
|
||||
}
|
||||
|
||||
public Collection<Element> getConfigXML() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setConfigXML(Collection<Element> configXML, boolean visAvailable) {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -115,6 +115,14 @@ public class ContikiClock extends Clock implements ContikiMoteInterface, PolledB
|
|||
return moteTime;
|
||||
}
|
||||
|
||||
public void setDeviation(double deviation) {
|
||||
logger.fatal("Can't change deviation");;
|
||||
}
|
||||
|
||||
public double getDeviation() {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
public void doActionsBeforeTick() {
|
||||
/* Update time */
|
||||
setTime(mote.getSimulation().getSimulationTime() + timeDrift);
|
||||
|
@ -161,5 +169,4 @@ public class ContikiClock extends Clock implements ContikiMoteInterface, PolledB
|
|||
|
||||
public void setConfigXML(Collection<Element> configXML, boolean visAvailable) {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,7 +30,19 @@
|
|||
|
||||
package org.contikios.cooja.interfaces;
|
||||
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
import org.contikios.cooja.*;
|
||||
import org.jdom.Element;
|
||||
|
||||
/**
|
||||
* Represents a mote's internal clock. Notice that the overall
|
||||
|
@ -39,10 +51,10 @@ import org.contikios.cooja.*;
|
|||
* This observable never notifies.
|
||||
*
|
||||
* @author Fredrik Osterlind
|
||||
* Andreas Löscher
|
||||
*/
|
||||
@ClassDescription("Clock")
|
||||
public abstract class Clock extends MoteInterface {
|
||||
|
||||
/**
|
||||
* Set mote's time to given time.
|
||||
*
|
||||
|
@ -76,4 +88,88 @@ public abstract class Clock extends MoteInterface {
|
|||
*/
|
||||
public abstract long getDrift();
|
||||
|
||||
|
||||
/**
|
||||
* The clock deviation is a factor that represents with how much speed the
|
||||
* mote progresses through the simulation in relation to the simulation speed.
|
||||
*
|
||||
* A value of 1.0 results in the mote being simulated with the same speed
|
||||
* as the simulation. A value of 0.5 results in the mote being simulation
|
||||
* at half of the simulation speed.
|
||||
*
|
||||
* @param deviation Deviation factor
|
||||
*/
|
||||
public abstract void setDeviation(double deviation);
|
||||
|
||||
/**
|
||||
* Get deviation factor
|
||||
*/
|
||||
public abstract double getDeviation();
|
||||
|
||||
@Override
|
||||
public JPanel getInterfaceVisualizer() {
|
||||
JPanel panel = new JPanel();
|
||||
GridLayout layout = new GridLayout(0,2);
|
||||
|
||||
/* elements */
|
||||
final JLabel timeLabel = new JLabel("Time (ms)");
|
||||
final JTextField timeField = new JTextField(String.valueOf(getTime() / 1000));
|
||||
final JLabel deviationLabel = new JLabel("Deviation Factor");
|
||||
final JTextField deviationField = new JTextField(String.valueOf(getDeviation()));
|
||||
final JButton readButton = new JButton("Read Clock Values");
|
||||
final JButton updateButton = new JButton("Write Clock Values");
|
||||
/* set layout */
|
||||
panel.setLayout(layout);
|
||||
/* add components */
|
||||
panel.add(timeLabel);
|
||||
panel.add(timeField);
|
||||
panel.add(deviationLabel);
|
||||
panel.add(deviationField);
|
||||
panel.add(readButton);
|
||||
panel.add(updateButton);
|
||||
|
||||
readButton.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent ev) {
|
||||
if (ev.getButton()==1) {
|
||||
timeField.setText(String.valueOf(getTime() / 1000));
|
||||
deviationField.setText(String.valueOf(getDeviation()));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
updateButton.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent ev) {
|
||||
if (ev.getButton()==1) {
|
||||
setTime(Long.parseLong(timeField.getText()) * 1000);
|
||||
setDeviation(Double.parseDouble(deviationField.getText()));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseInterfaceVisualizer(JPanel panel) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Element> getConfigXML() {
|
||||
ArrayList<Element> config = new ArrayList<Element>();
|
||||
Element element = new Element("deviation");
|
||||
element.setText(String.valueOf(getDeviation()));
|
||||
config.add(element);
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConfigXML(Collection<Element> configXML, boolean visAvailable) {
|
||||
for (Element element : configXML) {
|
||||
if (element.getName().equals("deviation")) {
|
||||
setDeviation(Double.parseDouble(element.getText()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue