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