A Discrete-Event Network Simulator
API
nist-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) 2010 The Boeing Company
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: Gary Pei <guangyu.pei@boeing.com>
19  * Sébastien Deronne <sebastien.deronne@gmail.com>
20  */
21 
22 #include <cmath>
23 #include "nist-error-rate-model.h"
24 #include "wifi-phy.h"
25 #include "ns3/log.h"
26 
27 namespace ns3 {
28 
29 NS_LOG_COMPONENT_DEFINE ("NistErrorRateModel");
30 
31 NS_OBJECT_ENSURE_REGISTERED (NistErrorRateModel);
32 
33 TypeId
35 {
36  static TypeId tid = TypeId ("ns3::NistErrorRateModel")
38  .SetGroupName ("Wifi")
39  .AddConstructor<NistErrorRateModel> ()
40  ;
41  return tid;
42 }
43 
45 {
46 }
47 
48 double
50 {
51  double z = std::sqrt (snr);
52  double ber = 0.5 * erfc (z);
53  NS_LOG_INFO ("bpsk snr=" << snr << " ber=" << ber);
54  return ber;
55 }
56 
57 double
59 {
60  double z = std::sqrt (snr / 2.0);
61  double ber = 0.5 * erfc (z);
62  NS_LOG_INFO ("qpsk snr=" << snr << " ber=" << ber);
63  return ber;
64 }
65 
66 double
68 {
69  double z = std::sqrt (snr / (5.0 * 2.0));
70  double ber = 0.75 * 0.5 * erfc (z);
71  NS_LOG_INFO ("16-Qam" << " snr=" << snr << " ber=" << ber);
72  return ber;
73 }
74 
75 double
77 {
78  double z = std::sqrt (snr / (21.0 * 2.0));
79  double ber = 7.0 / 12.0 * 0.5 * erfc (z);
80  NS_LOG_INFO ("64-Qam" << " snr=" << snr << " ber=" << ber);
81  return ber;
82 }
83 double
85 {
86  double z = std::sqrt (snr / (85.0 * 2.0));
87  double ber = 15.0 / 32.0 * 0.5 * erfc (z);
88  NS_LOG_INFO ("256-Qam" << " snr=" << snr << " ber=" << ber);
89  return ber;
90 }
91 
92 double
93 NistErrorRateModel::GetFecBpskBer (double snr, uint32_t nbits,
94  uint32_t bValue) const
95 {
96  double ber = GetBpskBer (snr);
97  if (ber == 0.0)
98  {
99  return 1.0;
100  }
101  double pe = CalculatePe (ber, bValue);
102  pe = std::min (pe, 1.0);
103  double pms = std::pow (1 - pe, (double)nbits);
104  return pms;
105 }
106 
107 double
108 NistErrorRateModel::GetFecQpskBer (double snr, uint32_t nbits,
109  uint32_t bValue) const
110 {
111  double ber = GetQpskBer (snr);
112  if (ber == 0.0)
113  {
114  return 1.0;
115  }
116  double pe = CalculatePe (ber, bValue);
117  pe = std::min (pe, 1.0);
118  double pms = std::pow (1 - pe, (double)nbits);
119  return pms;
120 }
121 
122 double
123 NistErrorRateModel::CalculatePe (double p, uint32_t bValue) const
124 {
125  double D = std::sqrt (4.0 * p * (1.0 - p));
126  double pe = 1.0;
127  if (bValue == 1)
128  {
129  //code rate 1/2, use table 3.1.1
130  pe = 0.5 * (36.0 * std::pow (D, 10)
131  + 211.0 * std::pow (D, 12)
132  + 1404.0 * std::pow (D, 14)
133  + 11633.0 * std::pow (D, 16)
134  + 77433.0 * std::pow (D, 18)
135  + 502690.0 * std::pow (D, 20)
136  + 3322763.0 * std::pow (D, 22)
137  + 21292910.0 * std::pow (D, 24)
138  + 134365911.0 * std::pow (D, 26));
139  }
140  else if (bValue == 2)
141  {
142  //code rate 2/3, use table 3.1.2
143  pe = 1.0 / (2.0 * bValue) *
144  (3.0 * std::pow (D, 6)
145  + 70.0 * std::pow (D, 7)
146  + 285.0 * std::pow (D, 8)
147  + 1276.0 * std::pow (D, 9)
148  + 6160.0 * std::pow (D, 10)
149  + 27128.0 * std::pow (D, 11)
150  + 117019.0 * std::pow (D, 12)
151  + 498860.0 * std::pow (D, 13)
152  + 2103891.0 * std::pow (D, 14)
153  + 8784123.0 * std::pow (D, 15));
154  }
155  else if (bValue == 3)
156  {
157  //code rate 3/4, use table 3.1.2
158  pe = 1.0 / (2.0 * bValue) *
159  (42.0 * std::pow (D, 5)
160  + 201.0 * std::pow (D, 6)
161  + 1492.0 * std::pow (D, 7)
162  + 10469.0 * std::pow (D, 8)
163  + 62935.0 * std::pow (D, 9)
164  + 379644.0 * std::pow (D, 10)
165  + 2253373.0 * std::pow (D, 11)
166  + 13073811.0 * std::pow (D, 12)
167  + 75152755.0 * std::pow (D, 13)
168  + 428005675.0 * std::pow (D, 14));
169  }
170  else if (bValue == 5)
171  {
172  //code rate 5/6, use table V from D. Haccoun and G. Begin, "High-Rate Punctured Convolutional Codes
173  //for Viterbi Sequential Decoding", IEEE Transactions on Communications, Vol. 32, Issue 3, pp.315-319.
174  pe = 1.0 / (2.0 * bValue) *
175  (92.0 * std::pow (D, 4.0)
176  + 528.0 * std::pow (D, 5.0)
177  + 8694.0 * std::pow (D, 6.0)
178  + 79453.0 * std::pow (D, 7.0)
179  + 792114.0 * std::pow (D, 8.0)
180  + 7375573.0 * std::pow (D, 9.0)
181  + 67884974.0 * std::pow (D, 10.0)
182  + 610875423.0 * std::pow (D, 11.0)
183  + 5427275376.0 * std::pow (D, 12.0)
184  + 47664215639.0 * std::pow (D, 13.0));
185  }
186  else
187  {
188  NS_ASSERT (false);
189  }
190  return pe;
191 }
192 
193 double
194 NistErrorRateModel::GetFec16QamBer (double snr, uint32_t nbits,
195  uint32_t bValue) const
196 {
197  double ber = Get16QamBer (snr);
198  if (ber == 0.0)
199  {
200  return 1.0;
201  }
202  double pe = CalculatePe (ber, bValue);
203  pe = std::min (pe, 1.0);
204  double pms = std::pow (1 - pe, static_cast<double> (nbits));
205  return pms;
206 }
207 
208 double
209 NistErrorRateModel::GetFec64QamBer (double snr, uint32_t nbits,
210  uint32_t bValue) const
211 {
212  double ber = Get64QamBer (snr);
213  if (ber == 0.0)
214  {
215  return 1.0;
216  }
217  double pe = CalculatePe (ber, bValue);
218  pe = std::min (pe, 1.0);
219  double pms = std::pow (1 - pe, static_cast<double> (nbits));
220  return pms;
221 }
222 
223 double
224 NistErrorRateModel::GetFec256QamBer (double snr, uint32_t nbits,
225  uint32_t bValue) const
226 {
227  double ber = Get256QamBer (snr);
228  if (ber == 0.0)
229  {
230  return 1.0;
231  }
232  double pe = CalculatePe (ber, bValue);
233  pe = std::min (pe, 1.0);
234  double pms = std::pow (1 - pe, static_cast<double> (nbits));
235  return pms;
236 }
237 
238 double
239 NistErrorRateModel::GetChunkSuccessRate (WifiMode mode, WifiTxVector txVector, double snr, uint32_t nbits) const
240 {
245  {
246  if (mode.GetConstellationSize (1) == 2)
247  {
248  if (mode.GetCodeRate (1) == WIFI_CODE_RATE_1_2)
249  {
250  return GetFecBpskBer (snr,
251  nbits,
252  1); //b value
253  }
254  else
255  {
256  return GetFecBpskBer (snr,
257  nbits,
258  3); //b value
259  }
260  }
261  else if (mode.GetConstellationSize (1) == 4)
262  {
263  if (mode.GetCodeRate (1) == WIFI_CODE_RATE_1_2)
264  {
265  return GetFecQpskBer (snr,
266  nbits,
267  1); //b value
268  }
269  else
270  {
271  return GetFecQpskBer (snr,
272  nbits,
273  3); //b value
274  }
275  }
276  else if (mode.GetConstellationSize (1) == 16)
277  {
278  if (mode.GetCodeRate (1) == WIFI_CODE_RATE_1_2)
279  {
280  return GetFec16QamBer (snr,
281  nbits,
282  1); //b value
283  }
284  else
285  {
286  return GetFec16QamBer (snr,
287  nbits,
288  3); //b value
289  }
290  }
291  else if (mode.GetConstellationSize (1) == 64)
292  {
293  if (mode.GetCodeRate (1) == WIFI_CODE_RATE_2_3)
294  {
295  return GetFec64QamBer (snr,
296  nbits,
297  2); //b value
298  }
299  else if (mode.GetCodeRate (1) == WIFI_CODE_RATE_5_6)
300  {
301  return GetFec64QamBer (snr,
302  nbits,
303  5); //b value
304  }
305  else
306  {
307  return GetFec64QamBer (snr,
308  nbits,
309  3); //b value
310  }
311  }
312  else if (mode.GetConstellationSize (1) == 256)
313  {
314  if (mode.GetCodeRate (1) == WIFI_CODE_RATE_5_6)
315  {
316  return GetFec256QamBer (snr,
317  nbits,
318  5 // b value
319  );
320  }
321  else
322  {
323  return GetFec256QamBer (snr,
324  nbits,
325  3 // b value
326  );
327  }
328  }
329  }
331  {
332  switch (mode.GetDataRate (20, 0, 1))
333  {
334  case 1000000:
336  case 2000000:
338  case 5500000:
340  case 11000000:
342  default:
343  NS_ASSERT ("undefined DSSS/HR-DSSS datarate");
344  }
345  }
346  return 0;
347 }
348 
349 } //namespace ns3
double GetQpskBer(double snr) const
Return BER of QPSK at the given SNR.
static double GetDsssDqpskCck11SuccessRate(double sinr, uint32_t nbits)
Return the chunk success rate of the differential encoded QPSK for 11Mbps data rate.
static TypeId GetTypeId(void)
ERP-OFDM PHY (19.5)
Definition: wifi-mode.h:56
enum WifiCodeRate GetCodeRate(uint8_t nss) const
Definition: wifi-mode.cc:227
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:44
uint16_t GetConstellationSize(uint8_t nss) const
Definition: wifi-mode.cc:282
enum WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:375
#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:201
static double GetDsssDqpskSuccessRate(double sinr, uint32_t nbits)
Return the chunk success rate of the differential encoded QPSK.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
VHT PHY (Clause 22)
Definition: wifi-mode.h:62
HR/DSSS PHY (Clause 18)
Definition: wifi-mode.h:50
double GetFec64QamBer(double snr, uint32_t nbits, uint32_t bValue) const
Return BER of QAM64 at the given SNR after applying FEC.
double GetFec16QamBer(double snr, uint32_t nbits, uint32_t bValue) const
Return BER of QAM16 at the given SNR after applying FEC.
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:97
double GetFec256QamBer(double snr, uint32_t nbits, uint32_t bValue) const
Return BER of QAM256 at the given SNR after applying FEC.
the interface for Wifi's error models
double CalculatePe(double p, uint32_t bValue) const
Return the coded BER for the given p and b.
virtual double GetChunkSuccessRate(WifiMode mode, WifiTxVector txVector, double snr, uint32_t nbits) const
A pure virtual method that must be implemented in the subclass.
double Get16QamBer(double snr) const
Return BER of QAM16 at the given SNR.
HT PHY (Clause 20)
Definition: wifi-mode.h:60
A model for the error rate for different modulations.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint64_t GetDataRate(uint32_t channelWidth, bool isShortGuardInterval, uint8_t nss) const
Definition: wifi-mode.cc:100
double GetFecQpskBer(double snr, uint32_t nbits, uint32_t bValue) const
Return BER of QPSK at the given SNR after applying FEC.
double Get64QamBer(double snr) const
Return BER of QAM64 at the given SNR.
double Get256QamBer(double snr) const
Return BER of QAM256 at the given SNR.
static double GetDsssDqpskCck5_5SuccessRate(double sinr, uint32_t nbits)
Return the chunk success rate of the differential encoded QPSK for 5.5Mbps data rate.
OFDM PHY (Clause 17)
Definition: wifi-mode.h:58
double GetFecBpskBer(double snr, uint32_t nbits, uint32_t bValue) const
Return BER of BPSK at the given SNR after applying FEC.
static double GetDsssDbpskSuccessRate(double sinr, uint32_t nbits)
Return the chunk success rate of the differential BPSK.
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:826
DSSS PHY (Clause 15)
Definition: wifi-mode.h:48
double GetBpskBer(double snr) const
Return BER of BPSK at the given SNR.