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.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
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:200
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:305
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:1336
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1348
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.