A Discrete-Event Network Simulator
API
three-gpp-propagation-loss-model-test-suite.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 SIGNET Lab, Department of Information Engineering,
3  * University of Padova
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */
18 
19 #include "ns3/abort.h"
20 #include "ns3/boolean.h"
21 #include "ns3/channel-condition-model.h"
22 #include "ns3/config.h"
23 #include "ns3/constant-position-mobility-model.h"
24 #include "ns3/constant-velocity-mobility-model.h"
25 #include "ns3/double.h"
26 #include "ns3/log.h"
27 #include "ns3/mobility-helper.h"
28 #include "ns3/simulator.h"
29 #include "ns3/test.h"
30 #include "ns3/three-gpp-propagation-loss-model.h"
31 #include "ns3/three-gpp-v2v-propagation-loss-model.h"
32 
33 using namespace ns3;
34 
35 NS_LOG_COMPONENT_DEFINE("ThreeGppPropagationLossModelsTest");
36 
45 {
46  public:
51 
56 
57  private:
61  void DoRun() override;
62 
66  struct TestVector
67  {
68  double m_distance;
69  bool m_isLos;
70  double m_frequency;
71  double m_pt;
72  double m_pr;
73  };
74 
76  double m_tolerance;
77 };
78 
80  : TestCase("Test for the ThreeGppRmaPropagationLossModel class"),
81  m_testVectors(),
82  m_tolerance(5e-2)
83 {
84 }
85 
87 {
88 }
89 
90 void
92 {
93  TestVector testVector;
94 
95  testVector.m_distance = 10.0;
96  testVector.m_isLos = true;
97  testVector.m_frequency = 5.0e9;
98  testVector.m_pt = 0.0;
99  testVector.m_pr = -77.3784;
100  m_testVectors.Add(testVector);
101 
102  testVector.m_distance = 100.0;
103  testVector.m_isLos = true;
104  testVector.m_frequency = 5.0e9;
105  testVector.m_pt = 0.0;
106  testVector.m_pr = -87.2965;
107  m_testVectors.Add(testVector);
108 
109  testVector.m_distance = 1000.0;
110  testVector.m_isLos = true;
111  testVector.m_frequency = 5.0e9;
112  testVector.m_pt = 0.0;
113  testVector.m_pr = -108.5577;
114  m_testVectors.Add(testVector);
115 
116  testVector.m_distance = 10000.0;
117  testVector.m_isLos = true;
118  testVector.m_frequency = 5.0e9;
119  testVector.m_pt = 0.0;
120  testVector.m_pr = -140.3896;
121  m_testVectors.Add(testVector);
122 
123  testVector.m_distance = 10.0;
124  testVector.m_isLos = false;
125  testVector.m_frequency = 5.0e9;
126  testVector.m_pt = 0.0;
127  testVector.m_pr = -77.3784;
128  m_testVectors.Add(testVector);
129 
130  testVector.m_distance = 100.0;
131  testVector.m_isLos = false;
132  testVector.m_frequency = 5.0e9;
133  testVector.m_pt = 0.0;
134  testVector.m_pr = -95.7718;
135  m_testVectors.Add(testVector);
136 
137  testVector.m_distance = 1000.0;
138  testVector.m_isLos = false;
139  testVector.m_frequency = 5.0e9;
140  testVector.m_pt = 0.0;
141  testVector.m_pr = -133.5223;
142  m_testVectors.Add(testVector);
143 
144  testVector.m_distance = 5000.0;
145  testVector.m_isLos = false;
146  testVector.m_frequency = 5.0e9;
147  testVector.m_pt = 0.0;
148  testVector.m_pr = -160.5169;
149  m_testVectors.Add(testVector);
150 
151  // Create the nodes for BS and UT
153  nodes.Create(2);
154 
155  // Create the mobility models
156  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
157  nodes.Get(0)->AggregateObject(a);
158  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
159  nodes.Get(1)->AggregateObject(b);
160 
161  // Use a deterministic channel condition model
162  Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel>();
163  Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel>();
164 
165  // Create the propagation loss model
167  CreateObject<ThreeGppRmaPropagationLossModel>();
168  lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
169 
170  for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
171  {
172  TestVector testVector = m_testVectors.Get(i);
173 
174  Vector posBs = Vector(0.0, 0.0, 35.0);
175  Vector posUt = Vector(testVector.m_distance, 0.0, 1.5);
176 
177  // set the LOS or NLOS condition
178  if (testVector.m_isLos)
179  {
180  lossModel->SetChannelConditionModel(losCondModel);
181  }
182  else
183  {
184  lossModel->SetChannelConditionModel(nlosCondModel);
185  }
186 
187  a->SetPosition(posBs);
188  b->SetPosition(posUt);
189 
190  lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
191  NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
192  testVector.m_pr,
193  m_tolerance,
194  "Got unexpected rcv power");
195  }
196 
197  Simulator::Destroy();
198 }
199 
208 {
209  public:
214 
219 
220  private:
224  void DoRun() override;
225 
229  struct TestVector
230  {
231  double m_distance;
232  bool m_isLos;
233  double m_frequency;
234  double m_pt;
235  double m_pr;
236  };
237 
239  double m_tolerance;
240 };
241 
243  : TestCase("Test for the ThreeGppUmaPropagationLossModel class"),
244  m_testVectors(),
245  m_tolerance(5e-2)
246 {
247 }
248 
250 {
251 }
252 
253 void
255 {
256  TestVector testVector;
257 
258  testVector.m_distance = 10.0;
259  testVector.m_isLos = true;
260  testVector.m_frequency = 5.0e9;
261  testVector.m_pt = 0.0;
262  testVector.m_pr = -72.9380;
263  m_testVectors.Add(testVector);
264 
265  testVector.m_distance = 100.0;
266  testVector.m_isLos = true;
267  testVector.m_frequency = 5.0e9;
268  testVector.m_pt = 0.0;
269  testVector.m_pr = -86.2362;
270  m_testVectors.Add(testVector);
271 
272  testVector.m_distance = 1000.0;
273  testVector.m_isLos = true;
274  testVector.m_frequency = 5.0e9;
275  testVector.m_pt = 0.0;
276  testVector.m_pr = -109.7252;
277  m_testVectors.Add(testVector);
278 
279  testVector.m_distance = 5000.0;
280  testVector.m_isLos = true;
281  testVector.m_frequency = 5.0e9;
282  testVector.m_pt = 0.0;
283  testVector.m_pr = -137.6794;
284  m_testVectors.Add(testVector);
285 
286  testVector.m_distance = 10.0;
287  testVector.m_isLos = false;
288  testVector.m_frequency = 5.0e9;
289  testVector.m_pt = 0.0;
290  testVector.m_pr = -82.5131;
291  m_testVectors.Add(testVector);
292 
293  testVector.m_distance = 100.0;
294  testVector.m_isLos = false;
295  testVector.m_frequency = 5.0e9;
296  testVector.m_pt = 0.0;
297  testVector.m_pr = -106.1356;
298  m_testVectors.Add(testVector);
299 
300  testVector.m_distance = 1000.0;
301  testVector.m_isLos = false;
302  testVector.m_frequency = 5.0e9;
303  testVector.m_pt = 0.0;
304  testVector.m_pr = -144.7641;
305  m_testVectors.Add(testVector);
306 
307  testVector.m_distance = 5000.0;
308  testVector.m_isLos = false;
309  testVector.m_frequency = 5.0e9;
310  testVector.m_pt = 0.0;
311  testVector.m_pr = -172.0753;
312  m_testVectors.Add(testVector);
313 
314  // Create the nodes for BS and UT
316  nodes.Create(2);
317 
318  // Create the mobility models
319  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
320  nodes.Get(0)->AggregateObject(a);
321  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
322  nodes.Get(1)->AggregateObject(b);
323 
324  // Use a deterministic channel condition model
325  Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel>();
326  Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel>();
327 
328  // Create the propagation loss model
330  CreateObject<ThreeGppUmaPropagationLossModel>();
331  lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
332 
333  for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
334  {
335  TestVector testVector = m_testVectors.Get(i);
336 
337  Vector posBs = Vector(0.0, 0.0, 25.0);
338  Vector posUt = Vector(testVector.m_distance, 0.0, 1.5);
339 
340  // set the LOS or NLOS condition
341  if (testVector.m_isLos)
342  {
343  lossModel->SetChannelConditionModel(losCondModel);
344  }
345  else
346  {
347  lossModel->SetChannelConditionModel(nlosCondModel);
348  }
349 
350  a->SetPosition(posBs);
351  b->SetPosition(posUt);
352 
353  lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
354  NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
355  testVector.m_pr,
356  m_tolerance,
357  "Got unexpected rcv power");
358  }
359 
360  Simulator::Destroy();
361 }
362 
371 {
372  public:
377 
382 
383  private:
387  void DoRun() override;
388 
392  struct TestVector
393  {
394  double m_distance;
395  bool m_isLos;
396  double m_frequency;
397  double m_pt;
398  double m_pr;
399  };
400 
402  double m_tolerance;
403 };
404 
406  : TestCase("Test for the ThreeGppUmiPropagationLossModel class"),
407  m_testVectors(),
408  m_tolerance(5e-2)
409 {
410 }
411 
413 {
414 }
415 
416 void
418 {
419  TestVector testVector;
420 
421  testVector.m_distance = 10.0;
422  testVector.m_isLos = true;
423  testVector.m_frequency = 5.0e9;
424  testVector.m_pt = 0.0;
425  testVector.m_pr = -69.8591;
426  m_testVectors.Add(testVector);
427 
428  testVector.m_distance = 100.0;
429  testVector.m_isLos = true;
430  testVector.m_frequency = 5.0e9;
431  testVector.m_pt = 0.0;
432  testVector.m_pr = -88.4122;
433  m_testVectors.Add(testVector);
434 
435  testVector.m_distance = 1000.0;
436  testVector.m_isLos = true;
437  testVector.m_frequency = 5.0e9;
438  testVector.m_pt = 0.0;
439  testVector.m_pr = -119.3114;
440 
441  testVector.m_distance = 5000.0;
442  testVector.m_isLos = true;
443  testVector.m_frequency = 5.0e9;
444  testVector.m_pt = 0.0;
445  testVector.m_pr = -147.2696;
446 
447  testVector.m_distance = 10.0;
448  testVector.m_isLos = false;
449  testVector.m_frequency = 5.0e9;
450  testVector.m_pt = 0.0;
451  testVector.m_pr = -76.7563;
452 
453  testVector.m_distance = 100.0;
454  testVector.m_isLos = false;
455  testVector.m_frequency = 5.0e9;
456  testVector.m_pt = 0.0;
457  testVector.m_pr = -107.9432;
458 
459  testVector.m_distance = 1000.0;
460  testVector.m_isLos = false;
461  testVector.m_frequency = 5.0e9;
462  testVector.m_pt = 0.0;
463  testVector.m_pr = -143.1886;
464 
465  testVector.m_distance = 5000.0;
466  testVector.m_isLos = false;
467  testVector.m_frequency = 5.0e9;
468  testVector.m_pt = 0.0;
469  testVector.m_pr = -167.8617;
470 
471  // Create the nodes for BS and UT
473  nodes.Create(2);
474 
475  // Create the mobility models
476  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
477  nodes.Get(0)->AggregateObject(a);
478  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
479  nodes.Get(1)->AggregateObject(b);
480 
481  // Use a deterministic channel condition model
482  Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel>();
483  Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel>();
484 
485  // Create the propagation loss model
487  CreateObject<ThreeGppUmiStreetCanyonPropagationLossModel>();
488  lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
489 
490  for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
491  {
492  TestVector testVector = m_testVectors.Get(i);
493 
494  Vector posBs = Vector(0.0, 0.0, 10.0);
495  Vector posUt = Vector(testVector.m_distance, 0.0, 1.5);
496 
497  // set the LOS or NLOS condition
498  if (testVector.m_isLos)
499  {
500  lossModel->SetChannelConditionModel(losCondModel);
501  }
502  else
503  {
504  lossModel->SetChannelConditionModel(nlosCondModel);
505  }
506 
507  a->SetPosition(posBs);
508  b->SetPosition(posUt);
509 
510  lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
511  NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
512  testVector.m_pr,
513  m_tolerance,
514  "Got unexpected rcv power");
515  }
516 
517  Simulator::Destroy();
518 }
519 
528 {
529  public:
534 
539 
540  private:
544  void DoRun() override;
545 
549  struct TestVector
550  {
551  double m_distance;
552  bool m_isLos;
553  double m_frequency;
554  double m_pt;
555  double m_pr;
556  };
557 
559  double m_tolerance;
560 };
561 
563  : TestCase("Test for the ThreeGppIndoorOfficePropagationLossModel class"),
564  m_testVectors(),
565  m_tolerance(5e-2)
566 {
567 }
568 
571 {
572 }
573 
574 void
576 {
577  TestVector testVector;
578 
579  testVector.m_distance = 1.0;
580  testVector.m_isLos = true;
581  testVector.m_frequency = 5.0e9;
582  testVector.m_pt = 0.0;
583  testVector.m_pr = -50.8072;
584  m_testVectors.Add(testVector);
585 
586  testVector.m_distance = 10.0;
587  testVector.m_isLos = true;
588  testVector.m_frequency = 5.0e9;
589  testVector.m_pt = 0.0;
590  testVector.m_pr = -63.7630;
591  m_testVectors.Add(testVector);
592 
593  testVector.m_distance = 50.0;
594  testVector.m_isLos = true;
595  testVector.m_frequency = 5.0e9;
596  testVector.m_pt = 0.0;
597  testVector.m_pr = -75.7750;
598  m_testVectors.Add(testVector);
599 
600  testVector.m_distance = 100.0;
601  testVector.m_isLos = true;
602  testVector.m_frequency = 5.0e9;
603  testVector.m_pt = 0.0;
604  testVector.m_pr = -80.9802;
605  m_testVectors.Add(testVector);
606 
607  testVector.m_distance = 1.0;
608  testVector.m_isLos = false;
609  testVector.m_frequency = 5.0e9;
610  testVector.m_pt = 0.0;
611  testVector.m_pr = -50.8072;
612  m_testVectors.Add(testVector);
613 
614  testVector.m_distance = 10.0;
615  testVector.m_isLos = false;
616  testVector.m_frequency = 5.0e9;
617  testVector.m_pt = 0.0;
618  testVector.m_pr = -73.1894;
619  m_testVectors.Add(testVector);
620 
621  testVector.m_distance = 50.0;
622  testVector.m_isLos = false;
623  testVector.m_frequency = 5.0e9;
624  testVector.m_pt = 0.0;
625  testVector.m_pr = -99.7824;
626  m_testVectors.Add(testVector);
627 
628  testVector.m_distance = 100.0;
629  testVector.m_isLos = false;
630  testVector.m_frequency = 5.0e9;
631  testVector.m_pt = 0.0;
632  testVector.m_pr = -111.3062;
633  m_testVectors.Add(testVector);
634 
635  // Create the nodes for BS and UT
637  nodes.Create(2);
638 
639  // Create the mobility models
640  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
641  nodes.Get(0)->AggregateObject(a);
642  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
643  nodes.Get(1)->AggregateObject(b);
644 
645  // Use a deterministic channel condition model
646  Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel>();
647  Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel>();
648 
649  // Create the propagation loss model
651  CreateObject<ThreeGppIndoorOfficePropagationLossModel>();
652  lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
653 
654  for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
655  {
656  TestVector testVector = m_testVectors.Get(i);
657 
658  Vector posBs = Vector(0.0, 0.0, 3.0);
659  Vector posUt = Vector(testVector.m_distance, 0.0, 1.5);
660 
661  // set the LOS or NLOS condition
662  if (testVector.m_isLos)
663  {
664  lossModel->SetChannelConditionModel(losCondModel);
665  }
666  else
667  {
668  lossModel->SetChannelConditionModel(nlosCondModel);
669  }
670 
671  a->SetPosition(posBs);
672  b->SetPosition(posUt);
673 
674  lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
675  NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
676  testVector.m_pr,
677  m_tolerance,
678  "Got unexpected rcv power");
679  }
680 
681  Simulator::Destroy();
682 }
683 
702 {
703  public:
708 
713 
714  private:
718  void DoRun() override;
719 
723  struct TestVector
724  {
725  double m_distance;
726  bool m_isLos;
727  double m_frequency;
728  double m_pt;
729  double m_pr;
730  };
731 
733  double m_tolerance;
734 };
735 
737  : TestCase("Test for the ThreeGppV2vUrbanPropagationLossModel class."),
738  m_testVectors(),
739  m_tolerance(5e-2)
740 {
741 }
742 
744 {
745 }
746 
747 void
749 {
750  TestVector testVector;
751 
752  testVector.m_distance = 10.0;
753  testVector.m_isLos = true;
754  testVector.m_frequency = 5.0e9;
755  testVector.m_pt = 0.0;
756  testVector.m_pr = -68.1913;
757  m_testVectors.Add(testVector);
758 
759  testVector.m_distance = 100.0;
760  testVector.m_isLos = true;
761  testVector.m_frequency = 5.0e9;
762  testVector.m_pt = 0.0;
763  testVector.m_pr = -84.8913;
764  m_testVectors.Add(testVector);
765 
766  testVector.m_distance = 1000.0;
767  testVector.m_isLos = true;
768  testVector.m_frequency = 5.0e9;
769  testVector.m_pt = 0.0;
770  testVector.m_pr = -101.5913;
771  m_testVectors.Add(testVector);
772 
773  testVector.m_distance = 10.0;
774  testVector.m_isLos = false;
775  testVector.m_frequency = 5.0e9;
776  testVector.m_pt = 0.0;
777  testVector.m_pr = -80.0605;
778  m_testVectors.Add(testVector);
779 
780  testVector.m_distance = 100.0;
781  testVector.m_isLos = false;
782  testVector.m_frequency = 5.0e9;
783  testVector.m_pt = 0.0;
784  testVector.m_pr = -110.0605;
785  m_testVectors.Add(testVector);
786 
787  testVector.m_distance = 1000.0;
788  testVector.m_isLos = false;
789  testVector.m_frequency = 5.0e9;
790  testVector.m_pt = 0.0;
791  testVector.m_pr = -140.0605;
792  m_testVectors.Add(testVector);
793 
794  // Create the nodes for BS and UT
796  nodes.Create(2);
797 
798  // Create the mobility models
799  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
800  nodes.Get(0)->AggregateObject(a);
801  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
802  nodes.Get(1)->AggregateObject(b);
803 
804  // Use a deterministic channel condition model
805  Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel>();
806  Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel>();
807 
808  // Create the propagation loss model
810  CreateObject<ThreeGppV2vUrbanPropagationLossModel>();
811  lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
812 
813  for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
814  {
815  TestVector testVector = m_testVectors.Get(i);
816 
817  Vector posUe1 = Vector(0.0, 0.0, 1.6);
818  Vector posUe2 = Vector(testVector.m_distance, 0.0, 1.6);
819 
820  // set the LOS or NLOS condition
821  if (testVector.m_isLos)
822  {
823  lossModel->SetChannelConditionModel(losCondModel);
824  }
825  else
826  {
827  lossModel->SetChannelConditionModel(nlosCondModel);
828  }
829 
830  a->SetPosition(posUe1);
831  b->SetPosition(posUe2);
832 
833  lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
834  NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
835  testVector.m_pr,
836  m_tolerance,
837  "Got unexpected rcv power");
838  }
839 
840  Simulator::Destroy();
841 }
842 
861 {
862  public:
867 
872 
873  private:
877  void DoRun() override;
878 
882  struct TestVector
883  {
884  double m_distance;
885  bool m_isLos;
886  double m_frequency;
887  double m_pt;
888  double m_pr;
889  };
890 
892  double m_tolerance;
893 };
894 
896  : TestCase("Test for the ThreeGppV2vHighwayPropagationLossModel"),
897  m_testVectors(),
898  m_tolerance(5e-2)
899 {
900 }
901 
903 {
904 }
905 
906 void
908 {
909  TestVector testVector;
910 
911  testVector.m_distance = 10.0;
912  testVector.m_isLos = true;
913  testVector.m_frequency = 5.0e9;
914  testVector.m_pt = 0.0;
915  testVector.m_pr = -66.3794;
916  m_testVectors.Add(testVector);
917 
918  testVector.m_distance = 100.0;
919  testVector.m_isLos = true;
920  testVector.m_frequency = 5.0e9;
921  testVector.m_pt = 0.0;
922  testVector.m_pr = -86.3794;
923  m_testVectors.Add(testVector);
924 
925  testVector.m_distance = 1000.0;
926  testVector.m_isLos = true;
927  testVector.m_frequency = 5.0e9;
928  testVector.m_pt = 0.0;
929  testVector.m_pr = -106.3794;
930  m_testVectors.Add(testVector);
931 
932  testVector.m_distance = 10.0;
933  testVector.m_isLos = false;
934  testVector.m_frequency = 5.0e9;
935  testVector.m_pt = 0.0;
936  testVector.m_pr = -80.0605;
937  m_testVectors.Add(testVector);
938 
939  testVector.m_distance = 100.0;
940  testVector.m_isLos = false;
941  testVector.m_frequency = 5.0e9;
942  testVector.m_pt = 0.0;
943  testVector.m_pr = -110.0605;
944  m_testVectors.Add(testVector);
945 
946  testVector.m_distance = 1000.0;
947  testVector.m_isLos = false;
948  testVector.m_frequency = 5.0e9;
949  testVector.m_pt = 0.0;
950  testVector.m_pr = -140.0605;
951  m_testVectors.Add(testVector);
952 
953  // Create the nodes for BS and UT
955  nodes.Create(2);
956 
957  // Create the mobility models
958  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
959  nodes.Get(0)->AggregateObject(a);
960  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
961  nodes.Get(1)->AggregateObject(b);
962 
963  // Use a deterministic channel condition model
964  Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel>();
965  Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel>();
966 
967  // Create the propagation loss model
969  CreateObject<ThreeGppV2vHighwayPropagationLossModel>();
970  lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
971 
972  for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
973  {
974  TestVector testVector = m_testVectors.Get(i);
975 
976  Vector posUe1 = Vector(0.0, 0.0, 1.6);
977  Vector posUe2 = Vector(testVector.m_distance, 0.0, 1.6);
978 
979  // set the LOS or NLOS condition
980  if (testVector.m_isLos)
981  {
982  lossModel->SetChannelConditionModel(losCondModel);
983  }
984  else
985  {
986  lossModel->SetChannelConditionModel(nlosCondModel);
987  }
988 
989  a->SetPosition(posUe1);
990  b->SetPosition(posUe2);
991 
992  lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
993  NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
994  testVector.m_pr,
995  m_tolerance,
996  "Got unexpected rcv power");
997  }
998 
999  Simulator::Destroy();
1000 }
1001 
1008 {
1009  public:
1011  ~ThreeGppShadowingTestCase() override;
1012 
1013  private:
1014  void DoRun() override;
1015 
1026  void RunTest(uint16_t testNum,
1027  std::string propagationLossModelType,
1028  double hBs,
1029  double hUt,
1030  double distance,
1031  bool shadowingEnabled);
1032 
1039  void EvaluateLoss(Ptr<MobilityModel> a, Ptr<MobilityModel> b, uint8_t testNum);
1040 
1046 
1050  struct TestVector
1051  {
1053  double m_hBs;
1054  double m_hUt;
1055  double m_distance;
1060  };
1061 
1064  std::map<uint16_t /* index of experiment */, std::vector<double> /* loss in dB for each run */>
1066 };
1067 
1069  : TestCase("Test to check if the shadow fading is correctly computed")
1070 {
1071 }
1072 
1074 {
1075 }
1076 
1077 void
1079 {
1080  double loss = m_lossModel->CalcRxPower(0, a, b);
1081  m_results.at(testNum).push_back(loss);
1082 }
1083 
1084 void
1086 {
1088 }
1089 
1090 void
1092  std::string propagationLossModelType,
1093  double hBs,
1094  double hUt,
1095  double distance,
1096  bool shadowingEnabled)
1097 {
1098  // Add a new entry for this test in the results map
1099  m_results[testNum] = std::vector<double>();
1100 
1101  // Create the nodes for BS and UT
1103  nodes.Create(2);
1104 
1105  // Create the mobility models
1106  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
1107  a->SetPosition(Vector(0.0, 0.0, hBs));
1108  nodes.Get(0)->AggregateObject(a);
1109 
1110  Ptr<ConstantVelocityMobilityModel> b = CreateObject<ConstantVelocityMobilityModel>();
1111  nodes.Get(1)->AggregateObject(b);
1112  b->SetPosition(Vector(0.0, distance, hUt));
1113  b->SetVelocity(Vector(1.0, 0.0, 0.0));
1114 
1115  // Create the propagation loss model
1116  ObjectFactory propagationLossModelFactory = ObjectFactory(propagationLossModelType);
1117  m_lossModel = propagationLossModelFactory.Create<ThreeGppPropagationLossModel>();
1118  m_lossModel->SetAttribute("Frequency", DoubleValue(3.5e9));
1119  m_lossModel->SetAttribute("ShadowingEnabled",
1120  BooleanValue(shadowingEnabled)); // enable the shadow fading
1121 
1122  // Set the channel condition to LOS
1123  Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel>();
1124  m_lossModel->SetChannelConditionModel(losCondModel);
1125  // Schedule a transition to NLOS
1126  Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel>();
1127  Simulator::Schedule(Seconds(99.5),
1129  this,
1130  nlosCondModel);
1131 
1132  // Schedule multiple calls to EvaluateLoss. Use both EvaluateLoss (a,b) and
1133  // EvaluateLoss (b,a) to check if the reciprocity holds.
1134  for (int i = 0; i < 200; i++)
1135  {
1136  if (i % 2 == 0)
1137  {
1138  Simulator::Schedule(MilliSeconds(1000 * i),
1140  this,
1141  a,
1142  b,
1143  testNum);
1144  }
1145  else
1146  {
1147  Simulator::Schedule(MilliSeconds(1000 * i),
1149  this,
1150  b,
1151  a,
1152  testNum);
1153  }
1154  }
1155 
1156  Simulator::Run();
1157  Simulator::Destroy();
1158 }
1159 
1160 void
1162 {
1163  // The test scenario is composed of two nodes, one fixed
1164  // at position (0,0) and the other moving with constant velocity from
1165  // position (0,50) to position (200,50).
1166  // The channel condition changes from LOS to NLOS when the second node
1167  // reaches position (100,50).
1168  // Each experiment computes the propagation loss between the two nodes
1169  // every second, until the final position is reached, and saves the
1170  // results in an entry of the map m_results.
1171  // We run numSamples experiments and estimate the mean propagation loss in
1172  // each position by averaging among the samples.
1173  // Then, we perform the null hypothesis test with a significance level of
1174  // 0.05.
1175  // This procedure is repeated for all the 3GPP propagation scenarios, i.e.,
1176  // RMa, UMa, UMi and Indoor-Office.
1177 
1178  TestVector testVector;
1179  testVector.m_propagationLossModelType = "ns3::ThreeGppRmaPropagationLossModel";
1180  testVector.m_hBs = 25;
1181  testVector.m_hUt = 1.6;
1182  testVector.m_distance = 100;
1183  testVector.m_shadowingStdLos = 4;
1184  testVector.m_shadowingStdNlos = 8;
1185  m_testVectors.Add(testVector);
1186 
1187  testVector.m_propagationLossModelType = "ns3::ThreeGppRmaPropagationLossModel";
1188  testVector.m_hBs = 25;
1189  testVector.m_hUt = 1.6;
1190  testVector.m_distance = 4000; // beyond the breakpoint distance
1191  testVector.m_shadowingStdLos = 6;
1192  testVector.m_shadowingStdNlos = 8;
1193  m_testVectors.Add(testVector);
1194 
1195  testVector.m_propagationLossModelType = "ns3::ThreeGppUmaPropagationLossModel";
1196  testVector.m_hBs = 25;
1197  testVector.m_hUt = 1.6;
1198  testVector.m_distance = 100;
1199  testVector.m_shadowingStdLos = 4;
1200  testVector.m_shadowingStdNlos = 6;
1201  m_testVectors.Add(testVector);
1202 
1203  testVector.m_propagationLossModelType = "ns3::ThreeGppUmiStreetCanyonPropagationLossModel";
1204  testVector.m_hBs = 10;
1205  testVector.m_hUt = 1.6;
1206  testVector.m_distance = 100;
1207  testVector.m_shadowingStdLos = 4;
1208  testVector.m_shadowingStdNlos = 7.82;
1209  m_testVectors.Add(testVector);
1210 
1211  testVector.m_propagationLossModelType = "ns3::ThreeGppIndoorOfficePropagationLossModel";
1212  testVector.m_hBs = 3;
1213  testVector.m_hUt = 1;
1214  testVector.m_distance = 50;
1215  testVector.m_shadowingStdLos = 3;
1216  testVector.m_shadowingStdNlos = 8.03;
1217  m_testVectors.Add(testVector);
1218 
1219  testVector.m_propagationLossModelType = "ns3::ThreeGppV2vUrbanPropagationLossModel";
1220  testVector.m_hBs = 1.6;
1221  testVector.m_hUt = 1.6;
1222  testVector.m_distance = 50;
1223  testVector.m_shadowingStdLos = 3;
1224  testVector.m_shadowingStdNlos = 4;
1225  m_testVectors.Add(testVector);
1226 
1227  testVector.m_propagationLossModelType = "ns3::ThreeGppV2vHighwayPropagationLossModel";
1228  testVector.m_hBs = 1.6;
1229  testVector.m_hUt = 1.6;
1230  testVector.m_distance = 50;
1231  testVector.m_shadowingStdLos = 3;
1232  testVector.m_shadowingStdNlos = 4;
1233  m_testVectors.Add(testVector);
1234 
1235  uint16_t numSamples = 250;
1236 
1237  for (std::size_t tvIndex = 0; tvIndex < m_testVectors.GetN(); tvIndex++)
1238  {
1239  TestVector tv = m_testVectors.Get(tvIndex);
1240 
1241  // run the experiments.
1242  for (uint16_t sampleIndex = 0; sampleIndex < numSamples; sampleIndex++)
1243  {
1244  RunTest(sampleIndex,
1246  tv.m_hBs,
1247  tv.m_hUt,
1248  tv.m_distance,
1249  true);
1250  }
1251 
1252  // analyze the results
1253  std::vector<double> mean_vector; // the vector containing the mean propagation loss for each
1254  // position (sample mean)
1255 
1256  uint16_t numPositions = m_results.at(0).size();
1257  for (uint16_t k = 0; k < numPositions; k++)
1258  {
1259  // compute the mean propagation loss in position k
1260  double mean = 0.0;
1261  for (auto resIt : m_results)
1262  {
1263  mean += resIt.second.at(k);
1264  }
1265  mean /= m_results.size();
1266  mean_vector.push_back(mean);
1267  }
1268 
1269  // compute the true mean - just the pathloss, without the shadowing component
1270  RunTest(numSamples,
1272  tv.m_hBs,
1273  tv.m_hUt,
1274  tv.m_distance,
1275  false);
1276  std::vector<double> true_mean =
1277  m_results.at(numSamples); // the result of the last test is the true mean
1278 
1279  // perform the null hypothesis test for the LOS case
1280  // positions from (0, 50) to (99, 50) are LOS
1281  for (std::size_t i = 0; i < mean_vector.size() / 2; i++)
1282  {
1283  double z = (mean_vector.at(i) - true_mean.at(i)) /
1284  (tv.m_shadowingStdLos / std::sqrt(mean_vector.size() / 2));
1286  z,
1287  0.0,
1288  1.96,
1289  "Null hypothesis test (LOS case) for the shadowing component rejected");
1290  }
1291 
1292  // perform the null hypothesis test for the NLOS case
1293  // positions from (100, 50) to (199, 50) are NLOS
1294  for (std::size_t i = mean_vector.size() / 2; i < mean_vector.size(); i++)
1295  {
1296  double z = (mean_vector.at(i) - true_mean.at(i)) /
1297  (tv.m_shadowingStdNlos / std::sqrt(mean_vector.size() / 2));
1299  z,
1300  0.0,
1301  1.96,
1302  "Null hypothesis test (NLOS case) for the shadowing component rejected");
1303  }
1304  }
1305 }
1306 
1322 {
1323  public:
1325 };
1326 
1328  : TestSuite("three-gpp-propagation-loss-model", UNIT)
1329 {
1336  AddTestCase(new ThreeGppShadowingTestCase, TestCase::QUICK);
1337 }
1338 
Test case for the class ThreeGppIndoorOfficePropagationLossModel.
void DoRun() override
Build the simulation scenario and run the tests.
TestVectors< TestVector > m_testVectors
array containing all the test vectors
Test case for the class ThreeGppRmaPropagationLossModel.
void DoRun() override
Build the simulation scenario and run the tests.
TestVectors< TestVector > m_testVectors
array containing all the test vectors
Test to check if the shadowing fading is correctly computed.
void EvaluateLoss(Ptr< MobilityModel > a, Ptr< MobilityModel > b, uint8_t testNum)
Compute the propagation loss.
void DoRun() override
Implementation to actually run this TestCase.
std::map< uint16_t, std::vector< double > > m_results
used to store the test results
void ChangeChannelCondition(Ptr< ChannelConditionModel > ccm)
Change the channel condition model.
Ptr< ThreeGppPropagationLossModel > m_lossModel
the propagation loss model
TestVectors< TestVector > m_testVectors
array containing all the test vectors
void RunTest(uint16_t testNum, std::string propagationLossModelType, double hBs, double hUt, double distance, bool shadowingEnabled)
Run the experiment.
Test case for the class ThreeGppUmaPropagationLossModel.
TestVectors< TestVector > m_testVectors
array containing all the test vectors
void DoRun() override
Build the simulation scenario and run the tests.
Test case for the class ThreeGppUmiStreetCanyonPropagationLossModel.
TestVectors< TestVector > m_testVectors
array containing all the test vectors
void DoRun() override
Build the simulation scenario and run the tests.
Test case for the class ThreeGppV2vHighwayPropagationLossModel.
TestVectors< TestVector > m_testVectors
array containing all the test vectors
void DoRun() override
Build the simulation scenario and run the tests.
Test case for the class ThreeGppV2vUrbanPropagationLossModel.
TestVectors< TestVector > m_testVectors
array containing all the test vectors
void DoRun() override
Build the simulation scenario and run the tests.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
void SetPosition(const Vector &position)
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:204
Instantiate subclasses of ns3::Object.
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:259
double CalcRxPower(double txPowerDbm, Ptr< MobilityModel > a, Ptr< MobilityModel > b) const
Returns the Rx Power taking into account all the PropagationLossModel(s) chained to the current one.
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
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1319
Base class for the 3GPP propagation models.
void SetChannelConditionModel(Ptr< ChannelConditionModel > model)
Set the channel condition model used to determine the channel state (e.g., the LOS/NLOS condition)
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_TEST_EXPECT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report if ...
Definition: test.h:510
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Struct containing the parameters for each test.
double m_distance
the initial 2D distance in meters between BS and UT in meters
std::string m_propagationLossModelType
the propagation loss model type id
double m_shadowingStdLos
the standard deviation of the shadowing component in the LOS case in dB
double m_shadowingStdNlos
the standard deviation of the shadowing component in the NLOS case in dB
static ThreeGppPropagationLossModelsTestSuite g_propagationLossModelsTestSuite
Static variable for test initialization.