improved capture effect support in mrm: capture effect is effective if the latter transmission is stronger and no later than half the preamble

This commit is contained in:
Fredrik Osterlind 2011-11-03 11:23:51 +01:00
parent 5cde978549
commit ffa4482799
4 changed files with 138 additions and 14 deletions

View file

@ -135,7 +135,10 @@ public class ChannelModel {
rt_reflec_coefficient, rt_reflec_coefficient,
rt_diffr_coefficient, rt_diffr_coefficient,
rt_scatt_coefficient, rt_scatt_coefficient,
obstacle_attenuation; obstacle_attenuation,
captureEffect,
captureEffectPreambleDuration,
captureEffectSignalTreshold;
public static Object getDefaultValue(Parameter p) { public static Object getDefaultValue(Parameter p) {
switch (p) { switch (p) {
@ -187,6 +190,12 @@ public class ChannelModel {
return new Double(-20); return new Double(-20);
case obstacle_attenuation: case obstacle_attenuation:
return new Double(-3); return new Double(-3);
case captureEffect:
return true;
case captureEffectPreambleDuration:
return (double) (1000*1000*4*0.5*8/250000); /* 2 bytes, 250kbit/s, us */
case captureEffectSignalTreshold:
return (double) 3; /* dB, according to previous 802.15.4 studies */
} }
throw new RuntimeException("Unknown default value: " + p); throw new RuntimeException("Unknown default value: " + p);
} }
@ -235,6 +244,12 @@ public class ChannelModel {
return rt_scatt_coefficient; return rt_scatt_coefficient;
} else if (name.equals("obstacle_attenuation")) { } else if (name.equals("obstacle_attenuation")) {
return obstacle_attenuation; return obstacle_attenuation;
} else if (name.equals("captureEffect")) {
return captureEffect;
} else if (name.equals("captureEffectPreambleDuration")) {
return captureEffectPreambleDuration;
} else if (name.equals("captureEffectSignalTreshold")) {
return captureEffectSignalTreshold;
} }
return null; return null;
} }
@ -263,6 +278,9 @@ public class ChannelModel {
case rt_reflec_coefficient: return "Reflection coefficient (dB)"; case rt_reflec_coefficient: return "Reflection coefficient (dB)";
case rt_diffr_coefficient: return "Diffraction coefficient (dB)"; case rt_diffr_coefficient: return "Diffraction coefficient (dB)";
case obstacle_attenuation: return "Obstacle attenuation (dB/m)"; case obstacle_attenuation: return "Obstacle attenuation (dB/m)";
case captureEffect: return "Use Capture Effect";
case captureEffectPreambleDuration: return "Capture effect preamble (us)";
case captureEffectSignalTreshold: return "Capture effect threshold (dB)";
} }
throw new RuntimeException("Unknown decrption: " + p); throw new RuntimeException("Unknown decrption: " + p);
} }

View file

@ -151,6 +151,27 @@ public class FormulaViewer extends se.sics.cooja.VisPlugin {
channelModel.getParameterDoubleValue(Parameter.frequency) channelModel.getParameterDoubleValue(Parameter.frequency)
); );
addBooleanParameter(
Parameter.captureEffect,
Parameter.getDescription(Parameter.captureEffect),
collapsableArea,
channelModel.getParameterBooleanValue(Parameter.captureEffect)
);
addDoubleParameter(
Parameter.captureEffectPreambleDuration,
Parameter.getDescription(Parameter.captureEffectPreambleDuration),
collapsableArea,
channelModel.getParameterDoubleValue(Parameter.captureEffectPreambleDuration)
);
addDoubleParameter(
Parameter.captureEffectSignalTreshold,
Parameter.getDescription(Parameter.captureEffectSignalTreshold),
collapsableArea,
channelModel.getParameterDoubleValue(Parameter.captureEffectSignalTreshold)
);
// Transmitter parameters // Transmitter parameters
collapsableArea = createCollapsableArea("Transmitter parameters", allComponents); collapsableArea = createCollapsableArea("Transmitter parameters", allComponents);
areaTransmitter = collapsableArea; areaTransmitter = collapsableArea;

