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"
25#include "wifi-utils.h"
26#include "wifi-tx-vector.h"
27
28namespace ns3 {
29
30NS_LOG_COMPONENT_DEFINE ("YansErrorRateModel");
31
32NS_OBJECT_ENSURE_REGISTERED (YansErrorRateModel);
33
34TypeId
36{
37 static TypeId tid = TypeId ("ns3::YansErrorRateModel")
39 .SetGroupName ("Wifi")
40 .AddConstructor<YansErrorRateModel> ()
41 ;
42 return tid;
43}
44
46{
47}
48
49double
50YansErrorRateModel::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
60double
61YansErrorRateModel::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
75{
76 uint32_t fact = 1;
77 while (k > 0)
78 {
79 fact *= k;
80 k--;
81 }
82 return fact;
83}
84
85double
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
92double
93YansErrorRateModel::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
107double
108YansErrorRateModel::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
124double
125YansErrorRateModel::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
140double
141YansErrorRateModel::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
158double
159YansErrorRateModel::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
182double
183YansErrorRateModel::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