24 #include "ns3/simulator.h"
38 m_txVector (txVector),
40 m_endTime (m_startTime + duration),
82 return m_txVector.GetMode ();
151 Add (packet, fakeTxVector, duration, rxPowerW);
192 double noiseInterferenceW = i->second.GetPower ();
194 if (noiseInterferenceW < energyW)
206 double previousPowerStart = 0;
207 double previousPowerEnd = 0;
220 for (
auto i =
first; i != last; ++i)
222 i->second.AddPower (event->GetRxPowerW ());
230 static const double BOLTZMANN = 1.3803e-23;
232 double Nt = BOLTZMANN * 290 * channelWidth * 1e6;
235 double noise = noiseFloor + noiseInterference;
236 double snr = signal / noise;
237 NS_LOG_DEBUG (
"bandwidth(MHz)=" << +channelWidth <<
", signal(W)= " << signal <<
", noise(W)=" << noiseFloor <<
", interference(W)=" << noiseInterference <<
", snr(linear)=" << snr);
245 auto it =
m_niChanges.find (event->GetStartTime ());
246 for (; it !=
m_niChanges.end () && it->second.GetEvent () != event; ++it)
248 noiseInterference = it->second.GetPower ();
250 ni->emplace (event->GetStartTime (),
NiChange (0, event));
251 while (++it !=
m_niChanges.end () && it->second.GetEvent () != event)
255 ni->emplace (event->GetEndTime (),
NiChange (0, event));
256 return noiseInterference;
267 uint64_t nbits =
static_cast<uint64_t
> (rate * duration.
GetSeconds ());
270 nbits /= txVector.
GetNss ();
274 ", SNIR improvement=+" << 10 * std::log10 (gain) <<
"dB");
277 double csr =
m_errorRateModel->GetChunkSuccessRate (mode, txVector, snir, nbits);
287 auto j = ni->begin ();
288 Time previous = j->first;
289 WifiMode payloadMode =
event->GetPayloadMode ();
296 double powerW =
event->GetRxPowerW ();
297 while (++j != ni->end ())
299 Time current = j->first;
300 NS_LOG_DEBUG (
"previous= " << previous <<
", current=" << current);
303 if (previous >= plcpPayloadStart)
309 payloadMode, txVector);
310 NS_LOG_DEBUG (
"Both previous and current point to the payload: mode=" << payloadMode <<
", psr=" << psr);
313 else if (current >= plcpPayloadStart)
318 current - plcpPayloadStart,
319 payloadMode, txVector);
320 NS_LOG_DEBUG (
"previous is before payload and current is in the payload: mode=" << payloadMode <<
", psr=" << psr);
322 noiseInterferenceW = j->second.GetPower () - powerW;
325 double per = 1 - psr;
335 auto j = ni->begin ();
336 Time previous = j->first;
360 double powerW =
event->GetRxPowerW ();
361 while (++j != ni->end ())
363 Time current = j->first;
364 NS_LOG_DEBUG (
"previous= " << previous <<
", current=" << current);
367 if (previous >= plcpPayloadStart)
370 NS_LOG_DEBUG (
"Case 1 - previous and current after playload start: nothing to do");
373 else if (previous >= plcpTrainingSymbolsStart)
377 if (current >= plcpPayloadStart)
382 plcpPayloadStart - previous,
383 mcsHeaderMode, txVector);
384 NS_LOG_DEBUG (
"Case 2a - previous is in training or in SIG-B and current after payload start: mode=" << mcsHeaderMode <<
", psr=" << psr);
393 mcsHeaderMode, txVector);
394 NS_LOG_DEBUG (
"Case 2b - previous is in training or in SIG-B and current is in training or in SIG-B: mode=" << mcsHeaderMode <<
", psr=" << psr);
398 else if (previous >= plcpHsigHeaderStart)
402 if (current >= plcpPayloadStart)
407 plcpPayloadStart - plcpTrainingSymbolsStart,
408 mcsHeaderMode, txVector);
416 plcpTrainingSymbolsStart - previous,
417 headerMode, txVector);
418 NS_LOG_DEBUG (
"Case 3ai - previous is in SIG-A and current after payload start: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
426 plcpTrainingSymbolsStart - previous,
427 mcsHeaderMode, txVector);
428 NS_LOG_DEBUG (
"Case 3aii - previous is in HT-SIG and current after payload start: mode=" << mcsHeaderMode <<
", psr=" << psr);
432 else if (current >= plcpTrainingSymbolsStart)
437 current - plcpTrainingSymbolsStart,
438 mcsHeaderMode, txVector);
446 plcpTrainingSymbolsStart - previous,
447 headerMode, txVector);
448 NS_LOG_DEBUG (
"Case 3bi - previous is in SIG-A and current is in training or in SIG-B: mode=" << headerMode <<
", psr=" << psr);
456 plcpTrainingSymbolsStart - previous,
457 mcsHeaderMode, txVector);
458 NS_LOG_DEBUG (
"Case 3bii - previous is in HT-SIG and current is in HT training: mode=" << mcsHeaderMode <<
", psr=" << psr);
472 headerMode, txVector);
473 NS_LOG_DEBUG (
"Case 3ci - previous with current in SIG-A: mode=" << headerMode <<
", psr=" << psr);
482 mcsHeaderMode, txVector);
483 NS_LOG_DEBUG (
"Case 3cii - previous with current in HT-SIG: mode=" << mcsHeaderMode <<
", psr=" << psr);
488 else if (previous >= plcpHeaderStart)
492 if (current >= plcpPayloadStart)
500 plcpPayloadStart - previous,
501 headerMode, txVector);
502 NS_LOG_DEBUG (
"Case 4ai - previous in L-SIG and current after payload start: mode=" << headerMode <<
", psr=" << psr);
510 plcpPayloadStart - plcpTrainingSymbolsStart,
511 mcsHeaderMode, txVector);
515 plcpTrainingSymbolsStart - previous,
516 headerMode, txVector);
517 NS_LOG_DEBUG (
"Case 4aii - previous is in L-SIG and current after payload start: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
525 plcpPayloadStart - plcpHsigHeaderStart,
526 mcsHeaderMode, txVector);
530 plcpHsigHeaderStart - previous,
531 headerMode, txVector);
532 NS_LOG_DEBUG (
"Case 4aiii - previous in L-SIG and current after payload start: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
536 else if (current >= plcpTrainingSymbolsStart)
545 current - plcpTrainingSymbolsStart,
546 mcsHeaderMode, txVector);
550 plcpTrainingSymbolsStart - previous,
551 headerMode, txVector);
552 NS_LOG_DEBUG (
"Case 4bi - previous is in L-SIG and current in training or in SIG-B: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
560 current - plcpHsigHeaderStart,
561 mcsHeaderMode, txVector);
565 plcpHsigHeaderStart - previous,
566 headerMode, txVector);
567 NS_LOG_DEBUG (
"Case 4bii - previous in L-SIG and current in HT training: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
571 else if (current >= plcpHsigHeaderStart)
581 headerMode, txVector);
582 NS_LOG_DEBUG (
"Case 4ci - previous is in L-SIG and current in SIG-A: mode=" << headerMode <<
", psr=" << psr);
590 current - plcpHsigHeaderStart,
591 mcsHeaderMode, txVector);
595 plcpHsigHeaderStart - previous,
596 headerMode, txVector);
597 NS_LOG_DEBUG (
"Case 4cii - previous in L-SIG and current in HT-SIG: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
607 headerMode, txVector);
608 NS_LOG_DEBUG (
"Case 3c - current with previous in L-SIG: mode=" << headerMode <<
", psr=" << psr);
615 if (current >= plcpPayloadStart)
623 plcpPayloadStart - plcpHeaderStart,
624 headerMode, txVector);
625 NS_LOG_DEBUG (
"Case 5a - previous is in the preamble and current is after payload start: mode=" << headerMode <<
", psr=" << psr);
633 plcpPayloadStart - plcpTrainingSymbolsStart,
634 mcsHeaderMode, txVector);
638 plcpTrainingSymbolsStart - plcpHeaderStart,
639 headerMode, txVector);
640 NS_LOG_DEBUG (
"Case 5aii - previous is in the preamble and current is after payload start: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
648 plcpPayloadStart - plcpHsigHeaderStart,
649 mcsHeaderMode, txVector);
653 plcpHsigHeaderStart - plcpHeaderStart,
654 headerMode, txVector);
655 NS_LOG_DEBUG (
"Case 5aiii - previous is in the preamble and current is after payload start: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
659 else if (current >= plcpTrainingSymbolsStart)
668 current - plcpTrainingSymbolsStart,
669 mcsHeaderMode, txVector);
673 plcpTrainingSymbolsStart - plcpHeaderStart,
674 headerMode, txVector);
675 NS_LOG_DEBUG (
"Case 5bi - previous is in the preamble and current in training or in SIG-B: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
683 current - plcpHsigHeaderStart,
684 mcsHeaderMode, txVector);
688 plcpHsigHeaderStart - plcpHeaderStart,
689 headerMode, txVector);
690 NS_LOG_DEBUG (
"Case 5bii - previous is in the preamble and current in HT training: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
694 else if (current >= plcpHsigHeaderStart)
703 current - plcpHeaderStart,
704 headerMode, txVector);
705 NS_LOG_DEBUG (
"Case 5ci - previous is in preamble and current in SIG-A: mode=" << headerMode <<
", psr=" << psr);
713 current - plcpHsigHeaderStart,
714 mcsHeaderMode, txVector);
718 plcpHsigHeaderStart - plcpHeaderStart,
719 headerMode, txVector);
720 NS_LOG_DEBUG (
"Case 5cii - previous in preamble and current in HT-SIG: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
724 else if (current >= plcpHeaderStart)
730 current - plcpHeaderStart,
731 headerMode, txVector);
732 NS_LOG_DEBUG (
"Case 5d - previous is in the preamble and current is in L-SIG: mode=" << headerMode <<
", psr=" << psr);
736 noiseInterferenceW = j->second.GetPower () - powerW;
740 double per = 1 - psr;
751 event->GetTxVector ().GetChannelWidth ());
771 event->GetTxVector ().GetChannelWidth ());
794 InterferenceHelper::NiChanges::const_iterator
800 InterferenceHelper::NiChanges::const_iterator
810 InterferenceHelper::NiChanges::iterator
void AddPower(double power)
Add a given amount of power.
Simulation virtual time values and global simulation resolution.
void AddForeignSignal(Time duration, double rxPower)
Add a non-Wifi signal to interference helper.
A struct for both SNR and PER.
Ptr< InterferenceHelper::Event > Add(Ptr< const Packet > packet, WifiTxVector txVector, Time duration, double rxPower)
Add the packet-related signal to interference helper.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
NiChanges::iterator AddNiChangeEvent(Time moment, NiChange change)
Add NiChange to the list at the appropriate position and return the iterator of the new event...
Control the scheduling of simulation events.
void SetNumberOfReceiveAntennas(uint8_t rx)
Set the number of RX antennas in the receiver corresponding to this interference helper.
Ptr< ErrorRateModel > GetErrorRateModel(void) const
Return the error rate model.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
handles interference calculations
static Time GetPlcpHtSigHeaderDuration(WifiPreamble preamble)
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Set the error rate model for this interference helper.
double CalculateChunkSuccessRate(double snir, Time duration, WifiMode mode, WifiTxVector txVector) const
Calculate the success rate of the chunk given the SINR, duration, and Wi-Fi mode. ...
double GetRxPowerW(void) const
Return the receive power (w).
Ptr< ErrorRateModel > m_errorRateModel
error rate model
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
double GetPower(void) const
Return the power.
static Time GetPlcpSigA1Duration(WifiPreamble preamble)
uint8_t GetChannelWidth(void) const
Ptr< const Packet > GetPacket(void) const
Return the packet.
NiChange(double power, Ptr< InterferenceHelper::Event > event)
Create a NiChange at the given time and the amount of NI change.
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
double CalculateNoiseInterferenceW(Ptr< Event > event, NiChanges *ni) const
Calculate noise and interference power in W.
Time GetStartTime(void) const
Return the start time of the signal.
static Time GetPlcpSigA2Duration(WifiPreamble preamble)
Event(Ptr< const Packet > packet, WifiTxVector txVector, Time duration, double rxPower)
Create an Event with the given parameters.
WifiTxVector GetTxVector(void) const
Return the TXVECTOR of the packet.
static Time GetPlcpPreambleDuration(WifiTxVector txVector)
static Time GetPlcpSigBDuration(WifiPreamble preamble)
NiChanges m_niChanges
Experimental: needed for energy duration calculation.
double CalculatePlcpPayloadPer(Ptr< const Event > event, NiChanges *ni) const
Calculate the error rate of the given plcp payload.
Time GetEnergyDuration(double energyW) const
double m_noiseFigure
noise figure (linear)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void NotifyRxStart()
Notify that RX has started.
Noise and Interference (thus Ni) event.
void EraseEvents(void)
Erase all events.
double CalculatePlcpHeaderPer(Ptr< const Event > event, NiChanges *ni) const
Calculate the error rate of the plcp header.
uint8_t m_numRxAntennas
the number of RX antennas in the corresponding receiver
static Time Now(void)
Return the current simulation virtual time.
Time GetEndTime(void) const
Return the end time of the signal.
Ptr< InterferenceHelper::Event > GetEvent(void) const
Return the event causes the corresponding NI change.
WifiPreamble GetPreambleType(void) const
uint8_t GetNss(void) const
void NotifyRxEnd()
Notify that RX has ended.
uint64_t GetPhyRate(uint8_t channelWidth, uint16_t guardInterval, uint8_t nss) const
void SetNoiseFigure(double value)
Set the noise figure.
double m_firstPower
first power
WifiMode GetPayloadMode(void) const
Return the Wi-Fi mode used for the payload.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
static WifiMode GetVhtPlcpHeaderMode()
uint8_t GetNTx(void) const
static WifiMode GetHePlcpHeaderMode()
void AppendEvent(Ptr< Event > event)
Append the given Event.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
NiChanges::const_iterator GetPreviousPosition(Time moment) const
Returns an iterator to the first nichange that is later than moment.
WifiModulationClass GetModulationClass() const
WifiMode GetMode(void) const
double GetNoiseFigure(void) const
Return the noise figure.
static WifiMode GetPlcpHeaderMode(WifiTxVector txVector)
static Time GetPlcpTrainingSymbolDuration(WifiTxVector txVector)
NiChanges::const_iterator GetNextPosition(Time moment) const
Returns an iterator to the first nichange that is later than moment.
static Time GetPlcpHeaderDuration(WifiTxVector txVector)
double CalculateSnr(double signal, double noiseInterference, uint8_t channelWidth) const
Calculate SNR (linear ratio) from the given signal power and noise+interference power.
static WifiMode GetHtPlcpHeaderMode()
std::multimap< Time, NiChange > NiChanges
typedef for a multimap of NiChanges
bool m_rxing
flag whether it is in receiving state