View file

@ -80,8 +80,13 @@ public class MRM extends AbstractRadioMedium {
public final static boolean WITH_NOISE = true; /* NoiseSourceRadio */ public final static boolean WITH_NOISE = true; /* NoiseSourceRadio */
public final static boolean WITH_DIRECTIONAL = true; /* DirectionalAntennaRadio */ public final static boolean WITH_DIRECTIONAL = true; /* DirectionalAntennaRadio */
public final static boolean WITH_CAPTURE_EFFECT = true;
private Observer channelModelObserver = null;
private boolean WITH_CAPTURE_EFFECT;
private double CAPTURE_EFFECT_THRESHOLD;
private double CAPTURE_EFFECT_PREAMBLE_DURATION;
private Simulation sim; private Simulation sim;
private Random random = null; private Random random = null;
private ChannelModel currentChannelModel = null; private ChannelModel currentChannelModel = null;
@ -100,7 +105,19 @@ public class MRM extends AbstractRadioMedium {
sim = simulation; sim = simulation;
random = simulation.getRandomGenerator(); random = simulation.getRandomGenerator();
currentChannelModel = new ChannelModel(sim); currentChannelModel = new ChannelModel(sim);
WITH_CAPTURE_EFFECT = currentChannelModel.getParameterBooleanValue(ChannelModel.Parameter.captureEffect);
CAPTURE_EFFECT_THRESHOLD = currentChannelModel.getParameterDoubleValue(ChannelModel.Parameter.captureEffectSignalTreshold);
CAPTURE_EFFECT_PREAMBLE_DURATION = currentChannelModel.getParameterDoubleValue(ChannelModel.Parameter.captureEffectPreambleDuration);
currentChannelModel.addSettingsObserver(channelModelObserver = new Observer() {
public void update(Observable o, Object arg) {
WITH_CAPTURE_EFFECT = currentChannelModel.getParameterBooleanValue(ChannelModel.Parameter.captureEffect);
CAPTURE_EFFECT_THRESHOLD = currentChannelModel.getParameterDoubleValue(ChannelModel.Parameter.captureEffectSignalTreshold);
CAPTURE_EFFECT_PREAMBLE_DURATION = currentChannelModel.getParameterDoubleValue(ChannelModel.Parameter.captureEffectPreambleDuration);
}
});
/* Register plugins */ /* Register plugins */
sim.getGUI().registerPlugin(AreaViewer.class); sim.getGUI().registerPlugin(AreaViewer.class);
sim.getGUI().registerPlugin(FormulaViewer.class); sim.getGUI().registerPlugin(FormulaViewer.class);
@ -114,6 +131,8 @@ public class MRM extends AbstractRadioMedium {
sim.getGUI().unregisterPlugin(AreaViewer.class); sim.getGUI().unregisterPlugin(AreaViewer.class);
sim.getGUI().unregisterPlugin(FormulaViewer.class); sim.getGUI().unregisterPlugin(FormulaViewer.class);
Visualizer.unregisterVisualizerSkin(MRMVisualizerSkin.class); Visualizer.unregisterVisualizerSkin(MRMVisualizerSkin.class);
currentChannelModel.deleteSettingsObserver(channelModelObserver);
} }
private NoiseLevelListener noiseListener = new NoiseLevelListener() { private NoiseLevelListener noiseListener = new NoiseLevelListener() {
@ -177,22 +196,26 @@ public class MRM extends AbstractRadioMedium {
newConnection.addInterfered(recv); newConnection.addInterfered(recv);
recv.interfereAnyReception(); recv.interfereAnyReception();
} else if (recv.isInterfered()) { } else if (recv.isInterfered()) {
/* Was interfered: keep interfering */ if (WITH_CAPTURE_EFFECT) {
newConnection.addInterfered(recv, recvSignalStrength); /* XXX TODO This may be wrong:
* If the interfering signal is both weaker and the SFD has not
* been received, then the stronger signal may actually be received.
*/
/* Was interfered: keep interfering */
newConnection.addInterfered(recv, recvSignalStrength);
} else {
/* Was interfered: keep interfering */
newConnection.addInterfered(recv, recvSignalStrength);
}
} else if (recv.isTransmitting()) { } else if (recv.isTransmitting()) {
newConnection.addInterfered(recv, recvSignalStrength); newConnection.addInterfered(recv, recvSignalStrength);
} else if (recv.isReceiving()) { } else if (recv.isReceiving()) {
/* Was already receiving: start interfering. /* Was already receiving: start interfering.
* Assuming no continuous preambles checking */ * Assuming no continuous preambles checking */
double currSignal = recv.getCurrentSignalStrength(); if (!WITH_CAPTURE_EFFECT) {
/* Capture effect: recv-radio is already receiving. newConnection.addInterfered(recv, recvSignalStrength);
* Are we strong enough to interfere? */
if (WITH_CAPTURE_EFFECT &&
recvSignalStrength < currSignal - 3 /* config */) {
/* No, we are too weak */
} else {
newConnection.addInterfered(recv, recvSignalStrength);
recv.interfereAnyReception(); recv.interfereAnyReception();
/* Interfere receiver in all other active radio connections */ /* Interfere receiver in all other active radio connections */
@ -201,7 +224,42 @@ public class MRM extends AbstractRadioMedium {
conn.addInterfered(recv); conn.addInterfered(recv);
} }
} }
} else {
/* CAPTURE EFFECT */
double currSignal = recv.getCurrentSignalStrength();
/* Capture effect: recv-radio is already receiving.
* Are we strong enough to interfere? */
if (recvSignalStrength < currSignal - CAPTURE_EFFECT_THRESHOLD /* config */) {
/* No, we are too weak */
} else {
/* New signal is strong enough to either interfere with ongoing transmission,
* or to be received/captured */
long startTime = newConnection.getReceptionStartTime();
boolean interfering = (sim.getSimulationTime()-startTime) >= CAPTURE_EFFECT_PREAMBLE_DURATION; /* us */
if (interfering) {
newConnection.addInterfered(recv, recvSignalStrength);
recv.interfereAnyReception();
/* Interfere receiver in all other active radio connections */
for (RadioConnection conn : getActiveConnections()) {
if (conn.isDestination(recv)) {
conn.addInterfered(recv);
}
} }
} else {
/* XXX Warning: removing destination from other connections */
for (RadioConnection conn : getActiveConnections()) {
if (conn.isDestination(recv)) {
conn.removeDestination(recv);
}
}
/* Success: radio starts receiving */
newConnection.addDestination(recv, recvSignalStrength);
}
}
}
} else { } else {
/* Success: radio starts receiving */ /* Success: radio starts receiving */

View file

@ -90,6 +90,15 @@ public class RadioConnection {
return startTime; return startTime;
} }
/**
* @return Start time of ongoing reception
*/
public long getReceptionStartTime() {
/* TODO XXX: This may currently return the start time of an ongoing
* interference. */
return getStartTime();
}
/** /**
* Add (non-interfered) destination radio to connection. * Add (non-interfered) destination radio to connection.
* *
@ -98,6 +107,24 @@ public class RadioConnection {
public void addDestination(Radio radio) { public void addDestination(Radio radio) {
addDestination(radio, new Long(0)); addDestination(radio, new Long(0));
} }
/**
* Experimental: remove destination.
*
* @param radio Radio
*/
public void removeDestination(Radio radio) {
int idx = allDestinations.indexOf(radio);
if (idx < 0) {
logger.fatal("Radio is not a connection destination: " + radio);
return;
}
allDestinations.remove(idx);
allDestinationDelays.remove(idx);
destinationsNonInterfered.remove(radio);
onlyInterfered.remove(radio);
}
/** /**
* Add (non-interfered) destination radio to connection. * Add (non-interfered) destination radio to connection.