removed tick lists and variable tick times
handling tick events in simulation loop: moving towards fully event based (as opposed to tick based)
This commit is contained in:
parent
5c2d5940ed
commit
456ef03dc1
|
@ -24,7 +24,7 @@
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: Simulation.java,v 1.26 2008/10/03 13:18:29 fros4943 Exp $
|
* $Id: Simulation.java,v 1.27 2008/10/28 13:35:59 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja;
|
package se.sics.cooja;
|
||||||
|
@ -38,17 +38,13 @@ import se.sics.cooja.dialogs.*;
|
||||||
/**
|
/**
|
||||||
* A simulation consists of a number of motes and mote types.
|
* A simulation consists of a number of motes and mote types.
|
||||||
*
|
*
|
||||||
* The motes in the simulation are ticked one by one in a simulation loop. When
|
* The motes in the simulation are ticked every millisecond.
|
||||||
* all motes have been ticked once, the simulation time is updated and then the
|
|
||||||
* simulation sleeps for some specified delay time. Any tick observers are also
|
|
||||||
* notified at this time.
|
|
||||||
*
|
*
|
||||||
* When observing the simulation itself, the simulation state, added or deleted
|
* A simulation is observable:
|
||||||
* motes etc. are observed, as opposed to individual mote changes. Changes of
|
* changed simulation state, added or deleted motes etc are observed.
|
||||||
* individual motes should instead be observed via corresponding mote
|
* To track mote changes, observe the mote (interfaces) itself.
|
||||||
* interfaces.
|
|
||||||
*
|
*
|
||||||
* @author Fredrik Osterlind
|
* @author Fredrik Österlind
|
||||||
*/
|
*/
|
||||||
public class Simulation extends Observable implements Runnable {
|
public class Simulation extends Observable implements Runnable {
|
||||||
|
|
||||||
|
@ -78,14 +74,8 @@ public class Simulation extends Observable implements Runnable {
|
||||||
|
|
||||||
private long randomSeed = 123456;
|
private long randomSeed = 123456;
|
||||||
|
|
||||||
private int currentTickListIndex = 0;
|
|
||||||
|
|
||||||
private int nrTickLists = 1;
|
|
||||||
|
|
||||||
private int maxMoteStartupDelay = 1000;
|
private int maxMoteStartupDelay = 1000;
|
||||||
|
|
||||||
private Random tickListRandom = new Random();
|
|
||||||
|
|
||||||
private Random delayMotesRandom = new Random();
|
private Random delayMotesRandom = new Random();
|
||||||
|
|
||||||
// Tick observable
|
// Tick observable
|
||||||
|
@ -121,97 +111,106 @@ public class Simulation extends Observable implements Runnable {
|
||||||
tickObservable.deleteObserver(observer);
|
tickObservable.deleteObserver(observer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedule event to be handled by event loop.
|
||||||
|
*
|
||||||
|
* @param e Event
|
||||||
|
* @param time Simulated time
|
||||||
|
*/
|
||||||
|
public void scheduleEvent(TimeEvent e, int time) {
|
||||||
|
eventQueue.addEvent(e, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
private EventQueue eventQueue = new EventQueue();
|
||||||
|
|
||||||
|
private Mote[] mspMoteArray;
|
||||||
|
private TimeEvent tickMspMotesEvent = new TimeEvent(0) {
|
||||||
|
public void execute(int t) {
|
||||||
|
/*logger.info("MSP motes tick at: " + t);*/
|
||||||
|
|
||||||
|
/* Tick MSP motes */
|
||||||
|
boolean wantMoreTicks = true;
|
||||||
|
while (wantMoreTicks) {
|
||||||
|
/* Tick all MSP motes until none need more ticks */
|
||||||
|
wantMoreTicks = false;
|
||||||
|
for (Mote element : mspMoteArray) {
|
||||||
|
if (element.tick(currentSimulationTime)) {
|
||||||
|
wantMoreTicks = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reschedule MSP motes */
|
||||||
|
scheduleEvent(this, t+1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private Mote[] moteArray;
|
||||||
|
private TimeEvent tickMotesEvent = new TimeEvent(0) {
|
||||||
|
public void execute(int t) {
|
||||||
|
/*logger.info("Contiki motes tick at: " + t);*/
|
||||||
|
|
||||||
|
/* Tick Contiki motes */
|
||||||
|
for (Mote mote : moteArray) {
|
||||||
|
mote.tick(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reschedule Contiki motes */
|
||||||
|
scheduleEvent(this, t+1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private TimeEvent delayEvent = new TimeEvent(0) {
|
||||||
|
public void execute(int t) {
|
||||||
|
/*logger.info("Delay at: " + t);*/
|
||||||
|
|
||||||
|
if (delayTime > 0) {
|
||||||
|
try { Thread.sleep(delayTime); } catch (InterruptedException e) { }
|
||||||
|
scheduleEvent(this, t+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
long lastStartTime = System.currentTimeMillis();
|
long lastStartTime = System.currentTimeMillis();
|
||||||
logger.info("Simulation main loop started, system time: " + lastStartTime);
|
logger.info("Simulation main loop started, system time: " + lastStartTime);
|
||||||
isRunning = true;
|
isRunning = true;
|
||||||
|
|
||||||
// Notify observers simulation is starting
|
/* Simulation starting */
|
||||||
this.setChanged();
|
this.setChanged();
|
||||||
this.notifyObservers(this);
|
this.notifyObservers(this);
|
||||||
|
|
||||||
/* Experimental: Tick MSP motes separately */
|
/* Tick MSP motes separately */
|
||||||
ArrayList<Mote> mspMotes = new ArrayList<Mote>();
|
ArrayList<Mote> mspMotes = new ArrayList<Mote>();
|
||||||
|
ArrayList<Mote> contikiMotes = new ArrayList<Mote>();
|
||||||
for (Mote mote: motes) {
|
for (Mote mote: motes) {
|
||||||
if (mote.getType().getClass().toString().contains(".mspmote.")) {
|
if (mote.getType().getClass().toString().contains(".mspmote.")) {
|
||||||
mspMotes.add(mote);
|
mspMotes.add(mote);
|
||||||
|
} else {
|
||||||
|
contikiMotes.add(mote);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mspMoteArray = mspMotes.toArray(new Mote[mspMotes.size()]);
|
||||||
|
moteArray = contikiMotes.toArray(new Mote[mspMotes.size()]);
|
||||||
|
|
||||||
// Distribute motes in tick lists according to random seed
|
|
||||||
// TODO Timeconsuming approach (but only performed once)
|
|
||||||
int motesToDistribute = motes.size() - mspMotes.size();
|
|
||||||
Mote[][] allLists = new Mote[nrTickLists][];
|
|
||||||
for (int i=0; i < nrTickLists; i++) {
|
|
||||||
allLists[i] = new Mote[(int) Math.ceil((double)motesToDistribute/(double)(nrTickLists - i))];
|
|
||||||
motesToDistribute -= allLists[i].length;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Distribute motes according to seed
|
|
||||||
tickListRandom.setSeed(randomSeed);
|
|
||||||
Vector<Mote> motesClone = new Vector<Mote>();
|
|
||||||
for (Mote mote: motes) {
|
|
||||||
if (!mote.getType().getClass().toString().contains(".mspmote.")) {
|
|
||||||
motesClone.add(mote);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i=0; i < allLists.length; i++) {
|
|
||||||
for (int j=0; j < allLists[i].length; j++) {
|
|
||||||
int moteNr = tickListRandom.nextInt(motesClone.size());
|
|
||||||
allLists[i][j] = motesClone.remove(moteNr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Mote[] mspArray = mspMotes.toArray(new Mote[mspMotes.size()]);
|
|
||||||
try {
|
try {
|
||||||
while (isRunning) {
|
while (isRunning) {
|
||||||
|
|
||||||
/* Tick MSP motes */
|
TimeEvent nextEvent = eventQueue.popFirst();
|
||||||
// try {
|
if (nextEvent == null) {
|
||||||
boolean wantMoreTicks = true;
|
throw new RuntimeException("No more events");
|
||||||
while (wantMoreTicks) {
|
|
||||||
/* Tick all MSP motes until none need more ticks */
|
|
||||||
wantMoreTicks = false;
|
|
||||||
for (int i = 0, n = mspArray.length; i < n; i++) {
|
|
||||||
if (mspArray[i].tick(currentSimulationTime)) {
|
|
||||||
wantMoreTicks = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// } catch (RuntimeException e) {
|
|
||||||
// isRunning = false;
|
|
||||||
// thread = null;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Tick current mote subset
|
|
||||||
for (Mote moteToTick : allLists[currentTickListIndex]) {
|
|
||||||
moteToTick.tick(currentSimulationTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select next mote subset (persistent)
|
currentSimulationTime = nextEvent.time;
|
||||||
currentTickListIndex++;
|
nextEvent.execute(currentSimulationTime);
|
||||||
if (currentTickListIndex >= nrTickLists) {
|
|
||||||
currentTickListIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Increase simulation time
|
/* Notify tick observers */
|
||||||
currentSimulationTime += tickTime;
|
|
||||||
|
|
||||||
// Notify tick observers
|
|
||||||
tickObservable.allTicksPerformed();
|
tickObservable.allTicksPerformed();
|
||||||
|
|
||||||
// Sleep
|
|
||||||
if (delayTime > 0) {
|
|
||||||
Thread.sleep(delayTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stopSimulation) {
|
if (stopSimulation) {
|
||||||
isRunning = false;
|
isRunning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
logger.warn("llegalArgumentException:" + e);
|
logger.warn("llegalArgumentException:" + e);
|
||||||
} catch (IllegalMonitorStateException e) {
|
} catch (IllegalMonitorStateException e) {
|
||||||
|
@ -238,6 +237,13 @@ public class Simulation extends Observable implements Runnable {
|
||||||
public Simulation(GUI gui) {
|
public Simulation(GUI gui) {
|
||||||
myGUI = gui;
|
myGUI = gui;
|
||||||
delayMotesRandom.setSeed(randomSeed);
|
delayMotesRandom.setSeed(randomSeed);
|
||||||
|
|
||||||
|
/* XXX Remove me */
|
||||||
|
scheduleEvent(tickMotesEvent, currentSimulationTime);
|
||||||
|
/* XXX Remove me */
|
||||||
|
scheduleEvent(tickMspMotesEvent, currentSimulationTime);
|
||||||
|
/* XXX Remove me? */
|
||||||
|
scheduleEvent(delayEvent, currentSimulationTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -314,20 +320,6 @@ public class Simulation extends Observable implements Runnable {
|
||||||
this.randomSeed = randomSeed;
|
this.randomSeed = randomSeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Number of tick lists
|
|
||||||
*/
|
|
||||||
public int getNrTickLists() {
|
|
||||||
return nrTickLists;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param nrTickLists Number of tick lists
|
|
||||||
*/
|
|
||||||
public void setNrTickLists(int nrTickLists) {
|
|
||||||
this.nrTickLists = Math.max(1, nrTickLists);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Maximum mote startup delay
|
* @return Maximum mote startup delay
|
||||||
*/
|
*/
|
||||||
|
@ -373,11 +365,6 @@ public class Simulation extends Observable implements Runnable {
|
||||||
element.setText(Long.toString(randomSeed));
|
element.setText(Long.toString(randomSeed));
|
||||||
config.add(element);
|
config.add(element);
|
||||||
|
|
||||||
// Number of tick lists
|
|
||||||
element = new Element("nrticklists");
|
|
||||||
element.setText(Integer.toString(nrTickLists));
|
|
||||||
config.add(element);
|
|
||||||
|
|
||||||
// Max mote startup delay
|
// Max mote startup delay
|
||||||
element = new Element("motedelay");
|
element = new Element("motedelay");
|
||||||
element.setText(Integer.toString(maxMoteStartupDelay));
|
element.setText(Integer.toString(maxMoteStartupDelay));
|
||||||
|
@ -460,11 +447,6 @@ public class Simulation extends Observable implements Runnable {
|
||||||
delayMotesRandom.setSeed(randomSeed);
|
delayMotesRandom.setSeed(randomSeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Number of tick lists
|
|
||||||
if (element.getName().equals("nrticklists")) {
|
|
||||||
nrTickLists = Integer.parseInt(element.getText());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max mote startup delay
|
// Max mote startup delay
|
||||||
if (element.getName().equals("motedelay")) {
|
if (element.getName().equals("motedelay")) {
|
||||||
maxMoteStartupDelay = Integer.parseInt(element.getText());
|
maxMoteStartupDelay = Integer.parseInt(element.getText());
|
||||||
|
@ -671,6 +653,8 @@ public class Simulation extends Observable implements Runnable {
|
||||||
public void setDelayTime(int delayTime) {
|
public void setDelayTime(int delayTime) {
|
||||||
this.delayTime = delayTime;
|
this.delayTime = delayTime;
|
||||||
|
|
||||||
|
scheduleEvent(delayEvent, currentSimulationTime);
|
||||||
|
|
||||||
this.setChanged();
|
this.setChanged();
|
||||||
this.notifyObservers(this);
|
this.notifyObservers(this);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue