📄 simulation.java
字号:
/* * Copyright (c) 2006, 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: Simulation.java,v 1.29 2008/11/03 18:09:43 fros4943 Exp $ */package se.sics.cooja;import java.util.*;import org.apache.log4j.Logger;import org.jdom.*;import se.sics.cooja.dialogs.*;/** * A simulation consists of a number of motes and mote types. * * The motes in the simulation are ticked every millisecond. * * A simulation is observable: * changed simulation state, added or deleted motes etc are observed. * To track mote changes, observe the mote (interfaces) itself. * * @author Fredrik 謘terlind */public class Simulation extends Observable implements Runnable { private Vector<Mote> motes = new Vector<Mote>(); private Vector<MoteType> moteTypes = new Vector<MoteType>(); private int delayTime = 5; private int currentSimulationTime = 0; private int tickTime = 1; private String title = null; private RadioMedium currentRadioMedium = null; private static Logger logger = Logger.getLogger(Simulation.class); private boolean isRunning = false; private boolean stopSimulation = false; private Thread thread = null; private GUI myGUI = null; private long randomSeed = 123456; private int maxMoteStartupDelay = 1000; private Random delayMotesRandom = new Random(); // Tick observable private class TickObservable extends Observable { private void allTicksPerformed() { setChanged(); notifyObservers(); } } private TickObservable tickObservable = new TickObservable(); /** * Add tick observer. This observer is notified once every tick loop, that is, * when all motes have been ticked. * * @see #deleteTickObserver(Observer) * @param newObserver * New observer */ public void addTickObserver(Observer newObserver) { tickObservable.addObserver(newObserver); } /** * Delete an existing tick observer. * * @see #addTickObserver(Observer) * @param observer * Observer to delete */ public void deleteTickObserver(Observer 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() { long lastStartTime = System.currentTimeMillis(); logger.info("Simulation main loop started, system time: " + lastStartTime); isRunning = true; /* Schedule tick events */ scheduleEvent(tickMotesEvent, currentSimulationTime); scheduleEvent(tickMspMotesEvent, currentSimulationTime); scheduleEvent(delayEvent, currentSimulationTime); /* Simulation starting */ this.setChanged(); this.notifyObservers(this); /* Tick MSP motes separately */ ArrayList<Mote> mspMotes = new ArrayList<Mote>(); ArrayList<Mote> contikiMotes = new ArrayList<Mote>(); for (Mote mote: motes) { if (mote.getType().getClass().toString().contains(".mspmote.")) { mspMotes.add(mote); } else { contikiMotes.add(mote); } } mspMoteArray = mspMotes.toArray(new Mote[mspMotes.size()]); moteArray = contikiMotes.toArray(new Mote[contikiMotes.size()]); try { while (isRunning) { TimeEvent nextEvent = eventQueue.popFirst(); if (nextEvent == null) { throw new RuntimeException("No more events"); } currentSimulationTime = nextEvent.time; nextEvent.execute(currentSimulationTime); /* Notify tick observers */ tickObservable.allTicksPerformed(); if (stopSimulation) { isRunning = false; } } } catch (IllegalArgumentException e) { logger.warn("llegalArgumentException:" + e); } catch (IllegalMonitorStateException e) { logger.warn("IllegalMonitorStateException:" + e); } catch (RuntimeException e) { logger.warn("Simulation stop requested: " + e); } isRunning = false; thread = null; stopSimulation = false; // Notify observers simulation has stopped this.setChanged(); this.notifyObservers(this); logger.info("Simulation main loop stopped, system time: " + System.currentTimeMillis() + "\tDuration: " + (System.currentTimeMillis() - lastStartTime) + " ms"); } /** * Creates a new simulation with a delay time of 100 ms. */ public Simulation(GUI gui) { myGUI = gui; delayMotesRandom.setSeed(randomSeed); } /** * Starts this simulation (notifies observers). */ public void startSimulation() { if (!isRunning()) { isRunning = true; thread = new Thread(this); thread.start(); } } /** * Stops this simulation (notifies observers). */ public void stopSimulation() { if (isRunning()) { stopSimulation = true; thread.interrupt(); // Wait until simulation stops if (Thread.currentThread() != thread) { while (thread != null && thread.isAlive()) { try { Thread.sleep(10); } catch (InterruptedException e) { } } } } } /** * Starts simulation if stopped, ticks all motes once, and finally stops * simulation again. */ public void tickSimulation() { stopSimulation = true; if (!isRunning()) { thread = new Thread(this); thread.start(); } // Wait until simulation stops while (thread != null && thread.isAlive()) { try { Thread.sleep(10); } catch (InterruptedException e) { } } } /** * @return GUI holding this simulation */ public GUI getGUI() { return myGUI; } /** * @return Random seed */ public long getRandomSeed() { return randomSeed; } /** * @param randomSeed Random seed */ public void setRandomSeed(long randomSeed) { this.randomSeed = randomSeed; } /** * @return Maximum mote startup delay */ public int getDelayedMoteStartupTime() { return maxMoteStartupDelay; } /** * @param maxMoteStartupDelay Maximum mote startup delay */ public void setDelayedMoteStartupTime(int maxMoteStartupDelay) { this.maxMoteStartupDelay = Math.max(0, maxMoteStartupDelay); } /** * Returns the current simulation config represented by XML elements. This * config also includes the current radio medium, all mote types and motes. * * @return Current simulation config */ public Collection<Element> getConfigXML() { Vector<Element> config = new Vector<Element>(); Element element; // Title element = new Element("title"); element.setText(title); config.add(element); // Delay time element = new Element("delaytime"); element.setText(Integer.toString(delayTime)); config.add(element); // Tick time element = new Element("ticktime"); element.setText(Integer.toString(tickTime)); config.add(element); // Random seed element = new Element("randomseed"); element.setText(Long.toString(randomSeed)); config.add(element); // Max mote startup delay element = new Element("motedelay"); element.setText(Integer.toString(maxMoteStartupDelay)); config.add(element); // Radio Medium element = new Element("radiomedium"); element.setText(currentRadioMedium.getClass().getName()); Collection radioMediumXML = currentRadioMedium.getConfigXML(); if (radioMediumXML != null) { element.addContent(radioMediumXML); } config.add(element); // Mote types for (MoteType moteType : getMoteTypes()) { element = new Element("motetype"); element.setText(moteType.getClass().getName()); Collection moteTypeXML = moteType.getConfigXML(); if (moteTypeXML != null) { element.addContent(moteTypeXML); } config.add(element); } // Motes for (Mote mote : motes) { element = new Element("mote"); element.setText(mote.getClass().getName());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -