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:
407};
408
416{
417 public:
420
421 private:
422 void DoRun() override;
423};
424
426 : TestCase("WifiErrorRateModel test case MIMO")
427{
428}
429
431{
432}
433
434void
436{
437 TestInterferenceHelper interference;
438 interference.SetNoiseFigure(0);
439 WifiMode mode = HtPhy::GetHtMcs0();
440 WifiTxVector txVector;
441
442 txVector.SetMode(mode);
443 txVector.SetTxPowerLevel(0);
444 txVector.SetChannelWidth(20);
445 txVector.SetNss(1);
446 txVector.SetNTx(1);
447
448 interference.SetNumberOfReceiveAntennas(1);
449 Ptr<NistErrorRateModel> nist = CreateObject<NistErrorRateModel>();
450 interference.SetErrorRateModel(nist);
451
452 // SISO: initial SNR set to 4dB
453 double initialSnr = 4.0;
454 double snr = interference.CalculateSnr(0.001,
455 0.001 / DbToRatio(initialSnr),
456 txVector.GetChannelWidth(),
457 txVector.GetNss());
459 initialSnr,
460 0.1,
461 "Attempt to set initial SNR to known value failed");
462 Time duration = MilliSeconds(2);
463 double chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
464 NS_TEST_ASSERT_MSG_EQ_TOL(chunkSuccess,
465 0.905685,
466 0.000001,
467 "CSR not within tolerance for SISO");
468 double sisoChunkSuccess = chunkSuccess;
469
470 // MIMO 2x1:2: expect no SNR gain in AWGN channel
471 txVector.SetNss(2);
472 txVector.SetNTx(2);
473 snr = interference.CalculateSnr(0.001,
474 0.001 / DbToRatio(initialSnr),
475 txVector.GetChannelWidth(),
476 txVector.GetNss());
478 initialSnr,
479 0.1,
480 "SNR not within tolerance for 2x1:2 MIMO");
481 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
482 NS_TEST_ASSERT_MSG_EQ_TOL(chunkSuccess,
483 0.905685,
484 0.000001,
485 "CSR not within tolerance for SISO");
486
487 // MIMO 1x2:1: expect that SNR is increased by a factor of 3 dB (10 log 2/1) compared to SISO
488 // thanks to RX diversity
489 txVector.SetNss(1);
490 txVector.SetNTx(1);
491 interference.SetNumberOfReceiveAntennas(2);
492 snr = interference.CalculateSnr(0.001,
493 0.001 / DbToRatio(initialSnr),
494 txVector.GetChannelWidth(),
495 txVector.GetNss());
497 initialSnr + 3,
498 0.1,
499 "SNR not within tolerance for 1x2:1 MIMO");
500 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
501 NS_TEST_ASSERT_MSG_GT(chunkSuccess,
502 sisoChunkSuccess,
503 "CSR not within tolerance for 1x2:1 MIMO");
504
505 // MIMO 2x2:1: expect that SNR is increased by a factor of 3 dB (10 log 2/1) compared to SISO
506 // thanks to RX diversity
507 txVector.SetNss(1);
508 txVector.SetNTx(2);
509 interference.SetNumberOfReceiveAntennas(2);
510 snr = interference.CalculateSnr(0.001,
511 0.001 / DbToRatio(initialSnr),
512 txVector.GetChannelWidth(),
513 txVector.GetNss());
515 initialSnr + 3,
516 0.1,
517 "SNR not equal within tolerance for 2x2:1 MIMO");
518 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
519 NS_TEST_ASSERT_MSG_GT(chunkSuccess,
520 sisoChunkSuccess,
521 "CSR not within tolerance for 2x2:1 MIMO");
522
523 // MIMO 2x2:2: expect no SNR gain in AWGN channel
524 txVector.SetNss(2);
525 txVector.SetNTx(2);
526 interference.SetNumberOfReceiveAntennas(2);
527 snr = interference.CalculateSnr(0.001,
528 0.001 / DbToRatio(initialSnr),
529 txVector.GetChannelWidth(),
530 txVector.GetNss());
532 initialSnr,
533 0.1,
534 "SNR not equal within tolerance for 2x2:2 MIMO");
535 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
536 NS_TEST_ASSERT_MSG_EQ_TOL(chunkSuccess,
537 sisoChunkSuccess,
538 0.000001,
539 "CSR not within tolerance for 2x2:2 MIMO");
540
541 // MIMO 3x3:1: expect that SNR is increased by a factor of 4.8 dB (10 log 3/1) compared to SISO
542 // thanks to RX diversity
543 txVector.SetNss(1);
544 txVector.SetNTx(3);
545 interference.SetNumberOfReceiveAntennas(3);
546 snr = interference.CalculateSnr(0.001,
547 0.001 / DbToRatio(initialSnr),
548 txVector.GetChannelWidth(),
549 txVector.GetNss());
551 initialSnr + 4.8,
552 0.1,
553 "SNR not within tolerance for 3x3:1 MIMO");
554 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
555 NS_TEST_ASSERT_MSG_GT(chunkSuccess,
556 sisoChunkSuccess,
557 "CSR not within tolerance for 3x3:1 MIMO");
558
559 // MIMO 3x3:2: expect that SNR is increased by a factor of 1.8 dB (10 log 3/2) compared to SISO
560 // thanks to RX diversity
561 txVector.SetNss(2);
562 txVector.SetNTx(3);
563 interference.SetNumberOfReceiveAntennas(3);
564 snr = interference.CalculateSnr(0.001,
565 0.001 / DbToRatio(initialSnr),
566 txVector.GetChannelWidth(),
567 txVector.GetNss());
569 initialSnr + 1.8,
570 0.1,
571 "SNR not within tolerance for 3x3:2 MIMO");
572 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
573 NS_TEST_ASSERT_MSG_GT(chunkSuccess,
574 sisoChunkSuccess,
575 "CSR not within tolerance for 3x3:2 MIMO");
576
577 // MIMO 3x3:3: expect no SNR gain in AWGN channel
578 txVector.SetNss(3);
579 txVector.SetNTx(3);
580 interference.SetNumberOfReceiveAntennas(3);
581 snr = interference.CalculateSnr(0.001,
582 0.001 / DbToRatio(initialSnr),
583 txVector.GetChannelWidth(),
584 txVector.GetNss());
586 initialSnr,
587 0.1,
588 "SNR not within tolerance for 3x3:3 MIMO");
589 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
590 NS_TEST_ASSERT_MSG_EQ_TOL(chunkSuccess,
591 sisoChunkSuccess,
592 0.000001,
593 "CSR not equal within tolerance for 3x3:3 MIMO");
594
595 // MIMO 4x4:1: expect that SNR is increased by a factor of 6 dB (10 log 4/1) compared to SISO
596 // thanks to RX diversity
597 txVector.SetNss(1);
598 txVector.SetNTx(4);
599 interference.SetNumberOfReceiveAntennas(4);
600 snr = interference.CalculateSnr(0.001,
601 0.001 / DbToRatio(initialSnr),
602 txVector.GetChannelWidth(),
603 txVector.GetNss());
605 initialSnr + 6,
606 0.1,
607 "SNR not within tolerance for 4x4:1 MIMO");
608 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
609 NS_TEST_ASSERT_MSG_GT(chunkSuccess,
610 sisoChunkSuccess,
611 "CSR not within tolerance for 4x4:1 MIMO");
612
613 // MIMO 4x4:2: expect that SNR is increased by a factor of 3 dB (10 log 4/2) compared to SISO
614 // thanks to RX diversity
615 txVector.SetNss(2);
616 txVector.SetNTx(4);
617 interference.SetNumberOfReceiveAntennas(4);
618 snr = interference.CalculateSnr(0.001,
619 0.001 / DbToRatio(initialSnr),
620 txVector.GetChannelWidth(),
621 txVector.GetNss());
623 initialSnr + 3,
624 0.1,
625 "SNR not within tolerance for 4x4:2 MIMO");
626 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
627 NS_TEST_ASSERT_MSG_GT(chunkSuccess,
628 sisoChunkSuccess,
629 "CSR not within tolerance for 4x4:2 MIMO");
630
631 // MIMO 4x4:3: expect that SNR is increased by a factor of 1.2 dB (10 log 4/3) compared to SISO
632 // thanks to RX diversity
633 txVector.SetNss(3);
634 txVector.SetNTx(4);
635 interference.SetNumberOfReceiveAntennas(4);
636 snr = interference.CalculateSnr(0.001,
637 0.001 / DbToRatio(initialSnr),
638 txVector.GetChannelWidth(),
639 txVector.GetNss());
641 initialSnr + 1.2,
642 0.1,
643 "SNR not within tolerance for 4x4:3 MIMO");
644 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
645 NS_TEST_ASSERT_MSG_GT(chunkSuccess,
646 sisoChunkSuccess,
647 "CSR not within tolerance for 4x4:1 MIMO");
648
649 // MIMO 4x4:4: expect no SNR gain in AWGN channel
650 txVector.SetNss(4);
651 txVector.SetNTx(4);
652 interference.SetNumberOfReceiveAntennas(4);
653 snr = interference.CalculateSnr(0.001,
654 0.001 / DbToRatio(initialSnr),
655 txVector.GetChannelWidth(),
656 txVector.GetNss());
658 initialSnr,
659 0.1,
660 "SNR not within tolerance for 4x4:4 MIMO");
661 chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
662 NS_TEST_ASSERT_MSG_EQ_TOL(chunkSuccess,
663 sisoChunkSuccess,
664 0.000001,
665 "CSR not within tolerance for 4x4:4 MIMO");
666}
667
672std::map<std::pair<uint8_t /* mcs */, uint32_t /* size */>,
673 std::map<double /* snr */, double /* per */>>
675 /* MCS 0 - 1458 bytes */
676 {std::make_pair(0, 1458),
677 {
678 {-4.00, 1.00000}, {-3.75, 1.00000}, {-3.50, 1.00000}, {-3.25, 1.00000},
679 {-3.00, 1.00000}, {-2.75, 1.00000}, {-2.50, 1.00000}, {-2.25, 1.00000},
680 {-2.00, 1.00000}, {-1.75, 1.00000}, {-1.50, 1.00000}, {-1.25, 1.00000},
681 {-1.00, 1.00000}, {-0.75, 0.99700}, {-0.50, 0.99400}, {-0.25, 0.90625},
682 {0.00, 0.81850}, {0.25, 0.55465}, {0.50, 0.29080}, {0.75, 0.17855},
683 {1.00, 0.06630}, {1.25, 0.03875}, {1.50, 0.01120}, {1.75, 0.00635},
684 {2.00, 0.00150}, {2.25, 0.00083}, {2.50, 0.00015}, {2.75, 0.00008},
685 {3.00, 0.00001}, {3.25, 0.00000}, {3.50, 0.00000}, {3.75, 0.00000},
686 {4.00, 0.00000}, {4.25, 0.00000}, {4.50, 0.00000}, {4.75, 0.00000},
687 {5.00, 0.00000}, {5.25, 0.00000}, {5.50, 0.00000}, {5.75, 0.00000},
688 {6.00, 0.00000}, {6.25, 0.00000}, {6.50, 0.00000}, {6.75, 0.00000},
689 {7.00, 0.00000}, {7.25, 0.00000}, {7.50, 0.00000}, {7.75, 0.00000},
690 {8.00, 0.00000}, {8.25, 0.00000}, {8.50, 0.00000}, {8.75, 0.00000},
691 {9.00, 0.00000}, {9.25, 0.00000}, {9.50, 0.00000}, {9.75, 0.00000},
692 {10.00, 0.00000}, {10.25, 0.00000}, {10.50, 0.00000}, {10.75, 0.00000},
693 {11.00, 0.00000}, {11.25, 0.00000}, {11.50, 0.00000}, {11.75, 0.00000},
694 {12.00, 0.00000}, {12.25, 0.00000}, {12.50, 0.00000}, {12.75, 0.00000},
695 {13.00, 0.00000}, {13.25, 0.00000}, {13.50, 0.00000}, {13.75, 0.00000},
696 {14.00, 0.00000}, {14.25, 0.00000}, {14.50, 0.00000}, {14.75, 0.00000},
697 {15.00, 0.00000}, {15.25, 0.00000}, {15.50, 0.00000}, {15.75, 0.00000},
698 {16.00, 0.00000}, {16.25, 0.00000}, {16.50, 0.00000}, {16.75, 0.00000},
699 {17.00, 0.00000}, {17.25, 0.00000}, {17.50, 0.00000}, {17.75, 0.00000},
700 {18.00, 0.00000}, {18.25, 0.00000}, {18.50, 0.00000}, {18.75, 0.00000},
701 {19.00, 0.00000}, {19.25, 0.00000}, {19.50, 0.00000}, {19.75, 0.00000},
702 {20.00, 0.00000}, {20.25, 0.00000}, {20.50, 0.00000}, {20.75, 0.00000},
703 {21.00, 0.00000}, {21.25, 0.00000}, {21.50, 0.00000}, {21.75, 0.00000},
704 {22.00, 0.00000}, {22.25, 0.00000}, {22.50, 0.00000}, {22.75, 0.00000},
705 {23.00, 0.00000}, {23.25, 0.00000}, {23.50, 0.00000}, {23.75, 0.00000},
706 {24.00, 0.00000}, {24.25, 0.00000}, {24.50, 0.00000}, {24.75, 0.00000},
707 {25.00, 0.00000}, {25.25, 0.00000}, {25.50, 0.00000}, {25.75, 0.00000},
708 {26.00, 0.00000}, {26.25, 0.00000}, {26.50, 0.00000}, {26.75, 0.00000},
709 {27.00, 0.00000}, {27.25, 0.00000}, {27.50, 0.00000}, {27.75, 0.00000},
710 {28.00, 0.00000}, {28.25, 0.00000}, {28.50, 0.00000}, {28.75, 0.00000},
711 {29.00, 0.00000}, {29.25, 0.00000}, {29.50, 0.00000}, {29.75, 0.00000},
712 {30.00, 0.00000},
713 }},
714 /* MCS 0 - 32 bytes */
715 {std::make_pair(0, 32),
716 {
717 {-4.00, 1.00000}, {-3.75, 1.00000}, {-3.50, 1.00000}, {-3.25, 0.99750},
718 {-3.00, 0.99500}, {-2.75, 0.96790}, {-2.50, 0.94080}, {-2.25, 0.88335},
719 {-2.00, 0.82590}, {-1.75, 0.70770}, {-1.50, 0.58950}, {-1.25, 0.44890},
720 {-1.00, 0.30830}, {-0.75, 0.21685}, {-0.50, 0.12540}, {-0.25, 0.07990},
721 {0.00, 0.03440}, {0.25, 0.02145}, {0.50, 0.00850}, {0.75, 0.00500},
722 {1.00, 0.00150}, {1.25, 0.00087}, {1.50, 0.00024}, {1.75, 0.00017},
723 {2.00, 0.00009}, {2.25, 0.00005}, {2.50, 0.00000}, {2.75, 0.00000},
724 {3.00, 0.00000}, {3.25, 0.00000}, {3.50, 0.00000}, {3.75, 0.00000},
725 {4.00, 0.00000}, {4.25, 0.00000}, {4.50, 0.00000}, {4.75, 0.00000},
726 {5.00, 0.00000}, {5.25, 0.00000}, {5.50, 0.00000}, {5.75, 0.00000},
727 {6.00, 0.00000}, {6.25, 0.00000}, {6.50, 0.00000}, {6.75, 0.00000},
728 {7.00, 0.00000}, {7.25, 0.00000}, {7.50, 0.00000}, {7.75, 0.00000},
729 {8.00, 0.00000}, {8.25, 0.00000}, {8.50, 0.00000}, {8.75, 0.00000},
730 {9.00, 0.00000}, {9.25, 0.00000}, {9.50, 0.00000}, {9.75, 0.00000},
731 {10.00, 0.00000}, {10.25, 0.00000}, {10.50, 0.00000}, {10.75, 0.00000},
732 {11.00, 0.00000}, {11.25, 0.00000}, {11.50, 0.00000}, {11.75, 0.00000},
733 {12.00, 0.00000}, {12.25, 0.00000}, {12.50, 0.00000}, {12.75, 0.00000},
734 {13.00, 0.00000}, {13.25, 0.00000}, {13.50, 0.00000}, {13.75, 0.00000},
735 {14.00, 0.00000}, {14.25, 0.00000}, {14.50, 0.00000}, {14.75, 0.00000},
736 {15.00, 0.00000}, {15.25, 0.00000}, {15.50, 0.00000}, {15.75, 0.00000},
737 {16.00, 0.00000}, {16.25, 0.00000}, {16.50, 0.00000}, {16.75, 0.00000},
738 {17.00, 0.00000}, {17.25, 0.00000}, {17.50, 0.00000}, {17.75, 0.00000},
739 {18.00, 0.00000}, {18.25, 0.00000}, {18.50, 0.00000}, {18.75, 0.00000},
740 {19.00, 0.00000}, {19.25, 0.00000}, {19.50, 0.00000}, {19.75, 0.00000},
741 {20.00, 0.00000}, {20.25, 0.00000}, {20.50, 0.00000}, {20.75, 0.00000},
742 {21.00, 0.00000}, {21.25, 0.00000}, {21.50, 0.00000}, {21.75, 0.00000},
743 {22.00, 0.00000}, {22.25, 0.00000}, {22.50, 0.00000}, {22.75, 0.00000},
744 {23.00, 0.00000}, {23.25, 0.00000}, {23.50, 0.00000}, {23.75, 0.00000},
745 {24.00, 0.00000}, {24.25, 0.00000}, {24.50, 0.00000}, {24.75, 0.00000},
746 {25.00, 0.00000}, {25.25, 0.00000}, {25.50, 0.00000}, {25.75, 0.00000},
747 {26.00, 0.00000}, {26.25, 0.00000}, {26.50, 0.00000}, {26.75, 0.00000},
748 {27.00, 0.00000}, {27.25, 0.00000}, {27.50, 0.00000}, {27.75, 0.00000},
749 {28.00, 0.00000}, {28.25, 0.00000}, {28.50, 0.00000}, {28.75, 0.00000},
750 {29.00, 0.00000}, {29.25, 0.00000}, {29.50, 0.00000}, {29.75, 0.00000},
751 {30.00, 0.00000},
752 }},
753 /* MCS 0 - 1000 bytes */
754 {std::make_pair(0, 1000),
755 {
756 {-4.00, 1.00000}, {-3.75, 1.00000}, {-3.50, 1.00000}, {-3.25, 1.00000},
757 {-3.00, 1.00000}, {-2.75, 1.00000}, {-2.50, 1.00000}, {-2.25, 1.00000},
758 {-2.00, 1.00000}, {-1.75, 1.00000}, {-1.50, 1.00000}, {-1.25, 1.00000},
759 {-1.00, 1.00000}, {-0.75, 0.98140}, {-0.50, 0.97007}, {-0.25, 0.80280},
760 {0.00, 0.68977}, {0.25, 0.42581}, {0.50, 0.20997}, {0.75, 0.12620},
761 {1.00, 0.04596}, {1.25, 0.02674}, {1.50, 0.00770}, {1.75, 0.00436},
762 {2.00, 0.00103}, {2.25, 0.00057}, {2.50, 0.00010}, {2.75, 0.00005},
763 {3.00, 0.00001}, {3.25, 0.00000}, {3.50, 0.00000}, {3.75, 0.00000},
764 {4.00, 0.00000}, {4.25, 0.00000}, {4.50, 0.00000}, {4.75, 0.00000},
765 {5.00, 0.00000}, {5.25, 0.00000}, {5.50, 0.00000}, {5.75, 0.00000},
766 {6.00, 0.00000}, {6.25, 0.00000}, {6.50, 0.00000}, {6.75, 0.00000},
767 {7.00, 0.00000}, {7.25, 0.00000}, {7.50, 0.00000}, {7.75, 0.00000},
768 {8.00, 0.00000}, {8.25, 0.00000}, {8.50, 0.00000}, {8.75, 0.00000},
769 {9.00, 0.00000}, {9.25, 0.00000}, {9.50, 0.00000}, {9.75, 0.00000},
770 {10.00, 0.00000}, {10.25, 0.00000}, {10.50, 0.00000}, {10.75, 0.00000},
771 {11.00, 0.00000}, {11.25, 0.00000}, {11.50, 0.00000}, {11.75, 0.00000},
772 {12.00, 0.00000}, {12.25, 0.00000}, {12.50, 0.00000}, {12.75, 0.00000},
773 {13.00, 0.00000}, {13.25, 0.00000}, {13.50, 0.00000}, {13.75, 0.00000},
774 {14.00, 0.00000}, {14.25, 0.00000}, {14.50, 0.00000}, {14.75, 0.00000},
775 {15.00, 0.00000}, {15.25, 0.00000}, {15.50, 0.00000}, {15.75, 0.00000},
776 {16.00, 0.00000}, {16.25, 0.00000}, {16.50, 0.00000}, {16.75, 0.00000},
777 {17.00, 0.00000}, {17.25, 0.00000}, {17.50, 0.00000}, {17.75, 0.00000},
778 {18.00, 0.00000}, {18.25, 0.00000}, {18.50, 0.00000}, {18.75, 0.00000},
779 {19.00, 0.00000}, {19.25, 0.00000}, {19.50, 0.00000}, {19.75, 0.00000},
780 {20.00, 0.00000}, {20.25, 0.00000}, {20.50, 0.00000}, {20.75, 0.00000},
781 {21.00, 0.00000}, {21.25, 0.00000}, {21.50, 0.00000}, {21.75, 0.00000},
782 {22.00, 0.00000}, {22.25, 0.00000}, {22.50, 0.00000}, {22.75, 0.00000},
783 {23.00, 0.00000}, {23.25, 0.00000}, {23.50, 0.00000}, {23.75, 0.00000},
784 {24.00, 0.00000}, {24.25, 0.00000}, {24.50, 0.00000}, {24.75, 0.00000},
785 {25.00, 0.00000}, {25.25, 0.00000}, {25.50, 0.00000}, {25.75, 0.00000},
786 {26.00, 0.00000}, {26.25, 0.00000}, {26.50, 0.00000}, {26.75, 0.00000},
787 {27.00, 0.00000}, {27.25, 0.00000}, {27.50, 0.00000}, {27.75, 0.00000},
788 {28.00, 0.00000}, {28.25, 0.00000}, {28.50, 0.00000}, {28.75, 0.00000},
789 {29.00, 0.00000}, {29.25, 0.00000}, {29.50, 0.00000}, {29.75, 0.00000},
790 {30.00, 0.00000},
791 }},
792 /* MCS 0 - 1 byte */
793 {std::make_pair(0, 1),
794 {
795 {-4.00, 1.00000}, {-3.75, 1.00000}, {-3.50, 1.00000}, {-3.25, 0.17075},
796 {-3.00, 0.15260}, {-2.75, 0.10190}, {-2.50, 0.08455}, {-2.25, 0.06494},
797 {-2.00, 0.05316}, {-1.75, 0.03771}, {-1.50, 0.02744}, {-1.25, 0.01845},
798 {-1.00, 0.01145}, {-0.75, 0.00761}, {-0.50, 0.00418}, {-0.25, 0.00260},
799 {0.00, 0.00110}, {0.25, 0.00068}, {0.50, 0.00027}, {0.75, 0.00016},
800 {1.00, 0.00005}, {1.25, 0.00003}, {1.50, 0.00000}, {1.75, 0.00000},
801 {2.00, 0.00000}, {2.25, 0.00000}, {2.50, 0.00000}, {2.75, 0.00000},
802 {3.00, 0.00000}, {3.25, 0.00000}, {3.50, 0.00000}, {3.75, 0.00000},
803 {4.00, 0.00000}, {4.25, 0.00000}, {4.50, 0.00000}, {4.75, 0.00000},
804 {5.00, 0.00000}, {5.25, 0.00000}, {5.50, 0.00000}, {5.75, 0.00000},
805 {6.00, 0.00000}, {6.25, 0.00000}, {6.50, 0.00000}, {6.75, 0.00000},
806 {7.00, 0.00000}, {7.25, 0.00000}, {7.50, 0.00000}, {7.75, 0.00000},
807 {8.00, 0.00000}, {8.25, 0.00000}, {8.50, 0.00000}, {8.75, 0.00000},
808 {9.00, 0.00000}, {9.25, 0.00000}, {9.50, 0.00000}, {9.75, 0.00000},
809 {10.00, 0.00000}, {10.25, 0.00000}, {10.50, 0.00000}, {10.75, 0.00000},
810 {11.00, 0.00000}, {11.25, 0.00000}, {11.50, 0.00000}, {11.75, 0.00000},
811 {12.00, 0.00000}, {12.25, 0.00000}, {12.50, 0.00000}, {12.75, 0.00000},
812 {13.00, 0.00000}, {13.25, 0.00000}, {13.50, 0.00000}, {13.75, 0.00000},
813 {14.00, 0.00000}, {14.25, 0.00000}, {14.50, 0.00000}, {14.75, 0.00000},
814 {15.00, 0.00000}, {15.25, 0.00000}, {15.50, 0.00000}, {15.75, 0.00000},
815 {16.00, 0.00000}, {16.25, 0.00000}, {16.50, 0.00000}, {16.75, 0.00000},
816 {17.00, 0.00000}, {17.25, 0.00000}, {17.50, 0.00000}, {17.75, 0.00000},
817 {18.00, 0.00000}, {18.25, 0.00000}, {18.50, 0.00000}, {18.75, 0.00000},
818 {19.00, 0.00000}, {19.25, 0.00000}, {19.50, 0.00000}, {19.75, 0.00000},
819 {20.00, 0.00000}, {20.25, 0.00000}, {20.50, 0.00000}, {20.75, 0.00000},
820 {21.00, 0.00000}, {21.25, 0.00000}, {21.50, 0.00000}, {21.75, 0.00000},
821 {22.00, 0.00000}, {22.25, 0.00000}, {22.50, 0.00000}, {22.75, 0.00000},
822 {23.00, 0.00000}, {23.25, 0.00000}, {23.50, 0.00000}, {23.75, 0.00000},
823 {24.00, 0.00000}, {24.25, 0.00000}, {24.50, 0.00000}, {24.75, 0.00000},
824 {25.00, 0.00000}, {25.25, 0.00000}, {25.50, 0.00000}, {25.75, 0.00000},
825 {26.00, 0.00000}, {26.25, 0.00000}, {26.50, 0.00000}, {26.75, 0.00000},
826 {27.00, 0.00000}, {27.25, 0.00000}, {27.50, 0.00000}, {27.75, 0.00000},
827 {28.00, 0.00000}, {28.25, 0.00000}, {28.50, 0.00000}, {28.75, 0.00000},
828 {29.00, 0.00000}, {29.25, 0.00000}, {29.50, 0.00000}, {29.75, 0.00000},
829 {30.00, 0.00000},
830 }},
831 /* MCS 0 - 2000 bytes */
832 {std::make_pair(0, 2000),
833 {
834 {-4.00, 1.00000}, {-3.75, 1.00000}, {-3.50, 1.00000}, {-3.25, 1.00000},
835 {-3.00, 1.00000}, {-2.75, 1.00000}, {-2.50, 1.00000}, {-2.25, 1.00000},
836 {-2.00, 1.00000}, {-1.75, 1.00000}, {-1.50, 1.00000}, {-1.25, 1.00000},
837 {-1.00, 1.00000}, {-0.75, 0.99965}, {-0.50, 0.99910}, {-0.25, 0.96111},
838 {0.00, 0.90376}, {0.25, 0.67031}, {0.50, 0.37584}, {0.75, 0.23647},
839 {1.00, 0.08981}, {1.25, 0.05277}, {1.50, 0.01533}, {1.75, 0.00870},
840 {2.00, 0.00206}, {2.25, 0.00113}, {2.50, 0.00021}, {2.75, 0.00011},
841 {3.00, 0.00001}, {3.25, 0.00000}, {3.50, 0.00000}, {3.75, 0.00000},
842 {4.00, 0.00000}, {4.25, 0.00000}, {4.50, 0.00000}, {4.75, 0.00000},
843 {5.00, 0.00000}, {5.25, 0.00000}, {5.50, 0.00000}, {5.75, 0.00000},
844 {6.00, 0.00000}, {6.25, 0.00000}, {6.50, 0.00000}, {6.75, 0.00000},
845 {7.00, 0.00000}, {7.25, 0.00000}, {7.50, 0.00000}, {7.75, 0.00000},
846 {8.00, 0.00000}, {8.25, 0.00000}, {8.50, 0.00000}, {8.75, 0.00000},
847 {9.00, 0.00000}, {9.25, 0.00000}, {9.50, 0.00000}, {9.75, 0.00000},
848 {10.00, 0.00000}, {10.25, 0.00000}, {10.50, 0.00000}, {10.75, 0.00000},
849 {11.00, 0.00000}, {11.25, 0.00000}, {11.50, 0.00000}, {11.75, 0.00000},
850 {12.00, 0.00000}, {12.25, 0.00000}, {12.50, 0.00000}, {12.75, 0.00000},
851 {13.00, 0.00000}, {13.25, 0.00000}, {13.50, 0.00000}, {13.75, 0.00000},
852 {14.00, 0.00000}, {14.25, 0.00000}, {14.50, 0.00000}, {14.75, 0.00000},
853 {15.00, 0.00000}, {15.25, 0.00000}, {15.50, 0.00000}, {15.75, 0.00000},
854 {16.00, 0.00000}, {16.25, 0.00000}, {16.50, 0.00000}, {16.75, 0.00000},
855 {17.00, 0.00000}, {17.25, 0.00000}, {17.50, 0.00000}, {17.75, 0.00000},
856 {18.00, 0.00000}, {18.25, 0.00000}, {18.50, 0.00000}, {18.75, 0.00000},
857 {19.00, 0.00000}, {19.25, 0.00000}, {19.50, 0.00000}, {19.75, 0.00000},
858 {20.00, 0.00000}, {20.25, 0.00000}, {20.50, 0.00000}, {20.75, 0.00000},
859 {21.00, 0.00000}, {21.25, 0.00000}, {21.50, 0.00000}, {21.75, 0.00000},
860 {22.00, 0.00000}, {22.25, 0.00000}, {22.50, 0.00000}, {22.75, 0.00000},
861 {23.00, 0.00000}, {23.25, 0.00000}, {23.50, 0.00000}, {23.75, 0.00000},
862 {24.00, 0.00000}, {24.25, 0.00000}, {24.50, 0.00000}, {24.75, 0.00000},
863 {25.00, 0.00000}, {25.25, 0.00000}, {25.50, 0.00000}, {25.75, 0.00000},
864 {26.00, 0.00000}, {26.25, 0.00000}, {26.50, 0.00000}, {26.75, 0.00000},
865 {27.00, 0.00000}, {27.25, 0.00000}, {27.50, 0.00000}, {27.75, 0.00000},
866 {28.00, 0.00000}, {28.25, 0.00000}, {28.50, 0.00000}, {28.75, 0.00000},
867 {29.00, 0.00000}, {29.25, 0.00000}, {29.50, 0.00000}, {29.75, 0.00000},
868 {30.00, 0.00000},
869 }},
870 /* MCS 7 - 1500 bytes */
871 {std::make_pair(7, 1500),
872 {
873 {-4.00, 1.00000}, {-3.75, 1.00000}, {-3.50, 1.00000}, {-3.25, 1.00000},
874 {-3.00, 1.00000}, {-2.75, 1.00000}, {-2.50, 1.00000}, {-2.25, 1.00000},
875 {-2.00, 1.00000}, {-1.75, 1.00000}, {-1.50, 1.00000}, {-1.25, 1.00000},
876 {-1.00, 1.00000}, {-0.75, 1.00000}, {-0.50, 1.00000}, {-0.25, 1.00000},
877 {0.00, 1.00000}, {0.25, 1.00000}, {0.50, 1.00000}, {0.75, 1.00000},
878 {1.00, 1.00000}, {1.25, 1.00000}, {1.50, 1.00000}, {1.75, 1.00000},
879 {2.00, 1.00000}, {2.25, 1.00000}, {2.50, 1.00000}, {2.75, 1.00000},
880 {3.00, 1.00000}, {3.25, 1.00000}, {3.50, 1.00000}, {3.75, 1.00000},
881 {4.00, 1.00000}, {4.25, 1.00000}, {4.50, 1.00000}, {4.75, 1.00000},
882 {5.00, 1.00000}, {5.25, 1.00000}, {5.50, 1.00000}, {5.75, 1.00000},
883 {6.00, 1.00000}, {6.25, 1.00000}, {6.50, 1.00000}, {6.75, 1.00000},
884 {7.00, 1.00000}, {7.25, 1.00000}, {7.50, 1.00000}, {7.75, 1.00000},
885 {8.00, 1.00000}, {8.25, 1.00000}, {8.50, 1.00000}, {8.75, 1.00000},
886 {9.00, 1.00000}, {9.25, 1.00000}, {9.50, 1.00000}, {9.75, 1.00000},
887 {10.00, 1.00000}, {10.25, 1.00000}, {10.50, 1.00000}, {10.75, 1.00000},
888 {11.00, 1.00000}, {11.25, 1.00000}, {11.50, 1.00000}, {11.75, 1.00000},
889 {12.00, 1.00000}, {12.25, 1.00000}, {12.50, 1.00000}, {12.75, 1.00000},
890 {13.00, 1.00000}, {13.25, 1.00000}, {13.50, 1.00000}, {13.75, 1.00000},
891 {14.00, 1.00000}, {14.25, 1.00000}, {14.50, 1.00000}, {14.75, 1.00000},
892 {15.00, 1.00000}, {15.25, 1.00000}, {15.50, 1.00000}, {15.75, 1.00000},
893 {16.00, 1.00000}, {16.25, 1.00000}, {16.50, 1.00000}, {16.75, 1.00000},
894 {17.00, 1.00000}, {17.25, 1.00000}, {17.50, 1.00000}, {17.75, 0.99057},
895 {18.00, 0.98075}, {18.25, 0.86664}, {18.50, 0.74920}, {18.75, 0.54857},
896 {19.00, 0.34531}, {19.25, 0.23624}, {19.50, 0.12672}, {19.75, 0.08164},
897 {20.00, 0.03650}, {20.25, 0.02340}, {20.50, 0.01029}, {20.75, 0.00653},
898 {21.00, 0.00278}, {21.25, 0.00165}, {21.50, 0.00051}, {21.75, 0.00030},
899 {22.00, 0.00009}, {22.25, 0.00005}, {22.50, 0.00001}, {22.75, 0.00000},
900 {23.00, 0.00000}, {23.25, 0.00000}, {23.50, 0.00000}, {23.75, 0.00000},
901 {24.00, 0.00000}, {24.25, 0.00000}, {24.50, 0.00000}, {24.75, 0.00000},
902 {25.00, 0.00000}, {25.25, 0.00000}, {25.50, 0.00000}, {25.75, 0.00000},
903 {26.00, 0.00000}, {26.25, 0.00000}, {26.50, 0.00000}, {26.75, 0.00000},
904 {27.00, 0.00000}, {27.25, 0.00000}, {27.50, 0.00000}, {27.75, 0.00000},
905 {28.00, 0.00000}, {28.25, 0.00000}, {28.50, 0.00000}, {28.75, 0.00000},
906 {29.00, 0.00000}, {29.25, 0.00000}, {29.50, 0.00000}, {29.75, 0.00000},
907 {30.00, 0.00000},
908 }},
909 /* MCS 8 - 1500 bytes */
910 {std::make_pair(8, 1500),
911 {
912 {-4.00, 1.00000}, {-3.75, 1.00000}, {-3.50, 1.00000}, {-3.25, 1.00000},
913 {-3.00, 1.00000}, {-2.75, 1.00000}, {-2.50, 1.00000}, {-2.25, 1.00000},
914 {-2.00, 1.00000}, {-1.75, 1.00000}, {-1.50, 1.00000}, {-1.25, 1.00000},
915 {-1.00, 1.00000}, {-0.75, 1.00000}, {-0.50, 1.00000}, {-0.25, 1.00000},
916 {0.00, 1.00000}, {0.25, 1.00000}, {0.50, 1.00000}, {0.75, 1.00000},
917 {1.00, 1.00000}, {1.25, 1.00000}, {1.50, 1.00000}, {1.75, 1.00000},
918 {2.00, 1.00000}, {2.25, 1.00000}, {2.50, 1.00000}, {2.75, 1.00000},
919 {3.00, 1.00000}, {3.25, 1.00000}, {3.50, 1.00000}, {3.75, 1.00000},
920 {4.00, 1.00000}, {4.25, 1.00000}, {4.50, 1.00000}, {4.75, 1.00000},
921 {5.00, 1.00000}, {5.25, 1.00000}, {5.50, 1.00000}, {5.75, 1.00000},
922 {6.00, 1.00000}, {6.25, 1.00000}, {6.50, 1.00000}, {6.75, 1.00000},
923 {7.00, 1.00000}, {7.25, 1.00000}, {7.50, 1.00000}, {7.75, 1.00000},
924 {8.00, 1.00000}, {8.25, 1.00000}, {8.50, 1.00000}, {8.75, 1.00000},
925 {9.00, 1.00000}, {9.25, 1.00000}, {9.50, 1.00000}, {9.75, 1.00000},
926 {10.00, 1.00000}, {10.25, 1.00000}, {10.50, 1.00000}, {10.75, 1.00000},
927 {11.00, 1.00000}, {11.25, 1.00000}, {11.50, 1.00000}, {11.75, 1.00000},
928 {12.00, 1.00000}, {12.25, 1.00000}, {12.50, 1.00000}, {12.75, 1.00000},
929 {13.00, 1.00000}, {13.25, 1.00000}, {13.50, 1.00000}, {13.75, 1.00000},
930 {14.00, 1.00000}, {14.25, 1.00000}, {14.50, 1.00000}, {14.75, 1.00000},
931 {15.00, 1.00000}, {15.25, 1.00000}, {15.50, 1.00000}, {15.75, 1.00000},
932 {16.00, 1.00000}, {16.25, 1.00000}, {16.50, 1.00000}, {16.75, 1.00000},
933 {17.00, 1.00000}, {17.25, 1.00000}, {17.50, 1.00000}, {17.75, 1.00000},
934 {18.00, 1.00000}, {18.25, 1.00000}, {18.50, 1.00000}, {18.75, 1.00000},
935 {19.00, 1.00000}, {19.25, 1.00000}, {19.50, 1.00000}, {19.75, 1.00000},
936 {20.00, 1.00000}, {20.25, 1.00000}, {20.50, 1.00000}, {20.75, 1.00000},
937 {21.00, 1.00000}, {21.25, 0.99918}, {21.50, 0.99833}, {21.75, 0.97191},
938 {22.00, 0.94458}, {22.25, 0.81436}, {22.50, 0.68127}, {22.75, 0.52168},
939 {23.00, 0.36056}, {23.25, 0.25114}, {23.50, 0.14127}, {23.75, 0.09509},
940 {24.00, 0.04883}, {24.25, 0.03234}, {24.50, 0.01584}, {24.75, 0.01060},
941 {25.00, 0.00535}, {25.25, 0.00345}, {25.50, 0.00154}, {25.75, 0.00096},
942 {26.00, 0.00037}, {26.25, 0.00022}, {26.50, 0.00007}, {26.75, 0.00004},
943 {27.00, 0.00000}, {27.25, 0.00000}, {27.50, 0.00000}, {27.75, 0.00000},
944 {28.00, 0.00000}, {28.25, 0.00000}, {28.50, 0.00000}, {28.75, 0.00000},
945 {29.00, 0.00000}, {29.25, 0.00000}, {29.50, 0.00000}, {29.75, 0.00000},
946 {30.00, 0.00000},
947 }},
948};
949
957{
958 public:
966 TableBasedErrorRateTestCase(const std::string& testName, WifiMode mode, uint32_t size);
968
969 private:
970 void DoRun() override;
971
972 std::string m_testName;
975};
976
978 WifiMode mode,
979 uint32_t size)
980 : TestCase(testName),
981 m_testName(testName),
982 m_mode(mode),
983 m_size(size)
984{
985}
986
988{
989}
990
991void
993{
994 // LogComponentEnable ("WifiErrorRateModelsTest", LOG_LEVEL_ALL);
995 // LogComponentEnable ("TableBasedErrorRateModel", LOG_LEVEL_ALL);
996 // LogComponentEnable ("YansErrorRateModel", LOG_LEVEL_ALL);
997
998 Ptr<TableBasedErrorRateModel> table = CreateObject<TableBasedErrorRateModel>();
999 WifiTxVector txVector;
1000 txVector.SetMode(m_mode);
1001
1002 // Spot test some values returned from TableBasedErrorRateModel
1003 for (double snr = -4; snr <= 30; snr += 0.25)
1004 {
1005 double expectedValue = 0;
1007 {
1008 Ptr<YansErrorRateModel> yans = CreateObject<YansErrorRateModel>();
1009 expectedValue =
1010 1 - yans->GetChunkSuccessRate(m_mode, txVector, std::pow(10, snr / 10), m_size * 8);
1011 }
1012 else
1013 {
1014 auto it = expectedTableValues.find(std::make_pair(m_mode.GetMcsValue(), m_size));
1015 if (it != expectedTableValues.end())
1016 {
1017 auto itValue = it->second.find(snr);
1018 if (itValue != it->second.end())
1019 {
1020 expectedValue = itValue->second;
1021 }
1022 else
1023 {
1024 NS_FATAL_ERROR("SNR value " << snr << " dB not found!");
1025 }
1026 }
1027 else
1028 {
1029 NS_FATAL_ERROR("No expected value found for the combination MCS "
1030 << +m_mode.GetMcsValue() << " and size " << m_size << " bytes");
1031 }
1032 }
1033 double per =
1034 1 - table->GetChunkSuccessRate(m_mode, txVector, std::pow(10, snr / 10), m_size * 8);
1035 NS_LOG_INFO(m_testName << ": snr=" << snr << "dB per=" << per
1036 << " expectedPER=" << expectedValue);
1037 NS_TEST_ASSERT_MSG_EQ_TOL(per, expectedValue, 1e-5, "Not equal within tolerance");
1038 }
1039}
1040
1048{
1049 public:
1051};
1052
1054 : TestSuite("wifi-error-rate-models", Type::UNIT)
1055{
1056 AddTestCase(new WifiErrorRateModelsTestCaseDsss, TestCase::Duration::QUICK);
1057 AddTestCase(new WifiErrorRateModelsTestCaseNist, TestCase::Duration::QUICK);
1058 AddTestCase(new WifiErrorRateModelsTestCaseMimo, TestCase::Duration::QUICK);
1059 AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedHtMcs0-1458bytes",
1061 1458),
1062 TestCase::Duration::QUICK);
1064 new TableBasedErrorRateTestCase("DefaultTableBasedHtMcs0-32bytes", HtPhy::GetHtMcs0(), 32),
1065 TestCase::Duration::QUICK);
1066 AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedHtMcs0-1000bytes",
1068 1000),
1069 TestCase::Duration::QUICK);
1071 new TableBasedErrorRateTestCase("DefaultTableBasedHtMcs0-1byte", HtPhy::GetHtMcs0(), 1),
1072 TestCase::Duration::QUICK);
1073 AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedHtMcs0-2000bytes",
1075 2000),
1076 TestCase::Duration::QUICK);
1077 AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedHtMcs7-1500bytes",
1079 1500),
1080 TestCase::Duration::QUICK);
1081 AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedVhtMcs0-1458bytes",
1083 1458),
1084 TestCase::Duration::QUICK);
1085 AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedVhtMcs0-32bytes",
1087 32),
1088 TestCase::Duration::QUICK);
1089 AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedVhtMcs0-1000bytes",
1091 1000),
1092 TestCase::Duration::QUICK);
1094 new TableBasedErrorRateTestCase("DefaultTableBasedVhtMcs0-1byte", VhtPhy::GetVhtMcs0(), 1),
1095 TestCase::Duration::QUICK);
1096 AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedVhtMcs0-2000bytes",
1098 2000),
1099 TestCase::Duration::QUICK);
1100 AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedVhtMcs8-1500bytes",
1102 1500),
1103 TestCase::Duration::QUICK);
1104 AddTestCase(new TableBasedErrorRateTestCase("FallbackTableBasedHeMcs11-1458bytes",
1106 1458),
1107 TestCase::Duration::QUICK);
1108}
1109
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:77
encapsulates test code
Definition: test.h:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
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:875
#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:338
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
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