Merge branch 'master' of ssh://contiki.git.sourceforge.net/gitroot/contiki/contiki
This commit is contained in:
commit
66f0a1bc95
|
@ -56,7 +56,7 @@ uart0_init()
|
|||
#endif
|
||||
|
||||
U0CSR = UCSR_MODE; /* UART mode */
|
||||
U0UCR = 0x80; /* Flush */
|
||||
U0UCR |= 0x80; /* Flush */
|
||||
UART0_RX_EN();
|
||||
|
||||
UART0_RX_INT(1);
|
||||
|
|
|
@ -201,7 +201,7 @@ clock_delay(unsigned int i)
|
|||
/*---------------------------------------------------------------------------*/
|
||||
#ifdef __GNUC__
|
||||
void
|
||||
__delay_cycles(int c)
|
||||
__delay_cycles(unsigned long c)
|
||||
{
|
||||
c /= 4;
|
||||
asm("add #-1, r15");
|
||||
|
|
|
@ -381,7 +381,12 @@ void halLcdActive(void)
|
|||
|
||||
// Wait a minimum of 25ms after issuing "start oscillation"
|
||||
// command (to accomodate for MCLK up to 25MHz)
|
||||
__delay_cycles(250000);
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < 5; ++i) {
|
||||
__delay_cycles(50000);
|
||||
}
|
||||
}
|
||||
|
||||
LcdInitMacro[3 * 6 + 5] |= BIT3;
|
||||
LcdInitMacro[3 * 6 + 5] &= ~BIT0;
|
||||
|
|
|
@ -214,10 +214,9 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
|
|||
this.myCpu.setMonitorExec(true);
|
||||
this.myCpu.setTrace(0); /* TODO Enable */
|
||||
|
||||
int[] memory = myCpu.memory;
|
||||
logger.info("Loading firmware from: " + fileELF.getAbsolutePath());
|
||||
GUI.setProgressMessage("Loading " + fileELF.getName());
|
||||
node.loadFirmware(((MspMoteType)getType()).getELF(), memory);
|
||||
node.loadFirmware(((MspMoteType)getType()).getELF());
|
||||
|
||||
/* Throw exceptions at bad memory access */
|
||||
/*myCpu.setThrowIfWarning(true);*/
|
||||
|
@ -417,6 +416,10 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
|
|||
}
|
||||
|
||||
MoteInterface moteInterface = getInterfaces().getInterfaceOfType(moteInterfaceClass);
|
||||
if (moteInterface == null) {
|
||||
logger.fatal("Could not find mote interface of class: " + moteInterfaceClass);
|
||||
return false;
|
||||
}
|
||||
moteInterface.setConfigXML(element.getChildren(), visAvailable);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,18 +69,21 @@ import org.jdom.Element;
|
|||
|
||||
import se.sics.cooja.ClassDescription;
|
||||
import se.sics.cooja.GUI;
|
||||
import se.sics.cooja.GUI.RunnableInEDT;
|
||||
import se.sics.cooja.Mote;
|
||||
import se.sics.cooja.MotePlugin;
|
||||
import se.sics.cooja.PluginType;
|
||||
import se.sics.cooja.Simulation;
|
||||
import se.sics.cooja.SupportedArguments;
|
||||
import se.sics.cooja.VisPlugin;
|
||||
import se.sics.cooja.GUI.RunnableInEDT;
|
||||
import se.sics.cooja.dialogs.CompileContiki;
|
||||
import se.sics.cooja.dialogs.MessageList;
|
||||
import se.sics.cooja.interfaces.IPAddress;
|
||||
import se.sics.cooja.interfaces.SerialPort;
|
||||
|
||||
@ClassDescription("Open Native IP Gateway")
|
||||
@PluginType(PluginType.MOTE_PLUGIN)
|
||||
@SupportedArguments(moteInterfaces = {IPAddress.class})
|
||||
public class NativeIPGateway extends VisPlugin implements MotePlugin {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static Logger logger = Logger.getLogger(NativeIPGateway.class);
|
||||
|
@ -564,7 +567,7 @@ public class NativeIPGateway extends VisPlugin implements MotePlugin {
|
|||
progressDialog.getContentPane().add(BorderLayout.NORTH, progressBar);
|
||||
progressDialog.getContentPane().add(BorderLayout.CENTER, new JScrollPane(output));
|
||||
progressDialog.setSize(350, 150);
|
||||
progressDialog.setLocationRelativeTo((Window)GUI.getTopParentContainer());
|
||||
progressDialog.setLocationRelativeTo(GUI.getTopParentContainer());
|
||||
progressDialog.setVisible(true);
|
||||
GUI.setProgressMessage("Compiling hello-world.minimal-net (Native IP Gateway)");
|
||||
return true;
|
||||
|
|
|
@ -4,7 +4,6 @@ KEYBOARD_SHORTCUTS = \
|
|||
<br><i>Ctrl+S:</i> Start/pause simulation\
|
||||
<br><i>Ctrl+R:</i> Reload current simulation. If no simulation exists, the last used simulation config is loaded\
|
||||
<br><i>Ctrl+Shift+R:</i> Reload current simulation with another random seed\
|
||||
<br><i>Ctrl+X:</i> Quit COOJA\
|
||||
<br>\
|
||||
<br><i>F1:</i> Toggle quick help
|
||||
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<simconf>
|
||||
<project>../apps/mrm</project>
|
||||
<project>../apps/mspsim</project>
|
||||
<project>../apps/avrora</project>
|
||||
<project>../apps/native_gateway</project>
|
||||
<simulation>
|
||||
<title>My simulation</title>
|
||||
<delaytime>0</delaytime>
|
||||
<title>Hello World test (Cooja motes)</title>
|
||||
<randomseed>generated</randomseed>
|
||||
<motedelay_us>1000000</motedelay_us>
|
||||
<radiomedium>
|
||||
|
@ -16,11 +11,14 @@
|
|||
<success_ratio_tx>1.0</success_ratio_tx>
|
||||
<success_ratio_rx>1.0</success_ratio_rx>
|
||||
</radiomedium>
|
||||
<events>
|
||||
<logoutput>40000</logoutput>
|
||||
</events>
|
||||
<motetype>
|
||||
se.sics.cooja.contikimote.ContikiMoteType
|
||||
<identifier>mtype82</identifier>
|
||||
<identifier>mtype725</identifier>
|
||||
<description>Contiki Mote Type #1</description>
|
||||
<contikiapp>../../../examples/hello-world/hello-world.c</contikiapp>
|
||||
<source>[CONTIKI_DIR]/examples/hello-world/hello-world.c</source>
|
||||
<commands>make hello-world.cooja TARGET=cooja</commands>
|
||||
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
|
||||
|
@ -28,6 +26,7 @@
|
|||
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
|
||||
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
|
||||
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
|
||||
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
|
||||
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
|
||||
|
@ -36,41 +35,35 @@
|
|||
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
|
||||
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<symbols>false</symbols>
|
||||
<commstack>Rime</commstack>
|
||||
</motetype>
|
||||
<mote>
|
||||
se.sics.cooja.contikimote.ContikiMote
|
||||
<motetype_identifier>mtype82</motetype_identifier>
|
||||
<interface_config>
|
||||
se.sics.cooja.interfaces.Position
|
||||
<x>69.64867743029201</x>
|
||||
<y>69.2570131081022</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
se.sics.cooja.interfaces.Battery
|
||||
<infinite>false</infinite>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
se.sics.cooja.contikimote.interfaces.ContikiMoteID
|
||||
<id>1</id>
|
||||
</interface_config>
|
||||
<motetype_identifier>mtype725</motetype_identifier>
|
||||
</mote>
|
||||
</simulation>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.Visualizer
|
||||
<plugin_config>
|
||||
<skin>Mote IDs</skin>
|
||||
<skin>Log output: printf()'s</skin>
|
||||
<skin>se.sics.cooja.plugins.skins.IDVisualizerSkin</skin>
|
||||
<skin>se.sics.cooja.plugins.skins.LogVisualizerSkin</skin>
|
||||
<viewport>0.9090909090909091 0.0 0.0 0.9090909090909091 59.68302051791636 6.039078992634368</viewport>
|
||||
</plugin_config>
|
||||
<width>259</width>
|
||||
<z>1</z>
|
||||
<height>198</height>
|
||||
<location_x>2</location_x>
|
||||
<location_y>203</location_y>
|
||||
<minimized>false</minimized>
|
||||
</plugin>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.LogListener
|
||||
|
@ -82,7 +75,6 @@
|
|||
<height>217</height>
|
||||
<location_x>2</location_x>
|
||||
<location_y>403</location_y>
|
||||
<minimized>false</minimized>
|
||||
</plugin>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.SimControl
|
||||
|
@ -91,23 +83,18 @@
|
|||
<height>200</height>
|
||||
<location_x>2</location_x>
|
||||
<location_y>3</location_y>
|
||||
<minimized>false</minimized>
|
||||
</plugin>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.ScriptRunner
|
||||
<plugin_config>
|
||||
<script>TIMEOUT(2000, log.log("last message: " + msg + "\n"));
|
||||
|
||||
WAIT_UNTIL(msg.equals('Hello, world'));
|
||||
log.testOK();</script>
|
||||
<scriptfile>[CONFIG_DIR]/hello-world.js</scriptfile>
|
||||
<active>true</active>
|
||||
</plugin_config>
|
||||
<width>592</width>
|
||||
<z>0</z>
|
||||
<height>618</height>
|
||||
<location_x>264</location_x>
|
||||
<location_y>3</location_y>
|
||||
<minimized>false</minimized>
|
||||
<location_x>318</location_x>
|
||||
<location_y>61</location_y>
|
||||
</plugin>
|
||||
</simconf>
|
||||
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<simconf>
|
||||
<project>[CONTIKI_DIR]/tools/cooja/apps/mrm</project>
|
||||
<project>[CONTIKI_DIR]/tools/cooja/apps/mspsim</project>
|
||||
<project>[CONTIKI_DIR]/tools/cooja/apps/avrora</project>
|
||||
<simulation>
|
||||
<title>My simulation</title>
|
||||
<delaytime>0</delaytime>
|
||||
<title>Hello World (ESB)</title>
|
||||
<randomseed>generated</randomseed>
|
||||
<motedelay_us>1000000</motedelay_us>
|
||||
<radiomedium>
|
||||
|
@ -22,10 +18,9 @@
|
|||
se.sics.cooja.mspmote.ESBMoteType
|
||||
<identifier>esb1</identifier>
|
||||
<description>ESB Mote Type #esb1</description>
|
||||
<source>[CONTIKI_DIR]/examples/hello-world/hello-world.c</source>
|
||||
<commands>make clean TARGET=esb
|
||||
make hello-world.esb TARGET=esb</commands>
|
||||
<firmware>[CONTIKI_DIR]/examples/hello-world/hello-world.esb</firmware>
|
||||
<source EXPORT="discard">[CONTIKI_DIR]/examples/hello-world/hello-world.c</source>
|
||||
<commands EXPORT="discard">make hello-world.esb TARGET=esb</commands>
|
||||
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/hello-world/hello-world.esb</firmware>
|
||||
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
|
||||
|
@ -36,9 +31,9 @@ make hello-world.esb TARGET=esb</commands>
|
|||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.TR1001Radio</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
</motetype>
|
||||
<mote>
|
||||
se.sics.cooja.mspmote.ESBMote
|
||||
<breakpoints />
|
||||
<interface_config>
|
||||
se.sics.cooja.interfaces.Position
|
||||
|
@ -53,65 +48,21 @@ make hello-world.esb TARGET=esb</commands>
|
|||
<motetype_identifier>esb1</motetype_identifier>
|
||||
</mote>
|
||||
</simulation>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.SimControl
|
||||
<width>259</width>
|
||||
<z>6</z>
|
||||
<height>184</height>
|
||||
<location_x>60</location_x>
|
||||
<location_y>60</location_y>
|
||||
<minimized>false</minimized>
|
||||
</plugin>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.Visualizer
|
||||
<plugin_config>
|
||||
<skin>se.sics.cooja.plugins.skins.IDVisualizerSkin</skin>
|
||||
<skin>se.sics.cooja.plugins.skins.LogVisualizerSkin</skin>
|
||||
<viewport>0.9090909090909091 0.0 0.0 0.9090909090909091 91.91230937183896 53.4476411035901</viewport>
|
||||
</plugin_config>
|
||||
<width>300</width>
|
||||
<z>3</z>
|
||||
<height>300</height>
|
||||
<location_x>945</location_x>
|
||||
<location_y>0</location_y>
|
||||
<minimized>false</minimized>
|
||||
</plugin>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.LogListener
|
||||
<plugin_config>
|
||||
<filter />
|
||||
</plugin_config>
|
||||
<width>1245</width>
|
||||
<z>5</z>
|
||||
<height>150</height>
|
||||
<location_x>0</location_x>
|
||||
<location_y>530</location_y>
|
||||
<minimized>false</minimized>
|
||||
</plugin>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.TimeLine
|
||||
<plugin_config>
|
||||
<mote>0</mote>
|
||||
<showRadioRXTX />
|
||||
<showRadioHW />
|
||||
<showLEDs />
|
||||
<split>109</split>
|
||||
<zoom>9</zoom>
|
||||
</plugin_config>
|
||||
<width>1245</width>
|
||||
<width>623</width>
|
||||
<z>1</z>
|
||||
<height>150</height>
|
||||
<location_x>0</location_x>
|
||||
<location_y>680</location_y>
|
||||
<minimized>false</minimized>
|
||||
<height>270</height>
|
||||
<location_x>29</location_x>
|
||||
<location_y>256</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.ScriptRunner
|
||||
<plugin_config>
|
||||
<script>TIMEOUT(5000, log.log("last message: " + msg + "\n"));
|
||||
|
||||
WAIT_UNTIL(msg.equals('Hello, world'));
|
||||
log.testOK();</script>
|
||||
<scriptfile>[CONFIG_DIR]/hello-world.js</scriptfile>
|
||||
<active>true</active>
|
||||
</plugin_config>
|
||||
<width>600</width>
|
||||
|
@ -119,7 +70,14 @@ log.testOK();</script>
|
|||
<height>453</height>
|
||||
<location_x>337</location_x>
|
||||
<location_y>25</location_y>
|
||||
<minimized>false</minimized>
|
||||
</plugin>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.SimControl
|
||||
<width>280</width>
|
||||
<z>2</z>
|
||||
<height>160</height>
|
||||
<location_x>20</location_x>
|
||||
<location_y>23</location_y>
|
||||
</plugin>
|
||||
</simconf>
|
||||
|
||||
|
|
83
tools/cooja/contiki_tests/exp5438_helloworld.csc
Normal file
83
tools/cooja/contiki_tests/exp5438_helloworld.csc
Normal file
|
@ -0,0 +1,83 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<simconf>
|
||||
<simulation>
|
||||
<title>Hello World (Exp5438)</title>
|
||||
<randomseed>generated</randomseed>
|
||||
<motedelay_us>1000000</motedelay_us>
|
||||
<radiomedium>
|
||||
se.sics.cooja.radiomediums.UDGM
|
||||
<transmitting_range>50.0</transmitting_range>
|
||||
<interference_range>100.0</interference_range>
|
||||
<success_ratio_tx>1.0</success_ratio_tx>
|
||||
<success_ratio_rx>1.0</success_ratio_rx>
|
||||
</radiomedium>
|
||||
<events>
|
||||
<logoutput>40000</logoutput>
|
||||
</events>
|
||||
<motetype>
|
||||
se.sics.cooja.mspmote.Exp5438MoteType
|
||||
<identifier>exp5438#1</identifier>
|
||||
<description>Exp5438 Mote Type exp5438#1</description>
|
||||
<source EXPORT="discard">[CONTIKI_DIR]/examples/hello-world/hello-world.c</source>
|
||||
<commands EXPORT="discard">make hello-world.exp5438 TARGET=exp5438</commands>
|
||||
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/hello-world/hello-world.exp5438</firmware>
|
||||
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.UsciA1Serial</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.Exp5438LED</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
|
||||
</motetype>
|
||||
<mote>
|
||||
<breakpoints />
|
||||
<interface_config>
|
||||
se.sics.cooja.interfaces.Position
|
||||
<x>26.321738050614275</x>
|
||||
<y>34.93092009073432</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
se.sics.cooja.mspmote.interfaces.MspMoteID
|
||||
<id>1</id>
|
||||
</interface_config>
|
||||
<motetype_identifier>exp5438#1</motetype_identifier>
|
||||
</mote>
|
||||
</simulation>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.SimControl
|
||||
<width>280</width>
|
||||
<z>2</z>
|
||||
<height>160</height>
|
||||
<location_x>38</location_x>
|
||||
<location_y>49</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.LogListener
|
||||
<plugin_config>
|
||||
<filter />
|
||||
</plugin_config>
|
||||
<width>680</width>
|
||||
<z>1</z>
|
||||
<height>240</height>
|
||||
<location_x>86</location_x>
|
||||
<location_y>384</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.ScriptRunner
|
||||
<plugin_config>
|
||||
<scriptfile>[CONFIG_DIR]/hello-world.js</scriptfile>
|
||||
<active>true</active>
|
||||
</plugin_config>
|
||||
<width>600</width>
|
||||
<z>0</z>
|
||||
<height>700</height>
|
||||
<location_x>347</location_x>
|
||||
<location_y>21</location_y>
|
||||
</plugin>
|
||||
</simconf>
|
||||
|
9
tools/cooja/contiki_tests/hello-world.js
Normal file
9
tools/cooja/contiki_tests/hello-world.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
TIMEOUT(5000);
|
||||
|
||||
while(true) {
|
||||
log.log("> " + msg + "\n");
|
||||
if (msg.equals('Hello, world')) {
|
||||
log.testOK();
|
||||
}
|
||||
YIELD();
|
||||
}
|
|
@ -1,11 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<simconf>
|
||||
<project>../apps/mrm</project>
|
||||
<project>../apps/mspsim</project>
|
||||
<project>../apps/avrora</project>
|
||||
<simulation>
|
||||
<title>My simulation</title>
|
||||
<delaytime>0</delaytime>
|
||||
<title>Hello World (MicaZ)</title>
|
||||
<randomseed>generated</randomseed>
|
||||
<motedelay_us>1000000</motedelay_us>
|
||||
<radiomedium>
|
||||
|
@ -22,99 +18,62 @@
|
|||
se.sics.cooja.avrmote.MicaZMoteType
|
||||
<identifier>micaz1</identifier>
|
||||
<description>MicaZ Mote Type #micaz1</description>
|
||||
<source>../../../examples/hello-world/hello-world.c</source>
|
||||
<commands>make clean TARGET=micaz
|
||||
make hello-world.elf TARGET=micaz</commands>
|
||||
<firmware>../../../examples/hello-world/hello-world.elf</firmware>
|
||||
<source>[CONTIKI_DIR]/examples/hello-world/hello-world.c</source>
|
||||
<commands>make hello-world.elf TARGET=micaz</commands>
|
||||
<firmware>[CONTIKI_DIR]/examples/hello-world/hello-world.elf</firmware>
|
||||
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>se.sics.cooja.avrmote.interfaces.MicaZID</moteinterface>
|
||||
<moteinterface>se.sics.cooja.avrmote.interfaces.MicaZLED</moteinterface>
|
||||
<moteinterface>se.sics.cooja.avrmote.interfaces.MicaZRadio</moteinterface>
|
||||
<moteinterface>se.sics.cooja.avrmote.interfaces.MicaClock</moteinterface>
|
||||
<moteinterface>se.sics.cooja.avrmote.interfaces.MicaSerial</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
</motetype>
|
||||
<mote>
|
||||
se.sics.cooja.avrmote.MicaZMote
|
||||
<motetype_identifier>micaz1</motetype_identifier>
|
||||
<interface_config>
|
||||
se.sics.cooja.interfaces.Position
|
||||
<x>68.44103812985554</x>
|
||||
<y>35.6791174319418</y>
|
||||
<x>36.478849033811386</x>
|
||||
<y>97.17795415366507</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
se.sics.cooja.avrmote.interfaces.MicaZID
|
||||
<id>1</id>
|
||||
</interface_config>
|
||||
<motetype_identifier>micaz1</motetype_identifier>
|
||||
</mote>
|
||||
</simulation>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.SimControl
|
||||
<width>259</width>
|
||||
<z>4</z>
|
||||
<height>184</height>
|
||||
<location_x>0</location_x>
|
||||
<location_y>0</location_y>
|
||||
<minimized>false</minimized>
|
||||
</plugin>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.Visualizer
|
||||
<plugin_config>
|
||||
<skin>se.sics.cooja.plugins.skins.IDVisualizerSkin</skin>
|
||||
<skin>se.sics.cooja.plugins.skins.LogVisualizerSkin</skin>
|
||||
<viewport>0.9090909090909091 0.0 0.0 0.9090909090909091 81.78087442740406 87.56443869823474</viewport>
|
||||
</plugin_config>
|
||||
<width>300</width>
|
||||
<z>1</z>
|
||||
<height>300</height>
|
||||
<location_x>456</location_x>
|
||||
<location_y>0</location_y>
|
||||
<minimized>false</minimized>
|
||||
<width>280</width>
|
||||
<z>2</z>
|
||||
<height>160</height>
|
||||
<location_x>17</location_x>
|
||||
<location_y>16</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.LogListener
|
||||
<plugin_config>
|
||||
<filter />
|
||||
</plugin_config>
|
||||
<width>756</width>
|
||||
<z>2</z>
|
||||
<height>150</height>
|
||||
<location_x>0</location_x>
|
||||
<location_y>286</location_y>
|
||||
<minimized>false</minimized>
|
||||
</plugin>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.TimeLine
|
||||
<plugin_config>
|
||||
<mote>0</mote>
|
||||
<showRadioRXTX />
|
||||
<showRadioHW />
|
||||
<showLEDs />
|
||||
<split>109</split>
|
||||
<zoom>9</zoom>
|
||||
</plugin_config>
|
||||
<width>756</width>
|
||||
<z>3</z>
|
||||
<height>150</height>
|
||||
<location_x>0</location_x>
|
||||
<location_y>436</location_y>
|
||||
<minimized>false</minimized>
|
||||
<width>680</width>
|
||||
<z>1</z>
|
||||
<height>240</height>
|
||||
<location_x>20</location_x>
|
||||
<location_y>285</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.ScriptRunner
|
||||
<plugin_config>
|
||||
<script>TIMEOUT(2000, log.log("last message: " + msg + "\n"));
|
||||
|
||||
WAIT_UNTIL(msg.startsWith('Hello, world'));
|
||||
log.testOK();</script>
|
||||
<scriptfile>[CONFIG_DIR]/hello-world.js</scriptfile>
|
||||
<active>true</active>
|
||||
</plugin_config>
|
||||
<width>600</width>
|
||||
<z>0</z>
|
||||
<height>305</height>
|
||||
<location_x>89</location_x>
|
||||
<location_y>211</location_y>
|
||||
<minimized>false</minimized>
|
||||
<height>535</height>
|
||||
<location_x>403</location_x>
|
||||
<location_y>23</location_y>
|
||||
</plugin>
|
||||
</simconf>
|
||||
|
||||
|
|
|
@ -15,8 +15,8 @@ msg = "";
|
|||
GENERATE_MSG(5000, "continue");
|
||||
WAIT_UNTIL(msg.equals("continue"));
|
||||
|
||||
/* override simulation delay to realtime */
|
||||
sim.setDelayTime(java.lang.Integer.MIN_VALUE);
|
||||
/* override simulation speed limit to realtime */
|
||||
sim.setSpeedLimit(1.0);
|
||||
|
||||
/* create tunnel interface */
|
||||
log.log("create tunnel interface\n");
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<simconf>
|
||||
<project>../apps/mrm</project>
|
||||
<project>../apps/mspsim</project>
|
||||
<project>../apps/avrora</project>
|
||||
<project>../apps/native_gateway</project>
|
||||
<simulation>
|
||||
<title>Hello World (Sky)</title>
|
||||
<delaytime>0</delaytime>
|
||||
<title>Hello World test (Sky)</title>
|
||||
<randomseed>generated</randomseed>
|
||||
<motedelay_us>1000000</motedelay_us>
|
||||
<radiomedium>
|
||||
|
@ -16,14 +11,16 @@
|
|||
<success_ratio_tx>1.0</success_ratio_tx>
|
||||
<success_ratio_rx>1.0</success_ratio_rx>
|
||||
</radiomedium>
|
||||
<events>
|
||||
<logoutput>40000</logoutput>
|
||||
</events>
|
||||
<motetype>
|
||||
se.sics.cooja.mspmote.SkyMoteType
|
||||
<identifier>sky1</identifier>
|
||||
<description>Sky Mote Type #1</description>
|
||||
<source>../../../examples/hello-world/hello-world.c</source>
|
||||
<commands>make clean TARGET=sky
|
||||
make hello-world.sky TARGET=sky</commands>
|
||||
<firmware>../../../examples/hello-world/hello-world.sky</firmware>
|
||||
<source EXPORT="discard">[CONTIKI_DIR]/examples/hello-world/hello-world.c</source>
|
||||
<commands EXPORT="discard">make hello-world.sky TARGET=sky</commands>
|
||||
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/hello-world/hello-world.sky</firmware>
|
||||
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
|
@ -31,13 +28,11 @@ make hello-world.sky TARGET=sky</commands>
|
|||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyButton</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyFlash</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyByteRadio</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.SkySerial</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspSerial</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyLED</moteinterface>
|
||||
</motetype>
|
||||
<mote>
|
||||
se.sics.cooja.mspmote.SkyMote
|
||||
<motetype_identifier>sky1</motetype_identifier>
|
||||
<breakpoints />
|
||||
<interface_config>
|
||||
se.sics.cooja.interfaces.Position
|
||||
|
@ -49,32 +44,39 @@ make hello-world.sky TARGET=sky</commands>
|
|||
se.sics.cooja.mspmote.interfaces.MspMoteID
|
||||
<id>1</id>
|
||||
</interface_config>
|
||||
<motetype_identifier>sky1</motetype_identifier>
|
||||
</mote>
|
||||
</simulation>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.SimControl
|
||||
<width>248</width>
|
||||
<z>1</z>
|
||||
<height>200</height>
|
||||
<location_x>0</location_x>
|
||||
<location_y>0</location_y>
|
||||
<minimized>false</minimized>
|
||||
</plugin>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.ScriptRunner
|
||||
<plugin_config>
|
||||
<script>TIMEOUT(2000, log.log("last message: " + msg + "\n"));
|
||||
|
||||
WAIT_UNTIL(msg.equals('Hello, world'));
|
||||
log.testOK();</script>
|
||||
<scriptfile>[CONFIG_DIR]/hello-world.js</scriptfile>
|
||||
<active>true</active>
|
||||
</plugin_config>
|
||||
<width>541</width>
|
||||
<z>0</z>
|
||||
<height>448</height>
|
||||
<location_x>248</location_x>
|
||||
<location_y>-1</location_y>
|
||||
<minimized>false</minimized>
|
||||
<location_x>299</location_x>
|
||||
<location_y>7</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.SimControl
|
||||
<width>280</width>
|
||||
<z>2</z>
|
||||
<height>160</height>
|
||||
<location_x>7</location_x>
|
||||
<location_y>10</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.LogListener
|
||||
<plugin_config>
|
||||
<filter />
|
||||
</plugin_config>
|
||||
<width>680</width>
|
||||
<z>1</z>
|
||||
<height>240</height>
|
||||
<location_x>51</location_x>
|
||||
<location_y>288</location_y>
|
||||
</plugin>
|
||||
</simconf>
|
||||
|
||||
|
|
84
tools/cooja/contiki_tests/wismote_helloworld.csc
Normal file
84
tools/cooja/contiki_tests/wismote_helloworld.csc
Normal file
|
@ -0,0 +1,84 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<simconf>
|
||||
<simulation>
|
||||
<title>Hello World (Wismote)</title>
|
||||
<randomseed>generated</randomseed>
|
||||
<motedelay_us>1000000</motedelay_us>
|
||||
<radiomedium>
|
||||
se.sics.cooja.radiomediums.UDGM
|
||||
<transmitting_range>50.0</transmitting_range>
|
||||
<interference_range>100.0</interference_range>
|
||||
<success_ratio_tx>1.0</success_ratio_tx>
|
||||
<success_ratio_rx>1.0</success_ratio_rx>
|
||||
</radiomedium>
|
||||
<events>
|
||||
<logoutput>40000</logoutput>
|
||||
</events>
|
||||
<motetype>
|
||||
se.sics.cooja.mspmote.WismoteMoteType
|
||||
<identifier>wismote1</identifier>
|
||||
<description>Wismote Mote Type #wismote1</description>
|
||||
<source EXPORT="discard">[CONTIKI_DIR]/examples/hello-world/hello-world.c</source>
|
||||
<commands EXPORT="discard">make hello-world.wismote TARGET=wismote</commands>
|
||||
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/hello-world/hello-world.wismote</firmware>
|
||||
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspButton</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspDefaultSerial</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspLED</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
|
||||
</motetype>
|
||||
<mote>
|
||||
<breakpoints />
|
||||
<interface_config>
|
||||
se.sics.cooja.interfaces.Position
|
||||
<x>36.76551518369201</x>
|
||||
<y>29.330591009779383</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
se.sics.cooja.mspmote.interfaces.MspMoteID
|
||||
<id>1</id>
|
||||
</interface_config>
|
||||
<motetype_identifier>wismote1</motetype_identifier>
|
||||
</mote>
|
||||
</simulation>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.SimControl
|
||||
<width>280</width>
|
||||
<z>2</z>
|
||||
<height>160</height>
|
||||
<location_x>22</location_x>
|
||||
<location_y>14</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.LogListener
|
||||
<plugin_config>
|
||||
<filter />
|
||||
</plugin_config>
|
||||
<width>680</width>
|
||||
<z>1</z>
|
||||
<height>240</height>
|
||||
<location_x>84</location_x>
|
||||
<location_y>408</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.ScriptRunner
|
||||
<plugin_config>
|
||||
<scriptfile>[CONFIG_DIR]/hello-world.js</scriptfile>
|
||||
<active>true</active>
|
||||
</plugin_config>
|
||||
<width>600</width>
|
||||
<z>0</z>
|
||||
<height>548</height>
|
||||
<location_x>335</location_x>
|
||||
<location_y>22</location_y>
|
||||
</plugin>
|
||||
</simconf>
|
||||
|
83
tools/cooja/contiki_tests/z1_helloworld.csc
Normal file
83
tools/cooja/contiki_tests/z1_helloworld.csc
Normal file
|
@ -0,0 +1,83 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<simconf>
|
||||
<simulation>
|
||||
<title>Hello World (Z1)</title>
|
||||
<randomseed>generated</randomseed>
|
||||
<motedelay_us>1000000</motedelay_us>
|
||||
<radiomedium>
|
||||
se.sics.cooja.radiomediums.UDGM
|
||||
<transmitting_range>50.0</transmitting_range>
|
||||
<interference_range>100.0</interference_range>
|
||||
<success_ratio_tx>1.0</success_ratio_tx>
|
||||
<success_ratio_rx>1.0</success_ratio_rx>
|
||||
</radiomedium>
|
||||
<events>
|
||||
<logoutput>40000</logoutput>
|
||||
</events>
|
||||
<motetype>
|
||||
se.sics.cooja.mspmote.Z1MoteType
|
||||
<identifier>z11</identifier>
|
||||
<description>Z1 Mote Type #z11</description>
|
||||
<source EXPORT="discard">[CONTIKI_DIR]/examples/hello-world/hello-world.c</source>
|
||||
<commands EXPORT="discard">make hello-world.z1 TARGET=z1</commands>
|
||||
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/hello-world/hello-world.z1</firmware>
|
||||
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspDefaultSerial</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspLED</moteinterface>
|
||||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
|
||||
</motetype>
|
||||
<mote>
|
||||
<breakpoints />
|
||||
<interface_config>
|
||||
se.sics.cooja.interfaces.Position
|
||||
<x>94.96401380574989</x>
|
||||
<y>21.247662337471553</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
se.sics.cooja.mspmote.interfaces.MspMoteID
|
||||
<id>1</id>
|
||||
</interface_config>
|
||||
<motetype_identifier>z11</motetype_identifier>
|
||||
</mote>
|
||||
</simulation>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.SimControl
|
||||
<width>280</width>
|
||||
<z>2</z>
|
||||
<height>160</height>
|
||||
<location_x>38</location_x>
|
||||
<location_y>13</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.LogListener
|
||||
<plugin_config>
|
||||
<filter />
|
||||
</plugin_config>
|
||||
<width>680</width>
|
||||
<z>1</z>
|
||||
<height>240</height>
|
||||
<location_x>109</location_x>
|
||||
<location_y>377</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
se.sics.cooja.plugins.ScriptRunner
|
||||
<plugin_config>
|
||||
<scriptfile>[CONFIG_DIR]/hello-world.js</scriptfile>
|
||||
<active>true</active>
|
||||
</plugin_config>
|
||||
<width>600</width>
|
||||
<z>0</z>
|
||||
<height>700</height>
|
||||
<location_x>330</location_x>
|
||||
<location_y>24</location_y>
|
||||
</plugin>
|
||||
</simconf>
|
||||
|
|
@ -39,6 +39,7 @@ import java.awt.Dimension;
|
|||
import java.awt.Frame;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Window;
|
||||
|
@ -296,12 +297,12 @@ public class GUI extends Observable {
|
|||
|
||||
protected GUIEventHandler guiEventHandler = new GUIEventHandler();
|
||||
|
||||
private JMenu toolsMenu, menuMoteTypeClasses, menuMoteTypes;
|
||||
private JMenu menuMoteTypeClasses, menuMoteTypes;
|
||||
|
||||
private JMenu menuOpenSimulation;
|
||||
private boolean hasFileHistoryChanged;
|
||||
|
||||
private Vector<Class<? extends Plugin>> menuMotePluginClasses;
|
||||
private Vector<Class<? extends Plugin>> menuMotePluginClasses = new Vector<Class<? extends Plugin>>();
|
||||
|
||||
private JDesktopPane myDesktopPane;
|
||||
|
||||
|
@ -369,17 +370,6 @@ public class GUI extends Observable {
|
|||
myGUI = this;
|
||||
mySimulation = null;
|
||||
myDesktopPane = desktop;
|
||||
if (toolsMenu == null) {
|
||||
toolsMenu = new JMenu("Tools");
|
||||
toolsMenu.removeAll();
|
||||
|
||||
/* COOJA/GUI plugins at top, simulation plugins in middle, mote plugins at bottom */
|
||||
/*toolsMenu.addSeparator();
|
||||
toolsMenu.addSeparator();*/
|
||||
}
|
||||
if (menuMotePluginClasses == null) {
|
||||
menuMotePluginClasses = new Vector<Class<? extends Plugin>>();
|
||||
}
|
||||
|
||||
/* Help panel */
|
||||
quickHelpTextPane = new JTextPane();
|
||||
|
@ -703,7 +693,7 @@ public class GUI extends Observable {
|
|||
JMenu fileMenu = new JMenu("File");
|
||||
JMenu simulationMenu = new JMenu("Simulation");
|
||||
JMenu motesMenu = new JMenu("Motes");
|
||||
/* toolsMenu = new JMenu("Tools"); */
|
||||
final JMenu toolsMenu = new JMenu("Tools");
|
||||
JMenu settingsMenu = new JMenu("Settings");
|
||||
JMenu helpMenu = new JMenu("Help");
|
||||
|
||||
|
@ -931,57 +921,119 @@ public class GUI extends Observable {
|
|||
|
||||
motesMenu.add(new JMenuItem(removeAllMotesAction));
|
||||
|
||||
// Tools menu
|
||||
/* Tools menu */
|
||||
toolsMenu.addMenuListener(new MenuListener() {
|
||||
public void menuSelected(MenuEvent e) {
|
||||
for (Component menuComponent: toolsMenu.getMenuComponents()) {
|
||||
if (!(menuComponent instanceof JMenuItem)) {
|
||||
continue;
|
||||
}
|
||||
JMenuItem menuItem = (JMenuItem) menuComponent;
|
||||
Class<? extends Plugin> pluginClass = (Class<? extends Plugin>) menuItem.getClientProperty("class");
|
||||
int pluginType;
|
||||
if (pluginClass.isAnnotationPresent(PluginType.class)) {
|
||||
pluginType = pluginClass.getAnnotation(PluginType.class).value();
|
||||
} else {
|
||||
pluginType = PluginType.UNDEFINED_PLUGIN;
|
||||
private ActionListener menuItemListener = new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Object pluginClass = ((JMenuItem)e.getSource()).getClientProperty("class");
|
||||
Object mote = ((JMenuItem)e.getSource()).getClientProperty("mote");
|
||||
tryStartPlugin((Class<? extends Plugin>) pluginClass, myGUI, getSimulation(), (Mote)mote);
|
||||
}
|
||||
};
|
||||
private JMenuItem createMenuItem(Class<? extends Plugin> newPluginClass, int pluginType) {
|
||||
String description = getDescriptionOf(newPluginClass);
|
||||
JMenuItem menuItem = new JMenuItem(description + "...");
|
||||
menuItem.putClientProperty("class", newPluginClass);
|
||||
menuItem.addActionListener(menuItemListener);
|
||||
|
||||
/* No simulation -> deactivate non-GUI plugins */
|
||||
String tooltip = "<html><pre>";
|
||||
if (pluginType == PluginType.COOJA_PLUGIN || pluginType == PluginType.COOJA_STANDARD_PLUGIN) {
|
||||
menuItem.setEnabled(true);
|
||||
continue;
|
||||
}
|
||||
/* Mote plugin -> not accessed from this menu */
|
||||
if (pluginType == PluginType.MOTE_PLUGIN) {
|
||||
menuItem.setEnabled(false);
|
||||
continue;
|
||||
}
|
||||
if (pluginType != PluginType.SIM_PLUGIN && pluginType != PluginType.SIM_STANDARD_PLUGIN) {
|
||||
/* Unknown */
|
||||
menuItem.setEnabled(false);
|
||||
continue;
|
||||
}
|
||||
tooltip += "Cooja plugin: ";
|
||||
} else if (pluginType == PluginType.SIM_PLUGIN || pluginType == PluginType.SIM_STANDARD_PLUGIN) {
|
||||
tooltip += "Simulation plugin: ";
|
||||
if (getSimulation() == null) {
|
||||
menuItem.setEnabled(false);
|
||||
continue;
|
||||
}
|
||||
} else if (pluginType == PluginType.MOTE_PLUGIN) {
|
||||
tooltip += "Mote plugin: ";
|
||||
}
|
||||
tooltip += description + " (" + newPluginClass.getName() + ")";
|
||||
|
||||
/* Check if simulation plugin depends on any particular radio medium */
|
||||
if (pluginClass.getAnnotation(SupportedArguments.class) != null) {
|
||||
menuItem.setEnabled(false);
|
||||
Class<? extends RadioMedium>[] radioMediums = pluginClass.getAnnotation(SupportedArguments.class).radioMediums();
|
||||
if (pluginType == PluginType.SIM_PLUGIN || pluginType == PluginType.SIM_STANDARD_PLUGIN) {
|
||||
if (newPluginClass.getAnnotation(SupportedArguments.class) != null) {
|
||||
boolean active = false;
|
||||
Class<? extends RadioMedium>[] radioMediums = newPluginClass.getAnnotation(SupportedArguments.class).radioMediums();
|
||||
for (Class<? extends Object> o: radioMediums) {
|
||||
if (o.isAssignableFrom(getSimulation().getRadioMedium().getClass())) {
|
||||
menuItem.setEnabled(true);
|
||||
active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
menuItem.setEnabled(true);
|
||||
if (!active) {
|
||||
menuItem.setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if plugin was imported by a extension directory */
|
||||
File project =
|
||||
getProjectConfig().getUserProjectDefining(GUI.class, "PLUGINS", newPluginClass.getName());
|
||||
if (project != null) {
|
||||
tooltip += "\nLoaded by extension: " + project.getPath();
|
||||
}
|
||||
|
||||
tooltip += "</html>";
|
||||
/*menuItem.setToolTipText(tooltip);*/
|
||||
return menuItem;
|
||||
}
|
||||
|
||||
public void menuSelected(MenuEvent e) {
|
||||
/* Populate tools menu */
|
||||
toolsMenu.removeAll();
|
||||
|
||||
/* Cooja plugins */
|
||||
boolean hasCoojaPlugins = false;
|
||||
for (Class<? extends Plugin> pluginClass: pluginClasses) {
|
||||
int pluginType = pluginClass.getAnnotation(PluginType.class).value();
|
||||
if (pluginType != PluginType.COOJA_PLUGIN && pluginType != PluginType.COOJA_STANDARD_PLUGIN) {
|
||||
continue;
|
||||
}
|
||||
toolsMenu.add(createMenuItem(pluginClass, pluginType));
|
||||
hasCoojaPlugins = true;
|
||||
}
|
||||
|
||||
/* Simulation plugins */
|
||||
boolean hasSimPlugins = false;
|
||||
for (Class<? extends Plugin> pluginClass: pluginClasses) {
|
||||
if (pluginClass.equals(SimControl.class)) {
|
||||
continue; /* ignore */
|
||||
}
|
||||
if (pluginClass.equals(SimInformation.class)) {
|
||||
continue; /* ignore */
|
||||
}
|
||||
if (pluginClass.equals(MoteTypeInformation.class)) {
|
||||
continue; /* ignore */
|
||||
}
|
||||
|
||||
int pluginType = pluginClass.getAnnotation(PluginType.class).value();
|
||||
if (pluginType != PluginType.SIM_PLUGIN && pluginType != PluginType.SIM_STANDARD_PLUGIN) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hasCoojaPlugins) {
|
||||
hasCoojaPlugins = false;
|
||||
toolsMenu.addSeparator();
|
||||
}
|
||||
|
||||
toolsMenu.add(createMenuItem(pluginClass, pluginType));
|
||||
hasSimPlugins = true;
|
||||
}
|
||||
|
||||
for (Class<? extends Plugin> pluginClass: pluginClasses) {
|
||||
int pluginType = pluginClass.getAnnotation(PluginType.class).value();
|
||||
if (pluginType != PluginType.MOTE_PLUGIN) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hasSimPlugins) {
|
||||
hasSimPlugins = false;
|
||||
toolsMenu.addSeparator();
|
||||
}
|
||||
|
||||
toolsMenu.add(createMotePluginsSubmenu(pluginClass));
|
||||
}
|
||||
}
|
||||
public void menuDeselected(MenuEvent e) {
|
||||
}
|
||||
public void menuCanceled(MenuEvent e) {
|
||||
|
@ -1051,10 +1103,6 @@ public class GUI extends Observable {
|
|||
menuItem.setEnabled(false);
|
||||
helpMenu.add(menuItem);
|
||||
|
||||
// Mote plugins popup menu (not available via menu bar)
|
||||
if (menuMotePluginClasses == null) {
|
||||
menuMotePluginClasses = new Vector<Class<? extends Plugin>>();
|
||||
}
|
||||
return menuBar;
|
||||
}
|
||||
|
||||
|
@ -1504,9 +1552,9 @@ public class GUI extends Observable {
|
|||
}
|
||||
|
||||
// Register plugins
|
||||
registerPlugin(SimControl.class, false); // Not in menu
|
||||
registerPlugin(SimInformation.class, false); // Not in menu
|
||||
registerPlugin(MoteTypeInformation.class, false); // Not in menu
|
||||
registerPlugin(SimControl.class);
|
||||
registerPlugin(SimInformation.class);
|
||||
registerPlugin(MoteTypeInformation.class);
|
||||
String[] pluginClassNames = projectConfig.getStringArrayValue(GUI.class,
|
||||
"PLUGINS");
|
||||
if (pluginClassNames != null) {
|
||||
|
@ -1816,155 +1864,54 @@ public class GUI extends Observable {
|
|||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a plugin to be included in the GUI. The plugin will be visible in
|
||||
* the menubar.
|
||||
*
|
||||
* @param newPluginClass
|
||||
* New plugin to register
|
||||
* @return True if this plugin was registered ok, false otherwise
|
||||
*/
|
||||
public boolean registerPlugin(Class<? extends Plugin> newPluginClass) {
|
||||
return registerPlugin(newPluginClass, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a plugin class. Removes any plugin menu items links as well.
|
||||
*
|
||||
* @param pluginClass Plugin class
|
||||
*/
|
||||
public void unregisterPlugin(Class<? extends Plugin> pluginClass) {
|
||||
/* Remove from menu */
|
||||
for (Component menuComponent : toolsMenu.getMenuComponents()) {
|
||||
if (!(menuComponent instanceof JMenuItem)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
JMenuItem menuItem = (JMenuItem) menuComponent;
|
||||
if (menuItem.getClientProperty("class").equals(pluginClass)) {
|
||||
toolsMenu.remove(menuItem);
|
||||
}
|
||||
}
|
||||
|
||||
menuMotePluginClasses.remove(pluginClass);
|
||||
pluginClasses.remove(pluginClass);
|
||||
menuMotePluginClasses.remove(pluginClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a plugin to be included in the GUI.
|
||||
*
|
||||
* @param newPluginClass
|
||||
* New plugin to register
|
||||
* @param addToMenu
|
||||
* Should this plugin be added to the dedicated plugins menubar?
|
||||
* @param pluginClass New plugin to register
|
||||
* @return True if this plugin was registered ok, false otherwise
|
||||
*/
|
||||
private boolean registerPlugin(final Class<? extends Plugin> newPluginClass,
|
||||
boolean addToMenu) {
|
||||
public boolean registerPlugin(final Class<? extends Plugin> pluginClass) {
|
||||
|
||||
// Get description annotation (if any)
|
||||
final String description = getDescriptionOf(newPluginClass);
|
||||
|
||||
// Get plugin type annotation (required)
|
||||
/* Check plugin type */
|
||||
final int pluginType;
|
||||
if (newPluginClass.isAnnotationPresent(PluginType.class)) {
|
||||
pluginType = newPluginClass.getAnnotation(PluginType.class).value();
|
||||
if (pluginClass.isAnnotationPresent(PluginType.class)) {
|
||||
pluginType = pluginClass.getAnnotation(PluginType.class).value();
|
||||
} else {
|
||||
pluginType = PluginType.UNDEFINED_PLUGIN;
|
||||
}
|
||||
|
||||
// Check that plugin type is valid and constructor exists
|
||||
try {
|
||||
if (pluginType == PluginType.MOTE_PLUGIN) {
|
||||
newPluginClass.getConstructor(new Class[] { Mote.class,
|
||||
Simulation.class, GUI.class });
|
||||
} else if (pluginType == PluginType.SIM_PLUGIN
|
||||
|| pluginType == PluginType.SIM_STANDARD_PLUGIN) {
|
||||
newPluginClass.getConstructor(new Class[] { Simulation.class, GUI.class });
|
||||
} else if (pluginType == PluginType.COOJA_PLUGIN
|
||||
|| pluginType == PluginType.COOJA_STANDARD_PLUGIN) {
|
||||
newPluginClass.getConstructor(new Class[] { GUI.class });
|
||||
} else {
|
||||
logger.fatal("Could not find valid plugin type annotation in class " + newPluginClass);
|
||||
logger.fatal("Could not register plugin, no plugin type found: " + pluginClass);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check plugin constructor */
|
||||
try {
|
||||
if (pluginType == PluginType.COOJA_PLUGIN || pluginType == PluginType.COOJA_STANDARD_PLUGIN) {
|
||||
pluginClass.getConstructor(new Class[] { GUI.class });
|
||||
} else if (pluginType == PluginType.SIM_PLUGIN || pluginType == PluginType.SIM_STANDARD_PLUGIN) {
|
||||
pluginClass.getConstructor(new Class[] { Simulation.class, GUI.class });
|
||||
} else if (pluginType == PluginType.MOTE_PLUGIN) {
|
||||
pluginClass.getConstructor(new Class[] { Mote.class, Simulation.class, GUI.class });
|
||||
menuMotePluginClasses.add(pluginClass);
|
||||
} else {
|
||||
logger.fatal("Could not register plugin, bad plugin type: " + pluginType);
|
||||
return false;
|
||||
}
|
||||
pluginClasses.add(pluginClass);
|
||||
} catch (NoClassDefFoundError e) {
|
||||
logger.fatal("No plugin class: " + newPluginClass + ": " + e.getMessage());
|
||||
logger.fatal("No plugin class: " + pluginClass + ": " + e.getMessage());
|
||||
return false;
|
||||
} catch (NoSuchMethodException e) {
|
||||
logger.fatal("No plugin class constructor: " + newPluginClass + ": " + e.getMessage());
|
||||
logger.fatal("No plugin class constructor: " + pluginClass + ": " + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (addToMenu && toolsMenu != null) {
|
||||
new RunnableInEDT<Boolean>() {
|
||||
public Boolean work() {
|
||||
// Create 'start plugin'-menu item
|
||||
JMenuItem menuItem;
|
||||
String tooltip = "<html><pre>";
|
||||
|
||||
/* Sort menu according to plugin type */
|
||||
int itemIndex=0;
|
||||
if (pluginType == PluginType.COOJA_PLUGIN || pluginType == PluginType.COOJA_STANDARD_PLUGIN) {
|
||||
for (; itemIndex < toolsMenu.getItemCount(); itemIndex++) {
|
||||
if (toolsMenu.getItem(itemIndex) == null /* separator */) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
tooltip += "Cooja plugin: " + newPluginClass.getName();
|
||||
menuItem = new JMenuItem(description);
|
||||
menuItem.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
tryStartPlugin(newPluginClass, myGUI, null, null);
|
||||
}
|
||||
});
|
||||
} else if (pluginType == PluginType.SIM_PLUGIN || pluginType == PluginType.SIM_STANDARD_PLUGIN) {
|
||||
for (; itemIndex < toolsMenu.getItemCount(); itemIndex++) {
|
||||
if (toolsMenu.getItem(itemIndex) == null /* separator */) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
itemIndex++;
|
||||
for (; itemIndex < toolsMenu.getItemCount(); itemIndex++) {
|
||||
if (toolsMenu.getItem(itemIndex) == null /* separator */) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
tooltip += "Simulation plugin: " + newPluginClass.getName();
|
||||
GUIAction guiAction = new StartPluginGUIAction(description);
|
||||
menuItem = new JMenuItem(guiAction);
|
||||
guiActions.add(guiAction);
|
||||
} else if (pluginType == PluginType.MOTE_PLUGIN) {
|
||||
// Disable previous menu item and add new item to mote plugins menu
|
||||
menuItem = new JMenuItem(description);
|
||||
menuItem.setEnabled(false);
|
||||
tooltip += "Mote plugin: " + newPluginClass.getName();
|
||||
tooltip += "\nStart mote plugins by right-clicking a mote in the simulation visualizer";
|
||||
menuMotePluginClasses.add(newPluginClass);
|
||||
itemIndex = toolsMenu.getItemCount();
|
||||
} else {
|
||||
logger.warn("Unknown plugin type: " + pluginType);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check if plugin was imported by a extension directory */
|
||||
File project =
|
||||
getProjectConfig().getUserProjectDefining(GUI.class, "PLUGINS", newPluginClass.getName());
|
||||
if (project != null) {
|
||||
tooltip += "\nLoaded by extension: " + project.getPath();
|
||||
}
|
||||
|
||||
tooltip += "</html>";
|
||||
/*menuItem.setToolTipText(tooltip); */
|
||||
menuItem.putClientProperty("class", newPluginClass);
|
||||
|
||||
toolsMenu.add(menuItem, itemIndex);
|
||||
return true;
|
||||
}
|
||||
}.invokeAndWait();
|
||||
}
|
||||
|
||||
pluginClasses.add(newPluginClass);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1972,16 +1919,7 @@ public class GUI extends Observable {
|
|||
* Unregister all plugin classes
|
||||
*/
|
||||
public void unregisterPlugins() {
|
||||
if (toolsMenu != null) {
|
||||
toolsMenu.removeAll();
|
||||
|
||||
/* COOJA/GUI plugins at top, simulation plugins in middle, mote plugins at bottom */
|
||||
toolsMenu.addSeparator();
|
||||
toolsMenu.addSeparator();
|
||||
}
|
||||
if (menuMotePluginClasses != null) {
|
||||
menuMotePluginClasses.clear();
|
||||
}
|
||||
pluginClasses.clear();
|
||||
}
|
||||
|
||||
|
@ -2016,6 +1954,107 @@ public class GUI extends Observable {
|
|||
return startedPlugins.toArray(new Plugin[0]);
|
||||
}
|
||||
|
||||
private boolean isMotePluginCompatible(Class<? extends Plugin> motePluginClass, Mote mote) {
|
||||
if (motePluginClass.getAnnotation(SupportedArguments.class) == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Check mote interfaces */
|
||||
boolean moteInterfacesOK = true;
|
||||
Class<? extends MoteInterface>[] moteInterfaces =
|
||||
motePluginClass.getAnnotation(SupportedArguments.class).moteInterfaces();
|
||||
StringBuilder moteTypeInterfacesError = new StringBuilder();
|
||||
moteTypeInterfacesError.append(
|
||||
"The plugin:\n" +
|
||||
getDescriptionOf(motePluginClass) +
|
||||
"\nrequires the following mote interfaces:\n"
|
||||
);
|
||||
for (Class<? extends MoteInterface> requiredMoteInterface: moteInterfaces) {
|
||||
moteTypeInterfacesError.append(getDescriptionOf(requiredMoteInterface) + "\n");
|
||||
if (mote.getInterfaces().getInterfaceOfType(requiredMoteInterface) == null) {
|
||||
moteInterfacesOK = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check mote type */
|
||||
boolean moteTypeOK = false;
|
||||
Class<? extends Mote>[] motes =
|
||||
motePluginClass.getAnnotation(SupportedArguments.class).motes();
|
||||
StringBuilder moteTypeError = new StringBuilder();
|
||||
moteTypeError.append(
|
||||
"The plugin:\n" +
|
||||
getDescriptionOf(motePluginClass) +
|
||||
"\ndoes not support motes of type:\n" +
|
||||
getDescriptionOf(mote) +
|
||||
"\n\nIt only supports motes of types:\n"
|
||||
);
|
||||
for (Class<? extends Mote> supportedMote: motes) {
|
||||
moteTypeError.append(getDescriptionOf(supportedMote) + "\n");
|
||||
if (supportedMote.isAssignableFrom(mote.getClass())) {
|
||||
moteTypeOK = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*if (!moteInterfacesOK) {
|
||||
menuItem.setToolTipText(
|
||||
"<html><pre>" + moteTypeInterfacesError + "</html>"
|
||||
);
|
||||
}
|
||||
if (!moteTypeOK) {
|
||||
menuItem.setToolTipText(
|
||||
"<html><pre>" + moteTypeError + "</html>"
|
||||
);
|
||||
}*/
|
||||
|
||||
return moteInterfacesOK && moteTypeOK;
|
||||
}
|
||||
|
||||
public JMenu createMotePluginsSubmenu(Class<? extends Plugin> pluginClass) {
|
||||
JMenu menu = new JMenu(getDescriptionOf(pluginClass));
|
||||
if (getSimulation() == null || getSimulation().getMotesCount() == 0) {
|
||||
menu.setEnabled(false);
|
||||
return menu;
|
||||
}
|
||||
|
||||
ActionListener menuItemListener = new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Object pluginClass = ((JMenuItem)e.getSource()).getClientProperty("class");
|
||||
Object mote = ((JMenuItem)e.getSource()).getClientProperty("mote");
|
||||
tryStartPlugin((Class<? extends Plugin>) pluginClass, myGUI, getSimulation(), (Mote)mote);
|
||||
}
|
||||
};
|
||||
|
||||
final int MAX_PER_ROW = 30;
|
||||
final int MAX_COLUMNS = 5;
|
||||
|
||||
int added = 0;
|
||||
for (Mote mote: getSimulation().getMotes()) {
|
||||
if (!isMotePluginCompatible(pluginClass, mote)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
JMenuItem menuItem = new JMenuItem(mote.toString() + "...");
|
||||
menuItem.putClientProperty("class", pluginClass);
|
||||
menuItem.putClientProperty("mote", mote);
|
||||
menuItem.addActionListener(menuItemListener);
|
||||
|
||||
menu.add(menuItem);
|
||||
added++;
|
||||
|
||||
if (added == MAX_PER_ROW) {
|
||||
menu.getPopupMenu().setLayout(new GridLayout(MAX_PER_ROW, MAX_COLUMNS));
|
||||
}
|
||||
if (added >= MAX_PER_ROW*MAX_COLUMNS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (added == 0) {
|
||||
menu.setEnabled(false);
|
||||
}
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a mote plugins submenu for given mote.
|
||||
*
|
||||
|
@ -2026,38 +2065,15 @@ public class GUI extends Observable {
|
|||
JMenu menuMotePlugins = new JMenu("Mote tools for " + mote);
|
||||
|
||||
for (Class<? extends Plugin> motePluginClass: menuMotePluginClasses) {
|
||||
GUIAction guiAction = new StartPluginGUIAction(getDescriptionOf(motePluginClass));
|
||||
if (!isMotePluginCompatible(motePluginClass, mote)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
GUIAction guiAction = new StartPluginGUIAction(getDescriptionOf(motePluginClass) + "...");
|
||||
JMenuItem menuItem = new JMenuItem(guiAction);
|
||||
menuItem.putClientProperty("class", motePluginClass);
|
||||
menuItem.putClientProperty("mote", mote);
|
||||
|
||||
/* Check if mote plugin depends on any particular type of mote */
|
||||
boolean enableMenuItem = true;
|
||||
if (motePluginClass.getAnnotation(SupportedArguments.class) != null) {
|
||||
enableMenuItem = false;
|
||||
Class<? extends Mote>[] motes = motePluginClass.getAnnotation(SupportedArguments.class).motes();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(
|
||||
"<html><pre>This plugin:\n" +
|
||||
motePluginClass.getName() +
|
||||
"\ndoes not support motes of type:\n" +
|
||||
mote.getClass().getName() +
|
||||
"\n\nIt only supports motes of types:\n"
|
||||
);
|
||||
for (Class<? extends Object> o: motes) {
|
||||
sb.append(o.getName() + "\n");
|
||||
if (o.isAssignableFrom(mote.getClass())) {
|
||||
enableMenuItem = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sb.append("</html>");
|
||||
if (!enableMenuItem) {
|
||||
menuItem.setToolTipText(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
menuItem.setEnabled(enableMenuItem);
|
||||
menuMotePlugins.add(menuItem);
|
||||
}
|
||||
return menuMotePlugins;
|
||||
|
@ -2607,6 +2623,7 @@ public class GUI extends Observable {
|
|||
mySimulation.addMote(newMote);
|
||||
}
|
||||
}
|
||||
updateGUIComponentState();
|
||||
|
||||
} else {
|
||||
logger.warn("No simulation active");
|
||||
|
@ -4521,6 +4538,7 @@ public class GUI extends Observable {
|
|||
return getSimulation() != null;
|
||||
}
|
||||
}
|
||||
|
||||
GUIAction removeAllMotesAction = new GUIAction("Remove all motes") {
|
||||
private static final long serialVersionUID = 4709776747913364419L;
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
|
|
@ -61,4 +61,9 @@ public @interface SupportedArguments {
|
|||
* @return List of accepted radio medium classes.
|
||||
*/
|
||||
Class<? extends RadioMedium>[] radioMediums() default { RadioMedium.class };
|
||||
|
||||
/**
|
||||
* @return List of required mote interfaces.
|
||||
*/
|
||||
Class<? extends MoteInterface>[] moteInterfaces() default { MoteInterface.class };
|
||||
}
|
||||
|
|
|
@ -25,19 +25,20 @@
|
|||
* 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: ContikiClock.java,v 1.13 2010/02/05 08:49:18 fros4943 Exp $
|
||||
*/
|
||||
|
||||
package se.sics.cooja.contikimote.interfaces;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.jdom.Element;
|
||||
|
||||
import se.sics.cooja.*;
|
||||
import se.sics.cooja.Mote;
|
||||
import se.sics.cooja.SectionMoteMemory;
|
||||
import se.sics.cooja.Simulation;
|
||||
import se.sics.cooja.contikimote.ContikiMote;
|
||||
import se.sics.cooja.contikimote.ContikiMoteInterface;
|
||||
import se.sics.cooja.interfaces.Clock;
|
||||
|
@ -137,12 +138,12 @@ public class ContikiClock extends Clock implements ContikiMoteInterface, PolledB
|
|||
/* Request tick next wakeup time */
|
||||
int nextExpirationTime = moteMem.getIntValueOf("simNextExpirationTime");
|
||||
if (nextExpirationTime <= 0) {
|
||||
logger.warn("Event timer already expired, but has been delayed: " + nextExpirationTime);
|
||||
/*logger.warn("Event timer already expired, but has been delayed: " + nextExpirationTime);*/
|
||||
mote.scheduleNextWakeup(simulation.getSimulationTime() + Simulation.MILLISECOND);
|
||||
return;
|
||||
}
|
||||
|
||||
mote.scheduleNextWakeup(simulation.getSimulationTime() + Simulation.MILLISECOND*(long)nextExpirationTime);
|
||||
mote.scheduleNextWakeup(simulation.getSimulationTime() + Simulation.MILLISECOND*nextExpirationTime);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
* 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: ScriptRunner.java,v 1.28 2010/08/17 15:03:52 fros4943 Exp $
|
||||
*/
|
||||
|
||||
package se.sics.cooja.plugins;
|
||||
|
@ -71,6 +69,8 @@ import javax.swing.JPopupMenu;
|
|||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.event.MenuEvent;
|
||||
import javax.swing.event.MenuListener;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
|
||||
import jsyntaxpane.DefaultSyntaxKit;
|
||||
|
@ -110,15 +110,13 @@ public class ScriptRunner extends VisPlugin {
|
|||
};
|
||||
|
||||
private Simulation simulation;
|
||||
|
||||
private LogScriptEngine engine = null;
|
||||
private LogScriptEngine engine;
|
||||
|
||||
private static BufferedWriter logWriter = null; /* For non-GUI tests */
|
||||
|
||||
private JEditorPane codeEditor = null;
|
||||
|
||||
private JTextArea logTextArea = null;
|
||||
/*private JButton toggleButton = null;*/
|
||||
private JEditorPane codeEditor;
|
||||
private JTextArea logTextArea;
|
||||
private JSplitPane centerPanel;
|
||||
|
||||
private JSyntaxLinkFile actionLinkFile = null;
|
||||
private File linkedFile = null;
|
||||
|
@ -126,6 +124,7 @@ public class ScriptRunner extends VisPlugin {
|
|||
public ScriptRunner(Simulation simulation, GUI gui) {
|
||||
super("Simulation script editor", gui, false);
|
||||
this.simulation = simulation;
|
||||
this.engine = null;
|
||||
|
||||
/* Menus */
|
||||
JMenuBar menuBar = new JMenuBar();
|
||||
|
@ -139,9 +138,8 @@ public class ScriptRunner extends VisPlugin {
|
|||
|
||||
this.setJMenuBar(menuBar);
|
||||
|
||||
/* Examples popup menu */
|
||||
JMenu examplesMenu = new JMenu("Load example script");
|
||||
|
||||
/* Example scripts */
|
||||
final JMenu examplesMenu = new JMenu("Load example script");
|
||||
for (int i=0; i < EXAMPLE_SCRIPTS.length; i += 2) {
|
||||
final String file = EXAMPLE_SCRIPTS[i];
|
||||
JMenuItem exampleItem = new JMenuItem(EXAMPLE_SCRIPTS[i+1]);
|
||||
|
@ -159,11 +157,10 @@ public class ScriptRunner extends VisPlugin {
|
|||
});
|
||||
examplesMenu.add(exampleItem);
|
||||
}
|
||||
|
||||
fileMenu.add(examplesMenu);
|
||||
|
||||
{
|
||||
/* Workaround to configure jsyntaxpane */
|
||||
/* XXX Workaround to configure jsyntaxpane */
|
||||
JEditorPane e = new JEditorPane();
|
||||
new JScrollPane(e);
|
||||
e.setContentType("text/javascript");
|
||||
|
@ -171,6 +168,7 @@ public class ScriptRunner extends VisPlugin {
|
|||
DefaultSyntaxKit kit = (DefaultSyntaxKit) e.getEditorKit();
|
||||
kit.setProperty("PopupMenu", "copy-to-clipboard,-,find,find-next,goto-line,-,linkfile");
|
||||
kit.setProperty("Action.linkfile", JSyntaxLinkFile.class.getName());
|
||||
kit.setProperty("Action.execute-script", "jsyntaxpane.actions.ScriptRunnerAction");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,16 +181,11 @@ public class ScriptRunner extends VisPlugin {
|
|||
logTextArea.setEditable(true);
|
||||
logTextArea.setCursor(null);
|
||||
|
||||
/*toggleButton = new JButton("Activate");*/
|
||||
JCheckBoxMenuItem activateMenuItem = new JCheckBoxMenuItem("Activate");
|
||||
final JCheckBoxMenuItem activateMenuItem = new JCheckBoxMenuItem("Activate");
|
||||
activateMenuItem.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent ev) {
|
||||
try {
|
||||
if (!isActive()) {
|
||||
setScriptActive(true);
|
||||
} else {
|
||||
setScriptActive(false);
|
||||
}
|
||||
setScriptActive(!isActive());
|
||||
} catch (Exception e) {
|
||||
logger.fatal("Error: " + e.getMessage(), e);
|
||||
}
|
||||
|
@ -200,8 +193,7 @@ public class ScriptRunner extends VisPlugin {
|
|||
});
|
||||
runMenu.add(activateMenuItem);
|
||||
|
||||
/*JButton runTestButton = new JButton("Run without GUI");*/
|
||||
JMenuItem runTestMenuItem = new JMenuItem("Save simulation and run with script");
|
||||
final JMenuItem runTestMenuItem = new JMenuItem("Save simulation and run with script");
|
||||
runMenu.add(runTestMenuItem);
|
||||
runTestMenuItem.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
@ -210,41 +202,58 @@ public class ScriptRunner extends VisPlugin {
|
|||
});
|
||||
|
||||
doLayout();
|
||||
JSplitPane centerPanel = new JSplitPane(
|
||||
centerPanel = new JSplitPane(
|
||||
JSplitPane.VERTICAL_SPLIT,
|
||||
new JScrollPane(codeEditor),
|
||||
new JScrollPane(logTextArea)
|
||||
);
|
||||
|
||||
MenuListener toggleMenuItems = new MenuListener() {
|
||||
public void menuSelected(MenuEvent e) {
|
||||
activateMenuItem.setSelected(isActive());
|
||||
runTestMenuItem.setEnabled(!isActive());
|
||||
examplesMenu.setEnabled(!isActive());
|
||||
}
|
||||
public void menuDeselected(MenuEvent e) {
|
||||
}
|
||||
public void menuCanceled(MenuEvent e) {
|
||||
}
|
||||
};
|
||||
fileMenu.addMenuListener(toggleMenuItems);
|
||||
editMenu.addMenuListener(toggleMenuItems);
|
||||
runMenu.addMenuListener(toggleMenuItems);
|
||||
|
||||
|
||||
codeEditor.setContentType("text/javascript");
|
||||
if (codeEditor.getEditorKit() instanceof DefaultSyntaxKit) {
|
||||
DefaultSyntaxKit kit = (DefaultSyntaxKit) codeEditor.getEditorKit();
|
||||
kit.setProperty("PopupMenu", "copy-to-clipboard,-,find,find-next,goto-line,-,linkfile");
|
||||
kit.setProperty("Action.linkfile", JSyntaxLinkFile.class.getName());
|
||||
kit.setProperty("Action.execute-script", "jsyntaxpane.actions.ScriptRunnerAction");
|
||||
}
|
||||
|
||||
JPopupMenu p = codeEditor.getComponentPopupMenu();
|
||||
if (p != null) {
|
||||
for (Component c: p.getComponents()) {
|
||||
if (c instanceof JMenuItem) {
|
||||
if (((JMenuItem) c).getAction() != null &&
|
||||
((JMenuItem) c).getAction() instanceof JSyntaxLinkFile) {
|
||||
actionLinkFile = (JSyntaxLinkFile)(((JMenuItem) c).getAction());
|
||||
if (!(c instanceof JMenuItem)) {
|
||||
continue;
|
||||
}
|
||||
if (((JMenuItem) c).getAction() == null) {
|
||||
continue;
|
||||
}
|
||||
Action a = ((JMenuItem) c).getAction();
|
||||
if (a instanceof JSyntaxLinkFile) {
|
||||
actionLinkFile = (JSyntaxLinkFile) a;
|
||||
actionLinkFile.setMenuText("Link script to disk file");
|
||||
actionLinkFile.putValue("ScriptRunner", this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
centerPanel.setOneTouchExpandable(true);
|
||||
centerPanel.setResizeWeight(0.5);
|
||||
|
||||
JPanel buttonPanel = new JPanel(new BorderLayout());
|
||||
/*buttonPanel.add(BorderLayout.CENTER, toggleButton);*/
|
||||
|
||||
/* buttonPanel.add(BorderLayout.EAST, runTestButton);*/
|
||||
|
||||
JPanel southPanel = new JPanel(new BorderLayout());
|
||||
southPanel.add(BorderLayout.EAST, buttonPanel);
|
||||
|
||||
|
@ -280,6 +289,7 @@ public class ScriptRunner extends VisPlugin {
|
|||
codeEditor.setEditable(true);
|
||||
} else {
|
||||
updateScript(linkedFile);
|
||||
GUI.setExternalToolsSetting("SCRIPTRUNNER_LAST_SCRIPTFILE", source.getAbsolutePath());
|
||||
|
||||
if (actionLinkFile != null) {
|
||||
actionLinkFile.setMenuText("Unlink script: " + source.getName());
|
||||
|
@ -357,9 +367,9 @@ public class ScriptRunner extends VisPlugin {
|
|||
engine.activateScript(codeEditor.getText());
|
||||
|
||||
if (!headless) {
|
||||
if (actionLinkFile != null) {
|
||||
actionLinkFile.setEnabled(false);
|
||||
/* toggleButton.setText("Deactivate");*/
|
||||
/*examplesButton.setEnabled(false);*/
|
||||
}
|
||||
logTextArea.setText("");
|
||||
codeEditor.setEnabled(false);
|
||||
updateTitle();
|
||||
|
@ -402,9 +412,9 @@ public class ScriptRunner extends VisPlugin {
|
|||
}
|
||||
|
||||
if (!headless) {
|
||||
if (actionLinkFile != null) {
|
||||
actionLinkFile.setEnabled(true);
|
||||
/*toggleButton.setText("Activate")*/;
|
||||
/*examplesButton.setEnabled(linkedFile==null?true:false);*/
|
||||
}
|
||||
codeEditor.setEnabled(true);
|
||||
updateTitle();
|
||||
}
|
||||
|
@ -413,14 +423,14 @@ public class ScriptRunner extends VisPlugin {
|
|||
}
|
||||
|
||||
private void updateTitle() {
|
||||
/*String title = "Contiki Test Editor ";
|
||||
String title = "Simulation script editor ";
|
||||
if (linkedFile != null) {
|
||||
title += ": " + linkedFile.getName() + " ";
|
||||
title += "(" + linkedFile.getName() + ") ";
|
||||
}
|
||||
if (isActive()) {
|
||||
title += "(ACTIVE) ";
|
||||
title += "*active*";
|
||||
}
|
||||
setTitle(title);*/
|
||||
setTitle(title);
|
||||
}
|
||||
|
||||
private void exportAndRun() {
|
||||
|
@ -609,7 +619,6 @@ public class ScriptRunner extends VisPlugin {
|
|||
element = new Element("scriptfile");
|
||||
element.setText(simulation.getGUI().createPortablePath(linkedFile).getPath().replace('\\', '/'));
|
||||
config.add(element);
|
||||
/*StringUtils.saveToFile(scriptFile, scriptTextArea.getText());*/
|
||||
} else {
|
||||
element = new Element("script");
|
||||
element.setText(codeEditor.getText());
|
||||
|
@ -692,7 +701,12 @@ public class ScriptRunner extends VisPlugin {
|
|||
}
|
||||
|
||||
JFileChooser fileChooser = new JFileChooser();
|
||||
String suggest = GUI.getExternalToolsSetting("SCRIPTRUNNER_LAST_SCRIPTFILE", null);
|
||||
if (suggest != null) {
|
||||
fileChooser.setSelectedFile(new File(suggest));
|
||||
} else {
|
||||
fileChooser.setCurrentDirectory(new java.io.File("."));
|
||||
}
|
||||
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
fileChooser.setDialogTitle("Select script file");
|
||||
fileChooser.setFileFilter(new FileFilter() {
|
||||
|
|
|
@ -37,7 +37,6 @@ import java.awt.Cursor;
|
|||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.MouseInfo;
|
||||
import java.awt.Point;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.RenderingHints;
|
||||
|
@ -54,6 +53,7 @@ import java.awt.event.ActionEvent;
|
|||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseMotionListener;
|
||||
|
@ -68,7 +68,7 @@ import java.util.Observable;
|
|||
import java.util.Observer;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.JCheckBoxMenuItem;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuBar;
|
||||
|
@ -77,9 +77,12 @@ import javax.swing.JOptionPane;
|
|||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JSeparator;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.MenuElement;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.Timer;
|
||||
import javax.swing.event.MenuEvent;
|
||||
import javax.swing.event.MenuListener;
|
||||
import javax.swing.plaf.basic.BasicInternalFrameUI;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
@ -87,16 +90,16 @@ import org.jdom.Element;
|
|||
|
||||
import se.sics.cooja.ClassDescription;
|
||||
import se.sics.cooja.GUI;
|
||||
import se.sics.cooja.GUI.MoteRelation;
|
||||
import se.sics.cooja.HasQuickHelp;
|
||||
import se.sics.cooja.Mote;
|
||||
import se.sics.cooja.MoteInterface;
|
||||
import se.sics.cooja.PluginType;
|
||||
import se.sics.cooja.RadioMedium;
|
||||
import se.sics.cooja.SimEventCentral.MoteCountListener;
|
||||
import se.sics.cooja.Simulation;
|
||||
import se.sics.cooja.SupportedArguments;
|
||||
import se.sics.cooja.VisPlugin;
|
||||
import se.sics.cooja.GUI.MoteRelation;
|
||||
import se.sics.cooja.SimEventCentral.MoteCountListener;
|
||||
import se.sics.cooja.interfaces.LED;
|
||||
import se.sics.cooja.interfaces.Position;
|
||||
import se.sics.cooja.interfaces.SerialPort;
|
||||
|
@ -160,7 +163,6 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
|||
private Cursor moveCursor = new Cursor(Cursor.MOVE_CURSOR);
|
||||
|
||||
/* Visualizers */
|
||||
private final JButton skinButton = new JButton("Select visualizer skins");
|
||||
private static ArrayList<Class<? extends VisualizerSkin>> visualizerSkins =
|
||||
new ArrayList<Class<? extends VisualizerSkin>>();
|
||||
static {
|
||||
|
@ -224,6 +226,16 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
|||
JMenuBar menuBar = new JMenuBar();
|
||||
|
||||
viewMenu = new JMenu("View");
|
||||
viewMenu.addMenuListener(new MenuListener() {
|
||||
public void menuSelected(MenuEvent e) {
|
||||
viewMenu.removeAll();
|
||||
populateSkinMenu(viewMenu);
|
||||
}
|
||||
public void menuDeselected(MenuEvent e) {
|
||||
}
|
||||
public void menuCanceled(MenuEvent e) {
|
||||
}
|
||||
});
|
||||
JMenu zoomMenu = new JMenu("Zoom");
|
||||
|
||||
menuBar.add(viewMenu);
|
||||
|
@ -231,20 +243,28 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
|||
|
||||
this.setJMenuBar(menuBar);
|
||||
|
||||
JMenuItem zoomInItem = new JMenuItem("Zoom in");
|
||||
zoomInItem.addActionListener(new ActionListener() {
|
||||
Action zoomInAction = new AbstractAction("Zoom in") {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
zoomToFactor(zoomFactor() * 1.2);
|
||||
}
|
||||
});
|
||||
};
|
||||
zoomInAction.putValue(
|
||||
Action.ACCELERATOR_KEY,
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, ActionEvent.CTRL_MASK)
|
||||
);
|
||||
JMenuItem zoomInItem = new JMenuItem(zoomInAction);
|
||||
zoomMenu.add(zoomInItem);
|
||||
|
||||
JMenuItem zoomOutItem = new JMenuItem("Zoom out");
|
||||
zoomOutItem.addActionListener(new ActionListener() {
|
||||
Action zoomOutAction = new AbstractAction("Zoom out") {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
zoomToFactor(zoomFactor() / 1.2);
|
||||
}
|
||||
});
|
||||
};
|
||||
zoomOutAction.putValue(
|
||||
Action.ACCELERATOR_KEY,
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, ActionEvent.CTRL_MASK)
|
||||
);
|
||||
JMenuItem zoomOutItem = new JMenuItem(zoomOutAction);
|
||||
zoomMenu.add(zoomOutItem);
|
||||
|
||||
JMenuItem resetViewportItem = new JMenuItem("Reset viewport");
|
||||
|
@ -280,20 +300,6 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
|||
canvas.setBackground(Color.WHITE);
|
||||
viewportTransform = new AffineTransform();
|
||||
|
||||
/* Skin selector */
|
||||
skinButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Point mouse = MouseInfo.getPointerInfo().getLocation();
|
||||
JPopupMenu skinPopupMenu = new JPopupMenu();
|
||||
|
||||
populateSkinMenu(skinPopupMenu);
|
||||
|
||||
skinPopupMenu.setLocation(mouse);
|
||||
skinPopupMenu.setInvoker(skinButton);
|
||||
skinPopupMenu.setVisible(true);
|
||||
}
|
||||
});
|
||||
/*this.add(BorderLayout.NORTH, skinButton);*/
|
||||
this.add(BorderLayout.CENTER, canvas);
|
||||
|
||||
/* Observe simulation and mote positions */
|
||||
|
@ -550,9 +556,6 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
|||
} catch (IllegalAccessException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
skinButton.setText("Select visualizer " +
|
||||
"(" + currentSkins.size() + "/" + visualizerSkins.size() + ")");
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
@ -572,7 +575,6 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
|||
simulation.getGUI().tryLoadClass(this, VisualizerSkin.class, skin);
|
||||
generateAndActivateSkin(skinClass);
|
||||
}
|
||||
populateSkinMenu(viewMenu);
|
||||
}
|
||||
|
||||
public VisualizerSkin[] getCurrentSkins() {
|
||||
|
@ -698,11 +700,15 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
|||
menu.setVisible(true);
|
||||
}
|
||||
|
||||
private void populateSkinMenu(MenuElement skinMenu) {
|
||||
JCheckBoxMenuItem item;
|
||||
private void populateSkinMenu(MenuElement menu) {
|
||||
for (Class<? extends VisualizerSkin> skinClass: visualizerSkins) {
|
||||
/* Should skin be enabled in this simulation? */
|
||||
if (!isSkinCompatible(skinClass)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String description = GUI.getDescriptionOf(skinClass);
|
||||
item = new JCheckBoxMenuItem(description, false);
|
||||
JCheckBoxMenuItem item = new JCheckBoxMenuItem(description, false);
|
||||
item.putClientProperty("skinclass", skinClass);
|
||||
|
||||
/* Select skin if active */
|
||||
|
@ -747,23 +753,15 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
|||
skinToDeactivate.setInactive();
|
||||
repaint();
|
||||
currentSkins.remove(skinToDeactivate);
|
||||
skinButton.setText("Select visualizers " +
|
||||
"(" + currentSkins.size() + "/" + visualizerSkins.size() + ")");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/* Should skin be enabled in this simulation? */
|
||||
if (!isSkinCompatible(skinClass)) {
|
||||
continue;
|
||||
if (menu instanceof JMenu) {
|
||||
((JMenu)menu).add(item);
|
||||
}
|
||||
|
||||
if (skinMenu instanceof JMenu) {
|
||||
((JMenu)skinMenu).add(item);
|
||||
}
|
||||
if (skinMenu instanceof JPopupMenu) {
|
||||
((JPopupMenu)skinMenu).add(item);
|
||||
if (menu instanceof JPopupMenu) {
|
||||
((JPopupMenu)menu).add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -833,24 +831,26 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
|||
repaint();
|
||||
}
|
||||
|
||||
private double zoomFactor()
|
||||
{
|
||||
private double zoomFactor() {
|
||||
return viewportTransform.getScaleX();
|
||||
}
|
||||
|
||||
private void zoomToFactor(double newZoom) {
|
||||
Position center = transformPixelToPosition(
|
||||
new Point(canvas.getWidth()/2, canvas.getHeight()/2)
|
||||
);
|
||||
viewportTransform.setToScale(
|
||||
newZoom,
|
||||
newZoom
|
||||
);
|
||||
|
||||
/*Position moved = transformPixelToPosition(zoomingPixel);
|
||||
Position newCenter = transformPixelToPosition(
|
||||
new Point(canvas.getWidth()/2, canvas.getHeight()/2)
|
||||
);
|
||||
viewportTransform.translate(
|
||||
moved.getXCoordinate() - zoomingPosition.getXCoordinate(),
|
||||
moved.getYCoordinate() - zoomingPosition.getYCoordinate()
|
||||
);*/
|
||||
newCenter.getXCoordinate() - center.getXCoordinate(),
|
||||
newCenter.getYCoordinate() - center.getYCoordinate()
|
||||
);
|
||||
repaint();
|
||||
|
||||
}
|
||||
|
||||
private void handleMouseMove(MouseEvent e, boolean stop) {
|
||||
|
@ -1335,7 +1335,6 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
|||
} else if (element.getName().equals("hidden")) {
|
||||
BasicInternalFrameUI ui = (BasicInternalFrameUI) getUI();
|
||||
ui.getNorthPane().setPreferredSize(new Dimension(0,0));
|
||||
skinButton.setVisible(false);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -1489,11 +1488,9 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
|||
ui.getNorthPane().getPreferredSize().height == 0) {
|
||||
/* Restore window decorations */
|
||||
ui.getNorthPane().setPreferredSize(null);
|
||||
visualizer.skinButton.setVisible(true);
|
||||
} else {
|
||||
/* Hide window decorations */
|
||||
ui.getNorthPane().setPreferredSize(new Dimension(0,0));
|
||||
visualizer.skinButton.setVisible(false);
|
||||
}
|
||||
visualizer.revalidate();
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
@ -1525,10 +1522,10 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
|||
public String getQuickHelp() {
|
||||
return
|
||||
"<b>Network</b> " +
|
||||
"<p>The network windo shows the positions of simulated motes. " +
|
||||
"<p>The network window shows the positions of simulated motes. " +
|
||||
"It is possible to zoom (CRTL+Mouse drag) and pan (Shift+Mouse drag) the current view. Motes can be moved by dragging them. " +
|
||||
"Mouse right-click motes for options. " +
|
||||
"<p>The network window suppors different views. " +
|
||||
"<p>The network window supports different views. " +
|
||||
"Each view provides some specific information, such as the IP addresses of motes. " +
|
||||
"Multiple views can be active at the same time. " +
|
||||
"Use the View menu to select views. ";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Swedish Institute of Computer Science.
|
||||
* Copyright (c) 2012, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -25,8 +25,6 @@
|
|||
* 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.5 2010/02/26 07:46:26 nifi Exp $
|
||||
*/
|
||||
|
||||
package se.sics.cooja.plugins.skins;
|
||||
|
@ -34,235 +32,171 @@ package se.sics.cooja.plugins.skins;
|
|||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Point;
|
||||
import java.util.ArrayDeque;
|
||||
import java.awt.Polygon;
|
||||
import java.util.ArrayList;
|
||||
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.SupportedArguments;
|
||||
import se.sics.cooja.TimeEvent;
|
||||
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.
|
||||
* Radio traffic history visualizer skin.
|
||||
*
|
||||
* @see UDGMVisualizerSkin
|
||||
* @author Fredrik Osterlind
|
||||
*/
|
||||
@ClassDescription("Radio traffic")
|
||||
@SupportedArguments(radioMediums = {AbstractRadioMedium.class})
|
||||
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 final int MAX_HISTORY_SIZE = 200;
|
||||
|
||||
private boolean active = false;
|
||||
private Simulation simulation = null;
|
||||
private Visualizer visualizer = null;
|
||||
private AbstractRadioMedium radioMedium = null;
|
||||
|
||||
private Box counters;
|
||||
private ArrayList<RadioConnectionArrow> historyList = new ArrayList<RadioConnectionArrow>();
|
||||
private RadioConnectionArrow[] history = null;
|
||||
|
||||
private final static int HISTORY_SIZE = 16;
|
||||
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());
|
||||
private Observer radioMediumObserver = new Observer() {
|
||||
public void update(Observable obs, Object obj) {
|
||||
RadioConnection last = radioMedium.getLastConnection();
|
||||
if (last != null && historyList.size() < MAX_HISTORY_SIZE) {
|
||||
historyList.add(new RadioConnectionArrow(last));
|
||||
history = historyList.toArray(new RadioConnectionArrow[0]);
|
||||
visualizer.repaint(500);
|
||||
}
|
||||
}
|
||||
};
|
||||
private TimeEvent ageArrowsTimeEvent = new TimeEvent(0) {
|
||||
public void execute(long t) {
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (historyList.size() > 0) {
|
||||
boolean hasOld = false;
|
||||
|
||||
/* Increase age */
|
||||
for (RadioConnectionArrow connArrow : historyList) {
|
||||
connArrow.increaseAge();
|
||||
if(connArrow.getAge() >= connArrow.getMaxAge()) {
|
||||
hasOld = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove too old arrows */
|
||||
if (hasOld) {
|
||||
RadioConnectionArrow[] historyArr = historyList.toArray(new RadioConnectionArrow[0]);
|
||||
for (RadioConnectionArrow connArrow : historyArr) {
|
||||
if(connArrow.getAge() >= connArrow.getMaxAge()) {
|
||||
historyList.remove(connArrow);
|
||||
}
|
||||
}
|
||||
historyArr = historyList.toArray(new RadioConnectionArrow[0]);
|
||||
}
|
||||
|
||||
visualizer.repaint(500);
|
||||
}
|
||||
|
||||
/* Reschedule myself */
|
||||
simulation.scheduleEvent(this, t + 100*Simulation.MILLISECOND);
|
||||
}
|
||||
};
|
||||
|
||||
public void setActive(final Simulation simulation, Visualizer vis) {
|
||||
this.radioMedium = (AbstractRadioMedium) simulation.getRadioMedium();
|
||||
this.simulation = simulation;
|
||||
this.visualizer = vis;
|
||||
this.active = true;
|
||||
|
||||
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);
|
||||
simulation.invokeSimulationThread(new Runnable() {
|
||||
public void run() {
|
||||
historyList.clear();
|
||||
history = null;
|
||||
|
||||
counters = Box.createHorizontalBox();
|
||||
counters.add(txCounter);
|
||||
counters.add(Box.createHorizontalStrut(10));
|
||||
counters.add(rxCounter);
|
||||
counters.add(Box.createHorizontalStrut(10));
|
||||
counters.add(interferedCounter);
|
||||
/* Start observing radio medium for transmissions */
|
||||
radioMedium.addRadioMediumObserver(radioMediumObserver);
|
||||
|
||||
/* 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 last = radioMedium.getLastConnection();
|
||||
if (last != null) {
|
||||
history.add(last);
|
||||
while (history.size() > HISTORY_SIZE) {
|
||||
history.removeFirst();
|
||||
}
|
||||
}
|
||||
}
|
||||
visualizer.repaint();
|
||||
/* Fade away arrows */
|
||||
simulation.scheduleEvent(ageArrowsTimeEvent, simulation.getSimulationTime() + 100*Simulation.MILLISECOND);
|
||||
}
|
||||
});
|
||||
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() {
|
||||
this.active = false;
|
||||
if (simulation == null) {
|
||||
/* Skin was never activated */
|
||||
return;
|
||||
}
|
||||
|
||||
visualizer.getCurrentCanvas().remove(counters);
|
||||
|
||||
/* Stop observing radio medium and radios */
|
||||
/* Stop observing radio medium */
|
||||
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;
|
||||
private Polygon arrowPoly = new Polygon();
|
||||
private void drawArrow(Graphics g, int xSource, int ySource, int xDest, int yDest, int delta) {
|
||||
double dx = xSource - xDest;
|
||||
double dy = ySource - yDest;
|
||||
double dir = Math.atan2(dx, dy);
|
||||
double len = Math.sqrt(dx * dx + dy * dy);
|
||||
dx /= len;
|
||||
dy /= len;
|
||||
len -= delta;
|
||||
xDest = xSource - (int) (dx * len);
|
||||
yDest = ySource - (int) (dy * len);
|
||||
g.drawLine(xDest, yDest, xSource, ySource);
|
||||
|
||||
final int size = 8;
|
||||
arrowPoly.reset();
|
||||
arrowPoly.addPoint(xDest, yDest);
|
||||
arrowPoly.addPoint(xDest + xCor(size, dir + 0.5), yDest + yCor(size, dir + 0.5));
|
||||
arrowPoly.addPoint(xDest + xCor(size, dir - 0.5), yDest + yCor(size, dir - 0.5));
|
||||
arrowPoly.addPoint(xDest, yDest);
|
||||
g.fillPolygon(arrowPoly);
|
||||
}
|
||||
|
||||
if (!moteRadio.isRadioOn()) {
|
||||
return new Color[] { Color.GRAY };
|
||||
private int yCor(int len, double dir) {
|
||||
return (int)(0.5 + len * Math.cos(dir));
|
||||
}
|
||||
|
||||
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;
|
||||
private int xCor(int len, double dir) {
|
||||
return (int)(0.5 + len * Math.sin(dir));
|
||||
}
|
||||
|
||||
public void paintBeforeMotes(Graphics g) {
|
||||
if (simulation == null) {
|
||||
/* Skin was never activated */
|
||||
RadioConnectionArrow[] historyCopy = history;
|
||||
if (historyCopy == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (showHistory) {
|
||||
/* Paint history in gray */
|
||||
RadioConnection[] historyArr = history.toArray(new RadioConnection[0]);
|
||||
for (RadioConnection conn : historyArr) {
|
||||
if (conn == null) {
|
||||
continue;
|
||||
}
|
||||
g.setColor(COLOR_HISTORY);
|
||||
Radio source = conn.getSource();
|
||||
for (RadioConnectionArrow connArrow : historyCopy) {
|
||||
float colorHistoryIndex = (float)connArrow.getAge() / (float)connArrow.getMaxAge();
|
||||
g.setColor(new Color(colorHistoryIndex, colorHistoryIndex, 1.0f));
|
||||
Radio source = connArrow.getConnection().getSource();
|
||||
Point sourcePoint = visualizer.transformPositionToPixel(source.getPosition());
|
||||
for (Radio destRadio : conn.getDestinations()) {
|
||||
for (Radio destRadio : connArrow.getConnection().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) {
|
||||
if (conn == null) {
|
||||
continue;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
drawArrow(g, sourcePoint.x, sourcePoint.y, destPoint.x, destPoint.y, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -270,37 +204,31 @@ public class TrafficVisualizerSkin implements VisualizerSkin {
|
|||
public void paintAfterMotes(Graphics g) {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
private static class RadioConnectionArrow {
|
||||
private RadioConnection conn;
|
||||
private int age;
|
||||
private static final int MAX_AGE = 10;
|
||||
RadioConnectionArrow(RadioConnection conn) {
|
||||
this.conn = conn;
|
||||
this.age = 0;
|
||||
}
|
||||
public void increaseAge() {
|
||||
if (age < MAX_AGE) {
|
||||
age++;
|
||||
}
|
||||
}
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
public RadioConnection getConnection() {
|
||||
return conn;
|
||||
}
|
||||
public int getMaxAge() {
|
||||
return MAX_AGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue