A Discrete-Event Network Simulator
API
interference-helper.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2005,2006 INRIA
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18  * Sébastien Deronne <sebastien.deronne@gmail.com>
19  */
20 
21 #include "interference-helper.h"
22 
23 #include "error-rate-model.h"
24 #include "wifi-phy.h"
25 #include "wifi-psdu.h"
26 #include "wifi-utils.h"
27 
28 #include "ns3/log.h"
29 #include "ns3/packet.h"
30 #include "ns3/simulator.h"
31 
32 #include <algorithm>
33 #include <numeric>
34 
35 namespace ns3
36 {
37 
38 NS_LOG_COMPONENT_DEFINE("InterferenceHelper");
39 
40 NS_OBJECT_ENSURE_REGISTERED(InterferenceHelper);
41 
42 /****************************************************************
43  * PHY event class
44  ****************************************************************/
45 
47  const WifiTxVector& txVector,
48  Time duration,
49  RxPowerWattPerChannelBand&& rxPower)
50  : m_ppdu(ppdu),
51  m_txVector(txVector),
52  m_startTime(Simulator::Now()),
53  m_endTime(m_startTime + duration),
54  m_rxPowerW(std::move(rxPower))
55 {
56 }
57 
59 {
60  m_ppdu = nullptr;
61  m_rxPowerW.clear();
62 }
63 
66 {
67  return m_ppdu;
68 }
69 
70 Time
72 {
73  return m_startTime;
74 }
75 
76 Time
78 {
79  return m_endTime;
80 }
81 
82 Time
84 {
85  return m_endTime - m_startTime;
86 }
87 
88 double
90 {
91  NS_ASSERT(!m_rxPowerW.empty());
92  // The total RX power corresponds to the maximum over all the bands
93  auto it = std::max_element(
94  m_rxPowerW.begin(),
95  m_rxPowerW.end(),
96  [](const std::pair<WifiSpectrumBand, double>& p1,
97  const std::pair<WifiSpectrumBand, double>& p2) { return p1.second < p2.second; });
98  return it->second;
99 }
100 
101 double
103 {
104  auto it = m_rxPowerW.find(band);
105  NS_ASSERT(it != m_rxPowerW.end());
106  return it->second;
107 }
108 
111 {
112  return m_rxPowerW;
113 }
114 
115 const WifiTxVector&
117 {
118  return m_txVector;
119 }
120 
121 void
123 {
124  NS_ASSERT(rxPower.size() == m_rxPowerW.size());
125  // Update power band per band
126  for (auto& currentRxPowerW : m_rxPowerW)
127  {
128  auto band = currentRxPowerW.first;
129  auto it = rxPower.find(band);
130  if (it != rxPower.end())
131  {
132  currentRxPowerW.second += it->second;
133  }
134  }
135 }
136 
137 std::ostream&
138 operator<<(std::ostream& os, const Event& event)
139 {
140  os << "start=" << event.GetStartTime() << ", end=" << event.GetEndTime()
141  << ", TXVECTOR=" << event.GetTxVector() << ", power=" << event.GetRxPowerW() << "W"
142  << ", PPDU=" << event.GetPpdu();
143  return os;
144 }
145 
146 /****************************************************************
147  * Class which records SNIR change events for a
148  * short period of time.
149  ****************************************************************/
150 
152  : m_power(power),
153  m_event(event)
154 {
155 }
156 
158 {
159  m_event = nullptr;
160 }
161 
162 double
164 {
165  return m_power;
166 }
167 
168 void
170 {
171  m_power += power;
172 }
173 
176 {
177  return m_event;
178 }
179 
180 /****************************************************************
181  * The actual InterferenceHelper
182  ****************************************************************/
183 
185  : m_errorRateModel(nullptr),
186  m_numRxAntennas(1),
187  m_rxing(false)
188 {
189  NS_LOG_FUNCTION(this);
190 }
191 
193 {
194  NS_LOG_FUNCTION(this);
195 }
196 
197 TypeId
199 {
200  static TypeId tid = TypeId("ns3::InterferenceHelper")
202  .SetGroupName("Wifi")
203  .AddConstructor<InterferenceHelper>();
204  return tid;
205 }
206 
207 void
209 {
210  NS_LOG_FUNCTION(this);
211  RemoveBands();
212  m_errorRateModel = nullptr;
213 }
214 
217  const WifiTxVector& txVector,
218  Time duration,
219  RxPowerWattPerChannelBand& rxPowerW,
220  bool isStartOfdmaRxing)
221 {
222  Ptr<Event> event = Create<Event>(ppdu, txVector, duration, std::move(rxPowerW));
223  AppendEvent(event, isStartOfdmaRxing);
224  return event;
225 }
226 
227 void
229 {
230  // Parameters other than duration and rxPowerW are unused for this type
231  // of signal, so we provide dummy versions
232  WifiMacHeader hdr;
234  hdr.SetQosTid(0);
235  Ptr<WifiPpdu> fakePpdu =
236  Create<WifiPpdu>(Create<WifiPsdu>(Create<Packet>(0), hdr), WifiTxVector(), 0);
237  Add(fakePpdu, WifiTxVector(), duration, rxPowerW);
238 }
239 
240 void
242 {
243  NS_LOG_FUNCTION(this);
244  for (auto it : m_niChangesPerBand)
245  {
246  it.second.clear();
247  }
248  m_niChangesPerBand.clear();
249  m_firstPowerPerBand.clear();
250 }
251 
252 void
254 {
255  NS_LOG_FUNCTION(this << band.first << band.second);
256  NS_ASSERT(m_niChangesPerBand.find(band) == m_niChangesPerBand.end());
257  NiChanges niChanges;
258  auto result = m_niChangesPerBand.insert({band, niChanges});
259  NS_ASSERT(result.second);
260  // Always have a zero power noise event in the list
261  AddNiChangeEvent(Time(0), NiChange(0.0, nullptr), result.first);
262  m_firstPowerPerBand.insert({band, 0.0});
263 }
264 
265 void
267 {
269 }
270 
271 void
273 {
274  m_errorRateModel = rate;
275 }
276 
279 {
280  return m_errorRateModel;
281 }
282 
283 void
285 {
286  m_numRxAntennas = rx;
287 }
288 
289 Time
291 {
292  Time now = Simulator::Now();
293  auto niIt = m_niChangesPerBand.find(band);
294  NS_ASSERT(niIt != m_niChangesPerBand.end());
295  auto i = GetPreviousPosition(now, niIt);
296  Time end = i->first;
297  for (; i != niIt->second.end(); ++i)
298  {
299  double noiseInterferenceW = i->second.GetPower();
300  end = i->first;
301  if (noiseInterferenceW < energyW)
302  {
303  break;
304  }
305  }
306  return end > now ? end - now : MicroSeconds(0);
307 }
308 
309 void
310 InterferenceHelper::AppendEvent(Ptr<Event> event, bool isStartOfdmaRxing)
311 {
312  NS_LOG_FUNCTION(this << event << isStartOfdmaRxing);
313  for (const auto& it : event->GetRxPowerWPerBand())
314  {
315  WifiSpectrumBand band = it.first;
316  auto niIt = m_niChangesPerBand.find(band);
317  NS_ASSERT(niIt != m_niChangesPerBand.end());
318  double previousPowerStart = 0;
319  double previousPowerEnd = 0;
320  auto previousPowerPosition = GetPreviousPosition(event->GetStartTime(), niIt);
321  previousPowerStart = previousPowerPosition->second.GetPower();
322  previousPowerEnd = GetPreviousPosition(event->GetEndTime(), niIt)->second.GetPower();
323  if (!m_rxing)
324  {
325  m_firstPowerPerBand.find(band)->second = previousPowerStart;
326  // Always leave the first zero power noise event in the list
327  niIt->second.erase(++(niIt->second.begin()), ++previousPowerPosition);
328  }
329  else if (isStartOfdmaRxing)
330  {
331  // When the first UL-OFDMA payload is received, we need to set m_firstPowerPerBand
332  // so that it takes into account interferences that arrived between the start of the
333  // UL MU transmission and the start of UL-OFDMA payload.
334  m_firstPowerPerBand.find(band)->second = previousPowerStart;
335  }
336  auto first =
337  AddNiChangeEvent(event->GetStartTime(), NiChange(previousPowerStart, event), niIt);
338  auto last = AddNiChangeEvent(event->GetEndTime(), NiChange(previousPowerEnd, event), niIt);
339  for (auto i = first; i != last; ++i)
340  {
341  i->second.AddPower(it.second);
342  }
343  }
344 }
345 
346 void
348 {
349  NS_LOG_FUNCTION(this << event);
350  // This is called for UL MU events, in order to scale power as long as UL MU PPDUs arrive
351  for (const auto& it : rxPower)
352  {
353  WifiSpectrumBand band = it.first;
354  auto niIt = m_niChangesPerBand.find(band);
355  NS_ASSERT(niIt != m_niChangesPerBand.end());
356  auto first = GetPreviousPosition(event->GetStartTime(), niIt);
357  auto last = GetPreviousPosition(event->GetEndTime(), niIt);
358  for (auto i = first; i != last; ++i)
359  {
360  i->second.AddPower(it.second);
361  }
362  }
363  event->UpdateRxPowerW(rxPower);
364 }
365 
366 double
368  double noiseInterference,
369  uint16_t channelWidth,
370  uint8_t nss) const
371 {
372  NS_LOG_FUNCTION(this << signal << noiseInterference << channelWidth << +nss);
373  // thermal noise at 290K in J/s = W
374  static const double BOLTZMANN = 1.3803e-23;
375  // Nt is the power of thermal noise in W
376  double Nt = BOLTZMANN * 290 * channelWidth * 1e6;
377  // receiver noise Floor (W) which accounts for thermal noise and non-idealities of the receiver
378  double noiseFloor = m_noiseFigure * Nt;
379  double noise = noiseFloor + noiseInterference;
380  double snr = signal / noise; // linear scale
381  NS_LOG_DEBUG("bandwidth(MHz)=" << channelWidth << ", signal(W)= " << signal << ", noise(W)="
382  << noiseFloor << ", interference(W)=" << noiseInterference
383  << ", snr=" << RatioToDb(snr) << "dB");
384  if (m_errorRateModel->IsAwgn())
385  {
386  double gain = 1;
387  if (m_numRxAntennas > nss)
388  {
389  gain = static_cast<double>(m_numRxAntennas) /
390  nss; // compute gain offered by diversity for AWGN
391  }
392  NS_LOG_DEBUG("SNR improvement thanks to diversity: " << 10 * std::log10(gain) << "dB");
393  snr *= gain;
394  }
395  return snr;
396 }
397 
398 double
400  NiChangesPerBand* nis,
401  WifiSpectrumBand band) const
402 {
403  NS_LOG_FUNCTION(this << band.first << band.second);
404  auto firstPower_it = m_firstPowerPerBand.find(band);
405  NS_ASSERT(firstPower_it != m_firstPowerPerBand.end());
406  double noiseInterferenceW = firstPower_it->second;
407  auto niIt = m_niChangesPerBand.find(band);
408  NS_ASSERT(niIt != m_niChangesPerBand.end());
409  auto it = niIt->second.find(event->GetStartTime());
410  for (; it != niIt->second.end() && it->first < Simulator::Now(); ++it)
411  {
412  noiseInterferenceW = it->second.GetPower() - event->GetRxPowerW(band);
413  }
414  it = niIt->second.find(event->GetStartTime());
415  NS_ASSERT(it != niIt->second.end());
416  for (; it != niIt->second.end() && it->second.GetEvent() != event; ++it)
417  {
418  ;
419  }
420  NiChanges ni;
421  ni.emplace(event->GetStartTime(), NiChange(0, event));
422  while (++it != niIt->second.end() && it->second.GetEvent() != event)
423  {
424  ni.insert(*it);
425  }
426  ni.emplace(event->GetEndTime(), NiChange(0, event));
427  nis->insert({band, ni});
428  NS_ASSERT_MSG(noiseInterferenceW >= 0,
429  "CalculateNoiseInterferenceW returns negative value " << noiseInterferenceW);
430  return noiseInterferenceW;
431 }
432 
433 double
435  Time duration,
436  WifiMode mode,
437  const WifiTxVector& txVector,
438  WifiPpduField field) const
439 {
440  if (duration.IsZero())
441  {
442  return 1.0;
443  }
444  uint64_t rate = mode.GetDataRate(txVector.GetChannelWidth());
445  uint64_t nbits = static_cast<uint64_t>(rate * duration.GetSeconds());
446  double csr =
447  m_errorRateModel->GetChunkSuccessRate(mode, txVector, snir, nbits, m_numRxAntennas, field);
448  return csr;
449 }
450 
451 double
453  Time duration,
454  const WifiTxVector& txVector,
455  uint16_t staId) const
456 {
457  if (duration.IsZero())
458  {
459  return 1.0;
460  }
461  WifiMode mode = txVector.GetMode(staId);
462  uint64_t rate = mode.GetDataRate(txVector, staId);
463  uint64_t nbits = static_cast<uint64_t>(rate * duration.GetSeconds());
464  nbits /= txVector.GetNss(staId); // divide effective number of bits by NSS to achieve same chunk
465  // error rate as SISO for AWGN
466  double csr = m_errorRateModel->GetChunkSuccessRate(mode,
467  txVector,
468  snir,
469  nbits,
472  staId);
473  return csr;
474 }
475 
476 double
478  uint16_t channelWidth,
479  NiChangesPerBand* nis,
480  WifiSpectrumBand band,
481  uint16_t staId,
482  std::pair<Time, Time> window) const
483 {
484  NS_LOG_FUNCTION(this << channelWidth << band.first << band.second << staId << window.first
485  << window.second);
486  double psr = 1.0; /* Packet Success Rate */
487  const auto& niIt = nis->find(band)->second;
488  auto j = niIt.cbegin();
489  Time previous = j->first;
490  WifiMode payloadMode = event->GetTxVector().GetMode(staId);
491  Time phyPayloadStart = j->first;
492  if (event->GetPpdu()->GetType() != WIFI_PPDU_TYPE_UL_MU &&
493  event->GetPpdu()->GetType() !=
494  WIFI_PPDU_TYPE_DL_MU) // j->first corresponds to the start of the OFDMA payload
495  {
496  phyPayloadStart =
497  j->first + WifiPhy::CalculatePhyPreambleAndHeaderDuration(event->GetTxVector());
498  }
499  Time windowStart = phyPayloadStart + window.first;
500  Time windowEnd = phyPayloadStart + window.second;
501  double noiseInterferenceW = m_firstPowerPerBand.find(band)->second;
502  double powerW = event->GetRxPowerW(band);
503  while (++j != niIt.cend())
504  {
505  Time current = j->first;
506  NS_LOG_DEBUG("previous= " << previous << ", current=" << current);
507  NS_ASSERT(current >= previous);
508  double snr = CalculateSnr(powerW,
509  noiseInterferenceW,
510  channelWidth,
511  event->GetTxVector().GetNss(staId));
512  // Case 1: Both previous and current point to the windowed payload
513  if (previous >= windowStart)
514  {
516  Min(windowEnd, current) - previous,
517  event->GetTxVector(),
518  staId);
519  NS_LOG_DEBUG("Both previous and current point to the windowed payload: mode="
520  << payloadMode << ", psr=" << psr);
521  }
522  // Case 2: previous is before windowed payload and current is in the windowed payload
523  else if (current >= windowStart)
524  {
526  Min(windowEnd, current) - windowStart,
527  event->GetTxVector(),
528  staId);
529  NS_LOG_DEBUG(
530  "previous is before windowed payload and current is in the windowed payload: mode="
531  << payloadMode << ", psr=" << psr);
532  }
533  noiseInterferenceW = j->second.GetPower() - powerW;
534  previous = j->first;
535  if (previous > windowEnd)
536  {
537  NS_LOG_DEBUG("Stop: new previous=" << previous
538  << " after time window end=" << windowEnd);
539  break;
540  }
541  }
542  double per = 1 - psr;
543  return per;
544 }
545 
546 double
548  Ptr<const Event> event,
549  NiChangesPerBand* nis,
550  uint16_t channelWidth,
551  WifiSpectrumBand band,
552  PhyEntity::PhyHeaderSections phyHeaderSections) const
553 {
554  NS_LOG_FUNCTION(this << band.first << band.second);
555  double psr = 1.0; /* Packet Success Rate */
556  auto niIt = nis->find(band)->second;
557  auto j = niIt.begin();
558 
559  NS_ASSERT(!phyHeaderSections.empty());
560  Time stopLastSection = Seconds(0);
561  for (const auto& section : phyHeaderSections)
562  {
563  stopLastSection = Max(stopLastSection, section.second.first.second);
564  }
565 
566  Time previous = j->first;
567  double noiseInterferenceW = m_firstPowerPerBand.find(band)->second;
568  double powerW = event->GetRxPowerW(band);
569  while (++j != niIt.end())
570  {
571  Time current = j->first;
572  NS_LOG_DEBUG("previous= " << previous << ", current=" << current);
573  NS_ASSERT(current >= previous);
574  double snr = CalculateSnr(powerW, noiseInterferenceW, channelWidth, 1);
575  for (const auto& section : phyHeaderSections)
576  {
577  Time start = section.second.first.first;
578  Time stop = section.second.first.second;
579 
580  if (previous <= stop || current >= start)
581  {
582  Time duration = Min(stop, current) - Max(start, previous);
583  if (duration.IsStrictlyPositive())
584  {
585  psr *= CalculateChunkSuccessRate(snr,
586  duration,
587  section.second.second,
588  event->GetTxVector(),
589  section.first);
590  NS_LOG_DEBUG("Current NI change in "
591  << section.first << " [" << start << ", " << stop << "] for "
592  << duration.As(Time::NS) << ": mode=" << section.second.second
593  << ", psr=" << psr);
594  }
595  }
596  }
597  noiseInterferenceW = j->second.GetPower() - powerW;
598  previous = j->first;
599  if (previous > stopLastSection)
600  {
601  NS_LOG_DEBUG("Stop: new previous=" << previous << " after stop of last section="
602  << stopLastSection);
603  break;
604  }
605  }
606  return psr;
607 }
608 
609 double
611  NiChangesPerBand* nis,
612  uint16_t channelWidth,
613  WifiSpectrumBand band,
614  WifiPpduField header) const
615 {
616  NS_LOG_FUNCTION(this << band.first << band.second << header);
617  auto niIt = nis->find(band)->second;
618  auto phyEntity = WifiPhy::GetStaticPhyEntity(event->GetTxVector().GetModulationClass());
619 
621  for (const auto& section :
622  phyEntity->GetPhyHeaderSections(event->GetTxVector(), niIt.begin()->first))
623  {
624  if (section.first == header)
625  {
626  sections[header] = section.second;
627  }
628  }
629 
630  double psr = 1.0;
631  if (!sections.empty())
632  {
633  psr = CalculatePhyHeaderSectionPsr(event, nis, channelWidth, band, sections);
634  }
635  return 1 - psr;
636 }
637 
638 struct PhyEntity::SnrPer
639 InterferenceHelper::CalculatePayloadSnrPer(Ptr<Event> event,
640  uint16_t channelWidth,
641  WifiSpectrumBand band,
642  uint16_t staId,
643  std::pair<Time, Time> relativeMpduStartStop) const
644 {
645  NS_LOG_FUNCTION(this << channelWidth << band.first << band.second << staId
646  << relativeMpduStartStop.first << relativeMpduStartStop.second);
647  NiChangesPerBand ni;
648  double noiseInterferenceW = CalculateNoiseInterferenceW(event, &ni, band);
649  double snr = CalculateSnr(event->GetRxPowerW(band),
650  noiseInterferenceW,
651  channelWidth,
652  event->GetTxVector().GetNss(staId));
653 
654  /* calculate the SNIR at the start of the MPDU (located through windowing) and accumulate
655  * all SNIR changes in the SNIR vector.
656  */
657  double per = CalculatePayloadPer(event, channelWidth, &ni, band, staId, relativeMpduStartStop);
658 
659  return PhyEntity::SnrPer(snr, per);
660 }
661 
662 double
664  uint16_t channelWidth,
665  uint8_t nss,
666  WifiSpectrumBand band) const
667 {
668  NiChangesPerBand ni;
669  double noiseInterferenceW = CalculateNoiseInterferenceW(event, &ni, band);
670  double snr = CalculateSnr(event->GetRxPowerW(band), noiseInterferenceW, channelWidth, nss);
671  return snr;
672 }
673 
674 struct PhyEntity::SnrPer
675 InterferenceHelper::CalculatePhyHeaderSnrPer(Ptr<Event> event,
676  uint16_t channelWidth,
677  WifiSpectrumBand band,
678  WifiPpduField header) const
679 {
680  NS_LOG_FUNCTION(this << band.first << band.second << header);
681  NiChangesPerBand ni;
682  double noiseInterferenceW = CalculateNoiseInterferenceW(event, &ni, band);
683  double snr = CalculateSnr(event->GetRxPowerW(band), noiseInterferenceW, channelWidth, 1);
684 
685  /* calculate the SNIR at the start of the PHY header and accumulate
686  * all SNIR changes in the SNIR vector.
687  */
688  double per = CalculatePhyHeaderPer(event, &ni, channelWidth, band, header);
689 
690  return PhyEntity::SnrPer(snr, per);
691 }
692 
693 void
695 {
696  for (auto niIt = m_niChangesPerBand.begin(); niIt != m_niChangesPerBand.end(); ++niIt)
697  {
698  niIt->second.clear();
699  // Always have a zero power noise event in the list
700  AddNiChangeEvent(Time(0), NiChange(0.0, nullptr), niIt);
701  m_firstPowerPerBand.at(niIt->first) = 0.0;
702  }
703  m_rxing = false;
704 }
705 
706 InterferenceHelper::NiChanges::iterator
707 InterferenceHelper::GetNextPosition(Time moment, NiChangesPerBand::iterator niIt)
708 {
709  return niIt->second.upper_bound(moment);
710 }
711 
712 InterferenceHelper::NiChanges::iterator
713 InterferenceHelper::GetPreviousPosition(Time moment, NiChangesPerBand::iterator niIt)
714 {
715  auto it = GetNextPosition(moment, niIt);
716  // This is safe since there is always an NiChange at time 0,
717  // before moment.
718  --it;
719  return it;
720 }
721 
722 InterferenceHelper::NiChanges::iterator
723 InterferenceHelper::AddNiChangeEvent(Time moment, NiChange change, NiChangesPerBand::iterator niIt)
724 {
725  return niIt->second.insert(GetNextPosition(moment, niIt), std::make_pair(moment, change));
726 }
727 
728 void
730 {
731  NS_LOG_FUNCTION(this);
732  m_rxing = true;
733 }
734 
735 void
737 {
738  NS_LOG_FUNCTION(this << endTime);
739  m_rxing = false;
740  // Update m_firstPowerPerBand for frame capture
741  for (auto niIt = m_niChangesPerBand.begin(); niIt != m_niChangesPerBand.end(); ++niIt)
742  {
743  NS_ASSERT(niIt->second.size() > 1);
744  auto it = GetPreviousPosition(endTime, niIt);
745  it--;
746  m_firstPowerPerBand.find(niIt->first)->second = it->second.GetPower();
747  }
748 }
749 
750 } // namespace ns3
handles interference calculations
Time m_endTime
end time
WifiTxVector m_txVector
TXVECTOR.
Time m_startTime
start time
Ptr< const WifiPpdu > GetPpdu() const
Return the PPDU.
Ptr< const WifiPpdu > m_ppdu
PPDU.
void UpdateRxPowerW(const RxPowerWattPerChannelBand &rxPower)
Update the received power (W) for all bands, i.e.
Event(Ptr< const WifiPpdu > ppdu, const WifiTxVector &txVector, Time duration, RxPowerWattPerChannelBand &&rxPower)
Create an Event with the given parameters.
Time GetEndTime() const
Return the end time of the signal.
Time GetDuration() const
Return the duration of the signal.
double GetRxPowerW() const
Return the total received power (W).
const WifiTxVector & GetTxVector() const
Return the TXVECTOR of the PPDU.
RxPowerWattPerChannelBand m_rxPowerW
received power in watts per band
const RxPowerWattPerChannelBand & GetRxPowerWPerBand() const
Return the received power (W) for all bands.
Time GetStartTime() const
Return the start time of the signal.
Noise and Interference (thus Ni) event.
void AddPower(double power)
Add a given amount of power.
NiChange(double power, Ptr< Event > event)
Create a NiChange at the given time and the amount of NI change.
double GetPower() const
Return the power.
Ptr< Event > GetEvent() const
Return the event causes the corresponding NI change.
handles interference calculations
void SetNoiseFigure(double value)
Set the noise figure.
double m_noiseFigure
noise figure (linear)
Ptr< ErrorRateModel > GetErrorRateModel() const
Return the error rate model.
void AddForeignSignal(Time duration, RxPowerWattPerChannelBand &rxPower)
Add a non-Wifi signal to interference helper.
bool m_rxing
flag whether it is in receiving state
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.
std::map< WifiSpectrumBand, NiChanges > NiChangesPerBand
Map of NiChanges per band.
uint8_t m_numRxAntennas
the number of RX antennas in the corresponding receiver
void DoDispose() override
Destructor implementation.
void RemoveBands()
Remove the frequency bands.
void NotifyRxEnd(Time endTime)
Notify that RX has ended.
double CalculateNoiseInterferenceW(Ptr< Event > event, NiChangesPerBand *nis, WifiSpectrumBand band) const
Calculate noise and interference power in W.
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Set the error rate model for this interference helper.
std::multimap< Time, NiChange > NiChanges
typedef for a multimap of NiChange
Time GetEnergyDuration(double energyW, WifiSpectrumBand band)
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 EraseEvents()
Erase all events.
Ptr< ErrorRateModel > m_errorRateModel
error rate model
void AppendEvent(Ptr< Event > event, bool isStartOfdmaRxing)
Append the given Event.
void NotifyRxStart()
Notify that RX has started.
NiChanges::iterator GetNextPosition(Time moment, NiChangesPerBand::iterator niIt)
Returns an iterator to the first NiChange that is later than moment.
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).
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 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...
NiChanges::iterator GetPreviousPosition(Time moment, NiChangesPerBand::iterator niIt)
Returns an iterator to the last NiChange that is before than moment.
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.
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.
static TypeId GetTypeId()
Get the type ID.
void UpdateEvent(Ptr< Event > event, const RxPowerWattPerChannelBand &rxPower)
Update event to scale its received power (W) per band.
void SetNumberOfReceiveAntennas(uint8_t rx)
Set the number of RX antennas in the receiver corresponding to this interference helper.
void AddBand(WifiSpectrumBand band)
Add a frequency band.
double CalculatePhyHeaderPer(Ptr< const Event > event, NiChangesPerBand *nis, uint16_t channelWidth, WifiSpectrumBand band, WifiPpduField header) const
Calculate the error rate of the PHY header.
NiChangesPerBand m_niChangesPerBand
NI Changes for each band.
std::map< WifiSpectrumBand, double > m_firstPowerPerBand
first power of each band in watts
A base class which provides memory management and object aggregation.
Definition: object.h:89
std::map< WifiPpduField, PhyHeaderChunkInfo > PhyHeaderSections
A map of PhyHeaderChunkInfo elements per PPDU field.
Definition: phy-entity.h:327
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
Control the scheduling of simulation events.
Definition: simulator.h:68
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:417
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:402
bool IsStrictlyPositive() const
Exactly equivalent to t > 0.
Definition: nstime.h:350
@ NS
nanosecond
Definition: nstime.h:119
bool IsZero() const
Exactly equivalent to t == 0.
Definition: nstime.h:314
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
Implements the IEEE 802.11 MAC header.
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
void SetQosTid(uint8_t tid)
Set the TID for the QoS header.
represent a single transmission mode
Definition: wifi-mode.h:50
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:122
static const Ptr< const PhyEntity > GetStaticPhyEntity(WifiModulationClass modulation)
Get the implemented PHY entity corresponding to the modulation class.
Definition: wifi-phy.cc:695
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
Definition: wifi-phy.cc:1473
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
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.
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.
uint16_t GetChannelWidth() const
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
int64x64_t Max(const int64x64_t &a, const int64x64_t &b)
Maximum.
Definition: int64x64.h:243
int64x64_t Min(const int64x64_t &a, const int64x64_t &b)
Minimum.
Definition: int64x64.h:229
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:296
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1360
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
WifiPpduField
The type of PPDU field (grouped for convenience)
@ WIFI_PPDU_TYPE_DL_MU
@ WIFI_PPDU_TYPE_UL_MU
@ WIFI_PPDU_FIELD_DATA
data field
Definition: first.py:1
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:848
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double RatioToDb(double ratio)
Convert from ratio to dB.
Definition: wifi-utils.cc:52
std::pair< uint32_t, uint32_t > WifiSpectrumBand
typedef for a pair of start and stop sub-band indexes
std::map< WifiSpectrumBand, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
Definition: phy-entity.h:78
@ WIFI_MAC_QOSDATA
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:129
value
Definition: second.py:41
A struct for both SNR and PER.
Definition: phy-entity.h:148
double snr
SNR in linear scale.
Definition: phy-entity.h:149