A Discrete-Event Network Simulator
API
yans-error-rate-model.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 "ns3/log.h"
23 #include "yans-error-rate-model.h"
24 #include "wifi-utils.h"
25 #include "wifi-phy.h"
26 
27 namespace ns3 {
28 
29 NS_LOG_COMPONENT_DEFINE ("YansErrorRateModel");
30 
31 NS_OBJECT_ENSURE_REGISTERED (YansErrorRateModel);
32 
33 TypeId
35 {
36  static TypeId tid = TypeId ("ns3::YansErrorRateModel")
38  .SetGroupName ("Wifi")
39  .AddConstructor<YansErrorRateModel> ()
40  ;
41  return tid;
42 }
43 
45 {
46 }
47 
48 double
49 YansErrorRateModel::GetBpskBer (double snr, uint32_t signalSpread, uint64_t phyRate) const
50 {
51  NS_LOG_FUNCTION (this << snr << signalSpread << phyRate);
52  double EbNo = snr * signalSpread / phyRate;
53  double z = std::sqrt (EbNo);
54  double ber = 0.5 * erfc (z);
55  NS_LOG_INFO ("bpsk snr=" << snr << " ber=" << ber);
56  return ber;
57 }
58 
59 double
60 YansErrorRateModel::GetQamBer (double snr, unsigned int m, uint32_t signalSpread, uint64_t phyRate) const
61 {
62  NS_LOG_FUNCTION (this << snr << m << signalSpread << phyRate);
63  double EbNo = snr * signalSpread / phyRate;
64  double z = std::sqrt ((1.5 * log2 (m) * EbNo) / (m - 1.0));
65  double z1 = ((1.0 - 1.0 / std::sqrt (m)) * erfc (z));
66  double z2 = 1 - std::pow ((1 - z1), 2);
67  double ber = z2 / log2 (m);
68  NS_LOG_INFO ("Qam m=" << m << " rate=" << phyRate << " snr=" << snr << " ber=" << ber);
69  return ber;
70 }
71 
72 uint32_t
74 {
75  uint32_t fact = 1;
76  while (k > 0)
77  {
78  fact *= k;
79  k--;
80  }
81  return fact;
82 }
83 
84 double
85 YansErrorRateModel::Binomial (uint32_t k, double p, uint32_t n) const
86 {
87  double retval = Factorial (n) / (Factorial (k) * Factorial (n - k)) * std::pow (p, static_cast<double> (k)) * std::pow (1 - p, static_cast<double> (n - k));
88  return retval;
89 }
90 
91 double
92 YansErrorRateModel::CalculatePdOdd (double ber, unsigned int d) const
93 {
94  NS_ASSERT ((d % 2) == 1);
95  unsigned int dstart = (d + 1) / 2;
96  unsigned int dend = d;
97  double pd = 0;
98 
99  for (unsigned int i = dstart; i < dend; i++)
100  {
101  pd += Binomial (i, ber, d);
102  }
103  return pd;
104 }
105 
106 double
107 YansErrorRateModel::CalculatePdEven (double ber, unsigned int d) const
108 {
109  NS_ASSERT ((d % 2) == 0);
110  unsigned int dstart = d / 2 + 1;
111  unsigned int dend = d;
112  double pd = 0;
113 
114  for (unsigned int i = dstart; i < dend; i++)
115  {
116  pd += Binomial (i, ber, d);
117  }
118  pd += 0.5 * Binomial (d / 2, ber, d);
119 
120  return pd;
121 }
122 
123 double
124 YansErrorRateModel::CalculatePd (double ber, unsigned int d) const
125 {
126  NS_LOG_FUNCTION (this << ber << d);
127  double pd;
128  if ((d % 2) == 0)
129  {
130  pd = CalculatePdEven (ber, d);
131  }
132  else
133  {
134  pd = CalculatePdOdd (ber, d);
135  }
136  return pd;
137 }
138 
139 double
140 YansErrorRateModel::GetFecBpskBer (double snr, uint64_t nbits,
141  uint32_t signalSpread, uint64_t phyRate,
142  uint32_t dFree, uint32_t adFree) const
143 {
144  NS_LOG_FUNCTION (this << snr << nbits << signalSpread << phyRate << dFree << adFree);
145  double ber = GetBpskBer (snr, signalSpread, phyRate);
146  if (ber == 0.0)
147  {
148  return 1.0;
149  }
150  double pd = CalculatePd (ber, dFree);
151  double pmu = adFree * pd;
152  pmu = std::min (pmu, 1.0);
153  double pms = std::pow (1 - pmu, nbits);
154  return pms;
155 }
156 
157 double
158 YansErrorRateModel::GetFecQamBer (double snr, uint64_t nbits,
159  uint32_t signalSpread,
160  uint64_t phyRate,
161  uint32_t m, uint32_t dFree,
162  uint32_t adFree, uint32_t adFreePlusOne) const
163 {
164  NS_LOG_FUNCTION (this << snr << nbits << signalSpread << phyRate << m << dFree << adFree << adFreePlusOne);
165  double ber = GetQamBer (snr, m, signalSpread, phyRate);
166  if (ber == 0.0)
167  {
168  return 1.0;
169  }
170  /* first term */
171  double pd = CalculatePd (ber, dFree);
172  double pmu = adFree * pd;
173  /* second term */
174  pd = CalculatePd (ber, dFree + 1);
175  pmu += adFreePlusOne * pd;
176  pmu = std::min (pmu, 1.0);
177  double pms = std::pow (1 - pmu, nbits);
178  return pms;
179 }
180 
181 double
182 YansErrorRateModel::DoGetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector, double snr, uint64_t nbits, uint8_t numRxAntennas, WifiPpduField field, uint16_t staId) const
183 {
184  NS_LOG_FUNCTION (this << mode << txVector << snr << nbits << +numRxAntennas << field << staId);
190  {
191  uint64_t phyRate;
192  if ((txVector.IsMu () && (staId == SU_STA_ID)) || (mode != txVector.GetMode ()))
193  {
194  phyRate = mode.GetPhyRate (txVector.GetChannelWidth () >= 40 ? 20 : txVector.GetChannelWidth ()); //This is the PHY header
195  }
196  else
197  {
198  phyRate = mode.GetPhyRate (txVector, staId);
199  }
200  if (mode.GetConstellationSize () == 2)
201  {
202  if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
203  {
204  return GetFecBpskBer (snr,
205  nbits,
206  txVector.GetChannelWidth () * 1000000, //signal spread
207  phyRate, //PHY rate
208  10, //dFree
209  11); //adFree
210  }
211  else
212  {
213  return GetFecBpskBer (snr,
214  nbits,
215  txVector.GetChannelWidth () * 1000000, //signal spread
216  phyRate, //PHY rate
217  5, //dFree
218  8); //adFree
219  }
220  }
221  else if (mode.GetConstellationSize () == 4)
222  {
223  if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
224  {
225  return GetFecQamBer (snr,
226  nbits,
227  txVector.GetChannelWidth () * 1000000, //signal spread
228  phyRate, //PHY rate
229  4, //m
230  10, //dFree
231  11, //adFree
232  0); //adFreePlusOne
233  }
234  else
235  {
236  return GetFecQamBer (snr,
237  nbits,
238  txVector.GetChannelWidth () * 1000000, //signal spread
239  phyRate, //PHY rate
240  4, //m
241  5, //dFree
242  8, //adFree
243  31); //adFreePlusOne
244  }
245  }
246  else if (mode.GetConstellationSize () == 16)
247  {
248  if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
249  {
250  return GetFecQamBer (snr,
251  nbits,
252  txVector.GetChannelWidth () * 1000000, //signal spread
253  phyRate, //PHY rate
254  16, //m
255  10, //dFree
256  11, //adFree
257  0); //adFreePlusOne
258  }
259  else
260  {
261  return GetFecQamBer (snr,
262  nbits,
263  txVector.GetChannelWidth () * 1000000, //signal spread
264  phyRate, //PHY rate
265  16, //m
266  5, //dFree
267  8, //adFree
268  31); //adFreePlusOne
269  }
270  }
271  else if (mode.GetConstellationSize () == 64)
272  {
273  if (mode.GetCodeRate () == WIFI_CODE_RATE_2_3)
274  {
275  return GetFecQamBer (snr,
276  nbits,
277  txVector.GetChannelWidth () * 1000000, //signal spread
278  phyRate, //PHY rate
279  64, //m
280  6, //dFree
281  1, //adFree
282  16); //adFreePlusOne
283  }
284  if (mode.GetCodeRate () == WIFI_CODE_RATE_5_6)
285  {
286  //Table B.32 in Pâl Frenger et al., "Multi-rate Convolutional Codes".
287  return GetFecQamBer (snr,
288  nbits,
289  txVector.GetChannelWidth () * 1000000, //signal spread
290  phyRate, //PHY rate
291  64, //m
292  4, //dFree
293  14, //adFree
294  69); //adFreePlusOne
295  }
296  else
297  {
298  return GetFecQamBer (snr,
299  nbits,
300  txVector.GetChannelWidth () * 1000000, //signal spread
301  phyRate, //PHY rate
302  64, //m
303  5, //dFree
304  8, //adFree
305  31); //adFreePlusOne
306  }
307  }
308  else if (mode.GetConstellationSize () == 256)
309  {
310  if (mode.GetCodeRate () == WIFI_CODE_RATE_5_6)
311  {
312  return GetFecQamBer (snr,
313  nbits,
314  txVector.GetChannelWidth () * 1000000, // signal spread
315  phyRate, //PHY rate
316  256, // m
317  4, // dFree
318  14, // adFree
319  69 // adFreePlusOne
320  );
321  }
322  else
323  {
324  return GetFecQamBer (snr,
325  nbits,
326  txVector.GetChannelWidth () * 1000000, // signal spread
327  phyRate, //PHY rate
328  256, // m
329  5, // dFree
330  8, // adFree
331  31 // adFreePlusOne
332  );
333  }
334  }
335  else if (mode.GetConstellationSize () == 1024)
336  {
337  if (mode.GetCodeRate () == WIFI_CODE_RATE_5_6)
338  {
339  return GetFecQamBer (snr,
340  nbits,
341  txVector.GetChannelWidth () * 1000000, // signal spread
342  phyRate, //PHY rate
343  1024, // m
344  4, // dFree
345  14, // adFree
346  69 // adFreePlusOne
347  );
348  }
349  else
350  {
351  return GetFecQamBer (snr,
352  nbits,
353  txVector.GetChannelWidth () * 1000000, // signal spread
354  phyRate, //PHY rate
355  1024, // m
356  5, // dFree
357  8, // adFree
358  31 // adFreePlusOne
359  );
360  }
361  }
362  }
363  return 0;
364 }
365 
366 } //namespace ns3
static TypeId GetTypeId(void)
Get the type ID.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
const uint16_t WIFI_CODE_RATE_2_3
2/3 coding rate
#define min(a, b)
Definition: 80211b.c:42
#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
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
bool IsMu(void) const
Return true if this TX vector is used for a multi-user transmission.
double GetFecQamBer(double snr, uint64_t nbits, uint32_t signalSpread, uint64_t phyRate, uint32_t m, uint32_t dfree, uint32_t adFree, uint32_t adFreePlusOne) const
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:47
the interface for Wifi&#39;s error models
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...
Model the error rate for different modulations.
double CalculatePdEven(double ber, unsigned int d) const
double DoGetChunkSuccessRate(WifiMode mode, const WifiTxVector &txVector, double snr, uint64_t nbits, uint8_t numRxAntennas, WifiPpduField field, uint16_t staId) const override
A pure virtual method that must be implemented in the subclass.
double GetQamBer(double snr, unsigned int m, uint32_t signalSpread, uint64_t phyRate) const
Return BER of QAM-m with the given parameters.
WifiPpduField
The type of PPDU field (grouped for convenience)
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:159
const uint16_t WIFI_CODE_RATE_5_6
5/6 coding rate
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint16_t GetConstellationSize(void) const
Definition: wifi-mode.cc:115
double CalculatePdOdd(double ber, unsigned int d) const
uint32_t Factorial(uint32_t k) const
Return k!
uint64_t GetPhyRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:73
double Binomial(uint32_t k, double p, uint32_t n) const
Return Binomial distribution for a given k, p, and n.
double GetBpskBer(double snr, uint32_t signalSpread, uint64_t phyRate) const
Return BER of BPSK with the given parameters.
uint16_t GetChannelWidth(void) const
WifiCodeRate GetCodeRate(void) const
Definition: wifi-mode.cc:108
double GetFecBpskBer(double snr, uint64_t nbits, uint32_t signalSpread, uint64_t phyRate, uint32_t dFree, uint32_t adFree) const
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
#define SU_STA_ID
Definition: wifi-mode.h:32
const uint16_t WIFI_CODE_RATE_1_2
1/2 coding rate
double CalculatePd(double ber, unsigned int d) const