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