|
A Discrete-Event Network Simulator
|
API
|
Go to the documentation of this file.
24 #include "ns3/simulator.h"
26 #include "ns3/packet.h"
43 m_txVector (txVector),
45 m_endTime (m_startTime + duration),
46 m_rxPowerW (std::move (rxPower))
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, std::move (rxPowerW));
205 Ptr<WifiPpdu> fakePpdu = Create<WifiPpdu> (Create<WifiPsdu> (Create<Packet> (0), hdr),
267 for (; i != niIt->second.end (); ++i)
269 double noiseInterferenceW = i->second.GetPower ();
271 if (noiseInterferenceW < energyW)
283 for (
auto const& it : event->GetRxPowerWPerBand ())
288 double previousPowerStart = 0;
289 double previousPowerEnd = 0;
291 previousPowerStart = previousPowerPosition->second.GetPower ();
297 niIt->second.erase (++(niIt->second.begin ()), ++previousPowerPosition);
299 else if (isStartOfdmaRxing)
308 for (
auto i =
first; i != last; ++i)
310 i->second.AddPower (it.second);
320 for (
auto const& it : rxPower)
327 for (
auto i =
first; i != last; ++i)
329 i->second.AddPower (it.second);
332 event->UpdateRxPowerW (rxPower);
338 NS_LOG_FUNCTION (
this << signal << noiseInterference << channelWidth << +nss);
340 static const double BOLTZMANN = 1.3803e-23;
342 double Nt = BOLTZMANN * 290 * channelWidth * 1e6;
345 double noise = noiseFloor + noiseInterference;
346 double snr = signal / noise;
347 NS_LOG_DEBUG (
"bandwidth(MHz)=" << channelWidth <<
", signal(W)= " << signal <<
", noise(W)=" << noiseFloor <<
", interference(W)=" << noiseInterference <<
", snr=" <<
RatioToDb(snr) <<
"dB");
355 NS_LOG_DEBUG (
"SNR improvement thanks to diversity: " << 10 * std::log10 (gain) <<
"dB");
367 double noiseInterferenceW = firstPower_it->second;
370 auto it = niIt->second.find (event->GetStartTime ());
371 for (; it != niIt->second.end () && it->first <
Simulator::Now (); ++it)
373 noiseInterferenceW = it->second.GetPower () -
event->GetRxPowerW (band);
375 it = niIt->second.find (event->GetStartTime ());
377 for (; it != niIt->second.end () && it->second.GetEvent () != event; ++it);
379 ni.emplace (event->GetStartTime (),
NiChange (0, event));
380 while (++it != niIt->second.end () && it->second.GetEvent () != event)
384 ni.emplace (event->GetEndTime (),
NiChange (0, event));
385 nis->insert ({band, ni});
386 NS_ASSERT_MSG (noiseInterferenceW >= 0,
"CalculateNoiseInterferenceW returns negative value " << noiseInterferenceW);
387 return noiseInterferenceW;
398 uint64_t nbits =
static_cast<uint64_t
> (rate * duration.
GetSeconds ());
411 uint64_t rate = mode.
GetDataRate (txVector, staId);
412 uint64_t nbits =
static_cast<uint64_t
> (rate * duration.
GetSeconds ());
413 nbits /= txVector.
GetNss (staId);
421 uint16_t staId, std::pair<Time, Time>
window)
const
425 auto niIt = nis->find (band)->second;
426 auto j = niIt.begin ();
427 Time previous = j->first;
428 WifiMode payloadMode =
event->GetTxVector ().GetMode (staId);
429 Time phyPayloadStart = j->first;
434 Time windowStart = phyPayloadStart +
window.first;
435 Time windowEnd = phyPayloadStart +
window.second;
437 double powerW =
event->GetRxPowerW (band);
438 while (++j != niIt.end ())
440 Time current = j->first;
441 NS_LOG_DEBUG (
"previous= " << previous <<
", current=" << current);
443 double snr =
CalculateSnr (powerW, noiseInterferenceW, channelWidth, event->GetTxVector ().GetNss (staId));
445 if (previous >= windowStart)
448 NS_LOG_DEBUG (
"Both previous and current point to the windowed payload: mode=" << payloadMode <<
", psr=" << psr);
451 else if (current >= windowStart)
454 NS_LOG_DEBUG (
"previous is before windowed payload and current is in the windowed payload: mode=" << payloadMode <<
", psr=" << psr);
456 noiseInterferenceW = j->second.GetPower () - powerW;
458 if (previous > windowEnd)
460 NS_LOG_DEBUG (
"Stop: new previous=" << previous <<
" after time window end=" << windowEnd);
464 double per = 1 - psr;
475 auto niIt = nis->find (band)->second;
476 auto j = niIt.begin ();
480 for (
const auto & section : phyHeaderSections)
482 stopLastSection =
Max (stopLastSection, section.second.first.second);
485 Time previous = j->first;
487 double powerW =
event->GetRxPowerW (band);
488 while (++j != niIt.end ())
490 Time current = j->first;
491 NS_LOG_DEBUG (
"previous= " << previous <<
", current=" << current);
493 double snr =
CalculateSnr (powerW, noiseInterferenceW, channelWidth, 1);
494 for (
const auto & section : phyHeaderSections)
497 Time stop = section.second.first.second;
499 if (previous <= stop || current >=
start)
505 NS_LOG_DEBUG (
"Current NI change in " << section.first <<
" [" <<
start <<
", " << stop <<
"] for "
506 << duration.
As (
Time::NS) <<
": mode=" << section.second.second <<
", psr=" << psr);
510 noiseInterferenceW = j->second.GetPower () - powerW;
512 if (previous > stopLastSection)
514 NS_LOG_DEBUG (
"Stop: new previous=" << previous <<
" after stop of last section=" << stopLastSection);
527 auto niIt = nis->find (band)->second;
531 for (
const auto & section : phyEntity->GetPhyHeaderSections (event->GetTxVector (), niIt.begin ()->first))
533 if (section.first == header)
535 sections[header] = section.second;
540 if (!sections.empty () > 0)
548 InterferenceHelper::CalculatePayloadSnrPer (Ptr<Event> event, uint16_t channelWidth, WifiSpectrumBand band,
549 uint16_t staId, std::pair<Time, Time> relativeMpduStartStop) const
551 NS_LOG_FUNCTION (
this << channelWidth << band.first << band.second << staId << relativeMpduStartStop.first << relativeMpduStartStop.second);
553 double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni, band);
554 double snr = CalculateSnr (event->GetRxPowerW (band),
557 event->GetTxVector ().GetNss (staId));
562 double per = CalculatePayloadPer (event, channelWidth, &ni, band, staId, relativeMpduStartStop);
580 InterferenceHelper::CalculatePhyHeaderSnrPer (Ptr<Event> event, uint16_t channelWidth, WifiSpectrumBand band,
581 WifiPpduField header) const
585 double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni, band);
586 double snr = CalculateSnr (event->GetRxPowerW (band),
594 double per = CalculatePhyHeaderPer (event, &ni, channelWidth, band, header);
604 niIt->second.clear ();
612 InterferenceHelper::NiChanges::iterator
615 return niIt->second.upper_bound (moment);
618 InterferenceHelper::NiChanges::iterator
628 InterferenceHelper::NiChanges::iterator
631 return niIt->second.insert (
GetNextPosition (moment, niIt), std::make_pair (moment, change));
void NotifyRxStart()
Notify that RX has started.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
std::map< WifiSpectrumBand, double > m_firstPowerPerBand
first power of each band in watts
double m_noiseFigure
noise figure (linear)
double CalculateNoiseInterferenceW(Ptr< Event > event, NiChangesPerBand *nis, WifiSpectrumBand band) const
Calculate noise and interference power in W.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Noise and Interference (thus Ni) event.
std::pair< uint32_t, uint32_t > WifiSpectrumBand
typedef for a pair of start and stop sub-band indexes
static Time Now(void)
Return the current simulation virtual time.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double GetRxPowerW(void) const
Return the total received power (W).
double snr
SNR in linear scale.
WifiTxVector m_txVector
TXVECTOR.
Time GetEnergyDuration(double energyW, WifiSpectrumBand band)
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
double CalculatePhyHeaderPer(Ptr< const Event > event, NiChangesPerBand *nis, uint16_t channelWidth, WifiSpectrumBand band, WifiPpduField header) const
Calculate the error rate of the PHY header.
Ptr< ErrorRateModel > GetErrorRateModel(void) const
Return the error rate model.
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Set the error rate model for this interference helper.
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
bool IsStrictlyPositive(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.
NiChangesPerBand m_niChangesPerBand
NI Changes for each band.
void SetNumberOfReceiveAntennas(uint8_t rx)
Set the number of RX antennas in the receiver corresponding to this interference helper.
Ptr< const WifiPpdu > m_ppdu
PPDU.
Ptr< ErrorRateModel > m_errorRateModel
error rate model
NiChanges::iterator AddNiChangeEvent(Time moment, NiChange change, NiChangesPerBand::iterator niIt)
Add NiChange to the list at the appropriate position and return the iterator of the new event.
handles interference calculations
void AddForeignSignal(Time duration, RxPowerWattPerChannelBand &rxPower)
Add a non-Wifi signal to interference helper.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
Time GetStartTime(void) const
Return the start time of the signal.
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
int64x64_t Min(const int64x64_t &a, const int64x64_t &b)
Minimum.
std::map< WifiSpectrumBand, NiChanges > NiChangesPerBand
Map of NiChanges per band.
Event(Ptr< const WifiPpdu > ppdu, const WifiTxVector &txVector, Time duration, RxPowerWattPerChannelBand &&rxPower)
Create an Event with the given parameters.
void EraseEvents(void)
Erase all events.
std::map< WifiPpduField, PhyHeaderChunkInfo > PhyHeaderSections
A map of PhyHeaderChunkInfo elements per PPDU field.
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...
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.
double GetPower(void) const
Return the power.
Ptr< const WifiPpdu > GetPpdu(void) const
Return the PPDU.
Smart pointer class similar to boost::intrusive_ptr.
int64x64_t Max(const int64x64_t &a, const int64x64_t &b)
Maximum.
void AddPower(double power)
Add a given amount of power.
NiChanges::iterator GetPreviousPosition(Time moment, NiChangesPerBand::iterator niIt)
Returns an iterator to the last NiChange that is before than moment.
void AppendEvent(Ptr< Event > event, bool isStartOfdmaRxing)
Append the given Event.
RxPowerWattPerChannelBand m_rxPowerW
received power in watts per band
represent a single transmission mode
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
bool IsZero(void) const
Exactly equivalent to t == 0.
Time GetEndTime(void) const
Return the end time of the signal.
Simulation virtual time values and global simulation resolution.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
uint16_t GetChannelWidth(void) const
WifiPpduField
The type of PPDU field (grouped for convenience)
void UpdateRxPowerW(const RxPowerWattPerChannelBand &rxPower)
Update the received power (W) for all bands, i.e.
bool m_rxing
flag whether it is in receiving state
const RxPowerWattPerChannelBand & GetRxPowerWPerBand(void) const
Return the received power (W) for all bands.
double RatioToDb(double ratio)
Convert from ratio to dB.
uint8_t m_numRxAntennas
the number of RX antennas in the corresponding receiver
void UpdateEvent(Ptr< Event > event, const RxPowerWattPerChannelBand &rxPower)
Update event to scale its received power (W) per band.
Ptr< Event > GetEvent(void) const
Return the event causes the corresponding NI change.
Time m_startTime
start time
std::multimap< Time, NiChange > NiChanges
typedef for a multimap of NiChange
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.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
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).
void AddBand(WifiSpectrumBand band)
Add a frequency band.
NiChange(double power, Ptr< Event > event)
Create a NiChange at the given time and the amount of NI change.
Time Seconds(double value)
Construct a Time in the indicated unit.
Control the scheduling of simulation events.
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.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
void RemoveBands(void)
Remove the frequency bands.
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.
void SetNoiseFigure(double value)
Set the noise figure.
@ WIFI_PPDU_FIELD_DATA
data field
A struct for both SNR and PER.
std::map< WifiSpectrumBand, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
std::ostream & operator<<(std::ostream &os, const Angles &a)
Time GetDuration(void) const
Return the duration of the signal.
NiChanges::iterator GetNextPosition(Time moment, NiChangesPerBand::iterator niIt)
Returns an iterator to the first NiChange that is later than moment.
const WifiTxVector & GetTxVector(void) const
Return the TXVECTOR of the PPDU.
static const Ptr< const PhyEntity > GetStaticPhyEntity(WifiModulationClass modulation)
Get the implemented PHY entity corresponding to the modulation class.
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
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.
handles interference calculations
void NotifyRxEnd(Time endTime)
Notify that RX has ended.