24 #include "ns3/simulator.h" 26 #include "ns3/packet.h" 43 m_txVector (txVector),
45 m_endTime (m_startTime + duration),
86 [] (
const std::pair<WifiSpectrumBand, double>& p1,
const std::pair<WifiSpectrumBand, double>& p2) {
87 return p1.second < p2.second;
119 auto band = currentRxPowerW.first;
120 auto it = rxPower.find (band);
121 if (it != rxPower.end ())
123 currentRxPowerW.second += it->second;
130 os <<
"start=" <<
event.GetStartTime () <<
", end=" <<
event.GetEndTime ()
131 <<
", TXVECTOR=" <<
event.GetTxVector ()
132 <<
", power=" <<
event.GetRxPowerW () <<
"W" 133 <<
", PPDU=" <<
event.GetPpdu ();
192 Ptr<Event> event = Create<Event> (ppdu, txVector, duration, rxPowerW);
205 Ptr<WifiPpdu> fakePpdu = Create<WifiPpdu> (Create<WifiPsdu> (Create<Packet> (0), hdr),
266 for (; i != ni_it->second.end (); ++i)
268 double noiseInterferenceW = i->second.GetPower ();
270 if (noiseInterferenceW < energyW)
283 for (
auto const& it : rxPowerWattPerChannelBand)
288 double previousPowerStart = 0;
289 double previousPowerEnd = 0;
296 ni_it->second.erase (++(ni_it->second.begin ()),
GetNextPosition (event->GetStartTime (), band));
298 else if (isStartOfdmaRxing)
307 for (
auto i =
first; i != last; ++i)
309 i->second.AddPower (it.second);
319 for (
auto const& it : rxPower)
326 for (
auto i =
first; i != last; ++i)
328 i->second.AddPower (it.second);
331 event->UpdateRxPowerW (rxPower);
337 NS_LOG_FUNCTION (
this << signal << noiseInterference << channelWidth << +nss);
339 static const double BOLTZMANN = 1.3803e-23;
341 double Nt = BOLTZMANN * 290 * channelWidth * 1e6;
344 double noise = noiseFloor + noiseInterference;
345 double snr = signal / noise;
346 NS_LOG_DEBUG (
"bandwidth(MHz)=" << channelWidth <<
", signal(W)= " << signal <<
", noise(W)=" << noiseFloor <<
", interference(W)=" << noiseInterference <<
", snr=" <<
RatioToDb(snr) <<
"dB");
354 NS_LOG_DEBUG (
"SNR improvement thanks to diversity: " << 10 * std::log10 (gain) <<
"dB");
366 double noiseInterferenceW = firstPower_it->second;
369 auto it = ni_it->second.find (event->GetStartTime ());
370 for (; it != ni_it->second.end () && it->first <
Simulator::Now (); ++it)
372 noiseInterferenceW = it->second.GetPower () -
event->GetRxPowerW (band);
374 it = ni_it->second.find (event->GetStartTime ());
376 for (; it != ni_it->second.end () && it->second.GetEvent () != event; ++it);
378 ni.emplace (event->GetStartTime (),
NiChange (0, event));
379 while (++it != ni_it->second.end () && it->second.GetEvent () != event)
383 ni.emplace (event->GetEndTime (),
NiChange (0, event));
384 nis->insert ({band, ni});
385 NS_ASSERT_MSG (noiseInterferenceW >= 0,
"CalculateNoiseInterferenceW returns negative value " << noiseInterferenceW);
386 return noiseInterferenceW;
397 uint64_t nbits =
static_cast<uint64_t
> (rate * duration.
GetSeconds ());
410 uint64_t rate = mode.
GetDataRate (txVector, staId);
411 uint64_t nbits =
static_cast<uint64_t
> (rate * duration.
GetSeconds ());
412 nbits /= txVector.
GetNss (staId);
420 uint16_t staId, std::pair<Time, Time>
window)
const 424 auto ni_it = nis->find (band)->second;
425 auto j = ni_it.begin ();
426 Time previous = j->first;
427 WifiMode payloadMode =
event->GetTxVector ().GetMode (staId);
428 Time phyPayloadStart = j->first;
433 Time windowStart = phyPayloadStart +
window.first;
434 Time windowEnd = phyPayloadStart +
window.second;
436 double powerW =
event->GetRxPowerW (band);
437 while (++j != ni_it.end ())
439 Time current = j->first;
440 NS_LOG_DEBUG (
"previous= " << previous <<
", current=" << current);
442 double snr =
CalculateSnr (powerW, noiseInterferenceW, channelWidth, event->GetTxVector ().GetNss (staId));
444 if (previous >= windowStart)
447 NS_LOG_DEBUG (
"Both previous and current point to the windowed payload: mode=" << payloadMode <<
", psr=" << psr);
450 else if (current >= windowStart)
453 NS_LOG_DEBUG (
"previous is before windowed payload and current is in the windowed payload: mode=" << payloadMode <<
", psr=" << psr);
455 noiseInterferenceW = j->second.GetPower () - powerW;
457 if (previous > windowEnd)
459 NS_LOG_DEBUG (
"Stop: new previous=" << previous <<
" after time window end=" << windowEnd);
463 double per = 1 - psr;
474 auto ni_it = nis->find (band)->second;
475 auto j = ni_it.begin ();
479 for (
const auto & section : phyHeaderSections)
481 stopLastSection =
Max (stopLastSection, section.second.first.second);
484 Time previous = j->first;
486 double powerW =
event->GetRxPowerW (band);
487 while (++j != ni_it.end ())
489 Time current = j->first;
490 NS_LOG_DEBUG (
"previous= " << previous <<
", current=" << current);
492 double snr =
CalculateSnr (powerW, noiseInterferenceW, channelWidth, 1);
493 for (
const auto & section : phyHeaderSections)
496 Time stop = section.second.first.second;
498 if (previous <= stop || current >=
start)
504 NS_LOG_DEBUG (
"Current NI change in " << section.first <<
" [" <<
start <<
", " << stop <<
"] for " 505 << duration.
As (
Time::NS) <<
": mode=" << section.second.second <<
", psr=" << psr);
509 noiseInterferenceW = j->second.GetPower () - powerW;
511 if (previous > stopLastSection)
513 NS_LOG_DEBUG (
"Stop: new previous=" << previous <<
" after stop of last section=" << stopLastSection);
526 auto ni_it = nis->find (band)->second;
530 for (
const auto & section : phyEntity->GetPhyHeaderSections (event->GetTxVector (), ni_it.begin ()->first))
532 if (section.first == header)
534 sections[header] = section.second;
539 if (!sections.empty () > 0)
547 InterferenceHelper::CalculatePayloadSnrPer (Ptr<Event> event, uint16_t channelWidth, WifiSpectrumBand band,
548 uint16_t staId, std::pair<Time, Time> relativeMpduStartStop) const
550 NS_LOG_FUNCTION (
this << channelWidth << band.first << band.second << staId << relativeMpduStartStop.first << relativeMpduStartStop.second);
552 double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni, band);
553 double snr = CalculateSnr (event->GetRxPowerW (band),
556 event->GetTxVector ().GetNss (staId));
561 double per = CalculatePayloadPer (event, channelWidth, &ni, band, staId, relativeMpduStartStop);
579 InterferenceHelper::CalculatePhyHeaderSnrPer (Ptr<Event> event, uint16_t channelWidth, WifiSpectrumBand band,
580 WifiPpduField header) const
584 double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni, band);
585 double snr = CalculateSnr (event->GetRxPowerW (band),
593 double per = CalculatePhyHeaderPer (event, &ni, channelWidth, band, header);
611 InterferenceHelper::NiChanges::iterator
616 return it->second.upper_bound (moment);
619 InterferenceHelper::NiChanges::iterator
629 InterferenceHelper::NiChanges::iterator
634 return it->second.insert (
GetNextPosition (moment, band), std::make_pair (moment, change));
double GetRxPowerW(void) const
Return the total received power (W).
double snr
SNR in linear scale.
double CalculatePayloadPer(Ptr< const Event > event, uint16_t channelWidth, NiChangesPerBand *nis, WifiSpectrumBand band, uint16_t staId, std::pair< Time, Time > window) const
Calculate the error rate of the given PHY payload only in the provided time window (thus enabling per...
void NotifyRxEnd(Time endTime)
Notify that RX has ended.
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
void AddPower(double power)
Add a given amount of power.
Simulation virtual time values and global simulation resolution.
Time GetEnergyDuration(double energyW, WifiSpectrumBand band)
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 "...
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...
Time GetEndTime(void) const
Return the end time of the signal.
void RemoveBands(void)
Remove the frequency bands.
void UpdateEvent(Ptr< Event > event, RxPowerWattPerChannelBand rxPower)
Update event to scale its received power (W) per band.
handles interference calculations
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.
NiChangesPerBand m_niChangesPerBand
NI Changes for each band.
Time GetStartTime(void) const
Return the start time of the signal.
Ptr< Event > GetEvent(void) const
Return the event causes the corresponding NI change.
void UpdateRxPowerW(RxPowerWattPerChannelBand rxPower)
Update the received power (W) for all bands, i.e.
bool IsStrictlyPositive(void) const
Exactly equivalent to t > 0.
double CalculatePayloadChunkSuccessRate(double snir, Time duration, const WifiTxVector &txVector, uint16_t staId=SU_STA_ID) const
Calculate the success rate of the payload chunk given the SINR, duration, and TXVECTOR.
Ptr< const WifiPpdu > GetPpdu(void) const
Return the PPDU.
uint8_t GetNss(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the number of spatial streams.
Ptr< ErrorRateModel > m_errorRateModel
error rate model
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Ptr< const WifiPpdu > m_ppdu
PPDU.
std::map< WifiPpduField, PhyHeaderChunkInfo > PhyHeaderSections
A map of PhyHeaderChunkInfo elements per PPDU field.
NiChanges::iterator AddNiChangeEvent(Time moment, NiChange change, WifiSpectrumBand band)
Add NiChange to the list at the appropriate position and return the iterator of the new event...
WifiMode GetMode(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the selected payload transmission mode...
std::ostream & operator<<(std::ostream &os, const Angles &a)
Ptr< Event > Add(Ptr< const WifiPpdu > ppdu, const WifiTxVector &txVector, Time duration, RxPowerWattPerChannelBand rxPower, bool isStartOfdmaRxing=false)
Add the PPDU-related signal to interference helper.
std::map< WifiSpectrumBand, double > m_firstPowerPerBand
first power of each band in watts
int64x64_t Min(const int64x64_t &a, const int64x64_t &b)
Minimum.
static const Ptr< const PhyEntity > GetStaticPhyEntity(WifiModulationClass modulation)
Get the implemented PHY entity corresponding to the modulation class.
bool IsZero(void) const
Exactly equivalent to t == 0.
double CalculatePhyHeaderSectionPsr(Ptr< const Event > event, NiChangesPerBand *nis, uint16_t channelWidth, WifiSpectrumBand band, PhyEntity::PhyHeaderSections phyHeaderSections) const
Calculate the success rate of the PHY header sections for the provided event.
Time GetDuration(void) const
Return the duration of the signal.
int64x64_t Max(const int64x64_t &a, const int64x64_t &b)
Maximum.
WifiPpduField
The type of PPDU field (grouped for convenience)
std::map< WifiSpectrumBand, NiChanges > NiChangesPerBand
Map of NiChanges per band.
std::pair< uint32_t, uint32_t > WifiSpectrumBand
typedef for a pair of start and stop sub-band indexes
A struct for both SNR and PER.
double m_noiseFigure
noise figure (linear)
Event(Ptr< const WifiPpdu > ppdu, const WifiTxVector &txVector, Time duration, RxPowerWattPerChannelBand rxPower)
Create an Event with the given parameters.
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.
const WifiTxVector & GetTxVector(void) const
Return the TXVECTOR of the PPDU.
double CalculatePhyHeaderPer(Ptr< const Event > event, NiChangesPerBand *nis, uint16_t channelWidth, WifiSpectrumBand band, WifiPpduField header) const
Calculate the error rate of the PHY header.
double CalculateChunkSuccessRate(double snir, Time duration, WifiMode mode, const WifiTxVector &txVector, WifiPpduField field) const
Calculate the success rate of the chunk given the SINR, duration, and TXVECTOR.
uint8_t m_numRxAntennas
the number of RX antennas in the corresponding receiver
static Time Now(void)
Return the current simulation virtual time.
void AppendEvent(Ptr< Event > event, bool isStartOfdmaRxing)
Append the given Event.
double RatioToDb(double ratio)
Convert from ratio to dB.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
void AddBand(WifiSpectrumBand band)
Add a frequency band.
double CalculateNoiseInterferenceW(Ptr< Event > event, NiChangesPerBand *nis, WifiSpectrumBand band) const
Calculate noise and interference power in W.
void AddForeignSignal(Time duration, RxPowerWattPerChannelBand rxPower)
Add a non-Wifi signal to interference helper.
void SetNoiseFigure(double value)
Set the noise figure.
RxPowerWattPerChannelBand m_rxPowerW
received power in watts per band
NiChange(double power, Ptr< Event > event)
Create a NiChange at the given time and the amount of NI change.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Time Seconds(double value)
Construct a Time in the indicated unit.
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
NiChanges::iterator GetPreviousPosition(Time moment, WifiSpectrumBand band)
Returns an iterator to the last NiChange that is before than moment.
WifiTxVector m_txVector
TXVECTOR.
double CalculateSnr(Ptr< Event > event, uint16_t channelWidth, uint8_t nss, WifiSpectrumBand band) const
Calculate the SNIR for the event (starting from now until the event end).
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.
double GetPower(void) const
Return the power.
uint16_t GetChannelWidth(void) const
handles interference calculations
RxPowerWattPerChannelBand GetRxPowerWPerBand(void) const
Return the received power (W) for all bands.
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
std::map< WifiSpectrumBand, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
std::multimap< Time, NiChange > NiChanges
typedef for a multimap of NiChange
bool m_rxing
flag whether it is in receiving state
NiChanges::iterator GetNextPosition(Time moment, WifiSpectrumBand band)
Returns an iterator to the first NiChange that is later than moment.
Time m_startTime
start time