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 /****************************************************************
38  * PHY event class
39  ****************************************************************/
40 
42  : m_ppdu (ppdu),
43  m_txVector (txVector),
44  m_startTime (Simulator::Now ()),
45  m_endTime (m_startTime + duration),
46  m_rxPowerW (rxPower)
47 {
48 }
49 
51 {
52  m_ppdu = 0;
53  m_rxPowerW.clear ();
54 }
55 
57 Event::GetPpdu (void) const
58 {
59  return m_ppdu;
60 }
61 
62 Time
63 Event::GetStartTime (void) const
64 {
65  return m_startTime;
66 }
67 
68 Time
69 Event::GetEndTime (void) const
70 {
71  return m_endTime;
72 }
73 
74 Time
75 Event::GetDuration (void) const
76 {
77  return m_endTime - m_startTime;
78 }
79 
80 double
81 Event::GetRxPowerW (void) const
82 {
83  NS_ASSERT (m_rxPowerW.size () > 0);
84  //The total RX power corresponds to the maximum over all the bands
85  auto it = std::max_element (m_rxPowerW.begin (), m_rxPowerW.end (),
86  [] (const std::pair<WifiSpectrumBand, double>& p1, const std::pair<WifiSpectrumBand, double>& p2) {
87  return p1.second < p2.second;
88  });
89  return it->second;
90 }
91 
92 double
94 {
95  auto it = m_rxPowerW.find (band);
96  NS_ASSERT (it != m_rxPowerW.end ());
97  return it->second;
98 }
99 
102 {
103  return m_rxPowerW;
104 }
105 
107 Event::GetTxVector (void) const
108 {
109  return m_txVector;
110 }
111 
112 void
114 {
115  NS_ASSERT (rxPower.size () == m_rxPowerW.size ());
116  //Update power band per band
117  for (auto & currentRxPowerW : m_rxPowerW)
118  {
119  auto band = currentRxPowerW.first;
120  auto it = rxPower.find (band);
121  if (it != rxPower.end ())
122  {
123  currentRxPowerW.second += it->second;
124  }
125  }
126 }
127 
128 std::ostream & operator << (std::ostream &os, const Event &event)
129 {
130  os << "start=" << event.GetStartTime () << ", end=" << event.GetEndTime ()
131  << ", TXVECTOR=" << event.GetTxVector ()
132  << ", power=" << event.GetRxPowerW () << "W"
133  << ", PPDU=" << event.GetPpdu ();
134  return os;
135 }
136 
137 /****************************************************************
138  * Class which records SNIR change events for a
139  * short period of time.
140  ****************************************************************/
141 
143  : m_power (power),
144  m_event (event)
145 {
146 }
147 
149 {
150  m_event = 0;
151 }
152 
153 double
155 {
156  return m_power;
157 }
158 
159 void
161 {
162  m_power += power;
163 }
164 
167 {
168  return m_event;
169 }
170 
171 
172 /****************************************************************
173  * The actual InterferenceHelper
174  ****************************************************************/
175 
177  : m_errorRateModel (0),
178  m_numRxAntennas (1),
179  m_rxing (false)
180 {
181 }
182 
184 {
185  RemoveBands ();
186  m_errorRateModel = 0;
187 }
188 
190 InterferenceHelper::Add (Ptr<const WifiPpdu> ppdu, const WifiTxVector& txVector, Time duration, RxPowerWattPerChannelBand rxPowerW, bool isStartOfdmaRxing)
191 {
192  Ptr<Event> event = Create<Event> (ppdu, txVector, duration, rxPowerW);
193  AppendEvent (event, isStartOfdmaRxing);
194  return event;
195 }
196 
197 void
199 {
200  // Parameters other than duration and rxPowerW are unused for this type
201  // of signal, so we provide dummy versions
202  WifiMacHeader hdr;
204  hdr.SetQosTid (0);
205  Ptr<WifiPpdu> fakePpdu = Create<WifiPpdu> (Create<WifiPsdu> (Create<Packet> (0), hdr),
206  WifiTxVector ());
207  Add (fakePpdu, WifiTxVector (), duration, rxPowerW);
208 }
209 
210 void
212 {
213  NS_LOG_FUNCTION (this);
214  for (auto it : m_niChangesPerBand)
215  {
216  it.second.clear ();
217  }
218  m_niChangesPerBand.clear();
219  m_firstPowerPerBand.clear();
220 }
221 
222 void
224 {
225  NS_LOG_FUNCTION (this << band.first << band.second);
226  NS_ASSERT (m_niChangesPerBand.find (band) == m_niChangesPerBand.end ());
227  NiChanges niChanges;
228  m_niChangesPerBand.insert ({band, niChanges});
229  // Always have a zero power noise event in the list
230  AddNiChangeEvent (Time (0), NiChange (0.0, 0), band);
231  m_firstPowerPerBand.insert ({band, 0.0});
232 }
233 
234 void
236 {
237  m_noiseFigure = value;
238 }
239 
240 void
242 {
243  m_errorRateModel = rate;
244 }
245 
248 {
249  return m_errorRateModel;
250 }
251 
252 void
254 {
255  m_numRxAntennas = rx;
256 }
257 
258 Time
260 {
261  Time now = Simulator::Now ();
262  auto i = GetPreviousPosition (now, band);
263  Time end = i->first;
264  auto ni_it = m_niChangesPerBand.find (band);
265  NS_ASSERT (ni_it != m_niChangesPerBand.end ());
266  for (; i != ni_it->second.end (); ++i)
267  {
268  double noiseInterferenceW = i->second.GetPower ();
269  end = i->first;
270  if (noiseInterferenceW < energyW)
271  {
272  break;
273  }
274  }
275  return end > now ? end - now : MicroSeconds (0);
276 }
277 
278 void
279 InterferenceHelper::AppendEvent (Ptr<Event> event, bool isStartOfdmaRxing)
280 {
281  NS_LOG_FUNCTION (this << event << isStartOfdmaRxing);
282  RxPowerWattPerChannelBand rxPowerWattPerChannelBand = event->GetRxPowerWPerBand ();
283  for (auto const& it : rxPowerWattPerChannelBand)
284  {
285  WifiSpectrumBand band = it.first;
286  auto ni_it = m_niChangesPerBand.find (band);
287  NS_ASSERT (ni_it != m_niChangesPerBand.end ());
288  double previousPowerStart = 0;
289  double previousPowerEnd = 0;
290  previousPowerStart = GetPreviousPosition (event->GetStartTime (), band)->second.GetPower ();
291  previousPowerEnd = GetPreviousPosition (event->GetEndTime (), band)->second.GetPower ();
292  if (!m_rxing)
293  {
294  m_firstPowerPerBand.find (band)->second = previousPowerStart;
295  // Always leave the first zero power noise event in the list
296  ni_it->second.erase (++(ni_it->second.begin ()), GetNextPosition (event->GetStartTime (), band));
297  }
298  else if (isStartOfdmaRxing)
299  {
300  //When the first UL-OFDMA payload is received, we need to set m_firstPowerPerBand
301  //so that it takes into account interferences that arrived between the start of the
302  //UL MU transmission and the start of UL-OFDMA payload.
303  m_firstPowerPerBand.find (band)->second = previousPowerStart;
304  }
305  auto first = AddNiChangeEvent (event->GetStartTime (), NiChange (previousPowerStart, event), band);
306  auto last = AddNiChangeEvent (event->GetEndTime (), NiChange (previousPowerEnd, event), band);
307  for (auto i = first; i != last; ++i)
308  {
309  i->second.AddPower (it.second);
310  }
311  }
312 }
313 
314 void
316 {
317  NS_LOG_FUNCTION (this << event);
318  //This is called for UL MU events, in order to scale power as long as UL MU PPDUs arrive
319  for (auto const& it : rxPower)
320  {
321  WifiSpectrumBand band = it.first;
322  auto ni_it = m_niChangesPerBand.find (band);
323  NS_ASSERT (ni_it != m_niChangesPerBand.end ());
324  auto first = GetPreviousPosition (event->GetStartTime (), band);
325  auto last = GetPreviousPosition (event->GetEndTime (), band);
326  for (auto i = first; i != last; ++i)
327  {
328  i->second.AddPower (it.second);
329  }
330  }
331  event->UpdateRxPowerW (rxPower);
332 }
333 
334 double
335 InterferenceHelper::CalculateSnr (double signal, double noiseInterference, uint16_t channelWidth, uint8_t nss) const
336 {
337  NS_LOG_FUNCTION (this << signal << noiseInterference << channelWidth << +nss);
338  //thermal noise at 290K in J/s = W
339  static const double BOLTZMANN = 1.3803e-23;
340  //Nt is the power of thermal noise in W
341  double Nt = BOLTZMANN * 290 * channelWidth * 1e6;
342  //receiver noise Floor (W) which accounts for thermal noise and non-idealities of the receiver
343  double noiseFloor = m_noiseFigure * Nt;
344  double noise = noiseFloor + noiseInterference;
345  double snr = signal / noise; //linear scale
346  NS_LOG_DEBUG ("bandwidth(MHz)=" << channelWidth << ", signal(W)= " << signal << ", noise(W)=" << noiseFloor << ", interference(W)=" << noiseInterference << ", snr=" << RatioToDb(snr) << "dB");
347  double gain = 1;
348  if (m_numRxAntennas > nss)
349  {
350  gain = static_cast<double>(m_numRxAntennas) / nss; //compute gain offered by diversity for AWGN
351  }
352  NS_LOG_DEBUG ("SNR improvement thanks to diversity: " << 10 * std::log10 (gain) << "dB");
353  snr *= gain;
354  return snr;
355 }
356 
357 double
359 {
360  NS_LOG_FUNCTION (this << band.first << band.second);
361  auto firstPower_it = m_firstPowerPerBand.find (band);
362  NS_ASSERT (firstPower_it != m_firstPowerPerBand.end ());
363  double noiseInterferenceW = firstPower_it->second;
364  auto ni_it = m_niChangesPerBand.find (band);
365  NS_ASSERT (ni_it != m_niChangesPerBand.end ());
366  auto it = ni_it->second.find (event->GetStartTime ());
367  for (; it != ni_it->second.end () && it->first < Simulator::Now (); ++it)
368  {
369  noiseInterferenceW = it->second.GetPower () - event->GetRxPowerW (band);
370  }
371  it = ni_it->second.find (event->GetStartTime ());
372  NS_ASSERT (it != ni_it->second.end ());
373  for (; it != ni_it->second.end () && it->second.GetEvent () != event; ++it);
374  NiChanges ni;
375  ni.emplace (event->GetStartTime (), NiChange (0, event));
376  while (++it != ni_it->second.end () && it->second.GetEvent () != event)
377  {
378  ni.insert (*it);
379  }
380  ni.emplace (event->GetEndTime (), NiChange (0, event));
381  nis->insert ({band, ni});
382  NS_ASSERT_MSG (noiseInterferenceW >= 0, "CalculateNoiseInterferenceW returns negative value " << noiseInterferenceW);
383  return noiseInterferenceW;
384 }
385 
386 double
387 InterferenceHelper::CalculateChunkSuccessRate (double snir, Time duration, WifiMode mode, const WifiTxVector& txVector) const
388 {
389  if (duration.IsZero ())
390  {
391  return 1.0;
392  }
393  uint64_t rate = mode.GetDataRate (txVector.GetChannelWidth ());
394  uint64_t nbits = static_cast<uint64_t> (rate * duration.GetSeconds ());
395  double csr = m_errorRateModel->GetChunkSuccessRate (mode, txVector, snir, nbits);
396  return csr;
397 }
398 
399 double
400 InterferenceHelper::CalculatePayloadChunkSuccessRate (double snir, Time duration, const WifiTxVector& txVector, uint16_t staId) const
401 {
402  if (duration.IsZero ())
403  {
404  return 1.0;
405  }
406  WifiMode mode = txVector.GetMode (staId);
407  uint64_t rate = mode.GetDataRate (txVector, staId);
408  uint64_t nbits = static_cast<uint64_t> (rate * duration.GetSeconds ());
409  nbits /= txVector.GetNss (staId); //divide effective number of bits by NSS to achieve same chunk error rate as SISO for AWGN
410  double csr = m_errorRateModel->GetChunkSuccessRate (mode, txVector, snir, nbits, staId);
411  return csr;
412 }
413 
414 double
417  uint16_t staId, std::pair<Time, Time> window) const
418 {
419  NS_LOG_FUNCTION (this << channelWidth << band.first << band.second << staId << window.first << window.second);
420  const WifiTxVector& txVector = event->GetTxVector ();
421  double psr = 1.0; /* Packet Success Rate */
422  auto ni_it = nis->find (band)->second;
423  auto j = ni_it.begin ();
424  Time previous = j->first;
425  WifiMode payloadMode = txVector.GetMode (staId);
426  Time phyPayloadStart = j->first;
427  if (event->GetPpdu ()->GetType () != WIFI_PPDU_TYPE_UL_MU) //j->first corresponds to the start of the UL-OFDMA payload
428  {
429  phyPayloadStart = j->first + WifiPhy::CalculatePhyPreambleAndHeaderDuration (txVector);
430  }
431  Time windowStart = phyPayloadStart + window.first;
432  Time windowEnd = phyPayloadStart + window.second;
433  double noiseInterferenceW = m_firstPowerPerBand.find (band)->second;
434  double powerW = event->GetRxPowerW (band);
435  while (++j != ni_it.end ())
436  {
437  Time current = j->first;
438  NS_LOG_DEBUG ("previous= " << previous << ", current=" << current);
439  NS_ASSERT (current >= previous);
440  double snr = CalculateSnr (powerW, noiseInterferenceW, channelWidth, txVector.GetNss (staId));
441  //Case 1: Both previous and current point to the windowed payload
442  if (previous >= windowStart)
443  {
444  psr *= CalculatePayloadChunkSuccessRate (snr, Min (windowEnd, current) - previous, txVector, staId);
445  NS_LOG_DEBUG ("Both previous and current point to the windowed payload: mode=" << payloadMode << ", psr=" << psr);
446  }
447  //Case 2: previous is before windowed payload and current is in the windowed payload
448  else if (current >= windowStart)
449  {
450  psr *= CalculatePayloadChunkSuccessRate (snr, Min (windowEnd, current) - windowStart, txVector, staId);
451  NS_LOG_DEBUG ("previous is before windowed payload and current is in the windowed payload: mode=" << payloadMode << ", psr=" << psr);
452  }
453  noiseInterferenceW = j->second.GetPower () - powerW;
454  previous = j->first;
455  if (previous > windowEnd)
456  {
457  NS_LOG_DEBUG ("Stop: new previous=" << previous << " after time window end=" << windowEnd);
458  break;
459  }
460  }
461  double per = 1 - psr;
462  return per;
463 }
464 
465 double
467  uint16_t channelWidth, WifiSpectrumBand band,
468  PhyEntity::PhyHeaderSections phyHeaderSections) const
469 {
470  NS_LOG_FUNCTION (this << band.first << band.second);
471  const WifiTxVector& txVector = event->GetTxVector ();
472  double psr = 1.0; /* Packet Success Rate */
473  auto ni_it = nis->find (band)->second;
474  auto j = ni_it.begin ();
475 
476  NS_ASSERT (!phyHeaderSections.empty ());
477  Time stopLastSection = Seconds (0);
478  for (const auto & section : phyHeaderSections)
479  {
480  stopLastSection = Max (stopLastSection, section.second.first.second);
481  }
482 
483  Time previous = j->first;
484  double noiseInterferenceW = m_firstPowerPerBand.find (band)->second;
485  double powerW = event->GetRxPowerW (band);
486  while (++j != ni_it.end ())
487  {
488  Time current = j->first;
489  NS_LOG_DEBUG ("previous= " << previous << ", current=" << current);
490  NS_ASSERT (current >= previous);
491  double snr = CalculateSnr (powerW, noiseInterferenceW, channelWidth, 1);
492  for (const auto & section : phyHeaderSections)
493  {
494  Time start = section.second.first.first;
495  Time stop = section.second.first.second;
496 
497  if (previous <= stop || current >= start)
498  {
499  Time duration = Min (stop, current) - Max (start, previous);
500  if (duration.IsStrictlyPositive ())
501  {
502  WifiMode mode = section.second.second;
503  psr *= CalculateChunkSuccessRate (snr, duration, mode, txVector);
504  NS_LOG_DEBUG ("Current NI change in " << section.first << " [" << start << ", " << stop << "] for "
505  << duration.As (Time::NS) << ": mode=" << mode << ", psr=" << psr);
506  }
507  }
508  }
509  noiseInterferenceW = j->second.GetPower () - powerW;
510  previous = j->first;
511  if (previous > stopLastSection)
512  {
513  NS_LOG_DEBUG ("Stop: new previous=" << previous << " after stop of last section=" << stopLastSection);
514  break;
515  }
516  }
517  return psr;
518 }
519 
520 double
522  uint16_t channelWidth, WifiSpectrumBand band,
523  WifiPpduField header) const
524 {
525  NS_LOG_FUNCTION (this << band.first << band.second << header);
526  const WifiTxVector& txVector = event->GetTxVector ();
527  auto ni_it = nis->find (band)->second;
528  auto phyEntity = WifiPhy::GetStaticPhyEntity (txVector.GetModulationClass ());
529 
531  for (const auto & section : phyEntity->GetPhyHeaderSections (txVector, ni_it.begin ()->first))
532  {
533  if (section.first == header)
534  {
535  sections[header] = section.second;
536  }
537  }
538 
539  double psr = 1.0;
540  if (!sections.empty () > 0)
541  {
542  psr = CalculatePhyHeaderSectionPsr (event, nis, channelWidth, band, sections);
543  }
544  return 1 - psr;
545 }
546 
547 struct PhyEntity::SnrPer
548 InterferenceHelper::CalculatePayloadSnrPer (Ptr<Event> event, uint16_t channelWidth, WifiSpectrumBand band,
549  uint16_t staId, std::pair<Time, Time> relativeMpduStartStop) const
550 {
551  NS_LOG_FUNCTION (this << channelWidth << band.first << band.second << staId << relativeMpduStartStop.first << relativeMpduStartStop.second);
552  NiChangesPerBand ni;
553  double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni, band);
554  double snr = CalculateSnr (event->GetRxPowerW (band),
555  noiseInterferenceW,
556  channelWidth,
557  event->GetTxVector ().GetNss (staId));
558 
559  /* calculate the SNIR at the start of the MPDU (located through windowing) and accumulate
560  * all SNIR changes in the SNIR vector.
561  */
562  double per = CalculatePayloadPer (event, channelWidth, &ni, band, staId, relativeMpduStartStop);
563 
564  return PhyEntity::SnrPer (snr, per);
565 }
566 
567 double
568 InterferenceHelper::CalculateSnr (Ptr<Event> event, uint16_t channelWidth, uint8_t nss, WifiSpectrumBand band) const
569 {
570  NiChangesPerBand ni;
571  double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni, band);
572  double snr = CalculateSnr (event->GetRxPowerW (band),
573  noiseInterferenceW,
574  channelWidth,
575  nss);
576  return snr;
577 }
578 
579 struct PhyEntity::SnrPer
580 InterferenceHelper::CalculatePhyHeaderSnrPer (Ptr<Event> event, uint16_t channelWidth, WifiSpectrumBand band,
581  WifiPpduField header) const
582 {
583  NS_LOG_FUNCTION (this << band.first << band.second << header);
584  NiChangesPerBand ni;
585  double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni, band);
586  double snr = CalculateSnr (event->GetRxPowerW (band),
587  noiseInterferenceW,
588  channelWidth,
589  1);
590 
591  /* calculate the SNIR at the start of the PHY header and accumulate
592  * all SNIR changes in the SNIR vector.
593  */
594  double per = CalculatePhyHeaderPer (event, &ni, channelWidth, band, header);
595 
596  return PhyEntity::SnrPer (snr, per);
597 }
598 
599 void
601 {
602  for (auto it : m_niChangesPerBand)
603  {
604  it.second.clear ();
605  // Always have a zero power noise event in the list
606  AddNiChangeEvent (Time (0), NiChange (0.0, 0), it.first);
607  m_firstPowerPerBand.at (it.first) = 0.0;
608  }
609  m_rxing = false;
610 }
611 
612 InterferenceHelper::NiChanges::iterator
614 {
615  auto it = m_niChangesPerBand.find (band);
616  NS_ASSERT (it != m_niChangesPerBand.end ());
617  return it->second.upper_bound (moment);
618 }
619 
620 InterferenceHelper::NiChanges::iterator
622 {
623  auto it = GetNextPosition (moment, band);
624  // This is safe since there is always an NiChange at time 0,
625  // before moment.
626  --it;
627  return it;
628 }
629 
630 InterferenceHelper::NiChanges::iterator
632 {
633  auto it = m_niChangesPerBand.find (band);
634  NS_ASSERT (it != m_niChangesPerBand.end ());
635  return it->second.insert (GetNextPosition (moment, band), std::make_pair (moment, change));
636 }
637 
638 void
640 {
641  NS_LOG_FUNCTION (this);
642  m_rxing = true;
643 }
644 
645 void
647 {
648  NS_LOG_FUNCTION (this << endTime);
649  m_rxing = false;
650  //Update m_firstPowerPerBand for frame capture
651  for (auto ni : m_niChangesPerBand)
652  {
653  NS_ASSERT (ni.second.size () > 1);
654  auto it = GetPreviousPosition (endTime, ni.first);
655  it--;
656  m_firstPowerPerBand.find (ni.first)->second = it->second.GetPower ();
657  }
658 }
659 
660 } //namespace ns3
double GetRxPowerW(void) const
Return the total received power (W).
double snr
SNR in linear scale.
Definition: phy-entity.h:138
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.
Definition: time.cc:429
nanosecond
Definition: nstime.h:118
void AddPower(double power)
Add a given amount of power.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
Time GetEnergyDuration(double energyW, WifiSpectrumBand band)
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#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.
Definition: simulator.h:68
void SetNumberOfReceiveAntennas(uint8_t rx)
Set the number of RX antennas in the receiver corresponding to this interference helper.
Definition: second.py:1
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
def start()
Definition: core.py:1855
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:380
WifiModulationClass GetModulationClass(void) const
Get the modulation class specified by this TXVECTOR.
#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_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
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.
Definition: nstime.h:333
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...
Definition: wifi-mode.h:47
Ptr< const WifiPpdu > m_ppdu
PPDU.
std::map< WifiPpduField, PhyHeaderChunkInfo > PhyHeaderSections
A map of PhyHeaderChunkInfo elements per PPDU field.
Definition: phy-entity.h:305
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)
Definition: angles.cc:137
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.
Definition: int64x64.h:218
static const Ptr< const PhyEntity > GetStaticPhyEntity(WifiModulationClass modulation)
Get the implemented PHY entity corresponding to the modulation class.
Definition: wifi-phy.cc:870
bool IsZero(void) const
Exactly equivalent to t == 0.
Definition: nstime.h:301
double CalculateChunkSuccessRate(double snir, Time duration, WifiMode mode, const WifiTxVector &txVector) const
Calculate the success rate of the chunk given the SINR, duration, and Wi-Fi mode. ...
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.
Definition: int64x64.h:230
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.
Definition: phy-entity.h:136
WifiTxVector GetTxVector(void) const
Return the TXVECTOR of the PPDU.
void SetQosTid(uint8_t tid)
Set the TID for the QoS header.
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.
double CalculatePhyHeaderPer(Ptr< const Event > event, NiChangesPerBand *nis, uint16_t channelWidth, WifiSpectrumBand band, WifiPpduField header) const
Calculate the error rate of the PHY header.
uint8_t m_numRxAntennas
the number of RX antennas in the corresponding receiver
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
void AppendEvent(Ptr< Event > event, bool isStartOfdmaRxing)
Append the given Event.
double RatioToDb(double ratio)
Convert from ratio to dB.
Definition: wifi-utils.cc:53
#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
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 SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
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.
Definition: log.h:273
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
Definition: wifi-phy.cc:1604
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 m_endTime
end time
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
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.
Definition: first.py:1
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:100
std::map< WifiSpectrumBand, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
Definition: phy-entity.h:75
Implements the IEEE 802.11 MAC header.
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.
double CalculatePayloadChunkSuccessRate(double snir, Time duration, const WifiTxVector &txVector, uint16_t staId) const
Calculate the success rate of the payload chunk given the SINR, duration, and Wi-Fi mode...
Time m_startTime
start time