updated to support new multiabstraction radios
+ extending abstract medium + fixed set config in area viewer
This commit is contained in:
parent
4f089d113e
commit
9e2059dcfc
3 changed files with 193 additions and 564 deletions
|
@ -16,7 +16,6 @@ import org.jdom.Element;
|
|||
|
||||
import se.sics.cooja.*;
|
||||
import se.sics.cooja.interfaces.*;
|
||||
import se.sics.mrm.MRM.*;
|
||||
|
||||
/**
|
||||
* The class AreaViewer belongs to the MRM package.
|
||||
|
@ -872,8 +871,7 @@ public class AreaViewer extends VisPlugin {
|
|||
tracker.waitForAll();
|
||||
if (tracker.isErrorAny()) {
|
||||
logger.fatal("Error when loading image: ");
|
||||
for (Object errorObject: tracker.getErrorsAny())
|
||||
logger.fatal("> " + errorObject);
|
||||
image = null;
|
||||
}
|
||||
if (image == null) {
|
||||
logger.fatal("Image is null, aborting");
|
||||
|
@ -1833,43 +1831,43 @@ public class AreaViewer extends VisPlugin {
|
|||
|
||||
// -- Draw radio activity --
|
||||
if (drawRadioActivity) {
|
||||
// Paint scaled (otherwise bad rounding to integers may occur)
|
||||
g2d.setTransform(realWorldTransformScaled);
|
||||
g2d.setStroke(new BasicStroke((float) 0.0));
|
||||
for (RadioConnection connection: currentRadioMedium.getActiveConnections()) {
|
||||
Position sourcePosition = connection.getSource().getPosition();
|
||||
|
||||
for (RadioInterference interference: currentRadioMedium.getCurrentInterferencesArray()) {
|
||||
g2d.setColor(Color.RED);
|
||||
// Paint scaled (otherwise bad rounding to integers may occur)
|
||||
g2d.setTransform(realWorldTransformScaled);
|
||||
g2d.setStroke(new BasicStroke((float) 0.0));
|
||||
|
||||
for (Radio receivingRadio: connection.getDestinations()) {
|
||||
g2d.setColor(Color.GREEN);
|
||||
|
||||
// Get source and destination coordinates
|
||||
Position sourcePosition = interference.mySource.source.position;
|
||||
Position destinationPosition = interference.myDestination.position;
|
||||
// Get source and destination coordinates
|
||||
Position destinationPosition = receivingRadio.getPosition();
|
||||
|
||||
g2d.draw(new Line2D.Double(
|
||||
sourcePosition.getXCoordinate()*100.0,
|
||||
sourcePosition.getYCoordinate()*100.0,
|
||||
destinationPosition.getXCoordinate()*100.0,
|
||||
destinationPosition.getYCoordinate()*100.0
|
||||
));
|
||||
}
|
||||
for (RadioTransfer transfer: currentRadioMedium.getCurrentTransfersArray()) {
|
||||
g2d.setColor(Color.GREEN);
|
||||
g2d.draw(new Line2D.Double(
|
||||
sourcePosition.getXCoordinate()*100.0,
|
||||
sourcePosition.getYCoordinate()*100.0,
|
||||
destinationPosition.getXCoordinate()*100.0,
|
||||
destinationPosition.getYCoordinate()*100.0
|
||||
));
|
||||
}
|
||||
|
||||
// Get source and destination coordinates
|
||||
Position sourcePosition = transfer.mySource.source.position;
|
||||
Position destinationPosition = transfer.myDestination.position;
|
||||
for (Radio interferedRadio: connection.getInterfered()) {
|
||||
g2d.setColor(Color.RED);
|
||||
|
||||
g2d.draw(new Line2D.Double(
|
||||
sourcePosition.getXCoordinate()*100.0,
|
||||
sourcePosition.getYCoordinate()*100.0,
|
||||
destinationPosition.getXCoordinate()*100.0,
|
||||
destinationPosition.getYCoordinate()*100.0
|
||||
));
|
||||
}
|
||||
for (RadioTransmission transmission: currentRadioMedium.getCurrentTransmissionsArray()) {
|
||||
// Get source and destination coordinates
|
||||
Position destinationPosition = interferedRadio.getPosition();
|
||||
|
||||
g2d.draw(new Line2D.Double(
|
||||
sourcePosition.getXCoordinate()*100.0,
|
||||
sourcePosition.getYCoordinate()*100.0,
|
||||
destinationPosition.getXCoordinate()*100.0,
|
||||
destinationPosition.getYCoordinate()*100.0
|
||||
));
|
||||
}
|
||||
|
||||
g2d.setColor(Color.BLUE);
|
||||
|
||||
g2d.setTransform(realWorldTransform);
|
||||
Position sourcePosition = transmission.source.position;
|
||||
|
||||
g2d.translate(
|
||||
sourcePosition.getXCoordinate(),
|
||||
|
@ -1890,8 +1888,7 @@ public class AreaViewer extends VisPlugin {
|
|||
(int) 5
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -- Draw scale arrow --
|
||||
|
@ -2096,7 +2093,7 @@ public class AreaViewer extends VisPlugin {
|
|||
* Config XML elements
|
||||
* @return True if config was set successfully, false otherwise
|
||||
*/
|
||||
public boolean setConfigXML(Collection<Element> configXML) {
|
||||
public boolean setConfigXML(Collection<Element> configXML, boolean visAvailable) {
|
||||
for (Element element : configXML) {
|
||||
if (element.getName().equals("controls_visible")) {
|
||||
showSettingsBox.setSelected(Boolean.parseBoolean(element.getText()));
|
||||
|
|
|
@ -5,10 +5,8 @@ import java.util.*;
|
|||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.jdom.Element;
|
||||
|
||||
import statistics.GaussianWrapper;
|
||||
|
||||
|
||||
/**
|
||||
* The channel model object in MRM is responsible for calulating propagation
|
||||
* impact on packets being sent in the radio medium.
|
||||
|
@ -1687,7 +1685,4 @@ public class ChannelModel {
|
|||
settingsObservable.notifySettingsChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
package se.sics.mrm;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.jdom.Element;
|
||||
|
||||
import se.sics.cooja.*;
|
||||
import se.sics.cooja.interfaces.*;
|
||||
import se.sics.cooja.radiomediums.AbstractRadioMedium;
|
||||
|
||||
/**
|
||||
* This is the main class of the COOJA Multi-path Ray-tracing Medium (MRM)
|
||||
* package.
|
||||
*
|
||||
* MRM is meant to be a replacement for the simpler radio mediums available in
|
||||
* MRM is meant to be an alternative to the simpler radio mediums available in
|
||||
* COOJA. It is packet based and uses a 2D ray-tracing approach to approximate
|
||||
* signal strength attenuations between simulated radios. Currently the
|
||||
* ray-tracing only supports reflections and refractions through homogeneous
|
||||
|
@ -21,278 +21,189 @@ import se.sics.cooja.interfaces.*;
|
|||
* MRM provides a number of plugins for example a plugin for visualizing radio
|
||||
* environments, and a plugin for configuring the radio medium.
|
||||
*
|
||||
* When a radio transmits data the area of interference around it will be
|
||||
* occupied for a time depending on the length of the packet sent. If the entire
|
||||
* transmission is completed without any interference the packet will be
|
||||
* delivered, otherwise nothing will be delivered.
|
||||
*
|
||||
* Future work includes adding diffractions and scattering support.
|
||||
*
|
||||
* @author Fredrik Osterlind
|
||||
*/
|
||||
@ClassDescription("Multi-path Ray-tracer Medium (MRM)")
|
||||
public class MRM extends RadioMedium {
|
||||
public class MRM extends AbstractRadioMedium {
|
||||
private static Logger logger = Logger.getLogger(MRM.class);
|
||||
|
||||
private ChannelModel currentChannelModel = null;
|
||||
private Observer simulationObserver = null;
|
||||
private Simulation mySimulation = null;
|
||||
|
||||
// Registered members of radio medium
|
||||
private Vector<MRMMember> registeredMembers = new Vector<MRMMember>();
|
||||
private Random random = new Random();
|
||||
|
||||
private Vector<RadioTransmission> allTransmissions = new Vector<RadioTransmission>();
|
||||
private Vector<RadioTransfer> allTransfers = new Vector<RadioTransfer>();
|
||||
private Vector<RadioInterference> allInterferences = new Vector<RadioInterference>();
|
||||
|
||||
|
||||
/**
|
||||
* Notifies observers when this radio medium is starting or has finished a packet delivery.
|
||||
*/
|
||||
private TransmissionsObservable radioActivityObservable = new TransmissionsObservable();
|
||||
|
||||
/**
|
||||
* Notifies observers when this radio medium has changed settings.
|
||||
*/
|
||||
private SettingsObservable settingsObservable = new SettingsObservable();
|
||||
|
||||
/**
|
||||
* Listens to all registered radios, and fetches any new incoming radio packets.
|
||||
*/
|
||||
private Observer radioObserver = new Observer() {
|
||||
public void update(Observable radio, Object obj) {
|
||||
Radio sendingRadio = (Radio) radio;
|
||||
if (sendingRadio.getLastEvent() != Radio.RadioEvent.TRANSMISSION_STARTED)
|
||||
return;
|
||||
|
||||
// Locate corresponding member
|
||||
MRMMember sendingMember = null;
|
||||
for (MRMMember member: registeredMembers) {
|
||||
if (member.radio == radio) {
|
||||
sendingMember = member;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sendingMember == null) {
|
||||
logger.fatal("MRM: Could not locate radio member - is radio registered? " + radio);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check that member is not receiving data
|
||||
if (sendingMember.isListeningOnTransmission()) {
|
||||
logger.fatal("MRM: Radio is trying to send data but is currently receiving! This must be fixed in Contiki!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check that member is not already sending data
|
||||
for (RadioTransmission transmission: allTransmissions) {
|
||||
if (transmission.source == sendingMember) {
|
||||
logger.fatal("MRM: Radio is trying to send data but is already sending! This must be fixed in Contiki!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int transmissionEndTime = sendingRadio.getTransmissionEndTime();
|
||||
|
||||
// Create transmission
|
||||
byte[] packetToSend = sendingRadio.getLastPacketTransmitted();
|
||||
RadioTransmission transmission = new RadioTransmission(sendingMember, transmissionEndTime, packetToSend);
|
||||
allTransmissions.add(transmission);
|
||||
radioActivityObservable.notifyRadioActivityChanged(); // Need to notify observers
|
||||
|
||||
double sendingX = sendingMember.position.getXCoordinate();
|
||||
double sendingY = sendingMember.position.getYCoordinate();
|
||||
Random random = new Random();
|
||||
|
||||
// Calculate how the other radios will be affected by this packet
|
||||
for (MRMMember member: registeredMembers) {
|
||||
// Ignore this sending radio
|
||||
if (member != sendingMember) {
|
||||
double receivingX = member.position.getXCoordinate();
|
||||
double receivingY = member.position.getYCoordinate();
|
||||
|
||||
double[] probData = currentChannelModel.getProbability(sendingX, sendingY, receivingX, receivingY, -Double.MAX_VALUE);
|
||||
|
||||
//logger.info("Probability of reception is " + probData[0]);
|
||||
//logger.info("Signal strength at destination is " + probData[1]);
|
||||
if (random.nextFloat() < probData[0]) {
|
||||
// Connection successful (if not interfered later)
|
||||
//logger.info("OK, creating connection and starting to transmit");
|
||||
tryCreateTransmission(transmission, member, probData[1]);
|
||||
} else if (probData[1] > 100) { // TODO Impossible value, what should it be?!
|
||||
// Transmission is only interference at destination
|
||||
tryCreateInterference(transmission, member, probData[1]);
|
||||
} else {
|
||||
//logger.info("Signal to low to be considered interference");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new Multi-path Ray-tracing Medium (MRM).
|
||||
*/
|
||||
public MRM(Simulation simulation) {
|
||||
|
||||
super(simulation);
|
||||
|
||||
// Create the channel model
|
||||
currentChannelModel = new ChannelModel();
|
||||
|
||||
// Register temporary plugins
|
||||
logger.info("Registering MRM plugins");
|
||||
simulation.getGUI().registerTemporaryPlugin(AreaViewer.class);
|
||||
simulation.getGUI().registerTemporaryPlugin(FormulaViewer.class);
|
||||
}
|
||||
|
||||
// -- Radio Medium standard methods --
|
||||
public MRMRadioConnection createConnections(Radio sendingRadio) {
|
||||
Position sendingPosition = sendingRadio.getPosition();
|
||||
MRMRadioConnection newConnection = new MRMRadioConnection(sendingRadio);
|
||||
|
||||
public void registerMote(Mote mote, Simulation sim) {
|
||||
registerRadioInterface(mote.getInterfaces().getRadio(), mote.getInterfaces().getPosition(), sim);
|
||||
}
|
||||
// Loop through all radios
|
||||
for (Radio listeningRadio: getRegisteredRadios()) {
|
||||
// Ignore sending radio and radios on different channels
|
||||
if (sendingRadio == listeningRadio)
|
||||
continue;
|
||||
if (sendingRadio.getChannel() != listeningRadio.getChannel())
|
||||
continue;
|
||||
|
||||
public void unregisterMote(Mote mote, Simulation sim) {
|
||||
unregisterRadioInterface(mote.getInterfaces().getRadio(), sim);
|
||||
}
|
||||
double listeningPositionX = listeningRadio.getPosition().getXCoordinate();
|
||||
double listeningPositionY = listeningRadio.getPosition().getYCoordinate();
|
||||
|
||||
public void registerRadioInterface(Radio radio, Position position, Simulation sim) {
|
||||
if (radio == null || position == null) {
|
||||
logger.fatal("Could not register radio: " + radio + " @ " + position);
|
||||
return;
|
||||
}
|
||||
|
||||
// If we are not already tick observering simulation, we should be
|
||||
if (simulationObserver == null) {
|
||||
mySimulation = sim;
|
||||
simulationObserver = new Observer() {
|
||||
public void update(Observable obs, Object obj) {
|
||||
// Check if any transmission is active in the radio medium
|
||||
if (allTransmissions.isEmpty())
|
||||
return;
|
||||
|
||||
Vector<RadioTransmission> uncompletedTransmissions = new Vector<RadioTransmission>();
|
||||
Vector<RadioTransmission> completedTransmissions = new Vector<RadioTransmission>();
|
||||
|
||||
// Check if any transmission has completed
|
||||
for (RadioTransmission transmission: allTransmissions) {
|
||||
if (transmission.isCompleted()) {
|
||||
completedTransmissions.add(transmission);
|
||||
} else {
|
||||
uncompletedTransmissions.add(transmission);
|
||||
}
|
||||
}
|
||||
|
||||
if (completedTransmissions.isEmpty())
|
||||
// Nothing to do
|
||||
return;
|
||||
// Calculate probability of reception of listening radio
|
||||
double[] probData = currentChannelModel.getProbability(
|
||||
sendingPosition.getXCoordinate(),
|
||||
sendingPosition.getYCoordinate(),
|
||||
listeningPositionX,
|
||||
listeningPositionY,
|
||||
-Double.MAX_VALUE
|
||||
);
|
||||
|
||||
// At least one transmission has completed - deliver data for associated transfers
|
||||
for (RadioTransmission transmission: completedTransmissions) {
|
||||
// Unregister interferences of this transmission source
|
||||
Vector<RadioInterference> intfToUnregister = new Vector<RadioInterference>();
|
||||
for (RadioInterference interference: allInterferences) {
|
||||
if (interference.mySource == transmission) {
|
||||
intfToUnregister.add(interference);
|
||||
//logger.info("Probability of reception is " + probData[0]);
|
||||
//logger.info("Signal strength at destination is " + probData[1]);
|
||||
if (random.nextFloat() < probData[0]) {
|
||||
// Check if this radio is able to receive transmission
|
||||
if (listeningRadio.isInterfered()) {
|
||||
// Keep interfering radio
|
||||
newConnection.addInterfered(listeningRadio, probData[1]);
|
||||
|
||||
} else if (listeningRadio.isReceiving()) {
|
||||
newConnection.addInterfered(listeningRadio, probData[1]);
|
||||
|
||||
// Start interfering radio
|
||||
listeningRadio.interfereAnyReception();
|
||||
|
||||
// Update connection that is transmitting to this radio
|
||||
MRMRadioConnection existingConn = null;
|
||||
for (RadioConnection conn : getActiveConnections()) {
|
||||
for (Radio dstRadio : ((MRMRadioConnection) conn).getDestinations()) {
|
||||
if (dstRadio == listeningRadio) {
|
||||
existingConn = (MRMRadioConnection) conn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (RadioInterference interference: intfToUnregister)
|
||||
unregisterInterference(interference);
|
||||
|
||||
// Deliver data and unregister transmission
|
||||
Vector<RadioTransfer> transToUnregister = new Vector<RadioTransfer>();
|
||||
for (RadioTransfer transfer: allTransfers) {
|
||||
if (transfer.mySource == transmission) {
|
||||
if (!transfer.interferenceDestroyedConnection()) {
|
||||
// Don't interfer connection
|
||||
} else {
|
||||
transfer.myDestination.radio.interferReception(0);
|
||||
}
|
||||
transToUnregister.add(transfer);
|
||||
}
|
||||
}
|
||||
for (RadioTransfer transfer: transToUnregister)
|
||||
unregisterTransmission(transfer);
|
||||
}
|
||||
|
||||
allTransmissions = uncompletedTransmissions;
|
||||
radioActivityObservable.notifyRadioActivityChanged(); // Need to notify observers
|
||||
|
||||
// Update all radio signal strengths
|
||||
for (MRMMember member: registeredMembers) {
|
||||
member.updateHeardSignalStrength();
|
||||
if (existingConn != null) {
|
||||
// Change radio from receiving to interfered
|
||||
existingConn.removeDestination(listeningRadio);
|
||||
existingConn.addInterfered(listeningRadio);
|
||||
|
||||
}
|
||||
} else {
|
||||
// Radio OK to receive
|
||||
//logger.info("OK, creating connection and starting to transmit");
|
||||
newConnection.addDestination(listeningRadio, probData[1]);
|
||||
listeningRadio.signalReceptionStart();
|
||||
}
|
||||
};
|
||||
|
||||
sim.addTickObserver(simulationObserver);
|
||||
} else if (probData[1] > currentChannelModel.getParameterDoubleValue("bg_noise_mean")) {
|
||||
// Interfere radio
|
||||
newConnection.addInterfered(listeningRadio, probData[1]);
|
||||
listeningRadio.interfereAnyReception();
|
||||
|
||||
// TODO Radios always get interfered right now, should recalculate probability
|
||||
// if (maxInterferenceSignalStrength + SOME_RELEVANT_LIMIT > transmissionSignalStrength) {
|
||||
// // Recalculating probability of delivery
|
||||
// double[] probData = currentChannelModel.getProbability(
|
||||
// mySource.source.position.getXCoordinate(),
|
||||
// mySource.source.position.getYCoordinate(),
|
||||
// myDestination.position.getXCoordinate(),
|
||||
// myDestination.position.getYCoordinate(),
|
||||
// maxInterferenceSignalStrength);
|
||||
//
|
||||
// if (new Random().nextFloat() >= probData[0]) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return newConnection;
|
||||
}
|
||||
|
||||
public void updateSignalStrengths() {
|
||||
// // Save old signal strengths
|
||||
// double[] oldSignalStrengths = new double[registeredRadios.size()];
|
||||
// for (int i = 0; i < registeredRadios.size(); i++) {
|
||||
// oldSignalStrengths[i] = registeredRadios.get(i)
|
||||
// .getCurrentSignalStrength();
|
||||
// }
|
||||
|
||||
// Reset signal strength on all radios
|
||||
for (Radio radio : getRegisteredRadios()) {
|
||||
radio.setCurrentSignalStrength(currentChannelModel.getParameterDoubleValue(("bg_noise_mean")));
|
||||
}
|
||||
|
||||
// Save both radio and its position, and also register us as an observer to the radio
|
||||
MRMMember member = new MRMMember(radio, position);
|
||||
registeredMembers.add(member);
|
||||
radio.addObserver(radioObserver);
|
||||
radio.setCurrentSignalStrength(currentChannelModel.getParameterDoubleValue(("bg_noise_mean")));
|
||||
|
||||
// Settings have changed - notify observers
|
||||
settingsObservable.notifySettingsChanged();
|
||||
}
|
||||
|
||||
public void unregisterRadioInterface(Radio radioToRemove, Simulation sim) {
|
||||
// Find corresponding radio member and remove it
|
||||
MRMMember memberToRemove = null;
|
||||
for (MRMMember member: registeredMembers) {
|
||||
if (member.radio == radioToRemove) {
|
||||
memberToRemove = member;
|
||||
break;
|
||||
// Set signal strength on all OK transmissions
|
||||
for (RadioConnection conn : getActiveConnections()) {
|
||||
// ((MRMRadioConnection) conn).getSource().setCurrentSignalStrength(12345); // TODO Set signal strength on source?
|
||||
for (Radio dstRadio : ((MRMRadioConnection) conn).getDestinations()) {
|
||||
double signalStrength = ((MRMRadioConnection) conn).getDestinationSignalStrength(dstRadio);
|
||||
if (signalStrength > dstRadio.getCurrentSignalStrength())
|
||||
dstRadio.setCurrentSignalStrength(signalStrength);
|
||||
}
|
||||
}
|
||||
|
||||
if (memberToRemove != null) {
|
||||
registeredMembers.remove(memberToRemove);
|
||||
} else
|
||||
logger.warn("MRM: Could not unregister radio: " + radioToRemove);
|
||||
|
||||
// Settings have changed - notify observers
|
||||
settingsObservable.notifySettingsChanged();
|
||||
}
|
||||
|
||||
public void addRadioMediumObserver(Observer observer) {
|
||||
// Add radio traffic observer to this radio medium
|
||||
radioActivityObservable.addObserver(observer);
|
||||
}
|
||||
// Set signal strength on all interferences
|
||||
for (RadioConnection conn : getActiveConnections()) {
|
||||
for (Radio interferedRadio : ((MRMRadioConnection) conn).getInterfered()) {
|
||||
double signalStrength = ((MRMRadioConnection) conn).getInterferenceSignalStrength(interferedRadio);
|
||||
if (signalStrength > interferedRadio.getCurrentSignalStrength())
|
||||
interferedRadio.setCurrentSignalStrength(signalStrength);
|
||||
|
||||
public Observable getRadioMediumObservable() {
|
||||
return radioActivityObservable;
|
||||
}
|
||||
if (!interferedRadio.isInterfered()) {
|
||||
// Set to interfered again
|
||||
interferedRadio.interfereAnyReception();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteRadioMediumObserver(Observer observer) {
|
||||
// Remove observer from this radio medium
|
||||
radioActivityObservable.deleteObserver(observer);
|
||||
}
|
||||
|
||||
public RadioConnection[] getLastTickConnections() {
|
||||
logger.fatal("MRM: getLastTickConnections() not implemented");
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setConnectionLogger(ConnectionLogger connection) {
|
||||
logger.fatal("MRM: setConnectionLogger() not implemented");
|
||||
// // Fetch new signal strengths
|
||||
// double[] newSignalStrengths = new double[registeredRadios.size()];
|
||||
// for (int i = 0; i < registeredRadios.size(); i++) {
|
||||
// newSignalStrengths[i] = registeredRadios.get(i)
|
||||
// .getCurrentSignalStrength();
|
||||
// }
|
||||
//
|
||||
// // Compare new and old signal strengths
|
||||
// for (int i = 0; i < registeredRadios.size(); i++) {
|
||||
// if (oldSignalStrengths[i] != newSignalStrengths[i])
|
||||
// logger.warn("Signal strengths changed on radio[" + i + "]: "
|
||||
// + oldSignalStrengths[i] + " -> " + newSignalStrengths[i]);
|
||||
// }
|
||||
}
|
||||
|
||||
public Collection<Element> getConfigXML() {
|
||||
// Just forwarding to current channel model
|
||||
// Forwarding to current channel model
|
||||
return currentChannelModel.getConfigXML();
|
||||
}
|
||||
|
||||
public boolean setConfigXML(Collection<Element> configXML,
|
||||
boolean visAvailable) {
|
||||
// Just forwarding to current channel model
|
||||
// Forwarding to current channel model
|
||||
return currentChannelModel.setConfigXML(configXML);
|
||||
}
|
||||
|
||||
|
||||
// -- Radio Medium specific methods --
|
||||
// -- MRM specific methods --
|
||||
|
||||
/**
|
||||
* Adds an observer which is notified when this radio medium has
|
||||
|
@ -321,21 +232,14 @@ public class MRM extends RadioMedium {
|
|||
* @return Position of given radio
|
||||
*/
|
||||
public Position getRadioPosition(Radio radio) {
|
||||
// Find radio, and return its position
|
||||
for (MRMMember member: registeredMembers) {
|
||||
if (member.radio == radio) {
|
||||
return member.position;
|
||||
}
|
||||
}
|
||||
logger.fatal("MRM: Given radio is not registered!");
|
||||
return null;
|
||||
return radio.getPosition();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Number of registered radios.
|
||||
*/
|
||||
public int getRegisteredRadioCount() {
|
||||
return registeredMembers.size();
|
||||
return getRegisteredRadios().size();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -345,7 +249,7 @@ public class MRM extends RadioMedium {
|
|||
* @return Radio at given index
|
||||
*/
|
||||
public Radio getRegisteredRadio(int index) {
|
||||
return registeredMembers.get(index).radio;
|
||||
return getRegisteredRadios().get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -358,258 +262,6 @@ public class MRM extends RadioMedium {
|
|||
return currentChannelModel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Tries to create a new transmission between given transmission and
|
||||
* destination. The given signal strength should be the incoming signal
|
||||
* strength at the destination. This value will be used after the transmission
|
||||
* is completed in order to compare the connection with any interference.
|
||||
*
|
||||
* @param source
|
||||
* @param destination
|
||||
* @param signalStrength
|
||||
* @return
|
||||
*/
|
||||
public void tryCreateTransmission(RadioTransmission source, MRMMember destination, double signalStrength) {
|
||||
// Check if destination is already listening to a connection
|
||||
if (destination.isListeningOnTransmission()) {
|
||||
RadioInterference newInterference = new RadioInterference(source, destination, signalStrength);
|
||||
destination.heardInterferences.add(newInterference);
|
||||
|
||||
registerInterference(newInterference);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create new transmission
|
||||
RadioTransfer newTransmission = new RadioTransfer(source, destination, signalStrength);
|
||||
destination.heardTransmission = newTransmission;
|
||||
|
||||
registerTransmission(newTransmission);
|
||||
}
|
||||
|
||||
public void tryCreateInterference(RadioTransmission source, MRMMember destination, double signalStrength) {
|
||||
RadioInterference newInterference = new RadioInterference(source, destination, signalStrength);
|
||||
destination.heardInterferences.add(newInterference);
|
||||
|
||||
registerInterference(newInterference);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ARM radio transmission.
|
||||
*/
|
||||
class RadioTransmission {
|
||||
MRMMember source = null;
|
||||
int endTime = 0;
|
||||
byte[] dataToTransfer = null;
|
||||
|
||||
public RadioTransmission(MRMMember source, int endTime, byte[] dataToTransfer) {
|
||||
this.source = source;
|
||||
|
||||
this.endTime = endTime;
|
||||
|
||||
this.dataToTransfer = dataToTransfer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if no longer transmitting.
|
||||
*/
|
||||
public boolean isCompleted() {
|
||||
return mySimulation.getSimulationTime() >= endTime;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* ARM radio interference
|
||||
*/
|
||||
class RadioInterference {
|
||||
RadioTransmission mySource;
|
||||
MRMMember myDestination;
|
||||
double interferenceSignalStrength;
|
||||
|
||||
public RadioInterference(RadioTransmission transmission, MRMMember destination, double signalStrength) {
|
||||
this.mySource = transmission;
|
||||
this.myDestination = destination;
|
||||
this.interferenceSignalStrength = signalStrength;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if interference is no more.
|
||||
*/
|
||||
public boolean isOld() {
|
||||
return mySource.isCompleted();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* ARM radio transfers
|
||||
*/
|
||||
class RadioTransfer {
|
||||
RadioTransmission mySource;
|
||||
MRMMember myDestination;
|
||||
double transmissionSignalStrength;
|
||||
double maxInterferenceSignalStrength;
|
||||
|
||||
public RadioTransfer(RadioTransmission source, MRMMember destination, double signalStrength) {
|
||||
this.mySource = source;
|
||||
this.myDestination = destination;
|
||||
this.transmissionSignalStrength = signalStrength;
|
||||
maxInterferenceSignalStrength = -Double.MAX_VALUE;
|
||||
|
||||
destination.radio.receivePacket(source.dataToTransfer, source.endTime);
|
||||
destination.radio.setCurrentSignalStrength(signalStrength);
|
||||
}
|
||||
|
||||
public void addInterference(double signalStrength) {
|
||||
if (signalStrength > maxInterferenceSignalStrength) {
|
||||
maxInterferenceSignalStrength = signalStrength;
|
||||
}
|
||||
myDestination.radio.setCurrentSignalStrength(Math.max(
|
||||
maxInterferenceSignalStrength, transmissionSignalStrength));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if transmission is completed.
|
||||
*/
|
||||
public boolean isOld() {
|
||||
return mySource.isCompleted();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if interference destroyed transmission
|
||||
*/
|
||||
public boolean interferenceDestroyedConnection() {
|
||||
if (maxInterferenceSignalStrength + 30 > transmissionSignalStrength) {
|
||||
// Recalculating probability of delivery
|
||||
double[] probData = currentChannelModel.getProbability(
|
||||
mySource.source.position.getXCoordinate(),
|
||||
mySource.source.position.getYCoordinate(),
|
||||
myDestination.position.getXCoordinate(),
|
||||
myDestination.position.getYCoordinate(),
|
||||
maxInterferenceSignalStrength);
|
||||
// logger.info("Transfer was interfered, recalculating probability of success: " + probData[0]);
|
||||
|
||||
if (new Random().nextFloat() >= probData[0]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inner class used for keeping track transceivers.
|
||||
*/
|
||||
class MRMMember {
|
||||
Radio radio = null;
|
||||
Position position = null;
|
||||
|
||||
private RadioTransfer heardTransmission;
|
||||
private Vector<RadioInterference> heardInterferences = new Vector<RadioInterference>();
|
||||
double currentSignalStrength = -Double.MAX_VALUE;
|
||||
|
||||
public MRMMember(Radio radio, Position position) {
|
||||
this.radio = radio;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public boolean isListeningOnTransmission() {
|
||||
if (heardTransmission == null)
|
||||
return false;
|
||||
|
||||
if (heardTransmission.isOld()) {
|
||||
heardTransmission = null;
|
||||
}
|
||||
|
||||
return heardTransmission != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates current incoming signal strength at this radio.
|
||||
* Observe, does not alter any transmissions!
|
||||
*/
|
||||
public void updateHeardSignalStrength() {
|
||||
double maxSignalStrength = -Double.MAX_VALUE;
|
||||
|
||||
// Get maximum interference and also update interference list
|
||||
Vector<RadioInterference> newInterferences = new Vector<RadioInterference>();
|
||||
for (RadioInterference interference: heardInterferences) {
|
||||
if (!interference.isOld()) {
|
||||
newInterferences.add(interference);
|
||||
maxSignalStrength = Math.max(maxSignalStrength,
|
||||
interference.interferenceSignalStrength);
|
||||
}
|
||||
}
|
||||
heardInterferences = newInterferences;
|
||||
|
||||
if (heardTransmission != null && !heardTransmission.isOld()) {
|
||||
maxSignalStrength = Math.max(maxSignalStrength,
|
||||
heardTransmission.transmissionSignalStrength);
|
||||
} else
|
||||
heardTransmission = null;
|
||||
|
||||
// Noise level
|
||||
maxSignalStrength = Math.max(maxSignalStrength, currentChannelModel
|
||||
.getParameterDoubleValue("bg_noise_mean"));
|
||||
|
||||
currentSignalStrength = maxSignalStrength;
|
||||
radio.setCurrentSignalStrength(currentSignalStrength);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void registerInterference(RadioInterference interference) {
|
||||
allInterferences.add(interference);
|
||||
|
||||
updateInterferences();
|
||||
radioActivityObservable.notifyRadioActivityChanged(); // Need to notify observers
|
||||
}
|
||||
|
||||
public void registerTransmission(RadioTransfer transmission) {
|
||||
allTransfers.add(transmission);
|
||||
|
||||
updateInterferences();
|
||||
radioActivityObservable.notifyRadioActivityChanged(); // Need to notify observers
|
||||
}
|
||||
|
||||
public void unregisterInterference(RadioInterference interference) {
|
||||
updateInterferences();
|
||||
|
||||
allInterferences.remove(interference);
|
||||
radioActivityObservable.notifyRadioActivityChanged(); // Need to notify observers
|
||||
}
|
||||
|
||||
public void unregisterTransmission(RadioTransfer transmission) {
|
||||
updateInterferences();
|
||||
|
||||
allTransfers.remove(transmission);
|
||||
radioActivityObservable.notifyRadioActivityChanged(); // Need to notify observers
|
||||
}
|
||||
|
||||
private void updateInterferences() {
|
||||
// We need to check impact of interferences on transmissions
|
||||
for (RadioTransfer transmission: allTransfers) {
|
||||
for (RadioInterference interference: allInterferences) {
|
||||
if (interference.myDestination == transmission.myDestination) {
|
||||
transmission.addInterference(interference.interferenceSignalStrength);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TransmissionsObservable extends Observable {
|
||||
private void notifyRadioActivityChanged() {
|
||||
setChanged();
|
||||
notifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
class SettingsObservable extends Observable {
|
||||
private void notifySettingsChanged() {
|
||||
setChanged();
|
||||
|
@ -617,49 +269,34 @@ public class MRM extends RadioMedium {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Current active transmissions
|
||||
*/
|
||||
public Vector<RadioTransmission> getCurrentTransmissions() {
|
||||
return allTransmissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Current active transmissions
|
||||
*/
|
||||
public RadioTransmission[] getCurrentTransmissionsArray() {
|
||||
return allTransmissions.toArray(new RadioTransmission[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Current active interferences
|
||||
*/
|
||||
public Vector<RadioInterference> getCurrentInterferences() {
|
||||
return allInterferences;
|
||||
}
|
||||
class MRMRadioConnection extends RadioConnection {
|
||||
private Hashtable<Radio, Double> signalStrengths = new Hashtable<Radio, Double>();
|
||||
|
||||
public MRMRadioConnection(Radio sourceRadio) {
|
||||
super(sourceRadio);
|
||||
}
|
||||
|
||||
public void addDestination(Radio radio, double signalStrength) {
|
||||
logger.debug("adding dest for " + radio + " => " + signalStrength);
|
||||
signalStrengths.put(radio, signalStrength);
|
||||
addDestination(radio);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Current active interferences
|
||||
*/
|
||||
public RadioInterference[] getCurrentInterferencesArray() {
|
||||
return allInterferences.toArray(new RadioInterference[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Current active transfers
|
||||
*/
|
||||
public Vector<RadioTransfer> getCurrentTransfers() {
|
||||
return allTransfers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Current active transfers
|
||||
*/
|
||||
public RadioTransfer[] getCurrentTransfersArray() {
|
||||
return allTransfers.toArray(new RadioTransfer[0]);
|
||||
}
|
||||
|
||||
public void addInterfered(Radio radio, double signalStrength) {
|
||||
logger.debug("adding interference for " + radio + " => " + signalStrength);
|
||||
signalStrengths.put(radio, signalStrength);
|
||||
addInterfered(radio);
|
||||
}
|
||||
|
||||
|
||||
public double getDestinationSignalStrength(Radio radio) {
|
||||
logger.debug("fetching dest for " + radio + " from " + signalStrengths);
|
||||
return signalStrengths.get(radio);
|
||||
}
|
||||
|
||||
public double getInterferenceSignalStrength(Radio radio) {
|
||||
logger.debug("fetching interference for " + radio + " from " + signalStrengths);
|
||||
return signalStrengths.get(radio);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue