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_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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -80,7 +80,12 @@ 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;
|
||||||
|
@ -101,6 +106,18 @@ public class MRM extends AbstractRadioMedium {
|
||||||
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 */
|
||||||
|
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
@ -99,6 +108,24 @@ public class RadioConnection {
|
||||||
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.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue