A Discrete-Event Network Simulator
QKDNetSim v2.0 (NS-3 v3.41) @ (+)
API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 
39 using namespace ns3;
40 
41 NS_LOG_COMPONENT_DEFINE("WifiErrorRateModelsTest");
42 
43 static double
44 FromRss(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 
80 void
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
89  value = DsssErrorRateModel::GetDsssDbpskSuccessRate(FromRss(-105.0), size);
90  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0, 1e-13, "Not equal within tolerance");
91  value = DsssErrorRateModel::GetDsssDbpskSuccessRate(FromRss(-100.0), size);
92  NS_TEST_ASSERT_MSG_EQ_TOL(value, 1.5e-13, 1e-13, "Not equal within tolerance");
93  value = DsssErrorRateModel::GetDsssDbpskSuccessRate(FromRss(-99.0), size);
94  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.0003, 0.0001, "Not equal within tolerance");
95  value = DsssErrorRateModel::GetDsssDbpskSuccessRate(FromRss(-98.0), size);
96  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.202, 0.005, "Not equal within tolerance");
97  value = DsssErrorRateModel::GetDsssDbpskSuccessRate(FromRss(-97.0), size);
98  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.813, 0.005, "Not equal within tolerance");
99  value = DsssErrorRateModel::GetDsssDbpskSuccessRate(FromRss(-96.0), size);
100  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.984, 0.005, "Not equal within tolerance");
101  value = DsssErrorRateModel::GetDsssDbpskSuccessRate(FromRss(-95.0), size);
102  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.999, 0.001, "Not equal within tolerance");
103  value = DsssErrorRateModel::GetDsssDbpskSuccessRate(FromRss(-90.0), size);
104  NS_TEST_ASSERT_MSG_EQ_TOL(value, 1, 0.001, "Not equal within tolerance");
105 
106  // DQPSK
107  //
108  value = DsssErrorRateModel::GetDsssDqpskSuccessRate(FromRss(-96.0), size);
109  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0, 1e-13, "Not equal within tolerance");
110  value = DsssErrorRateModel::GetDsssDqpskSuccessRate(FromRss(-95.0), size);
111  NS_TEST_ASSERT_MSG_EQ_TOL(value, 4.5e-6, 1e-6, "Not equal within tolerance");
112  value = DsssErrorRateModel::GetDsssDqpskSuccessRate(FromRss(-94.0), size);
113  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.036, 0.005, "Not equal within tolerance");
114  value = DsssErrorRateModel::GetDsssDqpskSuccessRate(FromRss(-93.0), size);
115  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.519, 0.005, "Not equal within tolerance");
116  value = DsssErrorRateModel::GetDsssDqpskSuccessRate(FromRss(-92.0), size);
117  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.915, 0.005, "Not equal within tolerance");
118  value = DsssErrorRateModel::GetDsssDqpskSuccessRate(FromRss(-91.0), size);
119  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.993, 0.005, "Not equal within tolerance");
120  value = DsssErrorRateModel::GetDsssDqpskSuccessRate(FromRss(-90.0), size);
121  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.999, 0.001, "Not equal within tolerance");
122  value = DsssErrorRateModel::GetDsssDqpskSuccessRate(FromRss(-89.0), size);
123  NS_TEST_ASSERT_MSG_EQ_TOL(value, 1, 0.001, "Not equal within tolerance");
124 
125 #ifdef HAVE_GSL
126  // DQPSK_CCK5.5
127  value = DsssErrorRateModel::GetDsssDqpskCck5_5SuccessRate(FromRss(-94.0), size);
128  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0, 1e-13, "Not equal within tolerance");
129  value = DsssErrorRateModel::GetDsssDqpskCck5_5SuccessRate(FromRss(-93.0), size);
130  NS_TEST_ASSERT_MSG_EQ_TOL(value, 6.6e-14, 5e-14, "Not equal within tolerance");
131  value = DsssErrorRateModel::GetDsssDqpskCck5_5SuccessRate(FromRss(-92.0), size);
132  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.0001, 0.00005, "Not equal within tolerance");
133  value = DsssErrorRateModel::GetDsssDqpskCck5_5SuccessRate(FromRss(-91.0), size);
134  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.132, 0.005, "Not equal within tolerance");
135  value = DsssErrorRateModel::GetDsssDqpskCck5_5SuccessRate(FromRss(-90.0), size);
136  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.744, 0.005, "Not equal within tolerance");
137  value = DsssErrorRateModel::GetDsssDqpskCck5_5SuccessRate(FromRss(-89.0), size);
138  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.974, 0.005, "Not equal within tolerance");
139  value = DsssErrorRateModel::GetDsssDqpskCck5_5SuccessRate(FromRss(-88.0), size);
140  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.999, 0.001, "Not equal within tolerance");
141  value = DsssErrorRateModel::GetDsssDqpskCck5_5SuccessRate(FromRss(-87.0), size);
142  NS_TEST_ASSERT_MSG_EQ_TOL(value, 1, 0.001, "Not equal within tolerance");
143 
144  // DQPSK_CCK11
145  value = DsssErrorRateModel::GetDsssDqpskCck11SuccessRate(FromRss(-91.0), size);
146  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0, 1e-14, "Not equal within tolerance");
147  value = DsssErrorRateModel::GetDsssDqpskCck11SuccessRate(FromRss(-90.0), size);
148  NS_TEST_ASSERT_MSG_EQ_TOL(value, 4.7e-14, 1e-14, "Not equal within tolerance");
149  value = DsssErrorRateModel::GetDsssDqpskCck11SuccessRate(FromRss(-89.0), size);
150  NS_TEST_ASSERT_MSG_EQ_TOL(value, 8.85e-5, 1e-5, "Not equal within tolerance");
151  value = DsssErrorRateModel::GetDsssDqpskCck11SuccessRate(FromRss(-88.0), size);
152  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.128, 0.005, "Not equal within tolerance");
153  value = DsssErrorRateModel::GetDsssDqpskCck11SuccessRate(FromRss(-87.0), size);
154  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.739, 0.005, "Not equal within tolerance");
155  value = DsssErrorRateModel::GetDsssDqpskCck11SuccessRate(FromRss(-86.0), size);
156  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.973, 0.005, "Not equal within tolerance");
157  value = DsssErrorRateModel::GetDsssDqpskCck11SuccessRate(FromRss(-85.0), size);
158  NS_TEST_ASSERT_MSG_EQ_TOL(value, 0.999, 0.001, "Not equal within tolerance");
159  value = DsssErrorRateModel::GetDsssDqpskCck11SuccessRate(FromRss(-84.0), size);
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 
189 void
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:
405  using InterferenceHelper::CalculatePayloadChunkSuccessRate;
406  using InterferenceHelper::CalculateSnr;
407  using InterferenceHelper::InterferenceHelper;
408 };
409 
417 {
418  public:
421 
422  private:
423  void DoRun() override;
424 };
425 
427  : TestCase("WifiErrorRateModel test case MIMO")
428 {
429 }
430 
432 {
433 }
434 
435 void
437 {
438  TestInterferenceHelper interference;
439  interference.SetNoiseFigure(0);
440  WifiMode mode = HtPhy::GetHtMcs0();
441  WifiTxVector txVector;
442 
443  txVector.SetMode(mode);
444  txVector.SetTxPowerLevel(0);
445  txVector.SetChannelWidth(20);
446  txVector.SetNss(1);
447  txVector.SetNTx(1);
448 
449  interference.SetNumberOfReceiveAntennas(1);
450  Ptr<NistErrorRateModel> nist = CreateObject<NistErrorRateModel>();
451  interference.SetErrorRateModel(nist);
452 
453  // SISO: initial SNR set to 4dB
454  double initialSnr = 4.0;
455  double snr = interference.CalculateSnr(0.001,
456  0.001 / DbToRatio(initialSnr),
457  txVector.GetChannelWidth(),
458  txVector.GetNss());
460  initialSnr,
461  0.1,
462  "Attempt to set initial SNR to known value failed");
463  Time duration = MilliSeconds(2);
464  double chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
465  NS_TEST_ASSERT_MSG_EQ_TOL(chunkSuccess,
466  0.905685,
467  0.000001,
468  "CSR not within tolerance for SISO");
469  double sisoChunkSuccess = chunkSuccess;
470 
471  // MIMO 2x1:2: expect no SNR gain in AWGN channel
472  txVector.SetNss(2);
473  txVector.SetNTx(2);
474  snr = interference.CalculateSnr(0.001,
475  0.001 / DbToRatio(initialSnr),
476  txVector.GetChannelWidth(),
477  txVector.GetNss());
479  initialSnr,
480  0.1,
481  "SNR not within tolerance for 2x1:2 MIMO");
482  chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
483  NS_TEST_ASSERT_MSG_EQ_TOL(chunkSuccess,
484  0.905685,
485  0.000001,
486  "CSR not within tolerance for SISO");
487 
488  // MIMO 1x2:1: expect that SNR is increased by a factor of 3 dB (10 log 2/1) compared to SISO
489  // thanks to RX diversity
490  txVector.SetNss(1);
491  txVector.SetNTx(1);
492  interference.SetNumberOfReceiveAntennas(2);
493  snr = interference.CalculateSnr(0.001,
494  0.001 / DbToRatio(initialSnr),
495  txVector.GetChannelWidth(),
496  txVector.GetNss());
498  initialSnr + 3,
499  0.1,
500  "SNR not within tolerance for 1x2:1 MIMO");
501  chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
502  NS_TEST_ASSERT_MSG_GT(chunkSuccess,
503  sisoChunkSuccess,
504  "CSR not within tolerance for 1x2:1 MIMO");
505 
506  // MIMO 2x2:1: expect that SNR is increased by a factor of 3 dB (10 log 2/1) compared to SISO
507  // thanks to RX diversity
508  txVector.SetNss(1);
509  txVector.SetNTx(2);
510  interference.SetNumberOfReceiveAntennas(2);
511  snr = interference.CalculateSnr(0.001,
512  0.001 / DbToRatio(initialSnr),
513  txVector.GetChannelWidth(),
514  txVector.GetNss());
516  initialSnr + 3,
517  0.1,
518  "SNR not equal within tolerance for 2x2:1 MIMO");
519  chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
520  NS_TEST_ASSERT_MSG_GT(chunkSuccess,
521  sisoChunkSuccess,
522  "CSR not within tolerance for 2x2:1 MIMO");
523 
524  // MIMO 2x2:2: expect no SNR gain in AWGN channel
525  txVector.SetNss(2);
526  txVector.SetNTx(2);
527  interference.SetNumberOfReceiveAntennas(2);
528  snr = interference.CalculateSnr(0.001,
529  0.001 / DbToRatio(initialSnr),
530  txVector.GetChannelWidth(),
531  txVector.GetNss());
533  initialSnr,
534  0.1,
535  "SNR not equal within tolerance for 2x2:2 MIMO");
536  chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
537  NS_TEST_ASSERT_MSG_EQ_TOL(chunkSuccess,
538  sisoChunkSuccess,
539  0.000001,
540  "CSR not within tolerance for 2x2:2 MIMO");
541 
542  // MIMO 3x3:1: expect that SNR is increased by a factor of 4.8 dB (10 log 3/1) compared to SISO
543  // thanks to RX diversity
544  txVector.SetNss(1);
545  txVector.SetNTx(3);
546  interference.SetNumberOfReceiveAntennas(3);
547  snr = interference.CalculateSnr(0.001,
548  0.001 / DbToRatio(initialSnr),
549  txVector.GetChannelWidth(),
550  txVector.GetNss());
552  initialSnr + 4.8,
553  0.1,
554  "SNR not within tolerance for 3x3:1 MIMO");
555  chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
556  NS_TEST_ASSERT_MSG_GT(chunkSuccess,
557  sisoChunkSuccess,
558  "CSR not within tolerance for 3x3:1 MIMO");
559 
560  // MIMO 3x3:2: expect that SNR is increased by a factor of 1.8 dB (10 log 3/2) compared to SISO
561  // thanks to RX diversity
562  txVector.SetNss(2);
563  txVector.SetNTx(3);
564  interference.SetNumberOfReceiveAntennas(3);
565  snr = interference.CalculateSnr(0.001,
566  0.001 / DbToRatio(initialSnr),
567  txVector.GetChannelWidth(),
568  txVector.GetNss());
570  initialSnr + 1.8,
571  0.1,
572  "SNR not within tolerance for 3x3:2 MIMO");
573  chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
574  NS_TEST_ASSERT_MSG_GT(chunkSuccess,
575  sisoChunkSuccess,
576  "CSR not within tolerance for 3x3:2 MIMO");
577 
578  // MIMO 3x3:3: expect no SNR gain in AWGN channel
579  txVector.SetNss(3);
580  txVector.SetNTx(3);
581  interference.SetNumberOfReceiveAntennas(3);
582  snr = interference.CalculateSnr(0.001,
583  0.001 / DbToRatio(initialSnr),
584  txVector.GetChannelWidth(),
585  txVector.GetNss());
587  initialSnr,
588  0.1,
589  "SNR not within tolerance for 3x3:3 MIMO");
590  chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
591  NS_TEST_ASSERT_MSG_EQ_TOL(chunkSuccess,
592  sisoChunkSuccess,
593  0.000001,
594  "CSR not equal within tolerance for 3x3:3 MIMO");
595 
596  // MIMO 4x4:1: expect that SNR is increased by a factor of 6 dB (10 log 4/1) compared to SISO
597  // thanks to RX diversity
598  txVector.SetNss(1);
599  txVector.SetNTx(4);
600  interference.SetNumberOfReceiveAntennas(4);
601  snr = interference.CalculateSnr(0.001,
602  0.001 / DbToRatio(initialSnr),
603  txVector.GetChannelWidth(),
604  txVector.GetNss());
606  initialSnr + 6,
607  0.1,
608  "SNR not within tolerance for 4x4:1 MIMO");
609  chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
610  NS_TEST_ASSERT_MSG_GT(chunkSuccess,
611  sisoChunkSuccess,
612  "CSR not within tolerance for 4x4:1 MIMO");
613 
614  // MIMO 4x4:2: expect that SNR is increased by a factor of 3 dB (10 log 4/2) compared to SISO
615  // thanks to RX diversity
616  txVector.SetNss(2);
617  txVector.SetNTx(4);
618  interference.SetNumberOfReceiveAntennas(4);
619  snr = interference.CalculateSnr(0.001,
620  0.001 / DbToRatio(initialSnr),
621  txVector.GetChannelWidth(),
622  txVector.GetNss());
624  initialSnr + 3,
625  0.1,
626  "SNR not within tolerance for 4x4:2 MIMO");
627  chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
628  NS_TEST_ASSERT_MSG_GT(chunkSuccess,
629  sisoChunkSuccess,
630  "CSR not within tolerance for 4x4:2 MIMO");
631 
632  // MIMO 4x4:3: expect that SNR is increased by a factor of 1.2 dB (10 log 4/3) compared to SISO
633  // thanks to RX diversity
634  txVector.SetNss(3);
635  txVector.SetNTx(4);
636  interference.SetNumberOfReceiveAntennas(4);
637  snr = interference.CalculateSnr(0.001,
638  0.001 / DbToRatio(initialSnr),
639  txVector.GetChannelWidth(),
640  txVector.GetNss());
642  initialSnr + 1.2,
643  0.1,
644  "SNR not within tolerance for 4x4:3 MIMO");
645  chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
646  NS_TEST_ASSERT_MSG_GT(chunkSuccess,
647  sisoChunkSuccess,
648  "CSR not within tolerance for 4x4:1 MIMO");
649 
650  // MIMO 4x4:4: expect no SNR gain in AWGN channel
651  txVector.SetNss(4);
652  txVector.SetNTx(4);
653  interference.SetNumberOfReceiveAntennas(4);
654  snr = interference.CalculateSnr(0.001,
655  0.001 / DbToRatio(initialSnr),
656  txVector.GetChannelWidth(),
657  txVector.GetNss());
659  initialSnr,
660  0.1,
661  "SNR not within tolerance for 4x4:4 MIMO");
662  chunkSuccess = interference.CalculatePayloadChunkSuccessRate(snr, duration, txVector);
663  NS_TEST_ASSERT_MSG_EQ_TOL(chunkSuccess,
664  sisoChunkSuccess,
665  0.000001,
666  "CSR not within tolerance for 4x4:4 MIMO");
667 }
668 
673 std::map<std::pair<uint8_t /* mcs */, uint32_t /* size */>,
674  std::map<double /* snr */, double /* per */>>
676  /* MCS 0 - 1458 bytes */
677  {std::make_pair(0, 1458),
678  {
679  {-4.00, 1.00000}, {-3.75, 1.00000}, {-3.50, 1.00000}, {-3.25, 1.00000},
680  {-3.00, 1.00000}, {-2.75, 1.00000}, {-2.50, 1.00000}, {-2.25, 1.00000},
681  {-2.00, 1.00000}, {-1.75, 1.00000}, {-1.50, 1.00000}, {-1.25, 1.00000},
682  {-1.00, 1.00000}, {-0.75, 0.99700}, {-0.50, 0.99400}, {-0.25, 0.90625},
683  {0.00, 0.81850}, {0.25, 0.55465}, {0.50, 0.29080}, {0.75, 0.17855},
684  {1.00, 0.06630}, {1.25, 0.03875}, {1.50, 0.01120}, {1.75, 0.00635},
685  {2.00, 0.00150}, {2.25, 0.00083}, {2.50, 0.00015}, {2.75, 0.00008},
686  {3.00, 0.00001}, {3.25, 0.00000}, {3.50, 0.00000}, {3.75, 0.00000},
687  {4.00, 0.00000}, {4.25, 0.00000}, {4.50, 0.00000}, {4.75, 0.00000},
688  {5.00, 0.00000}, {5.25, 0.00000}, {5.50, 0.00000}, {5.75, 0.00000},
689  {6.00, 0.00000}, {6.25, 0.00000}, {6.50, 0.00000}, {6.75, 0.00000},
690  {7.00, 0.00000}, {7.25, 0.00000}, {7.50, 0.00000}, {7.75, 0.00000},
691  {8.00, 0.00000}, {8.25, 0.00000}, {8.50, 0.00000}, {8.75, 0.00000},
692  {9.00, 0.00000}, {9.25, 0.00000}, {9.50, 0.00000}, {9.75, 0.00000},
693  {10.00, 0.00000}, {10.25, 0.00000}, {10.50, 0.00000}, {10.75, 0.00000},
694  {11.00, 0.00000}, {11.25, 0.00000}, {11.50, 0.00000}, {11.75, 0.00000},
695  {12.00, 0.00000}, {12.25, 0.00000}, {12.50, 0.00000}, {12.75, 0.00000},
696  {13.00, 0.00000}, {13.25, 0.00000}, {13.50, 0.00000}, {13.75, 0.00000},
697  {14.00, 0.00000}, {14.25, 0.00000}, {14.50, 0.00000}, {14.75, 0.00000},
698  {15.00, 0.00000}, {15.25, 0.00000}, {15.50, 0.00000}, {15.75, 0.00000},
699  {16.00, 0.00000}, {16.25, 0.00000}, {16.50, 0.00000}, {16.75, 0.00000},
700  {17.00, 0.00000}, {17.25, 0.00000}, {17.50, 0.00000}, {17.75, 0.00000},
701  {18.00, 0.00000}, {18.25, 0.00000}, {18.50, 0.00000}, {18.75, 0.00000},
702  {19.00, 0.00000}, {19.25, 0.00000}, {19.50, 0.00000}, {19.75, 0.00000},
703  {20.00, 0.00000}, {20.25, 0.00000}, {20.50, 0.00000}, {20.75, 0.00000},
704  {21.00, 0.00000}, {21.25, 0.00000}, {21.50, 0.00000}, {21.75, 0.00000},
705  {22.00, 0.00000}, {22.25, 0.00000}, {22.50, 0.00000}, {22.75, 0.00000},
706  {23.00, 0.00000}, {23.25, 0.00000}, {23.50, 0.00000}, {23.75, 0.00000},
707  {24.00, 0.00000}, {24.25, 0.00000}, {24.50, 0.00000}, {24.75, 0.00000},
708  {25.00, 0.00000}, {25.25, 0.00000}, {25.50, 0.00000}, {25.75, 0.00000},
709  {26.00, 0.00000}, {26.25, 0.00000}, {26.50, 0.00000}, {26.75, 0.00000},
710  {27.00, 0.00000}, {27.25, 0.00000}, {27.50, 0.00000}, {27.75, 0.00000},
711  {28.00, 0.00000}, {28.25, 0.00000}, {28.50, 0.00000}, {28.75, 0.00000},
712  {29.00, 0.00000}, {29.25, 0.00000}, {29.50, 0.00000}, {29.75, 0.00000},
713  {30.00, 0.00000},
714  }},
715  /* MCS 0 - 32 bytes */
716  {std::make_pair(0, 32),
717  {
718  {-4.00, 1.00000}, {-3.75, 1.00000}, {-3.50, 1.00000}, {-3.25, 0.99750},
719  {-3.00, 0.99500}, {-2.75, 0.96790}, {-2.50, 0.94080}, {-2.25, 0.88335},
720  {-2.00, 0.82590}, {-1.75, 0.70770}, {-1.50, 0.58950}, {-1.25, 0.44890},
721  {-1.00, 0.30830}, {-0.75, 0.21685}, {-0.50, 0.12540}, {-0.25, 0.07990},
722  {0.00, 0.03440}, {0.25, 0.02145}, {0.50, 0.00850}, {0.75, 0.00500},
723  {1.00, 0.00150}, {1.25, 0.00087}, {1.50, 0.00024}, {1.75, 0.00017},
724  {2.00, 0.00009}, {2.25, 0.00005}, {2.50, 0.00000}, {2.75, 0.00000},
725  {3.00, 0.00000}, {3.25, 0.00000}, {3.50, 0.00000}, {3.75, 0.00000},
726  {4.00, 0.00000}, {4.25, 0.00000}, {4.50, 0.00000}, {4.75, 0.00000},
727  {5.00, 0.00000}, {5.25, 0.00000}, {5.50, 0.00000}, {5.75, 0.00000},
728  {6.00, 0.00000}, {6.25, 0.00000}, {6.50, 0.00000}, {6.75, 0.00000},
729  {7.00, 0.00000}, {7.25, 0.00000}, {7.50, 0.00000}, {7.75, 0.00000},
730  {8.00, 0.00000}, {8.25, 0.00000}, {8.50, 0.00000}, {8.75, 0.00000},
731  {9.00, 0.00000}, {9.25, 0.00000}, {9.50, 0.00000}, {9.75, 0.00000},
732  {10.00, 0.00000}, {10.25, 0.00000}, {10.50, 0.00000}, {10.75, 0.00000},
733  {11.00, 0.00000}, {11.25, 0.00000}, {11.50, 0.00000}, {11.75, 0.00000},
734  {12.00, 0.00000}, {12.25, 0.00000}, {12.50, 0.00000}, {12.75, 0.00000},
735  {13.00, 0.00000}, {13.25, 0.00000}, {13.50, 0.00000}, {13.75, 0.00000},
736  {14.00, 0.00000}, {14.25, 0.00000}, {14.50, 0.00000}, {14.75, 0.00000},
737  {15.00, 0.00000}, {15.25, 0.00000}, {15.50, 0.00000}, {15.75, 0.00000},
738  {16.00, 0.00000}, {16.25, 0.00000}, {16.50, 0.00000}, {16.75, 0.00000},
739  {17.00, 0.00000}, {17.25, 0.00000}, {17.50, 0.00000}, {17.75, 0.00000},
740  {18.00, 0.00000}, {18.25, 0.00000}, {18.50, 0.00000}, {18.75, 0.00000},
741  {19.00, 0.00000}, {19.25, 0.00000}, {19.50, 0.00000}, {19.75, 0.00000},
742  {20.00, 0.00000}, {20.25, 0.00000}, {20.50, 0.00000}, {20.75, 0.00000},
743  {21.00, 0.00000}, {21.25, 0.00000}, {21.50, 0.00000}, {21.75, 0.00000},
744  {22.00, 0.00000}, {22.25, 0.00000}, {22.50, 0.00000}, {22.75, 0.00000},
745  {23.00, 0.00000}, {23.25, 0.00000}, {23.50, 0.00000}, {23.75, 0.00000},
746  {24.00, 0.00000}, {24.25, 0.00000}, {24.50, 0.00000}, {24.75, 0.00000},
747  {25.00, 0.00000}, {25.25, 0.00000}, {25.50, 0.00000}, {25.75, 0.00000},
748  {26.00, 0.00000}, {26.25, 0.00000}, {26.50, 0.00000}, {26.75, 0.00000},
749  {27.00, 0.00000}, {27.25, 0.00000}, {27.50, 0.00000}, {27.75, 0.00000},
750  {28.00, 0.00000}, {28.25, 0.00000}, {28.50, 0.00000}, {28.75, 0.00000},
751  {29.00, 0.00000}, {29.25, 0.00000}, {29.50, 0.00000}, {29.75, 0.00000},
752  {30.00, 0.00000},
753  }},
754  /* MCS 0 - 1000 bytes */
755  {std::make_pair(0, 1000),
756  {
757  {-4.00, 1.00000}, {-3.75, 1.00000}, {-3.50, 1.00000}, {-3.25, 1.00000},
758  {-3.00, 1.00000}, {-2.75, 1.00000}, {-2.50, 1.00000}, {-2.25, 1.00000},
759  {-2.00, 1.00000}, {-1.75, 1.00000}, {-1.50, 1.00000}, {-1.25, 1.00000},
760  {-1.00, 1.00000}, {-0.75, 0.98140}, {-0.50, 0.97007}, {-0.25, 0.80280},
761  {0.00, 0.68977}, {0.25, 0.42581}, {0.50, 0.20997}, {0.75, 0.12620},
762  {1.00, 0.04596}, {1.25, 0.02674}, {1.50, 0.00770}, {1.75, 0.00436},
763  {2.00, 0.00103}, {2.25, 0.00057}, {2.50, 0.00010}, {2.75, 0.00005},
764  {3.00, 0.00001}, {3.25, 0.00000}, {3.50, 0.00000}, {3.75, 0.00000},
765  {4.00, 0.00000}, {4.25, 0.00000}, {4.50, 0.00000}, {4.75, 0.00000},
766  {5.00, 0.00000}, {5.25, 0.00000}, {5.50, 0.00000}, {5.75, 0.00000},
767  {6.00, 0.00000}, {6.25, 0.00000}, {6.50, 0.00000}, {6.75, 0.00000},
768  {7.00, 0.00000}, {7.25, 0.00000}, {7.50, 0.00000}, {7.75, 0.00000},
769  {8.00, 0.00000}, {8.25, 0.00000}, {8.50, 0.00000}, {8.75, 0.00000},
770  {9.00, 0.00000}, {9.25, 0.00000}, {9.50, 0.00000}, {9.75, 0.00000},
771  {10.00, 0.00000}, {10.25, 0.00000}, {10.50, 0.00000}, {10.75, 0.00000},
772  {11.00, 0.00000}, {11.25, 0.00000}, {11.50, 0.00000}, {11.75, 0.00000},
773  {12.00, 0.00000}, {12.25, 0.00000}, {12.50, 0.00000}, {12.75, 0.00000},
774  {13.00, 0.00000}, {13.25, 0.00000}, {13.50, 0.00000}, {13.75, 0.00000},
775  {14.00, 0.00000}, {14.25, 0.00000}, {14.50, 0.00000}, {14.75, 0.00000},
776  {15.00, 0.00000}, {15.25, 0.00000}, {15.50, 0.00000}, {15.75, 0.00000},
777  {16.00, 0.00000}, {16.25, 0.00000}, {16.50, 0.00000}, {16.75, 0.00000},
778  {17.00, 0.00000}, {17.25, 0.00000}, {17.50, 0.00000}, {17.75, 0.00000},
779  {18.00, 0.00000}, {18.25, 0.00000}, {18.50, 0.00000}, {18.75, 0.00000},
780  {19.00, 0.00000}, {19.25, 0.00000}, {19.50, 0.00000}, {19.75, 0.00000},
781  {20.00, 0.00000}, {20.25, 0.00000}, {20.50, 0.00000}, {20.75, 0.00000},
782  {21.00, 0.00000}, {21.25, 0.00000}, {21.50, 0.00000}, {21.75, 0.00000},
783  {22.00, 0.00000}, {22.25, 0.00000}, {22.50, 0.00000}, {22.75, 0.00000},
784  {23.00, 0.00000}, {23.25, 0.00000}, {23.50, 0.00000}, {23.75, 0.00000},
785  {24.00, 0.00000}, {24.25, 0.00000}, {24.50, 0.00000}, {24.75, 0.00000},
786  {25.00, 0.00000}, {25.25, 0.00000}, {25.50, 0.00000}, {25.75, 0.00000},
787  {26.00, 0.00000}, {26.25, 0.00000}, {26.50, 0.00000}, {26.75, 0.00000},
788  {27.00, 0.00000}, {27.25, 0.00000}, {27.50, 0.00000}, {27.75, 0.00000},
789  {28.00, 0.00000}, {28.25, 0.00000}, {28.50, 0.00000}, {28.75, 0.00000},
790  {29.00, 0.00000}, {29.25, 0.00000}, {29.50, 0.00000}, {29.75, 0.00000},
791  {30.00, 0.00000},
792  }},
793  /* MCS 0 - 1 byte */
794  {std::make_pair(0, 1),
795  {
796  {-4.00, 1.00000}, {-3.75, 1.00000}, {-3.50, 1.00000}, {-3.25, 0.17075},
797  {-3.00, 0.15260}, {-2.75, 0.10190}, {-2.50, 0.08455}, {-2.25, 0.06494},
798  {-2.00, 0.05316}, {-1.75, 0.03771}, {-1.50, 0.02744}, {-1.25, 0.01845},
799  {-1.00, 0.01145}, {-0.75, 0.00761}, {-0.50, 0.00418}, {-0.25, 0.00260},
800  {0.00, 0.00110}, {0.25, 0.00068}, {0.50, 0.00027}, {0.75, 0.00016},
801  {1.00, 0.00005}, {1.25, 0.00003}, {1.50, 0.00000}, {1.75, 0.00000},
802  {2.00, 0.00000}, {2.25, 0.00000}, {2.50, 0.00000}, {2.75, 0.00000},
803  {3.00, 0.00000}, {3.25, 0.00000}, {3.50, 0.00000}, {3.75, 0.00000},
804  {4.00, 0.00000}, {4.25, 0.00000}, {4.50, 0.00000}, {4.75, 0.00000},
805  {5.00, 0.00000}, {5.25, 0.00000}, {5.50, 0.00000}, {5.75, 0.00000},
806  {6.00, 0.00000}, {6.25, 0.00000}, {6.50, 0.00000}, {6.75, 0.00000},
807  {7.00, 0.00000}, {7.25, 0.00000}, {7.50, 0.00000}, {7.75, 0.00000},
808  {8.00, 0.00000}, {8.25, 0.00000}, {8.50, 0.00000}, {8.75, 0.00000},
809  {9.00, 0.00000}, {9.25, 0.00000}, {9.50, 0.00000}, {9.75, 0.00000},
810  {10.00, 0.00000}, {10.25, 0.00000}, {10.50, 0.00000}, {10.75, 0.00000},
811  {11.00, 0.00000}, {11.25, 0.00000}, {11.50, 0.00000}, {11.75, 0.00000},
812  {12.00, 0.00000}, {12.25, 0.00000}, {12.50, 0.00000}, {12.75, 0.00000},
813  {13.00, 0.00000}, {13.25, 0.00000}, {13.50, 0.00000}, {13.75, 0.00000},
814  {14.00, 0.00000}, {14.25, 0.00000}, {14.50, 0.00000}, {14.75, 0.00000},
815  {15.00, 0.00000}, {15.25, 0.00000}, {15.50, 0.00000}, {15.75, 0.00000},
816  {16.00, 0.00000}, {16.25, 0.00000}, {16.50, 0.00000}, {16.75, 0.00000},
817  {17.00, 0.00000}, {17.25, 0.00000}, {17.50, 0.00000}, {17.75, 0.00000},
818  {18.00, 0.00000}, {18.25, 0.00000}, {18.50, 0.00000}, {18.75, 0.00000},
819  {19.00, 0.00000}, {19.25, 0.00000}, {19.50, 0.00000}, {19.75, 0.00000},
820  {20.00, 0.00000}, {20.25, 0.00000}, {20.50, 0.00000}, {20.75, 0.00000},
821  {21.00, 0.00000}, {21.25, 0.00000}, {21.50, 0.00000}, {21.75, 0.00000},
822  {22.00, 0.00000}, {22.25, 0.00000}, {22.50, 0.00000}, {22.75, 0.00000},
823  {23.00, 0.00000}, {23.25, 0.00000}, {23.50, 0.00000}, {23.75, 0.00000},
824  {24.00, 0.00000}, {24.25, 0.00000}, {24.50, 0.00000}, {24.75, 0.00000},
825  {25.00, 0.00000}, {25.25, 0.00000}, {25.50, 0.00000}, {25.75, 0.00000},
826  {26.00, 0.00000}, {26.25, 0.00000}, {26.50, 0.00000}, {26.75, 0.00000},
827  {27.00, 0.00000}, {27.25, 0.00000}, {27.50, 0.00000}, {27.75, 0.00000},
828  {28.00, 0.00000}, {28.25, 0.00000}, {28.50, 0.00000}, {28.75, 0.00000},
829  {29.00, 0.00000}, {29.25, 0.00000}, {29.50, 0.00000}, {29.75, 0.00000},
830  {30.00, 0.00000},
831  }},
832  /* MCS 0 - 2000 bytes */
833  {std::make_pair(0, 2000),
834  {
835  {-4.00, 1.00000}, {-3.75, 1.00000}, {-3.50, 1.00000}, {-3.25, 1.00000},
836  {-3.00, 1.00000}, {-2.75, 1.00000}, {-2.50, 1.00000}, {-2.25, 1.00000},
837  {-2.00, 1.00000}, {-1.75, 1.00000}, {-1.50, 1.00000}, {-1.25, 1.00000},
838  {-1.00, 1.00000}, {-0.75, 0.99965}, {-0.50, 0.99910}, {-0.25, 0.96111},
839  {0.00, 0.90376}, {0.25, 0.67031}, {0.50, 0.37584}, {0.75, 0.23647},
840  {1.00, 0.08981}, {1.25, 0.05277}, {1.50, 0.01533}, {1.75, 0.00870},
841  {2.00, 0.00206}, {2.25, 0.00113}, {2.50, 0.00021}, {2.75, 0.00011},
842  {3.00, 0.00001}, {3.25, 0.00000}, {3.50, 0.00000}, {3.75, 0.00000},
843  {4.00, 0.00000}, {4.25, 0.00000}, {4.50, 0.00000}, {4.75, 0.00000},
844  {5.00, 0.00000}, {5.25, 0.00000}, {5.50, 0.00000}, {5.75, 0.00000},
845  {6.00, 0.00000}, {6.25, 0.00000}, {6.50, 0.00000}, {6.75, 0.00000},
846  {7.00, 0.00000}, {7.25, 0.00000}, {7.50, 0.00000}, {7.75, 0.00000},
847  {8.00, 0.00000}, {8.25, 0.00000}, {8.50, 0.00000}, {8.75, 0.00000},
848  {9.00, 0.00000}, {9.25, 0.00000}, {9.50, 0.00000}, {9.75, 0.00000},
849  {10.00, 0.00000}, {10.25, 0.00000}, {10.50, 0.00000}, {10.75, 0.00000},
850  {11.00, 0.00000}, {11.25, 0.00000}, {11.50, 0.00000}, {11.75, 0.00000},
851  {12.00, 0.00000}, {12.25, 0.00000}, {12.50, 0.00000}, {12.75, 0.00000},
852  {13.00, 0.00000}, {13.25, 0.00000}, {13.50, 0.00000}, {13.75, 0.00000},
853  {14.00, 0.00000}, {14.25, 0.00000}, {14.50, 0.00000}, {14.75, 0.00000},
854  {15.00, 0.00000}, {15.25, 0.00000}, {15.50, 0.00000}, {15.75, 0.00000},
855  {16.00, 0.00000}, {16.25, 0.00000}, {16.50, 0.00000}, {16.75, 0.00000},
856  {17.00, 0.00000}, {17.25, 0.00000}, {17.50, 0.00000}, {17.75, 0.00000},
857  {18.00, 0.00000}, {18.25, 0.00000}, {18.50, 0.00000}, {18.75, 0.00000},
858  {19.00, 0.00000}, {19.25, 0.00000}, {19.50, 0.00000}, {19.75, 0.00000},
859  {20.00, 0.00000}, {20.25, 0.00000}, {20.50, 0.00000}, {20.75, 0.00000},
860  {21.00, 0.00000}, {21.25, 0.00000}, {21.50, 0.00000}, {21.75, 0.00000},
861  {22.00, 0.00000}, {22.25, 0.00000}, {22.50, 0.00000}, {22.75, 0.00000},
862  {23.00, 0.00000}, {23.25, 0.00000}, {23.50, 0.00000}, {23.75, 0.00000},
863  {24.00, 0.00000}, {24.25, 0.00000}, {24.50, 0.00000}, {24.75, 0.00000},
864  {25.00, 0.00000}, {25.25, 0.00000}, {25.50, 0.00000}, {25.75, 0.00000},
865  {26.00, 0.00000}, {26.25, 0.00000}, {26.50, 0.00000}, {26.75, 0.00000},
866  {27.00, 0.00000}, {27.25, 0.00000}, {27.50, 0.00000}, {27.75, 0.00000},
867  {28.00, 0.00000}, {28.25, 0.00000}, {28.50, 0.00000}, {28.75, 0.00000},
868  {29.00, 0.00000}, {29.25, 0.00000}, {29.50, 0.00000}, {29.75, 0.00000},
869  {30.00, 0.00000},
870  }},
871  /* MCS 7 - 1500 bytes */
872  {std::make_pair(7, 1500),
873  {
874  {-4.00, 1.00000}, {-3.75, 1.00000}, {-3.50, 1.00000}, {-3.25, 1.00000},
875  {-3.00, 1.00000}, {-2.75, 1.00000}, {-2.50, 1.00000}, {-2.25, 1.00000},
876  {-2.00, 1.00000}, {-1.75, 1.00000}, {-1.50, 1.00000}, {-1.25, 1.00000},
877  {-1.00, 1.00000}, {-0.75, 1.00000}, {-0.50, 1.00000}, {-0.25, 1.00000},
878  {0.00, 1.00000}, {0.25, 1.00000}, {0.50, 1.00000}, {0.75, 1.00000},
879  {1.00, 1.00000}, {1.25, 1.00000}, {1.50, 1.00000}, {1.75, 1.00000},
880  {2.00, 1.00000}, {2.25, 1.00000}, {2.50, 1.00000}, {2.75, 1.00000},
881  {3.00, 1.00000}, {3.25, 1.00000}, {3.50, 1.00000}, {3.75, 1.00000},
882  {4.00, 1.00000}, {4.25, 1.00000}, {4.50, 1.00000}, {4.75, 1.00000},
883  {5.00, 1.00000}, {5.25, 1.00000}, {5.50, 1.00000}, {5.75, 1.00000},
884  {6.00, 1.00000}, {6.25, 1.00000}, {6.50, 1.00000}, {6.75, 1.00000},
885  {7.00, 1.00000}, {7.25, 1.00000}, {7.50, 1.00000}, {7.75, 1.00000},
886  {8.00, 1.00000}, {8.25, 1.00000}, {8.50, 1.00000}, {8.75, 1.00000},
887  {9.00, 1.00000}, {9.25, 1.00000}, {9.50, 1.00000}, {9.75, 1.00000},
888  {10.00, 1.00000}, {10.25, 1.00000}, {10.50, 1.00000}, {10.75, 1.00000},
889  {11.00, 1.00000}, {11.25, 1.00000}, {11.50, 1.00000}, {11.75, 1.00000},
890  {12.00, 1.00000}, {12.25, 1.00000}, {12.50, 1.00000}, {12.75, 1.00000},
891  {13.00, 1.00000}, {13.25, 1.00000}, {13.50, 1.00000}, {13.75, 1.00000},
892  {14.00, 1.00000}, {14.25, 1.00000}, {14.50, 1.00000}, {14.75, 1.00000},
893  {15.00, 1.00000}, {15.25, 1.00000}, {15.50, 1.00000}, {15.75, 1.00000},
894  {16.00, 1.00000}, {16.25, 1.00000}, {16.50, 1.00000}, {16.75, 1.00000},
895  {17.00, 1.00000}, {17.25, 1.00000}, {17.50, 1.00000}, {17.75, 0.99057},
896  {18.00, 0.98075}, {18.25, 0.86664}, {18.50, 0.74920}, {18.75, 0.54857},
897  {19.00, 0.34531}, {19.25, 0.23624}, {19.50, 0.12672}, {19.75, 0.08164},
898  {20.00, 0.03650}, {20.25, 0.02340}, {20.50, 0.01029}, {20.75, 0.00653},
899  {21.00, 0.00278}, {21.25, 0.00165}, {21.50, 0.00051}, {21.75, 0.00030},
900  {22.00, 0.00009}, {22.25, 0.00005}, {22.50, 0.00001}, {22.75, 0.00000},
901  {23.00, 0.00000}, {23.25, 0.00000}, {23.50, 0.00000}, {23.75, 0.00000},
902  {24.00, 0.00000}, {24.25, 0.00000}, {24.50, 0.00000}, {24.75, 0.00000},
903  {25.00, 0.00000}, {25.25, 0.00000}, {25.50, 0.00000}, {25.75, 0.00000},
904  {26.00, 0.00000}, {26.25, 0.00000}, {26.50, 0.00000}, {26.75, 0.00000},
905  {27.00, 0.00000}, {27.25, 0.00000}, {27.50, 0.00000}, {27.75, 0.00000},
906  {28.00, 0.00000}, {28.25, 0.00000}, {28.50, 0.00000}, {28.75, 0.00000},
907  {29.00, 0.00000}, {29.25, 0.00000}, {29.50, 0.00000}, {29.75, 0.00000},
908  {30.00, 0.00000},
909  }},
910  /* MCS 8 - 1500 bytes */
911  {std::make_pair(8, 1500),
912  {
913  {-4.00, 1.00000}, {-3.75, 1.00000}, {-3.50, 1.00000}, {-3.25, 1.00000},
914  {-3.00, 1.00000}, {-2.75, 1.00000}, {-2.50, 1.00000}, {-2.25, 1.00000},
915  {-2.00, 1.00000}, {-1.75, 1.00000}, {-1.50, 1.00000}, {-1.25, 1.00000},
916  {-1.00, 1.00000}, {-0.75, 1.00000}, {-0.50, 1.00000}, {-0.25, 1.00000},
917  {0.00, 1.00000}, {0.25, 1.00000}, {0.50, 1.00000}, {0.75, 1.00000},
918  {1.00, 1.00000}, {1.25, 1.00000}, {1.50, 1.00000}, {1.75, 1.00000},
919  {2.00, 1.00000}, {2.25, 1.00000}, {2.50, 1.00000}, {2.75, 1.00000},
920  {3.00, 1.00000}, {3.25, 1.00000}, {3.50, 1.00000}, {3.75, 1.00000},
921  {4.00, 1.00000}, {4.25, 1.00000}, {4.50, 1.00000}, {4.75, 1.00000},
922  {5.00, 1.00000}, {5.25, 1.00000}, {5.50, 1.00000}, {5.75, 1.00000},
923  {6.00, 1.00000}, {6.25, 1.00000}, {6.50, 1.00000}, {6.75, 1.00000},
924  {7.00, 1.00000}, {7.25, 1.00000}, {7.50, 1.00000}, {7.75, 1.00000},
925  {8.00, 1.00000}, {8.25, 1.00000}, {8.50, 1.00000}, {8.75, 1.00000},
926  {9.00, 1.00000}, {9.25, 1.00000}, {9.50, 1.00000}, {9.75, 1.00000},
927  {10.00, 1.00000}, {10.25, 1.00000}, {10.50, 1.00000}, {10.75, 1.00000},
928  {11.00, 1.00000}, {11.25, 1.00000}, {11.50, 1.00000}, {11.75, 1.00000},
929  {12.00, 1.00000}, {12.25, 1.00000}, {12.50, 1.00000}, {12.75, 1.00000},
930  {13.00, 1.00000}, {13.25, 1.00000}, {13.50, 1.00000}, {13.75, 1.00000},
931  {14.00, 1.00000}, {14.25, 1.00000}, {14.50, 1.00000}, {14.75, 1.00000},
932  {15.00, 1.00000}, {15.25, 1.00000}, {15.50, 1.00000}, {15.75, 1.00000},
933  {16.00, 1.00000}, {16.25, 1.00000}, {16.50, 1.00000}, {16.75, 1.00000},
934  {17.00, 1.00000}, {17.25, 1.00000}, {17.50, 1.00000}, {17.75, 1.00000},
935  {18.00, 1.00000}, {18.25, 1.00000}, {18.50, 1.00000}, {18.75, 1.00000},
936  {19.00, 1.00000}, {19.25, 1.00000}, {19.50, 1.00000}, {19.75, 1.00000},
937  {20.00, 1.00000}, {20.25, 1.00000}, {20.50, 1.00000}, {20.75, 1.00000},
938  {21.00, 1.00000}, {21.25, 0.99918}, {21.50, 0.99833}, {21.75, 0.97191},
939  {22.00, 0.94458}, {22.25, 0.81436}, {22.50, 0.68127}, {22.75, 0.52168},
940  {23.00, 0.36056}, {23.25, 0.25114}, {23.50, 0.14127}, {23.75, 0.09509},
941  {24.00, 0.04883}, {24.25, 0.03234}, {24.50, 0.01584}, {24.75, 0.01060},
942  {25.00, 0.00535}, {25.25, 0.00345}, {25.50, 0.00154}, {25.75, 0.00096},
943  {26.00, 0.00037}, {26.25, 0.00022}, {26.50, 0.00007}, {26.75, 0.00004},
944  {27.00, 0.00000}, {27.25, 0.00000}, {27.50, 0.00000}, {27.75, 0.00000},
945  {28.00, 0.00000}, {28.25, 0.00000}, {28.50, 0.00000}, {28.75, 0.00000},
946  {29.00, 0.00000}, {29.25, 0.00000}, {29.50, 0.00000}, {29.75, 0.00000},
947  {30.00, 0.00000},
948  }},
949 };
950 
958 {
959  public:
967  TableBasedErrorRateTestCase(const std::string& testName, WifiMode mode, uint32_t size);
968  ~TableBasedErrorRateTestCase() override;
969 
970  private:
971  void DoRun() override;
972 
973  std::string m_testName;
975  uint32_t m_size;
976 };
977 
979  WifiMode mode,
980  uint32_t size)
981  : TestCase(testName),
982  m_testName(testName),
983  m_mode(mode),
984  m_size(size)
985 {
986 }
987 
989 {
990 }
991 
992 void
994 {
995  // LogComponentEnable ("WifiErrorRateModelsTest", LOG_LEVEL_ALL);
996  // LogComponentEnable ("TableBasedErrorRateModel", LOG_LEVEL_ALL);
997  // LogComponentEnable ("YansErrorRateModel", LOG_LEVEL_ALL);
998 
999  Ptr<TableBasedErrorRateModel> table = CreateObject<TableBasedErrorRateModel>();
1000  WifiTxVector txVector;
1001  txVector.SetMode(m_mode);
1002 
1003  // Spot test some values returned from TableBasedErrorRateModel
1004  for (double snr = -4; snr <= 30; snr += 0.25)
1005  {
1006  double expectedValue = 0;
1008  {
1009  Ptr<YansErrorRateModel> yans = CreateObject<YansErrorRateModel>();
1010  expectedValue =
1011  1 - yans->GetChunkSuccessRate(m_mode, txVector, std::pow(10, snr / 10), m_size * 8);
1012  }
1013  else
1014  {
1015  auto it = expectedTableValues.find(std::make_pair(m_mode.GetMcsValue(), m_size));
1016  if (it != expectedTableValues.end())
1017  {
1018  auto itValue = it->second.find(snr);
1019  if (itValue != it->second.end())
1020  {
1021  expectedValue = itValue->second;
1022  }
1023  else
1024  {
1025  NS_FATAL_ERROR("SNR value " << snr << " dB not found!");
1026  }
1027  }
1028  else
1029  {
1030  NS_FATAL_ERROR("No expected value found for the combination MCS "
1031  << +m_mode.GetMcsValue() << " and size " << m_size << " bytes");
1032  }
1033  }
1034  double per =
1035  1 - table->GetChunkSuccessRate(m_mode, txVector, std::pow(10, snr / 10), m_size * 8);
1036  NS_LOG_INFO(m_testName << ": snr=" << snr << "dB per=" << per
1037  << " expectedPER=" << expectedValue);
1038  NS_TEST_ASSERT_MSG_EQ_TOL(per, expectedValue, 1e-5, "Not equal within tolerance");
1039  }
1040 }
1041 
1049 {
1050  public:
1052 };
1053 
1055  : TestSuite("wifi-error-rate-models", UNIT)
1056 {
1057  AddTestCase(new WifiErrorRateModelsTestCaseDsss, TestCase::QUICK);
1058  AddTestCase(new WifiErrorRateModelsTestCaseNist, TestCase::QUICK);
1059  AddTestCase(new WifiErrorRateModelsTestCaseMimo, TestCase::QUICK);
1060  AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedHtMcs0-1458bytes",
1061  HtPhy::GetHtMcs0(),
1062  1458),
1063  TestCase::QUICK);
1064  AddTestCase(
1065  new TableBasedErrorRateTestCase("DefaultTableBasedHtMcs0-32bytes", HtPhy::GetHtMcs0(), 32),
1066  TestCase::QUICK);
1067  AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedHtMcs0-1000bytes",
1068  HtPhy::GetHtMcs0(),
1069  1000),
1070  TestCase::QUICK);
1071  AddTestCase(
1072  new TableBasedErrorRateTestCase("DefaultTableBasedHtMcs0-1byte", HtPhy::GetHtMcs0(), 1),
1073  TestCase::QUICK);
1074  AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedHtMcs0-2000bytes",
1075  HtPhy::GetHtMcs0(),
1076  2000),
1077  TestCase::QUICK);
1078  AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedHtMcs7-1500bytes",
1079  HtPhy::GetHtMcs7(),
1080  1500),
1081  TestCase::QUICK);
1082  AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedVhtMcs0-1458bytes",
1083  VhtPhy::GetVhtMcs0(),
1084  1458),
1085  TestCase::QUICK);
1086  AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedVhtMcs0-32bytes",
1087  VhtPhy::GetVhtMcs0(),
1088  32),
1089  TestCase::QUICK);
1090  AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedVhtMcs0-1000bytes",
1091  VhtPhy::GetVhtMcs0(),
1092  1000),
1093  TestCase::QUICK);
1094  AddTestCase(
1095  new TableBasedErrorRateTestCase("DefaultTableBasedVhtMcs0-1byte", VhtPhy::GetVhtMcs0(), 1),
1096  TestCase::QUICK);
1097  AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedVhtMcs0-2000bytes",
1098  VhtPhy::GetVhtMcs0(),
1099  2000),
1100  TestCase::QUICK);
1101  AddTestCase(new TableBasedErrorRateTestCase("DefaultTableBasedVhtMcs8-1500bytes",
1102  VhtPhy::GetVhtMcs8(),
1103  1500),
1104  TestCase::QUICK);
1105  AddTestCase(new TableBasedErrorRateTestCase("FallbackTableBasedHeMcs11-1458bytes",
1106  HePhy::GetHeMcs11(),
1107  1458),
1108  TestCase::QUICK);
1109 }
1110 
Wifi Table-based Error Rate Models Test Case.
void DoRun() override
Implementation to actually run this TestCase.
WifiMode m_mode
The WifiMode to test.
uint32_t m_size
The size (in bytes) to test.
TableBasedErrorRateTestCase(const std::string &testName, WifiMode mode, uint32_t size)
Constructor.
std::string m_testName
The name of the test to run.
Wifi Error Rate Models Test Case Dsss.
void DoRun() override
Implementation to actually run this TestCase.
Wifi Error Rate Models Test Case MIMO.
void DoRun() override
Implementation to actually run this TestCase.
Wifi Error Rate Models Test Case Nist.
void DoRun() override
Implementation to actually run this TestCase.
Wifi Error Rate Models Test Suite.
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:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
represent a single transmission mode
Definition: wifi-mode.h:51
uint8_t GetMcsValue() const
Definition: wifi-mode.cc:163
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetTxPowerLevel(uint8_t powerlevel)
Sets the selected transmission power level.
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
uint8_t GetNss(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the number of spatial streams.
void SetNTx(uint8_t nTx)
Sets the number of TX antennas.
uint16_t GetChannelWidth() const
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
void SetNss(uint8_t nss)
Sets the number of Nss.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_TEST_ASSERT_MSG_GT(actual, limit, msg)
Test that an actual value is greater than a limit and report and abort if not.
Definition: test.h:874
#define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report and...
Definition: test.h:337
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h: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
value
Definition: second.py:48
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