22 #include "ns3/packet.h" 23 #include "ns3/simulator.h" 39 m_txVector (txVector),
41 m_endTime (m_startTime + duration),
140 Ptr<Event> event = Create<Event> (packet, txVector, duration, rxPowerW);
152 Add (packet, fakeTxVector, duration, rxPowerW);
187 double noiseInterferenceW = i->second.GetPower ();
189 if (noiseInterferenceW < energyW)
201 double previousPowerStart = 0;
202 double previousPowerEnd = 0;
215 for (
auto i =
first; i != last; ++i)
217 i->second.AddPower (event->GetRxPowerW ());
225 static const double BOLTZMANN = 1.3803e-23;
227 double Nt = BOLTZMANN * 290 * channelWidth * 1e6;
230 double noise = noiseFloor + noiseInterference;
231 double snr = signal / noise;
232 NS_LOG_DEBUG (
"bandwidth(MHz)=" << channelWidth <<
", signal(W)= " << signal <<
", noise(W)=" << noiseFloor <<
", interference(W)=" << noiseInterference <<
", snr(linear)=" << snr);
240 auto it =
m_niChanges.find (event->GetStartTime ());
241 for (; it !=
m_niChanges.end () && it->second.GetEvent () != event; ++it)
243 noiseInterference = it->second.GetPower ();
245 ni->emplace (event->GetStartTime (),
NiChange (0, event));
246 while (++it !=
m_niChanges.end () && it->second.GetEvent () != event)
250 ni->emplace (event->GetEndTime (),
NiChange (0, event));
251 return noiseInterference;
262 uint64_t nbits =
static_cast<uint64_t
> (rate * duration.
GetSeconds ());
265 nbits /= txVector.
GetNss ();
269 ", SNIR improvement=+" << 10 * std::log10 (gain) <<
"dB");
272 double csr =
m_errorRateModel->GetChunkSuccessRate (mode, txVector, snir, nbits);
282 auto j = ni->begin ();
283 Time previous = j->first;
284 WifiMode payloadMode =
event->GetPayloadMode ();
291 double powerW =
event->GetRxPowerW ();
292 while (++j != ni->end ())
294 Time current = j->first;
295 NS_LOG_DEBUG (
"previous= " << previous <<
", current=" << current);
298 if (previous >= plcpPayloadStart)
304 payloadMode, txVector);
305 NS_LOG_DEBUG (
"Both previous and current point to the payload: mode=" << payloadMode <<
", psr=" << psr);
308 else if (current >= plcpPayloadStart)
313 current - plcpPayloadStart,
314 payloadMode, txVector);
315 NS_LOG_DEBUG (
"previous is before payload and current is in the payload: mode=" << payloadMode <<
", psr=" << psr);
317 noiseInterferenceW = j->second.GetPower () - powerW;
320 double per = 1 - psr;
330 auto j = ni->begin ();
331 Time previous = j->first;
355 double powerW =
event->GetRxPowerW ();
356 while (++j != ni->end ())
358 Time current = j->first;
359 NS_LOG_DEBUG (
"previous= " << previous <<
", current=" << current);
362 if (previous >= plcpPayloadStart)
365 NS_LOG_DEBUG (
"Case 1 - previous and current after playload start: nothing to do");
368 else if (previous >= plcpTrainingSymbolsStart)
372 if (current >= plcpPayloadStart)
377 plcpPayloadStart - previous,
378 mcsHeaderMode, txVector);
379 NS_LOG_DEBUG (
"Case 2a - previous is in training or in SIG-B and current after payload start: mode=" << mcsHeaderMode <<
", psr=" << psr);
388 mcsHeaderMode, txVector);
389 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);
393 else if (previous >= plcpHsigHeaderStart)
397 if (current >= plcpPayloadStart)
402 plcpPayloadStart - plcpTrainingSymbolsStart,
403 mcsHeaderMode, txVector);
411 plcpTrainingSymbolsStart - previous,
412 headerMode, txVector);
413 NS_LOG_DEBUG (
"Case 3ai - previous is in SIG-A and current after payload start: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
421 plcpTrainingSymbolsStart - previous,
422 mcsHeaderMode, txVector);
423 NS_LOG_DEBUG (
"Case 3aii - previous is in HT-SIG and current after payload start: mode=" << mcsHeaderMode <<
", psr=" << psr);
427 else if (current >= plcpTrainingSymbolsStart)
432 current - plcpTrainingSymbolsStart,
433 mcsHeaderMode, txVector);
441 plcpTrainingSymbolsStart - previous,
442 headerMode, txVector);
443 NS_LOG_DEBUG (
"Case 3bi - previous is in SIG-A and current is in training or in SIG-B: mode=" << headerMode <<
", psr=" << psr);
451 plcpTrainingSymbolsStart - previous,
452 mcsHeaderMode, txVector);
453 NS_LOG_DEBUG (
"Case 3bii - previous is in HT-SIG and current is in HT training: mode=" << mcsHeaderMode <<
", psr=" << psr);
467 headerMode, txVector);
468 NS_LOG_DEBUG (
"Case 3ci - previous with current in SIG-A: mode=" << headerMode <<
", psr=" << psr);
477 mcsHeaderMode, txVector);
478 NS_LOG_DEBUG (
"Case 3cii - previous with current in HT-SIG: mode=" << mcsHeaderMode <<
", psr=" << psr);
483 else if (previous >= plcpHeaderStart)
487 if (current >= plcpPayloadStart)
495 plcpPayloadStart - previous,
496 headerMode, txVector);
497 NS_LOG_DEBUG (
"Case 4ai - previous in L-SIG and current after payload start: mode=" << headerMode <<
", psr=" << psr);
505 plcpPayloadStart - plcpTrainingSymbolsStart,
506 mcsHeaderMode, txVector);
510 plcpTrainingSymbolsStart - previous,
511 headerMode, txVector);
512 NS_LOG_DEBUG (
"Case 4aii - previous is in L-SIG and current after payload start: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
520 plcpPayloadStart - plcpHsigHeaderStart,
521 mcsHeaderMode, txVector);
525 plcpHsigHeaderStart - previous,
526 headerMode, txVector);
527 NS_LOG_DEBUG (
"Case 4aiii - previous in L-SIG and current after payload start: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
531 else if (current >= plcpTrainingSymbolsStart)
540 current - plcpTrainingSymbolsStart,
541 mcsHeaderMode, txVector);
545 plcpTrainingSymbolsStart - previous,
546 headerMode, txVector);
547 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);
555 current - plcpHsigHeaderStart,
556 mcsHeaderMode, txVector);
560 plcpHsigHeaderStart - previous,
561 headerMode, txVector);
562 NS_LOG_DEBUG (
"Case 4bii - previous in L-SIG and current in HT training: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
566 else if (current >= plcpHsigHeaderStart)
576 headerMode, txVector);
577 NS_LOG_DEBUG (
"Case 4ci - previous is in L-SIG and current in SIG-A: mode=" << headerMode <<
", psr=" << psr);
585 current - plcpHsigHeaderStart,
586 mcsHeaderMode, txVector);
590 plcpHsigHeaderStart - previous,
591 headerMode, txVector);
592 NS_LOG_DEBUG (
"Case 4cii - previous in L-SIG and current in HT-SIG: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
602 headerMode, txVector);
603 NS_LOG_DEBUG (
"Case 4d - current with previous in L-SIG: mode=" << headerMode <<
", psr=" << psr);
610 if (current >= plcpPayloadStart)
618 plcpPayloadStart - plcpHeaderStart,
619 headerMode, txVector);
620 NS_LOG_DEBUG (
"Case 5a - previous is in the preamble and current is after payload start: mode=" << headerMode <<
", psr=" << psr);
628 plcpPayloadStart - plcpTrainingSymbolsStart,
629 mcsHeaderMode, txVector);
633 plcpTrainingSymbolsStart - plcpHeaderStart,
634 headerMode, txVector);
635 NS_LOG_DEBUG (
"Case 5aii - previous is in the preamble and current is after payload start: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
643 plcpPayloadStart - plcpHsigHeaderStart,
644 mcsHeaderMode, txVector);
648 plcpHsigHeaderStart - plcpHeaderStart,
649 headerMode, txVector);
650 NS_LOG_DEBUG (
"Case 5aiii - previous is in the preamble and current is after payload start: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
654 else if (current >= plcpTrainingSymbolsStart)
663 current - plcpTrainingSymbolsStart,
664 mcsHeaderMode, txVector);
668 plcpTrainingSymbolsStart - plcpHeaderStart,
669 headerMode, txVector);
670 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);
678 current - plcpHsigHeaderStart,
679 mcsHeaderMode, txVector);
683 plcpHsigHeaderStart - plcpHeaderStart,
684 headerMode, txVector);
685 NS_LOG_DEBUG (
"Case 5bii - previous is in the preamble and current in HT training: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
689 else if (current >= plcpHsigHeaderStart)
698 current - plcpHeaderStart,
699 headerMode, txVector);
700 NS_LOG_DEBUG (
"Case 5ci - previous is in preamble and current in SIG-A: mode=" << headerMode <<
", psr=" << psr);
708 current - plcpHsigHeaderStart,
709 mcsHeaderMode, txVector);
713 plcpHsigHeaderStart - plcpHeaderStart,
714 headerMode, txVector);
715 NS_LOG_DEBUG (
"Case 5cii - previous in preamble and current in HT-SIG: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
719 else if (current >= plcpHeaderStart)
725 current - plcpHeaderStart,
726 headerMode, txVector);
727 NS_LOG_DEBUG (
"Case 5d - previous is in the preamble and current is in L-SIG: mode=" << headerMode <<
", psr=" << psr);
731 noiseInterferenceW = j->second.GetPower () - powerW;
735 double per = 1 - psr;
746 event->GetTxVector ().GetChannelWidth ());
766 event->GetTxVector ().GetChannelWidth ());
789 InterferenceHelper::NiChanges::const_iterator
795 InterferenceHelper::NiChanges::const_iterator
805 InterferenceHelper::NiChanges::iterator
double GetRxPowerW(void) const
Return the receive 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.
Signal event for a packet.
#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
receive 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.
double CalculatePlcpPayloadPer(Ptr< const Event > event, NiChanges *ni) const
Calculate the error rate of the given plcp payload.
handles interference calculations
static Time GetPlcpHtSigHeaderDuration(WifiPreamble preamble)
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.
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< ErrorRateModel > m_errorRateModel
error rate model
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
static Time GetPlcpSigA1Duration(WifiPreamble preamble)
Event(Ptr< const Packet > packet, WifiTxVector txVector, Time duration, double rxPower)
Create an Event with the given parameters.
WifiMode GetPayloadMode(void) const
Return the Wi-Fi mode used for the payload.
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
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
static Time GetPlcpSigA2Duration(WifiPreamble preamble)
double CalculateSnr(double signal, double noiseInterference, uint16_t channelWidth) const
Calculate SNR (linear ratio) from the given signal power and noise+interference power.
static Time GetPlcpPreambleDuration(WifiTxVector txVector)
Time GetEnergyDuration(double energyW) const
Ptr< Event > Add(Ptr< const Packet > packet, WifiTxVector txVector, Time duration, double rxPower)
Add the packet-related signal to interference helper.
static Time GetPlcpSigBDuration(WifiPreamble preamble)
NiChanges m_niChanges
Experimental: needed for energy duration calculation.
WifiMode GetMode(void) const
Ptr< const Packet > GetPacket(void) const
Return the packet.
uint8_t GetNTx(void) const
WifiModulationClass GetModulationClass() 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 packet.
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.
uint8_t m_numRxAntennas
the number of RX antennas in the corresponding receiver
static Time Now(void)
Return the current simulation virtual time.
void NotifyRxEnd()
Notify that RX has ended.
void SetNoiseFigure(double value)
Set the noise figure.
double m_firstPower
first power
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.
static WifiMode GetVhtPlcpHeaderMode()
uint64_t GetPhyRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
WifiTxVector m_txVector
TXVECTOR.
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 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
double CalculatePlcpHeaderPer(Ptr< const Event > event, NiChanges *ni) const
Calculate the error rate of the plcp header.
Ptr< const Packet > m_packet
packet
static WifiMode GetPlcpHeaderMode(WifiTxVector txVector)
static Time GetPlcpTrainingSymbolDuration(WifiTxVector txVector)
static Time GetPlcpHeaderDuration(WifiTxVector txVector)
static WifiMode GetHtPlcpHeaderMode()
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