22 #include "ns3/simulator.h" 24 #include "ns3/packet.h" 42 m_txVector (txVector),
44 m_endTime (m_startTime + duration),
97 os <<
"start=" <<
event.GetStartTime () <<
", end=" <<
event.GetEndTime ()
98 <<
", TXVECTOR=" <<
event.GetTxVector ()
99 <<
", power=" <<
event.GetRxPowerW () <<
"W" 100 <<
", PPDU=" <<
event.GetPpdu ();
157 Ptr<Event> event = Create<Event> (ppdu, txVector, duration, rxPowerW);
169 Ptr<WifiPpdu> fakePpdu = Create<WifiPpdu> (Create<WifiPsdu> (Create<Packet> (0), hdr),
206 double noiseInterferenceW = i->second.GetPower ();
208 if (noiseInterferenceW < energyW)
220 double previousPowerStart = 0;
221 double previousPowerEnd = 0;
234 for (
auto i =
first; i != last; ++i)
236 i->second.AddPower (event->GetRxPowerW ());
244 static const double BOLTZMANN = 1.3803e-23;
247 double Nt = BOLTZMANN * 290 * channelWidth * 1e6;
250 double noise = noiseFloor + noiseInterference;
251 double snr = signal / noise;
252 NS_LOG_DEBUG (
"bandwidth(MHz)=" << channelWidth <<
", signal(W)= " << signal <<
", noise(W)=" << noiseFloor <<
", interference(W)=" << noiseInterference <<
", snr=" <<
RatioToDb(snr) <<
"dB");
258 NS_LOG_DEBUG (
"SNR improvement thanks to diversity: " << 10 * std::log10 (gain) <<
"dB");
267 auto it =
m_niChanges.find (event->GetStartTime ());
270 noiseInterferenceW = it->second.GetPower () -
event->GetRxPowerW ();
273 for (; it !=
m_niChanges.end () && it->second.GetEvent () != event; ++it);
274 ni->emplace (event->GetStartTime (),
NiChange (0, event));
275 while (++it !=
m_niChanges.end () && it->second.GetEvent () != event)
279 ni->emplace (event->GetEndTime (),
NiChange (0, event));
280 NS_ASSERT_MSG (noiseInterferenceW >= 0,
"CalculateNoiseInterferenceW returns negative value " << noiseInterferenceW);
281 return noiseInterferenceW;
292 uint64_t nbits =
static_cast<uint64_t
> (rate * duration.
GetSeconds ());
293 double csr =
m_errorRateModel->GetChunkSuccessRate (mode, txVector, snir, nbits);
306 uint64_t nbits =
static_cast<uint64_t
> (rate * duration.
GetSeconds ());
307 nbits /= txVector.
GetNss ();
308 double csr =
m_errorRateModel->GetChunkSuccessRate (mode, txVector, snir, nbits);
318 auto j = ni->begin ();
319 Time previous = j->first;
320 WifiMode payloadMode =
event->GetTxVector ().GetMode ();
326 Time windowStart = phyPayloadStart +
window.first;
327 Time windowEnd = phyPayloadStart +
window.second;
329 double powerW =
event->GetRxPowerW ();
330 while (++j != ni->end ())
332 Time current = j->first;
333 NS_LOG_DEBUG (
"previous= " << previous <<
", current=" << current);
335 double snr =
CalculateSnr (powerW, noiseInterferenceW, txVector);
337 if (previous >= windowStart)
340 NS_LOG_DEBUG (
"Both previous and current point to the windowed payload: mode=" << payloadMode <<
", psr=" << psr);
343 else if (current >= windowStart)
346 NS_LOG_DEBUG (
"previous is before windowed payload and current is in the windowed payload: mode=" << payloadMode <<
", psr=" << psr);
348 noiseInterferenceW = j->second.GetPower () - powerW;
350 if (previous > windowEnd)
352 NS_LOG_DEBUG (
"Stop: new previous=" << previous <<
" after time window end=" << windowEnd);
356 double per = 1 - psr;
366 auto j = ni->begin ();
367 Time previous = j->first;
375 double powerW =
event->GetRxPowerW ();
376 while (++j != ni->end ())
378 Time current = j->first;
379 NS_LOG_DEBUG (
"previous= " << previous <<
", current=" << current);
381 double snr =
CalculateSnr (powerW, noiseInterferenceW, txVector);
383 if (previous >= phyPayloadStart)
386 NS_LOG_DEBUG (
"Case 1 - previous and current after payload start: nothing to do");
389 else if (previous >= phyTrainingSymbolsStart)
393 NS_LOG_DEBUG (
"Case 2 - previous is in training or in SIG-B: nothing to do");
396 else if (previous >= phyLSigHeaderEnd)
400 NS_LOG_DEBUG (
"Case 3cii - previous is in HT-SIG or SIG-A: nothing to do");
403 else if (previous >= phyHeaderStart)
407 if (current >= phyPayloadStart)
410 NS_LOG_DEBUG (
"Case 4a - previous in L-SIG and current after payload start: mode=" << headerMode <<
", psr=" << psr);
413 else if (current >= phyTrainingSymbolsStart)
417 NS_LOG_DEBUG (
"Case 4a - previous in L-SIG and current is in training or in SIG-B: mode=" << headerMode <<
", psr=" << psr);
420 else if (current >= phyLSigHeaderEnd)
424 NS_LOG_DEBUG (
"Case 4ci - previous is in L-SIG and current in HT-SIG or in SIG-A: mode=" << headerMode <<
", psr=" << psr);
430 NS_LOG_DEBUG (
"Case 4d - current with previous in L-SIG: mode=" << headerMode <<
", psr=" << psr);
437 if (current >= phyPayloadStart)
440 NS_LOG_DEBUG (
"Case 5aii - previous is in the preamble and current is after payload start: mode=" << headerMode <<
", psr=" << psr);
443 else if (current >= phyTrainingSymbolsStart)
447 NS_LOG_DEBUG (
"Case 5b - previous is in the preamble and current is in training or in SIG-B: mode=" << headerMode <<
", psr=" << psr);
450 else if (current >= phyLSigHeaderEnd)
454 NS_LOG_DEBUG (
"Case 5b - previous is in the preamble and current in HT-SIG or in SIG-A: mode=" << headerMode <<
", psr=" << psr);
457 else if (current >= phyHeaderStart)
461 NS_LOG_DEBUG (
"Case 5d - previous is in the preamble and current is in L-SIG: mode=" << headerMode <<
", psr=" << psr);
465 noiseInterferenceW = j->second.GetPower () - powerW;
469 double per = 1 - psr;
479 auto j = ni->begin ();
480 Time previous = j->first;
504 double powerW =
event->GetRxPowerW ();
505 while (++j != ni->end ())
507 Time current = j->first;
508 NS_LOG_DEBUG (
"previous= " << previous <<
", current=" << current);
510 double snr =
CalculateSnr (powerW, noiseInterferenceW, txVector);
512 if (previous >= phyPayloadStart)
515 NS_LOG_DEBUG (
"Case 1 - previous and current after payload start: nothing to do");
518 else if (previous >= phyTrainingSymbolsStart)
522 if (current >= phyPayloadStart)
525 NS_LOG_DEBUG (
"Case 2a - previous is in training or in SIG-B and current after payload start: mode=" << mcsHeaderMode <<
", psr=" << psr);
531 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);
535 else if (previous >= phyLSigHeaderEnd)
539 if (current >= phyPayloadStart)
547 NS_LOG_DEBUG (
"Case 3ai - previous is in SIG-A and current after payload start: mcs mode=" << mcsHeaderMode <<
", non-HT mode=" << headerMode <<
", psr=" << psr);
553 NS_LOG_DEBUG (
"Case 3aii - previous is in HT-SIG and current after payload start: mode=" << mcsHeaderMode <<
", psr=" << psr);
557 else if (current >= phyTrainingSymbolsStart)
565 NS_LOG_DEBUG (
"Case 3bi - previous is in SIG-A and current is in training or in SIG-B: mode=" << headerMode <<
", psr=" << psr);
571 NS_LOG_DEBUG (
"Case 3bii - previous is in HT-SIG and current is in HT training: mode=" << mcsHeaderMode <<
", psr=" << psr);
582 NS_LOG_DEBUG (
"Case 3ci - previous with current in SIG-A: mode=" << headerMode <<
", psr=" << psr);
588 NS_LOG_DEBUG (
"Case 3cii - previous with current in HT-SIG: mode=" << mcsHeaderMode <<
", psr=" << psr);
593 else if (previous >= phyHeaderStart)
597 if (current >= phyPayloadStart)
603 NS_LOG_DEBUG (
"Case 4ai - previous in L-SIG and current after payload start: nothing to do");
610 NS_LOG_DEBUG (
"Case 4aii - previous is in L-SIG and current after payload start: mcs mode=" << mcsHeaderMode <<
", non-HT mode=" << headerMode <<
", psr=" << psr);
616 NS_LOG_DEBUG (
"Case 4aiii - previous in L-SIG and current after payload start: mcs mode=" << mcsHeaderMode <<
", psr=" << psr);
620 else if (current >= phyTrainingSymbolsStart)
628 NS_LOG_DEBUG (
"Case 4bi - previous is in L-SIG and current in training or in SIG-B: mcs mode=" << mcsHeaderMode <<
", non-HT mode=" << headerMode <<
", psr=" << psr);
634 NS_LOG_DEBUG (
"Case 4bii - previous in L-SIG and current in HT training: mcs mode=" << mcsHeaderMode <<
", psr=" << psr);
638 else if (current >= phyLSigHeaderEnd)
645 NS_LOG_DEBUG (
"Case 4ci - previous is in L-SIG and current in SIG-A: mode=" << headerMode <<
", psr=" << psr);
651 NS_LOG_DEBUG (
"Case 4cii - previous in L-SIG and current in HT-SIG: mcs mode=" << mcsHeaderMode <<
", psr=" << psr);
658 NS_LOG_DEBUG (
"Case 4d - current with previous in L-SIG: nothing to do");
665 if (current >= phyPayloadStart)
671 NS_LOG_DEBUG (
"Case 5ai - previous is in the preamble and current is after payload start: nothing to do");
678 NS_LOG_DEBUG (
"Case 5aii - previous is in the preamble and current is after payload start: mcs mode=" << mcsHeaderMode <<
", non-HT mode=" << headerMode <<
", psr=" << psr);
684 NS_LOG_DEBUG (
"Case 5aiii - previous is in the preamble and current is after payload start: mcs mode=" << mcsHeaderMode <<
", non-HT mode=" << headerMode <<
", psr=" << psr);
688 else if (current >= phyTrainingSymbolsStart)
696 NS_LOG_DEBUG (
"Case 5bi - previous is in the preamble and current in training or in SIG-B: mcs mode=" << mcsHeaderMode <<
", non-HT mode=" << headerMode <<
", psr=" << psr);
702 NS_LOG_DEBUG (
"Case 5bii - previous is in the preamble and current in HT training: mcs mode=" << mcsHeaderMode <<
", psr=" << psr);
706 else if (current >= phyLSigHeaderEnd)
713 NS_LOG_DEBUG (
"Case 5ci - previous is in preamble and current in SIG-A: mode=" << headerMode <<
", psr=" << psr);
719 NS_LOG_DEBUG (
"Case 5cii - previous in preamble and current in HT-SIG: mcs mode=" << mcsHeaderMode <<
", psr=" << psr);
723 else if (current >= phyHeaderStart)
727 NS_LOG_DEBUG (
"Case 5d - previous is in the preamble and current is in L-SIG: nothing to do");
731 noiseInterferenceW = j->second.GetPower () - powerW;
735 double per = 1 - psr;
740 InterferenceHelper::CalculatePayloadSnrPer (Ptr<Event> event, std::pair<Time, Time> relativeMpduStartStop) const
746 event->GetTxVector ());
766 event->GetTxVector ());
777 event->GetTxVector ());
797 event->GetTxVector ());
820 InterferenceHelper::NiChanges::const_iterator
826 InterferenceHelper::NiChanges::const_iterator
836 InterferenceHelper::NiChanges::iterator
double GetRxPowerW(void) const
Return the received power (w).
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.
Smart pointer class similar to boost::intrusive_ptr.
#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.
double m_rxPowerW
received power in watts
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...
Time GetEndTime(void) const
Return the end time of the signal.
handles interference calculations
double CalculateNonHtPhyHeaderPer(Ptr< const Event > event, NiChanges *ni) const
Calculate the error rate of the non-HT PHY header.
static WifiMode GetHePhyHeaderMode()
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
#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.
static Time GetPhyPreambleDuration(WifiTxVector txVector)
Time GetStartTime(void) const
Return the start time of the signal.
Ptr< Event > GetEvent(void) const
Return the event causes the corresponding NI change.
Ptr< const WifiPpdu > GetPpdu(void) const
Return the PPDU.
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 snr
SNR in linear scale.
Ptr< const WifiPpdu > m_ppdu
PPDU.
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. ...
WifiPreamble GetPreambleType(void) const
static Time GetPhyHtSigHeaderDuration(WifiPreamble preamble)
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
int64x64_t Min(const int64x64_t &a, const int64x64_t &b)
Minimum.
static WifiMode GetHtPhyHeaderMode()
bool IsZero(void) const
Exactly equivalent to t == 0.
Time GetEnergyDuration(double energyW) const
NiChanges m_niChanges
Experimental: needed for energy duration calculation.
double CalculatePayloadChunkSuccessRate(double snir, Time duration, WifiTxVector txVector) const
Calculate the success rate of the payload chunk given the SINR, duration, and Wi-Fi mode...
Time GetDuration(void) const
Return the duration of the signal.
WifiMode GetMode(void) const
double CalculateNoiseInterferenceW(Ptr< Event > event, NiChanges *ni) const
Calculate noise and interference power in W.
WifiTxVector GetTxVector(void) const
Return the TXVECTOR of the PPDU.
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
static WifiMode GetVhtPhyHeaderMode()
double m_noiseFigure
noise figure (linear)
static Time GetPhySigA1Duration(WifiPreamble preamble)
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.
static Time GetPhyTrainingSymbolDuration(WifiTxVector txVector)
double CalculateSnr(Ptr< Event > event) const
Calculate the SNIR for the event (starting from now until the event end).
uint8_t m_numRxAntennas
the number of RX antennas in the corresponding receiver
static Time Now(void)
Return the current simulation virtual time.
double CalculateHtPhyHeaderPer(Ptr< const Event > event, NiChanges *ni) const
Calculate the error rate of the HT PHY header.
Ptr< Event > Add(Ptr< const WifiPpdu > ppdu, WifiTxVector txVector, Time duration, double rxPower)
Add the PPDU-related signal to interference helper.
double RatioToDb(double ratio)
Convert from ratio to dB.
static WifiMode GetPhyHeaderMode(WifiTxVector txVector)
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Event(Ptr< const WifiPpdu > ppdu, WifiTxVector txVector, Time duration, double rxPower)
Create an Event with the given parameters.
void NotifyRxEnd()
Notify that RX has ended.
void SetNoiseFigure(double value)
Set the noise figure.
double m_firstPower
first power in watts
NiChange(double power, Ptr< Event > event)
Create a NiChange at the given time and the amount of NI change.
double CalculatePayloadPer(Ptr< const Event > event, NiChanges *ni, std::pair< Time, Time > window) const
Calculate the error rate of the given PHY payload only in the provided time window (thus enabling per...
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
static Time GetPhySigA2Duration(WifiPreamble preamble)
WifiTxVector m_txVector
TXVECTOR.
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 GetNextPosition(Time moment) const
Returns an iterator to the first NiChange that is later than moment.
double GetPower(void) const
Return the power.
uint16_t GetChannelWidth(void) const
static Time GetPhyHeaderDuration(WifiTxVector txVector)
handles interference calculations
Ptr< const WifiPsdu > GetPsdu(void) const
Return the PSDU in the PPDU.
static Time GetPhySigBDuration(WifiPreamble preamble)
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
NiChanges::const_iterator GetPreviousPosition(Time moment) const
Returns an iterator to the first NiChange that is later than moment.
uint8_t GetNss(void) const
std::multimap< Time, NiChange > NiChanges
typedef for a multimap of NiChanges
bool m_rxing
flag whether it is in receiving state
Time m_startTime
start time