A Discrete-Event Network Simulator
API
three-gpp-propagation-loss-model-test-suite.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2019 SIGNET Lab, Department of Information Engineering,
4  * University of Padova
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */
19 
20 #include "ns3/log.h"
21 #include "ns3/abort.h"
22 #include "ns3/test.h"
23 #include "ns3/config.h"
24 #include "ns3/double.h"
25 #include "ns3/boolean.h"
26 #include "ns3/channel-condition-model.h"
27 #include "ns3/three-gpp-propagation-loss-model.h"
28 #include "ns3/three-gpp-v2v-propagation-loss-model.h"
29 #include "ns3/constant-position-mobility-model.h"
30 #include "ns3/constant-velocity-mobility-model.h"
31 #include "ns3/mobility-helper.h"
32 #include "ns3/simulator.h"
33 
34 using namespace ns3;
35 
36 NS_LOG_COMPONENT_DEFINE ("ThreeGppPropagationLossModelsTest");
37 
46 {
47 public:
52 
57 
58 private:
62  virtual void DoRun (void);
63 
67  typedef struct
68  {
69  double m_distance;
70  bool m_isLos;
71  double m_frequency;
72  double m_pt;
73  double m_pr;
74  } TestVector;
75 
77  double m_tolerance;
78 };
79 
81  : TestCase ("Test for the ThreeGppRmaPropagationLossModel class"),
82  m_testVectors (),
83  m_tolerance (5e-2)
84 {
85 }
86 
88 {
89 }
90 
91 void
93 {
94  TestVector testVector;
95 
96  testVector.m_distance = 10.0;
97  testVector.m_isLos = true;
98  testVector.m_frequency = 5.0e9;
99  testVector.m_pt = 0.0;
100  testVector.m_pr = -77.3784;
101  m_testVectors.Add (testVector);
102 
103  testVector.m_distance = 100.0;
104  testVector.m_isLos = true;
105  testVector.m_frequency = 5.0e9;
106  testVector.m_pt = 0.0;
107  testVector.m_pr = -87.2965;
108  m_testVectors.Add (testVector);
109 
110  testVector.m_distance = 1000.0;
111  testVector.m_isLos = true;
112  testVector.m_frequency = 5.0e9;
113  testVector.m_pt = 0.0;
114  testVector.m_pr = -108.5577;
115  m_testVectors.Add (testVector);
116 
117  testVector.m_distance = 10000.0;
118  testVector.m_isLos = true;
119  testVector.m_frequency = 5.0e9;
120  testVector.m_pt = 0.0;
121  testVector.m_pr = -140.3896;
122  m_testVectors.Add (testVector);
123 
124  testVector.m_distance = 10.0;
125  testVector.m_isLos = false;
126  testVector.m_frequency = 5.0e9;
127  testVector.m_pt = 0.0;
128  testVector.m_pr = -77.3784;
129  m_testVectors.Add (testVector);
130 
131  testVector.m_distance = 100.0;
132  testVector.m_isLos = false;
133  testVector.m_frequency = 5.0e9;
134  testVector.m_pt = 0.0;
135  testVector.m_pr = -95.7718;
136  m_testVectors.Add (testVector);
137 
138  testVector.m_distance = 1000.0;
139  testVector.m_isLos = false;
140  testVector.m_frequency = 5.0e9;
141  testVector.m_pt = 0.0;
142  testVector.m_pr = -133.5223;
143  m_testVectors.Add (testVector);
144 
145  testVector.m_distance = 5000.0;
146  testVector.m_isLos = false;
147  testVector.m_frequency = 5.0e9;
148  testVector.m_pt = 0.0;
149  testVector.m_pr = -160.5169;
150  m_testVectors.Add (testVector);
151 
152  // Create the nodes for BS and UT
154  nodes.Create (2);
155 
156  // Create the mobility models
157  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
158  nodes.Get (0)->AggregateObject (a);
159  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
160  nodes.Get (1)->AggregateObject (b);
161 
162  // Use a deterministic channel condition model
163  Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel> ();
164  Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel> ();
165 
166  // Create the propagation loss model
167  Ptr<ThreeGppRmaPropagationLossModel> lossModel = CreateObject<ThreeGppRmaPropagationLossModel> ();
168  lossModel->SetAttribute ("ShadowingEnabled", BooleanValue (false)); // disable the shadow fading
169 
170  for (uint32_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), testVector.m_pr, m_tolerance, "Got unexpected rcv power");
192  }
193 
194  Simulator::Destroy ();
195 }
196 
205 {
206 public:
211 
216 
217 private:
221  virtual void DoRun (void);
222 
226  typedef struct
227  {
228  double m_distance;
229  bool m_isLos;
230  double m_frequency;
231  double m_pt;
232  double m_pr;
233  } TestVector;
234 
236  double m_tolerance;
237 };
238 
240  : TestCase ("Test for the ThreeGppUmaPropagationLossModel class"),
241  m_testVectors (),
242  m_tolerance (5e-2)
243 {
244 }
245 
247 {
248 }
249 
250 void
252 {
253  TestVector testVector;
254 
255  testVector.m_distance = 10.0;
256  testVector.m_isLos = true;
257  testVector.m_frequency = 5.0e9;
258  testVector.m_pt = 0.0;
259  testVector.m_pr = -72.9380;
260  m_testVectors.Add (testVector);
261 
262  testVector.m_distance = 100.0;
263  testVector.m_isLos = true;
264  testVector.m_frequency = 5.0e9;
265  testVector.m_pt = 0.0;
266  testVector.m_pr = -86.2362;
267  m_testVectors.Add (testVector);
268 
269  testVector.m_distance = 1000.0;
270  testVector.m_isLos = true;
271  testVector.m_frequency = 5.0e9;
272  testVector.m_pt = 0.0;
273  testVector.m_pr = -109.7252;
274  m_testVectors.Add (testVector);
275 
276  testVector.m_distance = 5000.0;
277  testVector.m_isLos = true;
278  testVector.m_frequency = 5.0e9;
279  testVector.m_pt = 0.0;
280  testVector.m_pr = -137.6794;
281  m_testVectors.Add (testVector);
282 
283  testVector.m_distance = 10.0;
284  testVector.m_isLos = false;
285  testVector.m_frequency = 5.0e9;
286  testVector.m_pt = 0.0;
287  testVector.m_pr = -82.5131;
288  m_testVectors.Add (testVector);
289 
290  testVector.m_distance = 100.0;
291  testVector.m_isLos = false;
292  testVector.m_frequency = 5.0e9;
293  testVector.m_pt = 0.0;
294  testVector.m_pr = -106.1356;
295  m_testVectors.Add (testVector);
296 
297  testVector.m_distance = 1000.0;
298  testVector.m_isLos = false;
299  testVector.m_frequency = 5.0e9;
300  testVector.m_pt = 0.0;
301  testVector.m_pr = -144.7641;
302  m_testVectors.Add (testVector);
303 
304  testVector.m_distance = 5000.0;
305  testVector.m_isLos = false;
306  testVector.m_frequency = 5.0e9;
307  testVector.m_pt = 0.0;
308  testVector.m_pr = -172.0753;
309  m_testVectors.Add (testVector);
310 
311  // Create the nodes for BS and UT
313  nodes.Create (2);
314 
315  // Create the mobility models
316  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
317  nodes.Get (0)->AggregateObject (a);
318  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
319  nodes.Get (1)->AggregateObject (b);
320 
321  // Use a deterministic channel condition model
322  Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel> ();
323  Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel> ();
324 
325  // Create the propagation loss model
326  Ptr<ThreeGppUmaPropagationLossModel> lossModel = CreateObject<ThreeGppUmaPropagationLossModel> ();
327  lossModel->SetAttribute ("ShadowingEnabled", BooleanValue (false)); // disable the shadow fading
328 
329  for (uint32_t i = 0; i < m_testVectors.GetN (); i++)
330  {
331  TestVector testVector = m_testVectors.Get (i);
332 
333  Vector posBs = Vector (0.0, 0.0, 25.0);
334  Vector posUt = Vector (testVector.m_distance, 0.0, 1.5);
335 
336  // set the LOS or NLOS condition
337  if (testVector.m_isLos)
338  {
339  lossModel->SetChannelConditionModel (losCondModel);
340  }
341  else
342  {
343  lossModel->SetChannelConditionModel (nlosCondModel);
344  }
345 
346  a->SetPosition (posBs);
347  b->SetPosition (posUt);
348 
349  lossModel->SetAttribute ("Frequency", DoubleValue (testVector.m_frequency));
350  NS_TEST_EXPECT_MSG_EQ_TOL (lossModel->CalcRxPower (testVector.m_pt, a, b), testVector.m_pr, m_tolerance, "Got unexpected rcv power");
351  }
352 
353  Simulator::Destroy ();
354 }
355 
364 {
365 public:
370 
375 
376 private:
380  virtual void DoRun (void);
381 
385  typedef struct
386  {
387  double m_distance;
388  bool m_isLos;
389  double m_frequency;
390  double m_pt;
391  double m_pr;
392  } TestVector;
393 
395  double m_tolerance;
396 };
397 
399  : TestCase ("Test for the ThreeGppUmiPropagationLossModel class"),
400  m_testVectors (),
401  m_tolerance (5e-2)
402 {
403 }
404 
406 {
407 }
408 
409 void
411 {
412  TestVector testVector;
413 
414  testVector.m_distance = 10.0;
415  testVector.m_isLos = true;
416  testVector.m_frequency = 5.0e9;
417  testVector.m_pt = 0.0;
418  testVector.m_pr = -69.8591;
419  m_testVectors.Add (testVector);
420 
421  testVector.m_distance = 100.0;
422  testVector.m_isLos = true;
423  testVector.m_frequency = 5.0e9;
424  testVector.m_pt = 0.0;
425  testVector.m_pr = -88.4122;
426  m_testVectors.Add (testVector);
427 
428  testVector.m_distance = 1000.0;
429  testVector.m_isLos = true;
430  testVector.m_frequency = 5.0e9;
431  testVector.m_pt = 0.0;
432  testVector.m_pr = -119.3114;
433 
434  testVector.m_distance = 5000.0;
435  testVector.m_isLos = true;
436  testVector.m_frequency = 5.0e9;
437  testVector.m_pt = 0.0;
438  testVector.m_pr = -147.2696;
439 
440  testVector.m_distance = 10.0;
441  testVector.m_isLos = false;
442  testVector.m_frequency = 5.0e9;
443  testVector.m_pt = 0.0;
444  testVector.m_pr = -76.7563;
445 
446  testVector.m_distance = 100.0;
447  testVector.m_isLos = false;
448  testVector.m_frequency = 5.0e9;
449  testVector.m_pt = 0.0;
450  testVector.m_pr = -107.9432;
451 
452  testVector.m_distance = 1000.0;
453  testVector.m_isLos = false;
454  testVector.m_frequency = 5.0e9;
455  testVector.m_pt = 0.0;
456  testVector.m_pr = -143.1886;
457 
458  testVector.m_distance = 5000.0;
459  testVector.m_isLos = false;
460  testVector.m_frequency = 5.0e9;
461  testVector.m_pt = 0.0;
462  testVector.m_pr = -167.8617;
463 
464  // Create the nodes for BS and UT
466  nodes.Create (2);
467 
468  // Create the mobility models
469  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
470  nodes.Get (0)->AggregateObject (a);
471  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
472  nodes.Get (1)->AggregateObject (b);
473 
474  // Use a deterministic channel condition model
475  Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel> ();
476  Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel> ();
477 
478  // Create the propagation loss model
479  Ptr<ThreeGppUmiStreetCanyonPropagationLossModel> lossModel = CreateObject<ThreeGppUmiStreetCanyonPropagationLossModel> ();
480  lossModel->SetAttribute ("ShadowingEnabled", BooleanValue (false)); // disable the shadow fading
481 
482  for (uint32_t i = 0; i < m_testVectors.GetN (); i++)
483  {
484  TestVector testVector = m_testVectors.Get (i);
485 
486  Vector posBs = Vector (0.0, 0.0, 10.0);
487  Vector posUt = Vector (testVector.m_distance, 0.0, 1.5);
488 
489  // set the LOS or NLOS condition
490  if (testVector.m_isLos)
491  {
492  lossModel->SetChannelConditionModel (losCondModel);
493  }
494  else
495  {
496  lossModel->SetChannelConditionModel (nlosCondModel);
497  }
498 
499  a->SetPosition (posBs);
500  b->SetPosition (posUt);
501 
502  lossModel->SetAttribute ("Frequency", DoubleValue (testVector.m_frequency));
503  NS_TEST_EXPECT_MSG_EQ_TOL (lossModel->CalcRxPower (testVector.m_pt, a, b), testVector.m_pr, m_tolerance, "Got unexpected rcv power");
504  }
505 
506  Simulator::Destroy ();
507 }
508 
517 {
518 public:
523 
528 
529 private:
533  virtual void DoRun (void);
534 
538  typedef struct
539  {
540  double m_distance;
541  bool m_isLos;
542  double m_frequency;
543  double m_pt;
544  double m_pr;
545  } TestVector;
546 
548  double m_tolerance;
549 };
550 
552  : TestCase ("Test for the ThreeGppIndoorOfficePropagationLossModel class"),
553  m_testVectors (),
554  m_tolerance (5e-2)
555 {
556 }
557 
559 {
560 }
561 
562 void
564 {
565  TestVector testVector;
566 
567  testVector.m_distance = 1.0;
568  testVector.m_isLos = true;
569  testVector.m_frequency = 5.0e9;
570  testVector.m_pt = 0.0;
571  testVector.m_pr = -50.8072;
572  m_testVectors.Add (testVector);
573 
574  testVector.m_distance = 10.0;
575  testVector.m_isLos = true;
576  testVector.m_frequency = 5.0e9;
577  testVector.m_pt = 0.0;
578  testVector.m_pr = -63.7630;
579  m_testVectors.Add (testVector);
580 
581  testVector.m_distance = 50.0;
582  testVector.m_isLos = true;
583  testVector.m_frequency = 5.0e9;
584  testVector.m_pt = 0.0;
585  testVector.m_pr = -75.7750;
586  m_testVectors.Add (testVector);
587 
588  testVector.m_distance = 100.0;
589  testVector.m_isLos = true;
590  testVector.m_frequency = 5.0e9;
591  testVector.m_pt = 0.0;
592  testVector.m_pr = -80.9802;
593  m_testVectors.Add (testVector);
594 
595  testVector.m_distance = 1.0;
596  testVector.m_isLos = false;
597  testVector.m_frequency = 5.0e9;
598  testVector.m_pt = 0.0;
599  testVector.m_pr = -50.8072;
600  m_testVectors.Add (testVector);
601 
602  testVector.m_distance = 10.0;
603  testVector.m_isLos = false;
604  testVector.m_frequency = 5.0e9;
605  testVector.m_pt = 0.0;
606  testVector.m_pr = -73.1894;
607  m_testVectors.Add (testVector);
608 
609  testVector.m_distance = 50.0;
610  testVector.m_isLos = false;
611  testVector.m_frequency = 5.0e9;
612  testVector.m_pt = 0.0;
613  testVector.m_pr = -99.7824;
614  m_testVectors.Add (testVector);
615 
616  testVector.m_distance = 100.0;
617  testVector.m_isLos = false;
618  testVector.m_frequency = 5.0e9;
619  testVector.m_pt = 0.0;
620  testVector.m_pr = -111.3062;
621  m_testVectors.Add (testVector);
622 
623  // Create the nodes for BS and UT
625  nodes.Create (2);
626 
627  // Create the mobility models
628  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
629  nodes.Get (0)->AggregateObject (a);
630  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
631  nodes.Get (1)->AggregateObject (b);
632 
633  // Use a deterministic channel condition model
634  Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel> ();
635  Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel> ();
636 
637  // Create the propagation loss model
638  Ptr<ThreeGppIndoorOfficePropagationLossModel> lossModel = CreateObject<ThreeGppIndoorOfficePropagationLossModel> ();
639  lossModel->SetAttribute ("ShadowingEnabled", BooleanValue (false)); // disable the shadow fading
640 
641  for (uint32_t i = 0; i < m_testVectors.GetN (); i++)
642  {
643  TestVector testVector = m_testVectors.Get (i);
644 
645  Vector posBs = Vector (0.0, 0.0, 3.0);
646  Vector posUt = Vector (testVector.m_distance, 0.0, 1.5);
647 
648  // set the LOS or NLOS condition
649  if (testVector.m_isLos)
650  {
651  lossModel->SetChannelConditionModel (losCondModel);
652  }
653  else
654  {
655  lossModel->SetChannelConditionModel (nlosCondModel);
656  }
657 
658  a->SetPosition (posBs);
659  b->SetPosition (posUt);
660 
661  lossModel->SetAttribute ("Frequency", DoubleValue (testVector.m_frequency));
662  NS_TEST_EXPECT_MSG_EQ_TOL (lossModel->CalcRxPower (testVector.m_pt, a, b), testVector.m_pr, m_tolerance, "Got unexpected rcv power");
663  }
664 
665  Simulator::Destroy ();
666 }
667 
686 {
687 public:
692 
697 
698 private:
702  virtual void DoRun (void);
703 
707  typedef struct
708  {
709  double m_distance;
710  bool m_isLos;
711  double m_frequency;
712  double m_pt;
713  double m_pr;
714  } TestVector;
715 
717  double m_tolerance;
718 };
719 
721  : TestCase ("Test for the ThreeGppV2vUrbanPropagationLossModel class."),
722  m_testVectors (),
723  m_tolerance (5e-2)
724 {
725 }
726 
728 {
729 }
730 
731 void
733 {
734  TestVector testVector;
735 
736  testVector.m_distance = 10.0;
737  testVector.m_isLos = true;
738  testVector.m_frequency = 5.0e9;
739  testVector.m_pt = 0.0;
740  testVector.m_pr = -68.1913;
741  m_testVectors.Add (testVector);
742 
743  testVector.m_distance = 100.0;
744  testVector.m_isLos = true;
745  testVector.m_frequency = 5.0e9;
746  testVector.m_pt = 0.0;
747  testVector.m_pr = -84.8913;
748  m_testVectors.Add (testVector);
749 
750  testVector.m_distance = 1000.0;
751  testVector.m_isLos = true;
752  testVector.m_frequency = 5.0e9;
753  testVector.m_pt = 0.0;
754  testVector.m_pr = -101.5913;
755  m_testVectors.Add (testVector);
756 
757  testVector.m_distance = 10.0;
758  testVector.m_isLos = false;
759  testVector.m_frequency = 5.0e9;
760  testVector.m_pt = 0.0;
761  testVector.m_pr = -80.0605;
762  m_testVectors.Add (testVector);
763 
764  testVector.m_distance = 100.0;
765  testVector.m_isLos = false;
766  testVector.m_frequency = 5.0e9;
767  testVector.m_pt = 0.0;
768  testVector.m_pr = -110.0605;
769  m_testVectors.Add (testVector);
770 
771  testVector.m_distance = 1000.0;
772  testVector.m_isLos = false;
773  testVector.m_frequency = 5.0e9;
774  testVector.m_pt = 0.0;
775  testVector.m_pr = -140.0605;
776  m_testVectors.Add (testVector);
777 
778  // Create the nodes for BS and UT
780  nodes.Create (2);
781 
782  // Create the mobility models
783  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
784  nodes.Get (0)->AggregateObject (a);
785  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
786  nodes.Get (1)->AggregateObject (b);
787 
788  // Use a deterministic channel condition model
789  Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel> ();
790  Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel> ();
791 
792  // Create the propagation loss model
793  Ptr<ThreeGppPropagationLossModel> lossModel = CreateObject<ThreeGppV2vUrbanPropagationLossModel> ();
794  lossModel->SetAttribute ("ShadowingEnabled", BooleanValue (false)); // disable the shadow fading
795 
796  for (uint32_t i = 0; i < m_testVectors.GetN (); i++)
797  {
798  TestVector testVector = m_testVectors.Get (i);
799 
800  Vector posUe1 = Vector (0.0, 0.0, 1.6);
801  Vector posUe2 = Vector (testVector.m_distance, 0.0, 1.6);
802 
803  // set the LOS or NLOS condition
804  if (testVector.m_isLos)
805  {
806  lossModel->SetChannelConditionModel (losCondModel);
807  }
808  else
809  {
810  lossModel->SetChannelConditionModel (nlosCondModel);
811  }
812 
813  a->SetPosition (posUe1);
814  b->SetPosition (posUe2);
815 
816  lossModel->SetAttribute ("Frequency", DoubleValue (testVector.m_frequency));
817  NS_TEST_EXPECT_MSG_EQ_TOL (lossModel->CalcRxPower (testVector.m_pt, a, b), testVector.m_pr, m_tolerance, "Got unexpected rcv power");
818  }
819 
820  Simulator::Destroy ();
821 }
822 
841 {
842 public:
847 
852 
853 private:
857  virtual void DoRun (void);
858 
862  typedef struct
863  {
864  double m_distance;
865  bool m_isLos;
866  double m_frequency;
867  double m_pt;
868  double m_pr;
869  } TestVector;
870 
872  double m_tolerance;
873 };
874 
876  : TestCase ("Test for the ThreeGppV2vHighwayPropagationLossModel"),
877  m_testVectors (),
878  m_tolerance (5e-2)
879 {
880 }
881 
883 {
884 }
885 
886 void
888 {
889  TestVector testVector;
890 
891  testVector.m_distance = 10.0;
892  testVector.m_isLos = true;
893  testVector.m_frequency = 5.0e9;
894  testVector.m_pt = 0.0;
895  testVector.m_pr = -66.3794;
896  m_testVectors.Add (testVector);
897 
898  testVector.m_distance = 100.0;
899  testVector.m_isLos = true;
900  testVector.m_frequency = 5.0e9;
901  testVector.m_pt = 0.0;
902  testVector.m_pr = -86.3794;
903  m_testVectors.Add (testVector);
904 
905  testVector.m_distance = 1000.0;
906  testVector.m_isLos = true;
907  testVector.m_frequency = 5.0e9;
908  testVector.m_pt = 0.0;
909  testVector.m_pr = -106.3794;
910  m_testVectors.Add (testVector);
911 
912  testVector.m_distance = 10.0;
913  testVector.m_isLos = false;
914  testVector.m_frequency = 5.0e9;
915  testVector.m_pt = 0.0;
916  testVector.m_pr = -80.0605;
917  m_testVectors.Add (testVector);
918 
919  testVector.m_distance = 100.0;
920  testVector.m_isLos = false;
921  testVector.m_frequency = 5.0e9;
922  testVector.m_pt = 0.0;
923  testVector.m_pr = -110.0605;
924  m_testVectors.Add (testVector);
925 
926  testVector.m_distance = 1000.0;
927  testVector.m_isLos = false;
928  testVector.m_frequency = 5.0e9;
929  testVector.m_pt = 0.0;
930  testVector.m_pr = -140.0605;
931  m_testVectors.Add (testVector);
932 
933  // Create the nodes for BS and UT
935  nodes.Create (2);
936 
937  // Create the mobility models
938  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
939  nodes.Get (0)->AggregateObject (a);
940  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
941  nodes.Get (1)->AggregateObject (b);
942 
943  // Use a deterministic channel condition model
944  Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel> ();
945  Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel> ();
946 
947  // Create the propagation loss model
948  Ptr<ThreeGppPropagationLossModel> lossModel = CreateObject<ThreeGppV2vHighwayPropagationLossModel> ();
949  lossModel->SetAttribute ("ShadowingEnabled", BooleanValue (false)); // disable the shadow fading
950 
951  for (uint32_t i = 0; i < m_testVectors.GetN (); i++)
952  {
953  TestVector testVector = m_testVectors.Get (i);
954 
955  Vector posUe1 = Vector (0.0, 0.0, 1.6);
956  Vector posUe2 = Vector (testVector.m_distance, 0.0, 1.6);
957 
958  // set the LOS or NLOS condition
959  if (testVector.m_isLos)
960  {
961  lossModel->SetChannelConditionModel (losCondModel);
962  }
963  else
964  {
965  lossModel->SetChannelConditionModel (nlosCondModel);
966  }
967 
968  a->SetPosition (posUe1);
969  b->SetPosition (posUe2);
970 
971  lossModel->SetAttribute ("Frequency", DoubleValue (testVector.m_frequency));
972  NS_TEST_EXPECT_MSG_EQ_TOL (lossModel->CalcRxPower (testVector.m_pt, a, b), testVector.m_pr, m_tolerance, "Got unexpected rcv power");
973  }
974 
975  Simulator::Destroy ();
976 }
977 
984 {
985 public:
987  virtual ~ThreeGppShadowingTestCase ();
988 
989 private:
990  virtual void DoRun (void);
991 
1002  void RunTest (uint16_t testNum, std::string propagationLossModelType, double hBs, double hUt, double distance, bool shadowingEnabled);
1003 
1004 
1011  void EvaluateLoss (Ptr<MobilityModel> a, Ptr<MobilityModel> b, uint8_t testNum);
1012 
1018 
1022  typedef struct
1023  {
1025  double m_hBs;
1026  double m_hUt;
1027  double m_distance;
1030  } TestVector;
1031 
1034  std::map<uint16_t /* index of experiment */, std::vector<double> /* loss in dB for each run */> m_results;
1035 };
1036 
1038  : TestCase ("Test to check if the shadow fading is correctly computed")
1039 {
1040 }
1041 
1043 {
1044 }
1045 
1046 void
1048 {
1049  double loss = m_lossModel->CalcRxPower (0, a, b);
1050  m_results.at (testNum).push_back (loss);
1051 }
1052 
1053 void
1055 {
1057 }
1058 
1059 void
1060 ThreeGppShadowingTestCase::RunTest (uint16_t testNum, std::string propagationLossModelType, double hBs, double hUt, double distance, bool shadowingEnabled)
1061 {
1062  // Add a new entry for this test in the results map
1063  m_results [testNum] = std::vector<double> ();
1064 
1065  // Create the nodes for BS and UT
1067  nodes.Create (2);
1068 
1069  // Create the mobility models
1070  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
1071  a->SetPosition (Vector (0.0, 0.0, hBs));
1072  nodes.Get (0)->AggregateObject (a);
1073 
1074  Ptr<ConstantVelocityMobilityModel> b = CreateObject<ConstantVelocityMobilityModel> ();
1075  nodes.Get (1)->AggregateObject (b);
1076  b->SetPosition (Vector (0.0, distance, hUt));
1077  b->SetVelocity (Vector (1.0, 0.0, 0.0));
1078 
1079  // Create the propagation loss model
1080  ObjectFactory propagationLossModelFactory = ObjectFactory (propagationLossModelType);
1081  m_lossModel = propagationLossModelFactory.Create<ThreeGppPropagationLossModel> ();
1082  m_lossModel->SetAttribute ("Frequency", DoubleValue (3.5e9));
1083  m_lossModel->SetAttribute ("ShadowingEnabled", BooleanValue (shadowingEnabled)); // enable the shadow fading
1084 
1085  // Set the channel condition to LOS
1086  Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel> ();
1087  m_lossModel->SetChannelConditionModel (losCondModel);
1088  // Schedule a transition to NLOS
1089  Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel> ();
1090  Simulator::Schedule (Seconds (99.5), &ThreeGppShadowingTestCase::ChangeChannelCondition, this, nlosCondModel);
1091 
1092  // Schedule multiple calls to EvaluateLoss. Use both EvaluateLoss (a,b) and
1093  // EvaluateLoss (b,a) to check if the reciprocity holds.
1094  for (int i = 0; i < 200; i++)
1095  {
1096  if (i % 2 == 0)
1097  Simulator::Schedule (MilliSeconds (1000 * i), &ThreeGppShadowingTestCase::EvaluateLoss, this, a, b, testNum);
1098  else
1099  Simulator::Schedule (MilliSeconds (1000 * i), &ThreeGppShadowingTestCase::EvaluateLoss, this, b, a, testNum);
1100  }
1101 
1102  Simulator::Run ();
1103  Simulator::Destroy ();
1104 }
1105 
1106 void
1108 {
1109  // The test scenario is composed of two nodes, one fixed
1110  // at position (0,0) and the other moving with constant velocity from
1111  // position (0,50) to position (200,50).
1112  // The channel condition changes from LOS to NLOS when the second node
1113  // reaches position (100,50).
1114  // Each experiment computes the propagation loss between the two nodes
1115  // every second, until the final position is reached, and saves the
1116  // results in an entry of the map m_results.
1117  // We run numSamples experiments and estimate the mean propagation loss in
1118  // each position by averaging among the samples.
1119  // Then, we perform the null hypothesis test with a significance level of
1120  // 0.05.
1121  // This procedure is repeated for all the 3GPP propagation scenarios, i.e.,
1122  // RMa, UMa, UMi and Indoor-Office.
1123 
1124  TestVector testVector;
1125  testVector.m_propagationLossModelType = "ns3::ThreeGppRmaPropagationLossModel";
1126  testVector.m_hBs = 25;
1127  testVector.m_hUt = 1.6;
1128  testVector.m_distance = 100;
1129  testVector.m_shadowingStdLos = 4;
1130  testVector.m_shadowingStdNlos = 8;
1131  m_testVectors.Add (testVector);
1132 
1133  testVector.m_propagationLossModelType = "ns3::ThreeGppRmaPropagationLossModel";
1134  testVector.m_hBs = 25;
1135  testVector.m_hUt = 1.6;
1136  testVector.m_distance = 4000; // beyond the breakpoint distance
1137  testVector.m_shadowingStdLos = 6;
1138  testVector.m_shadowingStdNlos = 8;
1139  m_testVectors.Add (testVector);
1140 
1141  testVector.m_propagationLossModelType = "ns3::ThreeGppUmaPropagationLossModel";
1142  testVector.m_hBs = 25;
1143  testVector.m_hUt = 1.6;
1144  testVector.m_distance = 100;
1145  testVector.m_shadowingStdLos = 4;
1146  testVector.m_shadowingStdNlos = 6;
1147  m_testVectors.Add (testVector);
1148 
1149  testVector.m_propagationLossModelType = "ns3::ThreeGppUmiStreetCanyonPropagationLossModel";
1150  testVector.m_hBs = 10;
1151  testVector.m_hUt = 1.6;
1152  testVector.m_distance = 100;
1153  testVector.m_shadowingStdLos = 4;
1154  testVector.m_shadowingStdNlos = 7.82;
1155  m_testVectors.Add (testVector);
1156 
1157  testVector.m_propagationLossModelType = "ns3::ThreeGppIndoorOfficePropagationLossModel";
1158  testVector.m_hBs = 3;
1159  testVector.m_hUt = 1;
1160  testVector.m_distance = 50;
1161  testVector.m_shadowingStdLos = 3;
1162  testVector.m_shadowingStdNlos = 8.03;
1163  m_testVectors.Add (testVector);
1164 
1165  testVector.m_propagationLossModelType = "ns3::ThreeGppV2vUrbanPropagationLossModel";
1166  testVector.m_hBs = 1.6;
1167  testVector.m_hUt = 1.6;
1168  testVector.m_distance = 50;
1169  testVector.m_shadowingStdLos = 3;
1170  testVector.m_shadowingStdNlos = 4;
1171  m_testVectors.Add (testVector);
1172 
1173  testVector.m_propagationLossModelType = "ns3::ThreeGppV2vHighwayPropagationLossModel";
1174  testVector.m_hBs = 1.6;
1175  testVector.m_hUt = 1.6;
1176  testVector.m_distance = 50;
1177  testVector.m_shadowingStdLos = 3;
1178  testVector.m_shadowingStdNlos = 4;
1179  m_testVectors.Add (testVector);
1180 
1181  uint16_t numSamples = 250;
1182 
1183  for (uint16_t tvIndex = 0; tvIndex < m_testVectors.GetN (); tvIndex++)
1184  {
1185  TestVector tv = m_testVectors.Get (tvIndex);
1186 
1187  // run the experiments.
1188  for (uint16_t sampleIndex = 0; sampleIndex < numSamples; sampleIndex++)
1189  {
1190  RunTest (sampleIndex, tv.m_propagationLossModelType, tv.m_hBs, tv.m_hUt, tv.m_distance, true);
1191  }
1192 
1193  // analyze the results
1194  std::vector<double> mean_vector; // the vector containing the mean propagation loss for each position (sample mean)
1195 
1196  uint16_t numPositions = m_results.at (0).size ();
1197  for (uint16_t k = 0; k < numPositions; k++)
1198  {
1199  // compute the mean propagation loss in position k
1200  double mean = 0.0;
1201  for (auto resIt : m_results)
1202  {
1203  mean += resIt.second.at (k);
1204  }
1205  mean /= m_results.size ();
1206  mean_vector.push_back (mean);
1207  }
1208 
1209  // compute the true mean - just the pathloss, without the shadowing component
1210  RunTest (numSamples, tv.m_propagationLossModelType, tv.m_hBs, tv.m_hUt, tv.m_distance, false);
1211  std::vector<double> true_mean = m_results.at (numSamples); // the result of the last test is the true mean
1212 
1213  // perform the null hypothesis test for the LOS case
1214  // positions from (0, 50) to (99, 50) are LOS
1215  for (uint16_t i = 0; i < mean_vector.size () / 2; i++)
1216  {
1217  double z = (mean_vector.at (i) - true_mean.at (i)) / (tv.m_shadowingStdLos / std::sqrt (mean_vector.size () / 2));
1218  NS_TEST_EXPECT_MSG_EQ_TOL (z, 0.0, 1.96, "Null hypothesis test (LOS case) for the shadowing component rejected");
1219  }
1220 
1221  // perform the null hypothesis test for the NLOS case
1222  // positions from (100, 50) to (199, 50) are NLOS
1223  for (uint16_t i = mean_vector.size () / 2; i < mean_vector.size (); i++)
1224  {
1225  double z = (mean_vector.at (i) - true_mean.at (i)) / (tv.m_shadowingStdNlos / std::sqrt (mean_vector.size () / 2));
1226  NS_TEST_EXPECT_MSG_EQ_TOL (z, 0.0, 1.96, "Null hypothesis test (NLOS case) for the shadowing component rejected");
1227  }
1228  }
1229 }
1230 
1246 {
1247 public:
1249 };
1250 
1252  : TestSuite ("three-gpp-propagation-loss-model", UNIT)
1253 {
1260  AddTestCase (new ThreeGppShadowingTestCase, TestCase::QUICK);
1261 }
1262 
Test case for the class ThreeGppIndoorOfficePropagationLossModel.
virtual void DoRun(void)
Build the simulation scenario and run the tests.
TestVectors< TestVector > m_testVectors
array containing all the test vectors
Test case for the class ThreeGppRmaPropagationLossModel.
virtual void DoRun(void)
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.
virtual void DoRun(void)
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
virtual void DoRun(void)
Build the simulation scenario and run the tests.
Test case for the class ThreeGppUmiStreetCanyonPropagationLossModel.
virtual void DoRun(void)
Build the simulation scenario and run the tests.
TestVectors< TestVector > m_testVectors
array containing all the test vectors
Test case for the class ThreeGppV2vHighwayPropagationLossModel.
virtual void DoRun(void)
Build the simulation scenario and run the tests.
TestVectors< TestVector > m_testVectors
array containing all the test vectors
Test case for the class ThreeGppV2vUrbanPropagationLossModel.
TestVectors< TestVector > m_testVectors
array containing all the test vectors
virtual void DoRun(void)
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:41
void SetPosition(const Vector &position)
keep track of a set of node pointers.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:256
Instantiate subclasses of ns3::Object.
Ptr< Object > Create(void) const
Create an Object instance of the configured TypeId.
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:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1251
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:205
#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:491
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1252
nodes
Definition: first.py:32
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.