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