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