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:
parent
5cde978549
commit
ffa4482799
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue