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_diffr_coefficient,
rt_scatt_coefficient,
obstacle_attenuation;
obstacle_attenuation,
captureEffect,
captureEffectPreambleDuration,
captureEffectSignalTreshold;
public static Object getDefaultValue(Parameter p) {
switch (p) {
@ -187,6 +190,12 @@ public class ChannelModel {
return new Double(-20);
case obstacle_attenuation:
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);
}
@ -235,6 +244,12 @@ public class ChannelModel {
return rt_scatt_coefficient;
} else if (name.equals("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;
}
@ -263,6 +278,9 @@ public class ChannelModel {
case rt_reflec_coefficient: return "Reflection coefficient (dB)";
case rt_diffr_coefficient: return "Diffraction coefficient (dB)";
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);
}

View file

@ -151,6 +151,27 @@ public class FormulaViewer extends se.sics.cooja.VisPlugin {
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
collapsableArea = createCollapsableArea("Transmitter parameters", allComponents);
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_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 Random random = null;
private ChannelModel currentChannelModel = null;
@ -100,7 +105,19 @@ public class MRM extends AbstractRadioMedium {
sim = simulation;
random = simulation.getRandomGenerator();
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 */
sim.getGUI().registerPlugin(AreaViewer.class);
sim.getGUI().registerPlugin(FormulaViewer.class);
@ -114,6 +131,8 @@ public class MRM extends AbstractRadioMedium {
sim.getGUI().unregisterPlugin(AreaViewer.class);
sim.getGUI().unregisterPlugin(FormulaViewer.class);
Visualizer.unregisterVisualizerSkin(MRMVisualizerSkin.class);
currentChannelModel.deleteSettingsObserver(channelModelObserver);
}
private NoiseLevelListener noiseListener = new NoiseLevelListener() {
@ -177,22 +196,26 @@ public class MRM extends AbstractRadioMedium {
newConnection.addInterfered(recv);
recv.interfereAnyReception();
} else if (recv.isInterfered()) {
/* Was interfered: keep interfering */
newConnection.addInterfered(recv, recvSignalStrength);
if (WITH_CAPTURE_EFFECT) {
/* 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()) {
newConnection.addInterfered(recv, recvSignalStrength);
} else if (recv.isReceiving()) {
/* Was already receiving: start interfering.
* Assuming no continuous preambles checking */
double currSignal = recv.getCurrentSignalStrength();
/* Capture effect: recv-radio is already receiving.
* Are we strong enough to interfere? */
if (WITH_CAPTURE_EFFECT &&
recvSignalStrength < currSignal - 3 /* config */) {
/* No, we are too weak */
} else {
newConnection.addInterfered(recv, recvSignalStrength);
if (!WITH_CAPTURE_EFFECT) {
newConnection.addInterfered(recv, recvSignalStrength);
recv.interfereAnyReception();
/* Interfere receiver in all other active radio connections */
@ -201,7 +224,42 @@ public class MRM extends AbstractRadioMedium {
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 {
/* Success: radio starts receiving */

View file

@ -90,6 +90,15 @@ public class RadioConnection {
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.
*
@ -98,6 +107,24 @@ public class RadioConnection {
public void addDestination(Radio radio) {
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.