A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
yans-error-rate-model.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005,2006 INRIA
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18 * Sébastien Deronne <sebastien.deronne@gmail.com>
19 */
20
22
23#include "wifi-tx-vector.h"
24#include "wifi-utils.h"
25
26#include "ns3/log.h"
27
28#include <cmath>
29
30namespace ns3
31{
32
33NS_LOG_COMPONENT_DEFINE("YansErrorRateModel");
34
35NS_OBJECT_ENSURE_REGISTERED(YansErrorRateModel);
36
37TypeId
39{
40 static TypeId tid = TypeId("ns3::YansErrorRateModel")
42 .SetGroupName("Wifi")
43 .AddConstructor<YansErrorRateModel>();
44 return tid;
45}
46
48{
49}
50
51double
52YansErrorRateModel::GetBpskBer(double snr, uint32_t signalSpread, uint64_t phyRate) const
53{
54 NS_LOG_FUNCTION(this << snr << signalSpread << phyRate);
55 double EbNo = snr * signalSpread / phyRate;
56 double z = std::sqrt(EbNo);
57 double ber = 0.5 * erfc(z);
58 NS_LOG_INFO("bpsk snr=" << snr << " ber=" << ber);
59 return ber;
60}
61
62double
64 unsigned int m,
65 uint32_t signalSpread,
66 uint64_t phyRate) const
67{
68 NS_LOG_FUNCTION(this << snr << m << signalSpread << phyRate);
69 double EbNo = snr * signalSpread / phyRate;
70 double z = std::sqrt((1.5 * log2(m) * EbNo) / (m - 1.0));
71 double z1 = ((1.0 - 1.0 / std::sqrt(m)) * erfc(z));
72 double z2 = 1 - std::pow((1 - z1), 2);
73 double ber = z2 / log2(m);
74 NS_LOG_INFO("Qam m=" << m << " rate=" << phyRate << " snr=" << snr << " ber=" << ber);
75 return ber;
76}
77
80{
81 uint32_t fact = 1;
82 while (k > 0)
83 {
84 fact *= k;
85 k--;
86 }
87 return fact;
88}
89
90double
92{
93 double retval = Factorial(n) / (Factorial(k) * Factorial(n - k)) *
94 std::pow(p, static_cast<double>(k)) *
95 std::pow(1 - p, static_cast<double>(n - k));
96 return retval;
97}
98
99double
100YansErrorRateModel::CalculatePdOdd(double ber, unsigned int d) const
101{
102 NS_ASSERT((d % 2) == 1);
103 unsigned int dstart = (d + 1) / 2;
104 unsigned int dend = d;
105 double pd = 0;
106
107 for (unsigned int i = dstart; i < dend; i++)
108 {
109 pd += Binomial(i, ber, d);
110 }
111 return pd;
112}
113
114double
115YansErrorRateModel::CalculatePdEven(double ber, unsigned int d) const
116{
117 NS_ASSERT((d % 2) == 0);
118 unsigned int dstart = d / 2 + 1;
119 unsigned int dend = d;
120 double pd = 0;
121
122 for (unsigned int i = dstart; i < dend; i++)
123 {
124 pd += Binomial(i, ber, d);
125 }
126 pd += 0.5 * Binomial(d / 2, ber, d);
127
128 return pd;
129}
130
131double
132YansErrorRateModel::CalculatePd(double ber, unsigned int d) const
133{
134 NS_LOG_FUNCTION(this << ber << d);
135 double pd;
136 if ((d % 2) == 0)
137 {
138 pd = CalculatePdEven(ber, d);
139 }
140 else
141 {
142 pd = CalculatePdOdd(ber, d);
143 }
144 return pd;
145}
146
147double
149 uint64_t nbits,
150 uint32_t signalSpread,
151 uint64_t phyRate,
152 uint32_t dFree,
153 uint32_t adFree) const
154{
155 NS_LOG_FUNCTION(this << snr << nbits << signalSpread << phyRate << dFree << adFree);
156 double ber = GetBpskBer(snr, signalSpread, phyRate);
157 if (ber == 0.0)
158 {
159 return 1.0;
160 }
161 double pd = CalculatePd(ber, dFree);
162 double pmu = adFree * pd;
163 pmu = std::min(pmu, 1.0);
164 double pms = std::pow(1 - pmu, nbits);
165 return pms;
166}
167
168double
170 uint64_t nbits,
171 uint32_t signalSpread,
172 uint64_t phyRate,
173 uint32_t m,
174 uint32_t dFree,
175 uint32_t adFree,
176 uint32_t adFreePlusOne) const
177{
178 NS_LOG_FUNCTION(this << snr << nbits << signalSpread << phyRate << m << dFree << adFree
179 << adFreePlusOne);
180 double ber = GetQamBer(snr, m, signalSpread, phyRate);
181 if (ber == 0.0)
182 {
183 return 1.0;
184 }
185 /* first term */
186 double pd = CalculatePd(ber, dFree);
187 double pmu = adFree * pd;
188 /* second term */
189 pd = CalculatePd(ber, dFree + 1);
190 pmu += adFreePlusOne * pd;
191 pmu = std::min(pmu, 1.0);
192 double pms = std::pow(1 - pmu, nbits);
193 return pms;
194}
195
196double
198 const WifiTxVector& txVector,
199 double snr,
200 uint64_t nbits,
201 uint8_t numRxAntennas,
202 WifiPpduField field,
203 uint16_t staId) const
204{
205 NS_LOG_FUNCTION(this << mode << txVector << snr << nbits << +numRxAntennas << field << staId);
207 {
208 uint64_t phyRate;
209 if ((txVector.IsMu() && (staId == SU_STA_ID)) || (mode != txVector.GetMode(staId)))
210 {
211 phyRate = mode.GetPhyRate(txVector.GetChannelWidth() >= 40
212 ? 20
213 : txVector.GetChannelWidth()); // This is the PHY header
214 }
215 else
216 {
217 phyRate = mode.GetPhyRate(txVector, staId);
218 }
219 if (mode.GetConstellationSize() == 2)
220 {
221 if (mode.GetCodeRate() == WIFI_CODE_RATE_1_2)
222 {
223 return GetFecBpskBer(snr,
224 nbits,
225 txVector.GetChannelWidth() * 1000000, // signal spread
226 phyRate, // PHY rate
227 10, // dFree
228 11); // adFree
229 }
230 else
231 {
232 return GetFecBpskBer(snr,
233 nbits,
234 txVector.GetChannelWidth() * 1000000, // signal spread
235 phyRate, // PHY rate
236 5, // dFree
237 8); // adFree
238 }
239 }
240 else if (mode.GetConstellationSize() == 4)
241 {
242 if (mode.GetCodeRate() == WIFI_CODE_RATE_1_2)
243 {
244 return GetFecQamBer(snr,
245 nbits,
246 txVector.GetChannelWidth() * 1000000, // signal spread
247 phyRate, // PHY rate
248 4, // m
249 10, // dFree
250 11, // adFree
251 0); // adFreePlusOne
252 }
253 else
254 {
255 return GetFecQamBer(snr,
256 nbits,
257 txVector.GetChannelWidth() * 1000000, // signal spread
258 phyRate, // PHY rate
259 4, // m
260 5, // dFree
261 8, // adFree
262 31); // adFreePlusOne
263 }
264 }
265 else if (mode.GetConstellationSize() == 16)
266 {
267 if (mode.GetCodeRate() == WIFI_CODE_RATE_1_2)
268 {
269 return GetFecQamBer(snr,
270 nbits,
271 txVector.GetChannelWidth() * 1000000, // signal spread
272 phyRate, // PHY rate
273 16, // m
274 10, // dFree
275 11, // adFree
276 0); // adFreePlusOne
277 }
278 else
279 {
280 return GetFecQamBer(snr,
281 nbits,
282 txVector.GetChannelWidth() * 1000000, // signal spread
283 phyRate, // PHY rate
284 16, // m
285 5, // dFree
286 8, // adFree
287 31); // adFreePlusOne
288 }
289 }
290 else if (mode.GetConstellationSize() == 64)
291 {
292 if (mode.GetCodeRate() == WIFI_CODE_RATE_2_3)
293 {
294 return GetFecQamBer(snr,
295 nbits,
296 txVector.GetChannelWidth() * 1000000, // signal spread
297 phyRate, // PHY rate
298 64, // m
299 6, // dFree
300 1, // adFree
301 16); // adFreePlusOne
302 }
303 if (mode.GetCodeRate() == WIFI_CODE_RATE_5_6)
304 {
305 // Table B.32 in Pâl Frenger et al., "Multi-rate Convolutional Codes".
306 return GetFecQamBer(snr,
307 nbits,
308 txVector.GetChannelWidth() * 1000000, // signal spread
309 phyRate, // PHY rate
310 64, // m
311 4, // dFree
312 14, // adFree
313 69); // adFreePlusOne
314 }
315 else
316 {
317 return GetFecQamBer(snr,
318 nbits,
319 txVector.GetChannelWidth() * 1000000, // signal spread
320 phyRate, // PHY rate
321 64, // m
322 5, // dFree
323 8, // adFree
324 31); // adFreePlusOne
325 }
326 }
327 else if (mode.GetConstellationSize() == 256)
328 {
329 if (mode.GetCodeRate() == WIFI_CODE_RATE_5_6)
330 {
331 return GetFecQamBer(snr,
332 nbits,
333 txVector.GetChannelWidth() * 1000000, // signal spread
334 phyRate, // PHY rate
335 256, // m
336 4, // dFree
337 14, // adFree
338 69 // adFreePlusOne
339 );
340 }
341 else
342 {
343 return GetFecQamBer(snr,
344 nbits,
345 txVector.GetChannelWidth() * 1000000, // signal spread
346 phyRate, // PHY rate
347 256, // m
348 5, // dFree
349 8, // adFree
350 31 // adFreePlusOne
351 );
352 }
353 }
354 else if (mode.GetConstellationSize() == 1024)
355 {
356 if (mode.GetCodeRate() == WIFI_CODE_RATE_5_6)
357 {
358 return GetFecQamBer(snr,
359 nbits,
360 txVector.GetChannelWidth() * 1000000, // signal spread
361 phyRate, // PHY rate
362 1024, // m
363 4, // dFree
364 14, // adFree
365 69 // adFreePlusOne
366 );
367 }
368 else
369 {
370 return GetFecQamBer(snr,
371 nbits,
372 txVector.GetChannelWidth() * 1000000, // signal spread
373 phyRate, // PHY rate
374 1024, // m
375 5, // dFree
376 8, // adFree
377 31 // adFreePlusOne
378 );
379 }
380 }
381 else if (mode.GetConstellationSize() == 4096)
382 {
383 if (mode.GetCodeRate() == WIFI_CODE_RATE_5_6)
384 {
385 return GetFecQamBer(snr,
386 nbits,
387 txVector.GetChannelWidth() * 1000000, // signal spread
388 phyRate, // PHY rate
389 4096, // m
390 4, // dFree
391 14, // adFree
392 69 // adFreePlusOne
393 );
394 }
395 else
396 {
397 return GetFecQamBer(snr,
398 nbits,
399 txVector.GetChannelWidth() * 1000000, // signal spread
400 phyRate, // PHY rate
401 4096, // m
402 5, // dFree
403 8, // adFree
404 31 // adFreePlusOne
405 );
406 }
407 }
408 }
409 return 0;
410}
411
412} // namespace ns3
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:932
represent a single transmission mode
Definition: wifi-mode.h:51
uint16_t GetConstellationSize() const
Definition: wifi-mode.cc:141
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:185
uint64_t GetPhyRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:91
WifiCodeRate GetCodeRate() const
Definition: wifi-mode.cc:134
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.
uint16_t GetChannelWidth() 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.
static TypeId GetTypeId()
Get the type ID.
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.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#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:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
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.
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
Definition: wifi-mode.h:35
@ WIFI_CODE_RATE_2_3
2/3 coding rate
@ WIFI_CODE_RATE_1_2
1/2 coding rate
@ WIFI_CODE_RATE_5_6
5/6 coding rate