A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-error-rate-models-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2016 University of Washington
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Tom Henderson (tomhend@u.washington.edu)
7 * Sébastien Deronne (sebastien.deronne@gmail.com)
8 */
9
10#ifdef HAVE_GSL
11#include <gsl/gsl_cdf.h>
12#include <gsl/gsl_integration.h>
13#include <gsl/gsl_math.h>
14#include <gsl/gsl_sf_bessel.h>
15#endif
16
17#include "ns3/dsss-error-rate-model.h"
18#include "ns3/he-phy.h" //includes HT and VHT
19#include "ns3/interference-helper.h"
20#include "ns3/log.h"
21#include "ns3/nist-error-rate-model.h"
22#include "ns3/table-based-error-rate-model.h"
23#include "ns3/test.h"
24#include "ns3/wifi-phy.h"
25#include "ns3/wifi-utils.h"
26#include "ns3/yans-error-rate-model.h"
27
28using namespace ns3;
29
30NS_LOG_COMPONENT_DEFINE("WifiErrorRateModelsTest");
31
32static double
34{
35 // SINR is based on receiver noise figure of 7 dB and thermal noise
36 // of -100.5522786 dBm in this 22 MHz bandwidth at 290K
37 dBW_u noisePower = -100.5522786 + 7;
38
39 dB_u sinr = rss - noisePower;
40 // return SINR expressed as ratio
41 return pow(10.0, sinr / 10.0);
42}
43
44/**
45 * @ingroup wifi-test
46 * @ingroup tests
47 *
48 * @brief Wifi Error Rate Models Test Case Dsss
49 */
51{
52 public:
55
56 private:
57 void DoRun() override;
58};
59
61 : TestCase("WifiErrorRateModel test case DSSS")
62{
63}
64
68
69void
71{
72 // 1024 bytes plus headers
73 uint64_t size = (1024 + 40 + 14) * 8;
74 // Spot test some values returned from DsssErrorRateModel
75 // Values taken from sample 80211b.c program used in validation paper
76 double value;
77 // DBPSK
79 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0, 1e-13, "Not equal within tolerance");
81 NS_TEST_ASSERT_MSG_EQ_TOL(value, 1.5e-13, 1e-13, "Not equal within tolerance");
83 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.0003, 0.0001, "Not equal within tolerance");
85 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.202, 0.005, "Not equal within tolerance");
87 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.813, 0.005, "Not equal within tolerance");
89 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.984, 0.005, "Not equal within tolerance");
91 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.999, 0.001, "Not equal within tolerance");
93 NS_TEST_ASSERT_MSG_EQ_TOL(value, 1, 0.001, "Not equal within tolerance");
94
95 // DQPSK
96 //
98 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0, 1e-13, "Not equal within tolerance");
100 NS_TEST_ASSERT_MSG_EQ_TOL(value, 4.5e-6, 1e-6, "Not equal within tolerance");
102 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.036, 0.005, "Not equal within tolerance");
104 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.519, 0.005, "Not equal within tolerance");
106 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.915, 0.005, "Not equal within tolerance");
108 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.993, 0.005, "Not equal within tolerance");
110 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.999, 0.001, "Not equal within tolerance");
112 NS_TEST_ASSERT_MSG_EQ_TOL(value, 1, 0.001, "Not equal within tolerance");
113
114#ifdef HAVE_GSL
115 // DQPSK_CCK5.5
117 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0, 1e-13, "Not equal within tolerance");
119 NS_TEST_ASSERT_MSG_EQ_TOL(value, 6.6e-14, 5e-14, "Not equal within tolerance");
121 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.0001, 0.00005, "Not equal within tolerance");
123 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.132, 0.005, "Not equal within tolerance");
125 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.744, 0.005, "Not equal within tolerance");
127 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.974, 0.005, "Not equal within tolerance");
129 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.999, 0.001, "Not equal within tolerance");
131 NS_TEST_ASSERT_MSG_EQ_TOL(value, 1, 0.001, "Not equal within tolerance");
132
133 // DQPSK_CCK11
135 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0, 1e-14, "Not equal within tolerance");
137 NS_TEST_ASSERT_MSG_EQ_TOL(value, 4.7e-14, 1e-14, "Not equal within tolerance");
139 NS_TEST_ASSERT_MSG_EQ_TOL(value, 8.85e-5, 1e-5, "Not equal within tolerance");
141 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.128, 0.005, "Not equal within tolerance");
143 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.739, 0.005, "Not equal within tolerance");
145 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.973, 0.005, "Not equal within tolerance");
147 NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.999, 0.001, "Not equal within tolerance");
149 NS_TEST_ASSERT_MSG_EQ_TOL(value, 1, 0.001, "Not equal within tolerance");
150#endif
151}
152
153/**
154 * @ingroup wifi-test
155 * @ingroup tests
156 *
157 * @brief Wifi Error Rate Models Test Case Nist
158 */
160{
161 public:
164
165 private:
166 void DoRun() override;
167};
168
170 : TestCase("WifiErrorRateModel test case NIST")
171{
172}
173
177
178void
180{
181 uint32_t frameSize = 2000;
182 WifiTxVector txVector;
184
185 // Spot test some values returned from NistErrorRateModel
186 // values can be generated by the example program ofdm-validation.cc
187 dB_u snr{2.5};
188 auto ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate6Mbps"),
189 txVector,
190 std::pow(10.0, snr / 10.0),
191 frameSize * 8);
192 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 2.04e-10, 1e-10, "Not equal within tolerance");
193 snr = 3.0;
194 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate6Mbps"),
195 txVector,
196 std::pow(10.0, snr / 10.0),
197 frameSize * 8);
198 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.020, 0.001, "Not equal within tolerance");
199 snr = 4.0;
200 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate6Mbps"),
201 txVector,
202 std::pow(10.0, snr / 10.0),
203 frameSize * 8);
204 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.885, 0.001, "Not equal within tolerance");
205 snr = 5.0;
206 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate6Mbps"),
207 txVector,
208 std::pow(10.0, snr / 10.0),
209 frameSize * 8);
210 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.997, 0.001, "Not equal within tolerance");
211
212 snr = 6.0;
213 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate9Mbps"),
214 txVector,
215 std::pow(10.0, snr / 10.0),
216 frameSize * 8);
217 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.097, 0.001, "Not equal within tolerance");
218 snr = 7.0;
219 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate9Mbps"),
220 txVector,
221 std::pow(10.0, snr / 10.0),
222 frameSize * 8);
223 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.918, 0.001, "Not equal within tolerance");
224 snr = 8.0;
225 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate9Mbps"),
226 txVector,
227 std::pow(10.0, snr / 10.0),
228 frameSize * 8);
229 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.998, 0.001, "Not equal within tolerance");
230 snr = 9.0;
231 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate9Mbps"),
232 txVector,
233 std::pow(10.0, snr / 10.0),
234 frameSize * 8);
235 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.999, 0.001, "Not equal within tolerance");
236
237 snr = 6.0;
238 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate12Mbps"),
239 txVector,
240 std::pow(10.0, snr / 10.0),
241 frameSize * 8);
242 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.0174, 0.001, "Not equal within tolerance");
243 snr = 7.0;
244 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate12Mbps"),
245 txVector,
246 std::pow(10.0, snr / 10.0),
247 frameSize * 8);
248 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.881, 0.001, "Not equal within tolerance");
249 snr = 8.0;
250 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate12Mbps"),
251 txVector,
252 std::pow(10.0, snr / 10.0),
253 frameSize * 8);
254 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.997, 0.001, "Not equal within tolerance");
255 snr = 9.0;
256 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate12Mbps"),
257 txVector,
258 std::pow(10.0, snr / 10.0),
259 frameSize * 8);
260 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.999, 0.001, "Not equal within tolerance");
261
262 snr = 8.5;
263 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate18Mbps"),
264 txVector,
265 std::pow(10.0, snr / 10.0),
266 frameSize * 8);
267 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 2.85e-6, 1e-6, "Not equal within tolerance");
268 snr = 9.5;
269 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate18Mbps"),
270 txVector,
271 std::pow(10.0, snr / 10.0),
272 frameSize * 8);
273 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.623, 0.001, "Not equal within tolerance");
274 snr = 10.5;
275 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate18Mbps"),
276 txVector,
277 std::pow(10.0, snr / 10.0),
278 frameSize * 8);
279 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.985, 0.001, "Not equal within tolerance");
280 snr = 11.5;
281 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate18Mbps"),
282 txVector,
283 std::pow(10.0, snr / 10.0),
284 frameSize * 8);
285 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.999, 0.001, "Not equal within tolerance");
286
287 snr = 12.0;
288 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate24Mbps"),
289 txVector,
290 std::pow(10.0, snr / 10.0),
291 frameSize * 8);
292 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 2.22e-7, 1e-7, "Not equal within tolerance");
293 snr = 13.0;
294 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate24Mbps"),
295 txVector,
296 std::pow(10.0, snr / 10.0),
297 frameSize * 8);
298 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.495, 0.001, "Not equal within tolerance");
299 snr = 14.0;
300 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate24Mbps"),
301 txVector,
302 std::pow(10.0, snr / 10.0),
303 frameSize * 8);
304 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.974, 0.001, "Not equal within tolerance");
305 snr = 15.0;
306 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate24Mbps"),
307 txVector,
308 std::pow(10.0, snr / 10.0),
309 frameSize * 8);
310 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.999, 0.001, "Not equal within tolerance");
311
312 snr = 15.5;
313 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate36Mbps"),
314 txVector,
315 std::pow(10.0, snr / 10.0),
316 frameSize * 8);
317 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.012, 0.001, "Not equal within tolerance");
318 snr = 16.5;
319 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate36Mbps"),
320 txVector,
321 std::pow(10.0, snr / 10.0),
322 frameSize * 8);
323 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.818, 0.001, "Not equal within tolerance");
324 snr = 17.5;
325 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate36Mbps"),
326 txVector,
327 std::pow(10.0, snr / 10.0),
328 frameSize * 8);
329 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.993, 0.001, "Not equal within tolerance");
330 snr = 18.5;
331 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate36Mbps"),
332 txVector,
333 std::pow(10.0, snr / 10.0),
334 frameSize * 8);
335 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.999, 0.001, "Not equal within tolerance");
336
337 snr = 20.0;
338 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate48Mbps"),
339 txVector,
340 std::pow(10.0, snr / 10.0),
341 frameSize * 8);
342 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 1.3e-4, 1e-4, "Not equal within tolerance");
343 snr = 21.0;
344 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate48Mbps"),
345 txVector,
346 std::pow(10.0, snr / 10.0),
347 frameSize * 8);
348 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.649, 0.001, "Not equal within tolerance");
349 snr = 22.0;
350 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate48Mbps"),
351 txVector,
352 std::pow(10.0, snr / 10.0),
353 frameSize * 8);
354 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.983, 0.001, "Not equal within tolerance");
355 snr = 23.0;
356 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate48Mbps"),
357 txVector,
358 std::pow(10.0, snr / 10.0),
359 frameSize * 8);
360 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.999, 0.001, "Not equal within tolerance");
361
362 snr = 21.0;
363 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate54Mbps"),
364 txVector,
365 std::pow(10.0, snr / 10.0),
366 frameSize * 8);
367 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 5.44e-8, 1e-8, "Not equal within tolerance");
368 snr = 22.0;
369 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate54Mbps"),
370 txVector,
371 std::pow(10.0, snr / 10.0),
372 frameSize * 8);
373 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.410, 0.001, "Not equal within tolerance");
374 snr = 23.0;
375 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate54Mbps"),
376 txVector,
377 std::pow(10.0, snr / 10.0),
378 frameSize * 8);
379 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.958, 0.001, "Not equal within tolerance");
380 snr = 24.0;
381 ps = nist->GetChunkSuccessRate(WifiMode("OfdmRate54Mbps"),
382 txVector,
383 std::pow(10.0, snr / 10.0),
384 frameSize * 8);
385 NS_TEST_ASSERT_MSG_EQ_TOL(ps, 0.999, 0.001, "Not equal within tolerance");
386}
387
394
395/**
396 * @ingroup wifi-test
397 * @ingroup tests
398 *
399 * @brief Wifi Error Rate Models Test Case MIMO
400 */
402{
403 public:
406
407 private:
408 void DoRun() override;
409};
410
412 : TestCase("WifiErrorRateModel test case MIMO")
413{
414}
415
419
420void
422{
423 TestInterferenceHelper interference;
424 interference.SetNoiseFigure(0);
425 WifiMode mode = HtPhy::GetHtMcs0();
426 WifiTxVector txVector;
427
428 txVector.SetMode(mode);
429 txVector.SetTxPowerLevel(0);
430 txVector.SetChannelWidth(20);
431 txVector.SetNss(1);
432 txVector.SetNTx(1);
433
434 interference.SetNumberOfReceiveAntennas(1);
436 interference.SetErrorRateModel(nist);
437
438 // SISO: initial SNR set to 4dB
439 dB_u initialSnr{4.0};
440 dB_u tol{0.1};
441 auto snr = interference.CalculateSnr(0.001,
442 0.001 / DbToRatio(initialSnr),
443 txVector.GetChannelWidth(),
444 txVector.GetNss());
446 initialSnr,
447 tol,
448 "Attempt to set initial SNR to known value failed");
449 Time duration = MilliSeconds(2);
450 auto chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
451 NS_TEST_ASSERT_MSG_EQ_TOL(chunkSuccess,
452 0.905685,
453 0.000001,
454 "CSR not within tolerance for SISO");
455 auto sisoChunkSuccess = chunkSuccess;
456
457 // MIMO 2x1:2: expect no SNR gain in AWGN channel
458 txVector.SetNss(2);
459 txVector.SetNTx(2);
460 snr = interference.CalculateSnr(0.001,
461 0.001 / DbToRatio(initialSnr),
462 txVector.GetChannelWidth(),
463 txVector.GetNss());
465 initialSnr,
466 tol,
467 "SNR not within tolerance for 2x1:2 MIMO");
468 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
469 NS_TEST_ASSERT_MSG_EQ_TOL(chunkSuccess,
470 0.905685,
471 0.000001,
472 "CSR not within tolerance for SISO");
473
474 // MIMO 1x2:1: expect that SNR is increased by a factor of 3 dB (10 log 2/1) compared to SISO
475 // thanks to RX diversity
476 txVector.SetNss(1);
477 txVector.SetNTx(1);
478 interference.SetNumberOfReceiveAntennas(2);
479 snr = interference.CalculateSnr(0.001,
480 0.001 / DbToRatio(initialSnr),
481 txVector.GetChannelWidth(),
482 txVector.GetNss());
484 initialSnr + static_cast<dB_u>(3.0),
485 tol,
486 "SNR not within tolerance for 1x2:1 MIMO");
487 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
488 NS_TEST_ASSERT_MSG_GT(chunkSuccess,
489 sisoChunkSuccess,
490 "CSR not within tolerance for 1x2:1 MIMO");
491
492 // MIMO 2x2:1: expect that SNR is increased by a factor of 3 dB (10 log 2/1) compared to SISO
493 // thanks to RX diversity
494 txVector.SetNss(1);
495 txVector.SetNTx(2);
496 interference.SetNumberOfReceiveAntennas(2);
497 snr = interference.CalculateSnr(0.001,
498 0.001 / DbToRatio(initialSnr),
499 txVector.GetChannelWidth(),
500 txVector.GetNss());
502 initialSnr + static_cast<dB_u>(3.0),
503 tol,
504 "SNR not equal within tolerance for 2x2:1 MIMO");
505 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
506 NS_TEST_ASSERT_MSG_GT(chunkSuccess,
507 sisoChunkSuccess,
508 "CSR not within tolerance for 2x2:1 MIMO");
509
510 // MIMO 2x2:2: expect no SNR gain in AWGN channel
511 txVector.SetNss(2);
512 txVector.SetNTx(2);
513 interference.SetNumberOfReceiveAntennas(2);
514 snr = interference.CalculateSnr(0.001,
515 0.001 / DbToRatio(initialSnr),
516 txVector.GetChannelWidth(),
517 txVector.GetNss());
519 initialSnr,
520 tol,
521 "SNR not equal within tolerance for 2x2:2 MIMO");
522 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
523 NS_TEST_ASSERT_MSG_EQ_TOL(chunkSuccess,
524 sisoChunkSuccess,
525 0.000001,
526 "CSR not within tolerance for 2x2:2 MIMO");
527
528 // MIMO 3x3:1: expect that SNR is increased by a factor of 4.8 dB (10 log 3/1) compared to SISO
529 // thanks to RX diversity
530 txVector.SetNss(1);
531 txVector.SetNTx(3);
532 interference.SetNumberOfReceiveAntennas(3);
533 snr = interference.CalculateSnr(0.001,
534 0.001 / DbToRatio(initialSnr),
535 txVector.GetChannelWidth(),
536 txVector.GetNss());
538 initialSnr + static_cast<dB_u>(4.8),
539 tol,
540 "SNR not within tolerance for 3x3:1 MIMO");
541 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
542 NS_TEST_ASSERT_MSG_GT(chunkSuccess,
543 sisoChunkSuccess,
544 "CSR not within tolerance for 3x3:1 MIMO");
545
546 // MIMO 3x3:2: expect that SNR is increased by a factor of 1.8 dB (10 log 3/2) compared to SISO
547 // thanks to RX diversity
548 txVector.SetNss(2);
549 txVector.SetNTx(3);
550 interference.SetNumberOfReceiveAntennas(3);
551 snr = interference.CalculateSnr(0.001,
552 0.001 / DbToRatio(initialSnr),
553 txVector.GetChannelWidth(),
554 txVector.GetNss());
556 initialSnr + static_cast<dB_u>(1.8),
557 tol,
558 "SNR not within tolerance for 3x3:2 MIMO");
559 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
560 NS_TEST_ASSERT_MSG_GT(chunkSuccess,
561 sisoChunkSuccess,
562 "CSR not within tolerance for 3x3:2 MIMO");
563
564 // MIMO 3x3:3: expect no SNR gain in AWGN channel
565 txVector.SetNss(3);
566 txVector.SetNTx(3);
567 interference.SetNumberOfReceiveAntennas(3);
568 snr = interference.CalculateSnr(0.001,
569 0.001 / DbToRatio(initialSnr),
570 txVector.GetChannelWidth(),
571 txVector.GetNss());
573 initialSnr,
574 tol,
575 "SNR not within tolerance for 3x3:3 MIMO");
576 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
577 NS_TEST_ASSERT_MSG_EQ_TOL(chunkSuccess,
578 sisoChunkSuccess,
579 0.000001,
580 "CSR not equal within tolerance for 3x3:3 MIMO");
581
582 // MIMO 4x4:1: expect that SNR is increased by a factor of 6 dB (10 log 4/1) compared to SISO
583 // thanks to RX diversity
584 txVector.SetNss(1);
585 txVector.SetNTx(4);
586 interference.SetNumberOfReceiveAntennas(4);
587 snr = interference.CalculateSnr(0.001,
588 0.001 / DbToRatio(initialSnr),
589 txVector.GetChannelWidth(),
590 txVector.GetNss());
592 initialSnr + static_cast<dB_u>(6.0),
593 tol,
594 "SNR not within tolerance for 4x4:1 MIMO");
595 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
596 NS_TEST_ASSERT_MSG_GT(chunkSuccess,
597 sisoChunkSuccess,
598 "CSR not within tolerance for 4x4:1 MIMO");
599
600 // MIMO 4x4:2: expect that SNR is increased by a factor of 3 dB (10 log 4/2) compared to SISO
601 // thanks to RX diversity
602 txVector.SetNss(2);
603 txVector.SetNTx(4);
604 interference.SetNumberOfReceiveAntennas(4);
605 snr = interference.CalculateSnr(0.001,
606 0.001 / DbToRatio(initialSnr),
607 txVector.GetChannelWidth(),
608 txVector.GetNss());
610 initialSnr + static_cast<dB_u>(3.0),
611 tol,
612 "SNR not within tolerance for 4x4:2 MIMO");
613 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
614 NS_TEST_ASSERT_MSG_GT(chunkSuccess,
615 sisoChunkSuccess,
616 "CSR not within tolerance for 4x4:2 MIMO");
617
618 // MIMO 4x4:3: expect that SNR is increased by a factor of 1.2 dB (10 log 4/3) compared to SISO
619 // thanks to RX diversity
620 txVector.SetNss(3);
621 txVector.SetNTx(4);
622 interference.SetNumberOfReceiveAntennas(4);
623 snr = interference.CalculateSnr(0.001,
624 0.001 / DbToRatio(initialSnr),
625 txVector.GetChannelWidth(),
626 txVector.GetNss());
628 initialSnr + static_cast<dB_u>(1.2),
629 tol,
630 "SNR not within tolerance for 4x4:3 MIMO");
631 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
632 NS_TEST_ASSERT_MSG_GT(chunkSuccess,
633 sisoChunkSuccess,
634 "CSR not within tolerance for 4x4:1 MIMO");
635
636 // MIMO 4x4:4: expect no SNR gain in AWGN channel
637 txVector.SetNss(4);
638 txVector.SetNTx(4);
639 interference.SetNumberOfReceiveAntennas(4);
640 snr = interference.CalculateSnr(0.001,
641 0.001 / DbToRatio(initialSnr),
642 txVector.GetChannelWidth(),
643 txVector.GetNss());
645 initialSnr,
646 tol,
647 "SNR not within tolerance for 4x4:4 MIMO");
648 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
649 NS_TEST_ASSERT_MSG_EQ_TOL(chunkSuccess,
650 sisoChunkSuccess,
651 0.000001,
652 "CSR not within tolerance for 4x4:4 MIMO");
653}
654
655/**
656 * map of PER values that have been manually computed for a given MCS, size (in bytes) and SNR (in
657 * dB) in order to verify against the PER calculated by the model
658 */
659std::map<std::pair<uint8_t /* mcs */, uint32_t /* size */>,
660 std::map<dB_u /* snr */, double /* per */>>
662 /* MCS 0 - 1458 bytes */
663 {std::make_pair(0, 1458),
664 {
665 {-4.00, 1.00000}, {-3.75, 1.00000}, {-3.50, 1.00000}, {-3.25, 1.00000},
666 {-3.00, 1.00000}, {-2.75, 1.00000}, {-2.50, 1.00000}, {-2.25, 1.00000},
667 {-2.00, 1.00000}, {-1.75, 1.00000}, {-1.50, 1.00000}, {-1.25, 1.00000},
668 {-1.00, 1.00000}, {-0.75, 0.99700}, {-0.50, 0.99400}, {-0.25, 0.90625},
669 {0.00, 0.81850}, {0.25, 0.55465}, {0.50, 0.29080}, {0.75, 0.17855},
670 {1.00, 0.06630}, {1.25, 0.03875}, {1.50, 0.01120}, {1.75, 0.00635},
671 {2.00, 0.00150}, {2.25, 0.00083}, {2.50, 0.00015}, {2.75, 0.00008},
672 {3.00, 0.00001}, {3.25, 0.00000}, {3.50, 0.00000}, {3.75, 0.00000},
673 {4.00, 0.00000}, {4.25, 0.00000}, {4.50, 0.00000}, {4.75, 0.00000},
674 {5.00, 0.00000}, {5.25, 0.00000}, {5.50, 0.00000}, {5.75, 0.00000},
675 {6.00, 0.00000}, {6.25, 0.00000}, {6.50, 0.00000}, {6.75, 0.00000},
676 {7.00, 0.00000}, {7.25, 0.00000}, {7.50, 0.00000}, {7.75, 0.00000},
677 {8.00, 0.00000}, {8.25, 0.00000}, {8.50, 0.00000}, {8.75, 0.00000},
678 {9.00, 0.00000}, {9.25, 0.00000}, {9.50, 0.00000}, {9.75, 0.00000},
679 {10.00, 0.00000}, {10.25, 0.00000}, {10.50, 0.00000}, {10.75, 0.00000},
680 {11.00, 0.00000}, {11.25, 0.00000}, {11.50, 0.00000}, {11.75, 0.00000},
681 {12.00, 0.00000}, {12.25, 0.00000}, {12.50, 0.00000}, {12.75, 0.00000},
682 {13.00, 0.00000}, {13.25, 0.00000}, {13.50, 0.00000}, {13.75, 0.00000},
683 {14.00, 0.00000}, {14.25, 0.00000}, {14.50, 0.00000}, {14.75, 0.00000},
684 {15.00, 0.00000}, {15.25, 0.00000}, {15.50, 0.00000}, {15.75, 0.00000},
685 {16.00, 0.00000}, {16.25, 0.00000}, {16.50, 0.00000}, {16.75, 0.00000},
686 {17.00, 0.00000}, {17.25, 0.00000}, {17.50, 0.00000}, {17.75, 0.00000},
687 {18.00, 0.00000}, {18.25, 0.00000}, {18.50, 0.00000}, {18.75, 0.00000},
688 {19.00, 0.00000}, {19.25, 0.00000}, {19.50, 0.00000}, {19.75, 0.00000},
689 {20.00, 0.00000}, {20.25, 0.00000}, {20.50, 0.00000}, {20.75, 0.00000},
690 {21.00, 0.00000}, {21.25, 0.00000}, {21.50, 0.00000}, {21.75, 0.00000},
691 {22.00, 0.00000}, {22.25, 0.00000}, {22.50, 0.00000}, {22.75, 0.00000},
692 {23.00, 0.00000}, {23.25, 0.00000}, {23.50, 0.00000}, {23.75, 0.00000},
693 {24.00, 0.00000}, {24.25, 0.00000}, {24.50, 0.00000}, {24.75, 0.00000},
694 {25.00, 0.00000}, {25.25, 0.00000}, {25.50, 0.00000}, {25.75, 0.00000},
695 {26.00, 0.00000}, {26.25, 0.00000}, {26.50, 0.00000}, {26.75, 0.00000},
696 {27.00, 0.00000}, {27.25, 0.00000}, {27.50, 0.00000}, {27.75, 0.00000},
697 {28.00, 0.00000}, {28.25, 0.00000}, {28.50, 0.00000}, {28.75, 0.00000},
698 {29.00, 0.00000}, {29.25, 0.00000}, {29.50, 0.00000}, {29.75, 0.00000},
699 {30.00, 0.00000},
700 }},
701 /* MCS 0 - 32 bytes */
702 {std::make_pair(0, 32),
703 {
704 {-4.00, 1.00000}, {-3.75, 1.00000}, {-3.50, 1.00000}, {-3.25, 0.99750},
705 {-3.00, 0.99500}, {-2.75, 0.96790}, {-2.50, 0.94080}, {-2.25, 0.88335},
706 {-2.00, 0.82590}, {-1.75, 0.70770}, {-1.50, 0.58950}, {-1.25, 0.44890},
707 {-1.00, 0.30830}, {-0.75, 0.21685}, {-0.50, 0.12540}, {-0.25, 0.07990},
708 {0.00, 0.03440}, {0.25, 0.02145}, {0.50, 0.00850}, {0.75, 0.00500},
709 {1.00, 0.00150}, {1.25, 0.00087}, {1.50, 0.00024}, {1.75, 0.00017},
710 {2.00, 0.00009}, {2.25, 0.00005}, {2.50, 0.00000}, {2.75, 0.00000},
711 {3.00, 0.00000}, {3.25, 0.00000}, {3.50, 0.00000}, {3.75, 0.00000},
712 {4.00, 0.00000}, {4.25, 0.00000}, {4.50, 0.00000}, {4.75, 0.00000},
713 {5.00, 0.00000}, {5.25, 0.00000}, {5.50, 0.00000}, {5.75, 0.00000},
714 {6.00, 0.00000}, {6.25, 0.00000}, {6.50, 0.00000}, {6.75, 0.00000},
715 {7.00, 0.00000}, {7.25, 0.00000}, {7.50, 0.00000}, {7.75, 0.00000},
716 {8.00, 0.00000}, {8.25, 0.00000}, {8.50, 0.00000}, {8.75, 0.00000},
717 {9.00, 0.00000}, {9.25, 0.00000}, {9.50, 0.00000}, {9.75, 0.00000},
718 {10.00, 0.00000}, {10.25, 0.00000}, {10.50, 0.00000}, {10.75, 0.00000},
719 {11.00, 0.00000}, {11.25, 0.00000}, {11.50, 0.00000}, {11.75, 0.00000},
720 {12.00, 0.00000}, {12.25, 0.00000}, {12.50, 0.00000}, {12.75, 0.00000},
721 {13.00, 0.00000}, {13.25, 0.00000}, {13.50, 0.00000}, {13.75, 0.00000},
722 {14.00, 0.00000}, {14.25, 0.00000}, {14.50, 0.00000}, {14.75, 0.00000},
723 {15.00, 0.00000}, {15.25, 0.00000}, {15.50, 0.00000}, {15.75, 0.00000},
724 {16.00, 0.00000}, {16.25, 0.00000}, {16.50, 0.00000}, {16.75, 0.00000},
725 {17.00, 0.00000}, {17.25, 0.00000}, {17.50, 0.00000}, {17.75, 0.00000},
726 {18.00, 0.00000}, {18.25, 0.00000}, {18.50, 0.00000}, {18.75, 0.00000},
727 {19.00, 0.00000}, {19.25, 0.00000}, {19.50, 0.00000}, {19.75, 0.00000},
728 {20.00, 0.00000}, {20.25, 0.00000}, {20.50, 0.00000}, {20.75, 0.00000},
729 {21.00, 0.00000}, {21.25, 0.00000}, {21.50, 0.00000}, {21.75, 0.00000},
730 {22.00, 0.00000}, {22.25, 0.00000}, {22.50, 0.00000}, {22.75, 0.00000},
731 {23.00, 0.00000}, {23.25, 0.00000}, {23.50, 0.00000}, {23.75, 0.00000},
732 {24.00, 0.00000}, {24.25, 0.00000}, {24.50, 0.00000}, {24.75, 0.00000},
733 {25.00, 0.00000}, {25.25, 0.00000}, {25.50, 0.00000}, {25.75, 0.00000},
734 {26.00, 0.00000}, {26.25, 0.00000}, {26.50, 0.00000}, {26.75, 0.00000},
735 {27.00, 0.00000}, {27.25, 0.00000}, {27.50, 0.00000}, {27.75, 0.00000},
736 {28.00, 0.00000}, {28.25, 0.00000}, {28.50, 0.00000}, {28.75, 0.00000},
737 {29.00, 0.00000}, {29.25, 0.00000}, {29.50, 0.00000}, {29.75, 0.00000},
738 {30.00, 0.00000},
739 }},
740 /* MCS 0 - 1000 bytes */
741 {std::make_pair(0, 1000),
742 {
743 {-4.00, 1.00000}, {-3.75, 1.00000}, {-3.50, 1.00000}, {-3.25, 1.00000},
744 {-3.00, 1.00000}, {-2.75, 1.00000}, {-2.50, 1.00000}, {-2.25, 1.00000},
745 {-2.00, 1.00000}, {-1.75, 1.00000}, {-1.50, 1.00000}, {-1.25, 1.00000},
746 {-1.00, 1.00000}, {-0.75, 0.98140}, {-0.50, 0.97007}, {-0.25, 0.80280},
747 {0.00, 0.68977}, {0.25, 0.42581}, {0.50, 0.20997}, {0.75, 0.12620},
748 {1.00, 0.04596}, {1.25, 0.02674}, {1.50, 0.00770}, {1.75, 0.00436},
749 {2.00, 0.00103}, {2.25, 0.00057}, {2.50, 0.00010}, {2.75, 0.00005},
750 {3.00, 0.00001}, {3.25, 0.00000}, {3.50, 0.00000}, {3.75, 0.00000},
751 {4.00, 0.00000}, {4.25, 0.00000}, {4.50, 0.00000}, {4.75, 0.00000},
752 {5.00, 0.00000}, {5.25, 0.00000}, {5.50, 0.00000}, {5.75, 0.00000},
753 {6.00, 0.00000}, {6.25, 0.00000}, {6.50, 0.00000}, {6.75, 0.00000},
754 {7.00, 0.00000}, {7.25, 0.00000}, {7.50, 0.00000}, {7.75, 0.00000},
755 {8.00, 0.00000}, {8.25, 0.00000}, {8.50, 0.00000}, {8.75, 0.00000},
756 {9.00, 0.00000}, {9.25, 0.00000}, {9.50, 0.00000}, {9.75, 0.00000},
757 {10.00, 0.00000}, {10.25, 0.00000}, {10.50, 0.00000}, {10.75, 0.00000},
758 {11.00, 0.00000}, {11.25, 0.00000}, {11.50, 0.00000}, {11.75, 0.00000},
759 {12.00, 0.00000}, {12.25, 0.00000}, {12.50, 0.00000}, {12.75, 0.00000},
760 {13.00, 0.00000}, {13.25, 0.00000}, {13.50, 0.00000}, {13.75, 0.00000},
761 {14.00, 0.00000}, {14.25, 0.00000}, {14.50, 0.00000}, {14.75, 0.00000},
762 {15.00, 0.00000}, {15.25, 0.00000}, {15.50, 0.00000}, {15.75, 0.00000},
763 {16.00, 0.00000}, {16.25, 0.00000}, {16.50, 0.00000}, {16.75, 0.00000},
764 {17.00, 0.00000}, {17.25, 0.00000}, {17.50, 0.00000}, {17.75, 0.00000},
765 {18.00, 0.00000}, {18.25, 0.00000}, {18.50, 0.00000}, {18.75, 0.00000},
766 {19.00, 0.00000}, {19.25, 0.00000}, {19.50, 0.00000}, {19.75, 0.00000},
767 {20.00, 0.00000}, {20.25, 0.00000}, {20.50, 0.00000}, {20.75, 0.00000},
768 {21.00, 0.00000}, {21.25, 0.00000}, {21.50, 0.00000}, {21.75, 0.00000},
769 {22.00, 0.00000}, {22.25, 0.00000}, {22.50, 0.00000}, {22.75, 0.00000},
770 {23.00, 0.00000}, {23.25, 0.00000}, {23.50, 0.00000}, {23.75, 0.00000},
771 {24.00, 0.00000}, {24.25, 0.00000}, {24.50, 0.00000}, {24.75, 0.00000},
772 {25.00, 0.00000}, {25.25, 0.00000}, {25.50, 0.00000}, {25.75, 0.00000},
773 {26.00, 0.00000}, {26.25, 0.00000}, {26.50, 0.00000}, {26.75, 0.00000},
774 {27.00, 0.00000}, {27.25, 0.00000}, {27.50, 0.00000}, {27.75, 0.00000},
775 {28.00, 0.00000}, {28.25, 0.00000}, {28.50, 0.00000}, {28.75, 0.00000},
776 {29.00, 0.00000}, {29.25, 0.00000}, {29.50, 0.00000}, {29.75, 0.00000},
777 {30.00, 0.00000},
778 }},
779 /* MCS 0 - 1 byte */
780 {std::make_pair(0, 1),
781 {
782 {-4.00, 1.00000}, {-3.75, 1.00000}, {-3.50, 1.00000}, {-3.25, 0.17075},
783 {-3.00, 0.15260}, {-2.75, 0.10190}, {-2.50, 0.08455}, {-2.25, 0.06494},
784 {-2.00, 0.05316}, {-1.75, 0.03771}, {-1.50, 0.02744}, {-1.25, 0.01845},
785 {-1.00, 0.01145}, {-0.75, 0.00761}, {-0.50, 0.00418}, {-0.25, 0.00260},
786 {0.00, 0.00110}, {0.25, 0.00068}, {0.50, 0.00027}, {0.75, 0.00016},
787 {1.00, 0.00005}, {1.25, 0.00003}, {1.50, 0.00000}, {1.75, 0.00000},
788 {2.00, 0.00000}, {2.25, 0.00000}, {2.50, 0.00000}, {2.75, 0.00000},
789 {3.00, 0.00000}, {3.25, 0.00000}, {3.50, 0.00000}, {3.75, 0.00000},
790 {4.00, 0.00000}, {4.25, 0.00000}, {4.50, 0.00000}, {4.75, 0.00000},
791 {5.00, 0.00000}, {5.25, 0.00000}, {5.50, 0.00000}, {5.75, 0.00000},
792 {6.00, 0.00000}, {6.25, 0.00000}, {6.50, 0.00000}, {6.75, 0.00000},
793 {7.00, 0.00000}, {7.25, 0.00000}, {7.50, 0.00000}, {7.75, 0.00000},
794 {8.00, 0.00000}, {8.25, 0.00000}, {8.50, 0.00000}, {8.75, 0.00000},
795 {9.00, 0.00000}, {9.25, 0.00000}, {9.50, 0.00000}, {9.75, 0.00000},
796 {10.00, 0.00000}, {10.25, 0.00000}, {10.50, 0.00000}, {10.75, 0.00000},
797 {11.00, 0.00000}, {11.25, 0.00000}, {11.50, 0.00000}, {11.75, 0.00000},
798 {12.00, 0.00000}, {12.25, 0.00000}, {12.50, 0.00000}, {12.75, 0.00000},
799 {13.00, 0.00000}, {13.25, 0.00000}, {13.50, 0.00000}, {13.75, 0.00000},
800 {14.00, 0.00000}, {14.25, 0.00000}, {14.50, 0.00000}, {14.75, 0.00000},
801 {15.00, 0.00000}, {15.25, 0.00000}, {15.50, 0.00000}, {15.75, 0.00000},
802 {16.00, 0.00000}, {16.25, 0.00000}, {16.50, 0.00000}, {16.75, 0.00000},
803 {17.00, 0.00000}, {17.25, 0.00000}, {17.50, 0.00000}, {17.75, 0.00000},
804 {18.00, 0.00000}, {18.25, 0.00000}, {18.50, 0.00000}, {18.75, 0.00000},
805 {19.00, 0.00000}, {19.25, 0.00000}, {19.50, 0.00000}, {19.75, 0.00000},
806 {20.00, 0.00000}, {20.25, 0.00000}, {20.50, 0.00000}, {20.75, 0.00000},
807 {21.00, 0.00000}, {21.25, 0.00000}, {21.50, 0.00000}, {21.75, 0.00000},
808 {22.00, 0.00000}, {22.25, 0.00000}, {22.50, 0.00000}, {22.75, 0.00000},
809 {23.00, 0.00000}, {23.25, 0.00000}, {23.50, 0.00000}, {23.75, 0.00000},
810 {24.00, 0.00000}, {24.25, 0.00000}, {24.50, 0.00000}, {24.75, 0.00000},
811 {25.00, 0.00000}, {25.25, 0.00000}, {25.50, 0.00000}, {25.75, 0.00000},
812 {26.00, 0.00000}, {26.25, 0.00000}, {26.50, 0.00000}, {26.75, 0.00000},
813 {27.00, 0.00000}, {27.25, 0.00000}, {27.50, 0.00000}, {27.75, 0.00000},
814 {28.00, 0.00000}, {28.25, 0.00000}, {28.50, 0.00000}, {28.75, 0.00000},
815 {29.00, 0.00000}, {29.25, 0.00000}, {29.50, 0.00000}, {29.75, 0.00000},
816 {30.00, 0.00000},
817 }},
818 /* MCS 0 - 2000 bytes */
819 {std::make_pair(0, 2000),
820 {
821 {-4.00, 1.00000}, {-3.75, 1.00000}, {-3.50, 1.00000}, {-3.25, 1.00000},
822 {-3.00, 1.00000}, {-2.75, 1.00000}, {-2.50, 1.00000}, {-2.25, 1.00000},
823 {-2.00, 1.00000}, {-1.75, 1.00000}, {-1.50, 1.00000}, {-1.25, 1.00000},
824 {-1.00, 1.00000}, {-0.75, 0.99965}, {-0.50, 0.99910}, {-0.25, 0.96111},
825 {0.00, 0.90376}, {0.25, 0.67031}, {0.50, 0.37584}, {0.75, 0.23647},
826 {1.00, 0.08981}, {1.25, 0.05277}, {1.50, 0.01533}, {1.75, 0.00870},
827 {2.00, 0.00206}, {2.25, 0.00113}, {2.50, 0.00021}, {2.75, 0.00011},
828 {3.00, 0.00001}, {3.25, 0.00000}, {3.50, 0.00000}, {3.75, 0.00000},
829 {4.00, 0.00000}, {4.25, 0.00000}, {4.50, 0.00000}, {4.75, 0.00000},
830 {5.00, 0.00000}, {5.25, 0.00000}, {5.50, 0.00000}, {5.75, 0.00000},
831 {6.00, 0.00000}, {6.25, 0.00000}, {6.50, 0.00000}, {6.75, 0.00000},
832 {7.00, 0.00000}, {7.25, 0.00000}, {7.50, 0.00000}, {7.75, 0.00000},
833 {8.00, 0.00000}, {8.25, 0.00000}, {8.50, 0.00000}, {8.75, 0.00000},
834 {9.00, 0.00000}, {9.25, 0.00000}, {9.50, 0.00000}, {9.75, 0.00000},
835 {10.00, 0.00000}, {10.25, 0.00000}, {10.50, 0.00000}, {10.75, 0.00000},
836 {11.00, 0.00000}, {11.25, 0.00000}, {11.50, 0.00000}, {11.75, 0.00000},
837 {12.00, 0.00000}, {12.25, 0.00000}, {12.50, 0.00000}, {12.75, 0.00000},
838 {13.00, 0.00000}, {13.25, 0.00000}, {13.50, 0.00000}, {13.75, 0.00000},
839 {14.00, 0.00000}, {14.25, 0.00000}, {14.50, 0.00000}, {14.75, 0.00000},
840 {15.00, 0.00000}, {15.25, 0.00000}, {15.50, 0.00000}, {15.75, 0.00000},
841 {16.00, 0.00000}, {16.25, 0.00000}, {16.50, 0.00000}, {16.75, 0.00000},
842 {17.00, 0.00000}, {17.25, 0.00000}, {17.50, 0.00000}, {17.75, 0.00000},
843 {18.00, 0.00000}, {18.25, 0.00000}, {18.50, 0.00000}, {18.75, 0.00000},
844 {19.00, 0.00000}, {19.25, 0.00000}, {19.50, 0.00000}, {19.75, 0.00000},
845 {20.00, 0.00000}, {20.25, 0.00000}, {20.50, 0.00000}, {20.75, 0.00000},
846 {21.00, 0.00000}, {21.25, 0.00000}, {21.50, 0.00000}, {21.75, 0.00000},
847 {22.00, 0.00000}, {22.25, 0.00000}, {22.50, 0.00000}, {22.75, 0.00000},
848 {23.00, 0.00000}, {23.25, 0.00000}, {23.50, 0.00000}, {23.75, 0.00000},
849 {24.00, 0.00000}, {24.25, 0.00000}, {24.50, 0.00000}, {24.75, 0.00000},
850 {25.00, 0.00000}, {25.25, 0.00000}, {25.50, 0.00000}, {25.75, 0.00000},
851 {26.00, 0.00000}, {26.25, 0.00000}, {26.50, 0.00000}, {26.75, 0.00000},
852 {27.00, 0.00000}, {27.25, 0.00000}, {27.50, 0.00000}, {27.75, 0.00000},
853 {28.00, 0.00000}, {28.25, 0.00000}, {28.50, 0.00000}, {28.75, 0.00000},
854 {29.00, 0.00000}, {29.25, 0.00000}, {29.50, 0.00000}, {29.75, 0.00000},
855 {30.00, 0.00000},
856 }},
857 /* MCS 7 - 1500 bytes */
858 {std::make_pair(7, 1500),
859 {
860 {-4.00, 1.00000}, {-3.75, 1.00000}, {-3.50, 1.00000}, {-3.25, 1.00000},
861 {-3.00, 1.00000}, {-2.75, 1.00000}, {-2.50, 1.00000}, {-2.25, 1.00000},
862 {-2.00, 1.00000}, {-1.75, 1.00000}, {-1.50, 1.00000}, {-1.25, 1.00000},
863 {-1.00, 1.00000}, {-0.75, 1.00000}, {-0.50, 1.00000}, {-0.25, 1.00000},
864 {0.00, 1.00000}, {0.25, 1.00000}, {0.50, 1.00000}, {0.75, 1.00000},
865 {1.00, 1.00000}, {1.25, 1.00000}, {1.50, 1.00000}, {1.75, 1.00000},
866 {2.00, 1.00000}, {2.25, 1.00000}, {2.50, 1.00000}, {2.75, 1.00000},
867 {3.00, 1.00000}, {3.25, 1.00000}, {3.50, 1.00000}, {3.75, 1.00000},
868 {4.00, 1.00000}, {4.25, 1.00000}, {4.50, 1.00000}, {4.75, 1.00000},
869 {5.00, 1.00000}, {5.25, 1.00000}, {5.50, 1.00000}, {5.75, 1.00000},
870 {6.00, 1.00000}, {6.25, 1.00000}, {6.50, 1.00000}, {6.75, 1.00000},
871 {7.00, 1.00000}, {7.25, 1.00000}, {7.50, 1.00000}, {7.75, 1.00000},
872 {8.00, 1.00000}, {8.25, 1.00000}, {8.50, 1.00000}, {8.75, 1.00000},
873 {9.00, 1.00000}, {9.25, 1.00000}, {9.50, 1.00000}, {9.75, 1.00000},
874 {10.00, 1.00000}, {10.25, 1.00000}, {10.50, 1.00000}, {10.75, 1.00000},
875 {11.00, 1.00000}, {11.25, 1.00000}, {11.50, 1.00000}, {11.75, 1.00000},
876 {12.00, 1.00000}, {12.25, 1.00000}, {12.50, 1.00000}, {12.75, 1.00000},
877 {13.00, 1.00000}, {13.25, 1.00000}, {13.50, 1.00000}, {13.75, 1.00000},
878 {14.00, 1.00000}, {14.25, 1.00000}, {14.50, 1.00000}, {14.75, 1.00000},
879 {15.00, 1.00000}, {15.25, 1.00000}, {15.50, 1.00000}, {15.75, 1.00000},
880 {16.00, 1.00000}, {16.25, 1.00000}, {16.50, 1.00000}, {16.75, 1.00000},
881 {17.00, 1.00000}, {17.25, 1.00000}, {17.50, 1.00000}, {17.75, 0.99057},
882 {18.00, 0.98075}, {18.25, 0.86664}, {18.50, 0.74920}, {18.75, 0.54857},
883 {19.00, 0.34531}, {19.25, 0.23624}, {19.50, 0.12672}, {19.75, 0.08164},
884 {20.00, 0.03650}, {20.25, 0.02340}, {20.50, 0.01029}, {20.75, 0.00653},
885 {21.00, 0.00278}, {21.25, 0.00165}, {21.50, 0.00051}, {21.75, 0.00030},
886 {22.00, 0.00009}, {22.25, 0.00005}, {22.50, 0.00001}, {22.75, 0.00000},
887 {23.00, 0.00000}, {23.25, 0.00000}, {23.50, 0.00000}, {23.75, 0.00000},
888 {24.00, 0.00000}, {24.25, 0.00000}, {24.50, 0.00000}, {24.75, 0.00000},
889 {25.00, 0.00000}, {25.25, 0.00000}, {25.50, 0.00000}, {25.75, 0.00000},
890 {26.00, 0.00000}, {26.25, 0.00000}, {26.50, 0.00000}, {26.75, 0.00000},
891 {27.00, 0.00000}, {27.25, 0.00000}, {27.50, 0.00000}, {27.75, 0.00000},
892 {28.00, 0.00000}, {28.25, 0.00000}, {28.50, 0.00000}, {28.75, 0.00000},
893 {29.00, 0.00000}, {29.25, 0.00000}, {29.50, 0.00000}, {29.75, 0.00000},
894 {30.00, 0.00000},
895 }},
896 /* MCS 8 - 1500 bytes */
897 {std::make_pair(8, 1500),
898 {
899 {-4.00, 1.00000}, {-3.75, 1.00000}, {-3.50, 1.00000}, {-3.25, 1.00000},
900 {-3.00, 1.00000}, {-2.75, 1.00000}, {-2.50, 1.00000}, {-2.25, 1.00000},
901 {-2.00, 1.00000}, {-1.75, 1.00000}, {-1.50, 1.00000}, {-1.25, 1.00000},
902 {-1.00, 1.00000}, {-0.75, 1.00000}, {-0.50, 1.00000}, {-0.25, 1.00000},
903 {0.00, 1.00000}, {0.25, 1.00000}, {0.50, 1.00000}, {0.75, 1.00000},
904 {1.00, 1.00000}, {1.25, 1.00000}, {1.50, 1.00000}, {1.75, 1.00000},
905 {2.00, 1.00000}, {2.25, 1.00000}, {2.50, 1.00000}, {2.75, 1.00000},
906 {3.00, 1.00000}, {3.25, 1.00000}, {3.50, 1.00000}, {3.75, 1.00000},
907 {4.00, 1.00000}, {4.25, 1.00000}, {4.50, 1.00000}, {4.75, 1.00000},
908 {5.00, 1.00000}, {5.25, 1.00000}, {5.50, 1.00000}, {5.75, 1.00000},
909 {6.00, 1.00000}, {6.25, 1.00000}, {6.50, 1.00000}, {6.75, 1.00000},
910 {7.00, 1.00000}, {7.25, 1.00000}, {7.50, 1.00000}, {7.75, 1.00000},
911 {8.00, 1.00000}, {8.25, 1.00000}, {8.50, 1.00000}, {8.75, 1.00000},
912 {9.00, 1.00000}, {9.25, 1.00000}, {9.50, 1.00000}, {9.75, 1.00000},
913 {10.00, 1.00000}, {10.25, 1.00000}, {10.50, 1.00000}, {10.75, 1.00000},
914 {11.00, 1.00000}, {11.25, 1.00000}, {11.50, 1.00000}, {11.75, 1.00000},
915 {12.00, 1.00000}, {12.25, 1.00000}, {12.50, 1.00000}, {12.75, 1.00000},
916 {13.00, 1.00000}, {13.25, 1.00000}, {13.50, 1.00000}, {13.75, 1.00000},
917 {14.00, 1.00000}, {14.25, 1.00000}, {14.50, 1.00000}, {14.75, 1.00000},
918 {15.00, 1.00000}, {15.25, 1.00000}, {15.50, 1.00000}, {15.75, 1.00000},
919 {16.00, 1.00000}, {16.25, 1.00000}, {16.50, 1.00000}, {16.75, 1.00000},
920 {17.00, 1.00000}, {17.25, 1.00000}, {17.50, 1.00000}, {17.75, 1.00000},
921 {18.00, 1.00000}, {18.25, 1.00000}, {18.50, 1.00000}, {18.75, 1.00000},
922 {19.00, 1.00000}, {19.25, 1.00000}, {19.50, 1.00000}, {19.75, 1.00000},
923 {20.00, 1.00000}, {20.25, 1.00000}, {20.50, 1.00000}, {20.75, 1.00000},
924 {21.00, 1.00000}, {21.25, 0.99918}, {21.50, 0.99833}, {21.75, 0.97191},
925 {22.00, 0.94458}, {22.25, 0.81436}, {22.50, 0.68127}, {22.75, 0.52168},
926 {23.00, 0.36056}, {23.25, 0.25114}, {23.50, 0.14127}, {23.75, 0.09509},
927 {24.00, 0.04883}, {24.25, 0.03234}, {24.50, 0.01584}, {24.75, 0.01060},
928 {25.00, 0.00535}, {25.25, 0.00345}, {25.50, 0.00154}, {25.75, 0.00096},
929 {26.00, 0.00037}, {26.25, 0.00022}, {26.50, 0.00007}, {26.75, 0.00004},
930 {27.00, 0.00000}, {27.25, 0.00000}, {27.50, 0.00000}, {27.75, 0.00000},
931 {28.00, 0.00000}, {28.25, 0.00000}, {28.50, 0.00000}, {28.75, 0.00000},
932 {29.00, 0.00000}, {29.25, 0.00000}, {29.50, 0.00000}, {29.75, 0.00000},
933 {30.00, 0.00000},
934 }},
935};
936
937/**
938 * @ingroup wifi-test
939 * @ingroup tests
940 *
941 * @brief Wifi Table-based Error Rate Models Test Case
942 */
944{
945 public:
946 /**
947 * Constructor
948 *
949 * @param testName the test name
950 * @param mode the WifiMode to use for the test
951 * @param size the number of bytes to use for the test
952 */
953 TableBasedErrorRateTestCase(const std::string& testName, WifiMode mode, uint32_t size);
955
956 private:
957 void DoRun() override;
958
959 std::string m_testName; ///< The name of the test to run
960 WifiMode m_mode; ///< The WifiMode to test
961 uint32_t m_size; ///< The size (in bytes) to test
962};
963
965 WifiMode mode,
966 uint32_t size)
967 : TestCase(testName),
968 m_testName(testName),
969 m_mode(mode),
970 m_size(size)
971{
972}
973
977
978void
980{
981 // LogComponentEnable ("WifiErrorRateModelsTest", LOG_LEVEL_ALL);
982 // LogComponentEnable ("TableBasedErrorRateModel", LOG_LEVEL_ALL);
983 // LogComponentEnable ("YansErrorRateModel", LOG_LEVEL_ALL);
984
986 WifiTxVector txVector;
987 txVector.SetMode(m_mode);
988
989 // Spot test some values returned from TableBasedErrorRateModel
990 for (dB_u snr = -4; snr <= dB_u{30}; snr += dB_u{0.25})
991 {
992 double expectedValue = 0;
994 {
996 expectedValue =
997 1 - yans->GetChunkSuccessRate(m_mode, txVector, std::pow(10, snr / 10), m_size * 8);
998 }
999 else
1000 {
1001 auto it = expectedTableValues.find(std::make_pair(m_mode.GetMcsValue(), m_size));
1002 if (it != expectedTableValues.end())
1003 {
1004 auto itValue = it->second.find(snr);
1005 if (itValue != it->second.end())
1006 {
1007 expectedValue = itValue->second;
1008 }
1009 else
1010 {
1011 NS_FATAL_ERROR("SNR value " << snr << " dB not found!");
1012 }
1013 }
1014 else
1015 {
1016 NS_FATAL_ERROR("No expected value found for the combination MCS "
1017 << +m_mode.GetMcsValue() << " and size " << m_size << " bytes");
1018 }
1019 }
1020 const auto per =
1021 1 - table->GetChunkSuccessRate(m_mode, txVector, std::pow(10, snr / 10), m_size * 8);
1022 NS_LOG_INFO(m_testName << ": snr=" << snr << "dB per=" << per
1023 << " expectedPER=" << expectedValue);
1024 NS_TEST_ASSERT_MSG_EQ_TOL(per, expectedValue, 1e-5, "Not equal within tolerance");
1025 }
1026}
1027
1028/**
1029 * @ingroup wifi-test
1030 * @ingroup tests
1031 *
1032 * @brief Wifi Error Rate Models Test Suite
1033 */
1035{
1036 public:
1038};
1039
1041 : TestSuite("wifi-error-rate-models", Type::UNIT)
1042{
1043 AddTestCase(new WifiErrorRateModelsTestCaseDsss, TestCase::Duration::QUICK);
1044 AddTestCase(new WifiErrorRateModelsTestCaseNist, TestCase::Duration::QUICK);
1045 AddTestCase(new WifiErrorRateModelsTestCaseMimo, TestCase::Duration::QUICK);
1046 AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedHtMcs0-1458bytes",
1048 1458),
1049 TestCase::Duration::QUICK);
1051 new TableBasedErrorRateTestCase("DefaultTableBasedHtMcs0-32bytes", HtPhy::GetHtMcs0(), 32),
1052 TestCase::Duration::QUICK);
1053 AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedHtMcs0-1000bytes",
1055 1000),
1056 TestCase::Duration::QUICK);
1058 new TableBasedErrorRateTestCase("DefaultTableBasedHtMcs0-1byte", HtPhy::GetHtMcs0(), 1),
1059 TestCase::Duration::QUICK);
1060 AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedHtMcs0-2000bytes",
1062 2000),
1063 TestCase::Duration::QUICK);
1064 AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedHtMcs7-1500bytes",
1066 1500),
1067 TestCase::Duration::QUICK);
1068 AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedVhtMcs0-1458bytes",
1070 1458),
1071 TestCase::Duration::QUICK);
1072 AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedVhtMcs0-32bytes",
1074 32),
1075 TestCase::Duration::QUICK);
1076 AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedVhtMcs0-1000bytes",
1078 1000),
1079 TestCase::Duration::QUICK);
1081 new TableBasedErrorRateTestCase("DefaultTableBasedVhtMcs0-1byte", VhtPhy::GetVhtMcs0(), 1),
1082 TestCase::Duration::QUICK);
1083 AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedVhtMcs0-2000bytes",
1085 2000),
1086 TestCase::Duration::QUICK);
1087 AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedVhtMcs8-1500bytes",
1089 1500),
1090 TestCase::Duration::QUICK);
1091 AddTestCase(new TableBasedErrorRateTestCase("FallbackTableBasedHeMcs11-1458bytes",
1093 1458),
1094 TestCase::Duration::QUICK);
1095}
1096
Wifi Table-based Error Rate Models Test Case.
void DoRun() override
Implementation to actually run this TestCase.
WifiMode m_mode
The WifiMode to test.
uint32_t m_size
The size (in bytes) to test.
TableBasedErrorRateTestCase(const std::string &testName, WifiMode mode, uint32_t size)
Constructor.
std::string m_testName
The name of the test to run.
double CalculatePayloadChunkSuccessRate(double snir, Time duration, const WifiTxVector &txVector, uint16_t staId=SU_STA_ID) const
Calculate the success rate of the payload chunk given the SINR, duration, and TXVECTOR.
double CalculateSnr(Ptr< Event > event, MHz_u channelWidth, uint8_t nss, const WifiSpectrumBandInfo &band) const
Calculate the SNIR for the event (starting from now until the event end).
Wifi Error Rate Models Test Case Dsss.
void DoRun() override
Implementation to actually run this TestCase.
Wifi Error Rate Models Test Case MIMO.
void DoRun() override
Implementation to actually run this TestCase.
Wifi Error Rate Models Test Case Nist.
void DoRun() override
Implementation to actually run this TestCase.
Wifi Error Rate Models Test Suite.
static double GetDsssDqpskSuccessRate(double sinr, uint64_t nbits)
Return the chunk success rate of the differential encoded QPSK.
static double GetDsssDbpskSuccessRate(double sinr, uint64_t nbits)
Return the chunk success rate of the differential BPSK.
static double GetDsssDqpskCck5_5SuccessRate(double sinr, uint64_t nbits)
Return the chunk success rate of the differential encoded QPSK for 5.5Mbps data rate.
static double GetDsssDqpskCck11SuccessRate(double sinr, uint64_t nbits)
Return the chunk success rate of the differential encoded QPSK for 11Mbps data rate.
static WifiMode GetHeMcs11()
Return MCS 11 from HE MCS values.
static WifiMode GetHtMcs0()
Return MCS 0 from HT MCS values.
static WifiMode GetHtMcs7()
Return MCS 7 from HT MCS values.
handles interference calculations
void SetNoiseFigure(double value)
Set the noise figure.
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Set the error rate model for this interference helper.
double CalculatePayloadChunkSuccessRate(double snir, Time duration, const WifiTxVector &txVector, uint16_t staId=SU_STA_ID) const
Calculate the success rate of the payload chunk given the SINR, duration, and TXVECTOR.
void SetNumberOfReceiveAntennas(uint8_t rx)
Set the number of RX antennas in the receiver corresponding to this interference helper.
double CalculateSnr(Ptr< Event > event, MHz_u channelWidth, uint8_t nss, const WifiSpectrumBandInfo &band) const
Calculate the SNIR for the event (starting from now until the event end).
Smart pointer class similar to boost::intrusive_ptr.
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
static WifiMode GetVhtMcs0()
Return MCS 0 from VHT MCS values.
static WifiMode GetVhtMcs8()
Return MCS 8 from VHT MCS values.
represent a single transmission mode
Definition wifi-mode.h:40
uint8_t GetMcsValue() const
Definition wifi-mode.cc:152
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetTxPowerLevel(uint8_t powerlevel)
Sets the selected transmission power level.
void SetChannelWidth(MHz_u channelWidth)
Sets the selected channelWidth.
uint8_t GetNss(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the number of spatial streams.
MHz_u GetChannelWidth() const
void SetNTx(uint8_t nTx)
Sets the number of TX antennas.
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
void SetNss(uint8_t nss)
Sets the number of Nss.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#define NS_TEST_ASSERT_MSG_GT(actual, limit, msg)
Test that an actual value is greater than a limit and report and abort if not.
Definition test.h:864
#define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report and...
Definition test.h:327
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1356
Every class exported by the ns3 library is enclosed in the ns3 namespace.
dB_u RatioToDb(double ratio)
Convert from ratio to dB.
Definition wifi-utils.cc:44
const uint8_t ERROR_TABLE_BCC_MAX_NUM_MCS
maximum number of MCSs for BCC
double DbToRatio(dB_u val)
Convert from dB to ratio.
Definition wifi-utils.cc:25
static double FromRss(dBW_u rss)
std::map< std::pair< uint8_t, uint32_t >, std::map< dB_u, double > > expectedTableValues
map of PER values that have been manually computed for a given MCS, size (in bytes) and SNR (in dB) i...
static WifiErrorRateModelsTestSuite wifiErrorRateModelsTestSuite
the test suite