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 
44 {
45 public:
50 
55 
56 private:
60  virtual void DoRun (void);
61 
65  typedef struct
66  {
67  double m_distance;
68  bool m_isLos;
69  double m_frequency;
70  double m_pt;
71  double m_pr;
72  } TestVector;
73 
75  double m_tolerance;
76 };
77 
79  : TestCase ("Test for the ThreeGppRmaPropagationLossModel class"),
80  m_testVectors (),
81  m_tolerance (5e-2)
82 {
83 }
84 
86 {
87 }
88 
89 void
91 {
92  TestVector testVector;
93 
94  testVector.m_distance = 10.0;
95  testVector.m_isLos = true;
96  testVector.m_frequency = 5.0e9;
97  testVector.m_pt = 0.0;
98  testVector.m_pr = -77.3784;
99  m_testVectors.Add (testVector);
100 
101  testVector.m_distance = 100.0;
102  testVector.m_isLos = true;
103  testVector.m_frequency = 5.0e9;
104  testVector.m_pt = 0.0;
105  testVector.m_pr = -87.2965;
106  m_testVectors.Add (testVector);
107 
108  testVector.m_distance = 1000.0;
109  testVector.m_isLos = true;
110  testVector.m_frequency = 5.0e9;
111  testVector.m_pt = 0.0;
112  testVector.m_pr = -108.5577;
113  m_testVectors.Add (testVector);
114 
115  testVector.m_distance = 10000.0;
116  testVector.m_isLos = true;
117  testVector.m_frequency = 5.0e9;
118  testVector.m_pt = 0.0;
119  testVector.m_pr = -140.3896;
120  m_testVectors.Add (testVector);
121 
122  testVector.m_distance = 10.0;
123  testVector.m_isLos = false;
124  testVector.m_frequency = 5.0e9;
125  testVector.m_pt = 0.0;
126  testVector.m_pr = -77.3784;
127  m_testVectors.Add (testVector);
128 
129  testVector.m_distance = 100.0;
130  testVector.m_isLos = false;
131  testVector.m_frequency = 5.0e9;
132  testVector.m_pt = 0.0;
133  testVector.m_pr = -95.7718;
134  m_testVectors.Add (testVector);
135 
136  testVector.m_distance = 1000.0;
137  testVector.m_isLos = false;
138  testVector.m_frequency = 5.0e9;
139  testVector.m_pt = 0.0;
140  testVector.m_pr = -133.5223;
141  m_testVectors.Add (testVector);
142 
143  testVector.m_distance = 5000.0;
144  testVector.m_isLos = false;
145  testVector.m_frequency = 5.0e9;
146  testVector.m_pt = 0.0;
147  testVector.m_pr = -160.5169;
148  m_testVectors.Add (testVector);
149 
150  // Create the nodes for BS and UT
152  nodes.Create (2);
153 
154  // Create the mobility models
155  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
156  nodes.Get (0)->AggregateObject (a);
157  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
158  nodes.Get (1)->AggregateObject (b);
159 
160  // Use a deterministic channel condition model
161  Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel> ();
162  Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel> ();
163 
164  // Create the propagation loss model
165  Ptr<ThreeGppRmaPropagationLossModel> lossModel = CreateObject<ThreeGppRmaPropagationLossModel> ();
166  lossModel->SetAttribute ("ShadowingEnabled", BooleanValue (false)); // disable the shadow fading
167 
168  for (uint32_t i = 0; i < m_testVectors.GetN (); i++)
169  {
170  TestVector testVector = m_testVectors.Get (i);
171 
172  Vector posBs = Vector (0.0, 0.0, 35.0);
173  Vector posUt = Vector (testVector.m_distance, 0.0, 1.5);
174 
175  // set the LOS or NLOS condition
176  if (testVector.m_isLos)
177  {
178  lossModel->SetChannelConditionModel (losCondModel);
179  }
180  else
181  {
182  lossModel->SetChannelConditionModel (nlosCondModel);
183  }
184 
185  a->SetPosition (posBs);
186  b->SetPosition (posUt);
187 
188  lossModel->SetAttribute ("Frequency", DoubleValue (testVector.m_frequency));
189  NS_TEST_EXPECT_MSG_EQ_TOL (lossModel->CalcRxPower (testVector.m_pt, a, b), testVector.m_pr, m_tolerance, "Got unexpected rcv power");
190  }
191 
192  Simulator::Destroy ();
193 }
194 
201 {
202 public:
207 
212 
213 private:
217  virtual void DoRun (void);
218 
222  typedef struct
223  {
224  double m_distance;
225  bool m_isLos;
226  double m_frequency;
227  double m_pt;
228  double m_pr;
229  } TestVector;
230 
232  double m_tolerance;
233 };
234 
236  : TestCase ("Test for the ThreeGppUmaPropagationLossModel class"),
237  m_testVectors (),
238  m_tolerance (5e-2)
239 {
240 }
241 
243 {
244 }
245 
246 void
248 {
249  TestVector testVector;
250 
251  testVector.m_distance = 10.0;
252  testVector.m_isLos = true;
253  testVector.m_frequency = 5.0e9;
254  testVector.m_pt = 0.0;
255  testVector.m_pr = -72.9380;
256  m_testVectors.Add (testVector);
257 
258  testVector.m_distance = 100.0;
259  testVector.m_isLos = true;
260  testVector.m_frequency = 5.0e9;
261  testVector.m_pt = 0.0;
262  testVector.m_pr = -86.2362;
263  m_testVectors.Add (testVector);
264 
265  testVector.m_distance = 1000.0;
266  testVector.m_isLos = true;
267  testVector.m_frequency = 5.0e9;
268  testVector.m_pt = 0.0;
269  testVector.m_pr = -109.7252;
270  m_testVectors.Add (testVector);
271 
272  testVector.m_distance = 5000.0;
273  testVector.m_isLos = true;
274  testVector.m_frequency = 5.0e9;
275  testVector.m_pt = 0.0;
276  testVector.m_pr = -137.6794;
277  m_testVectors.Add (testVector);
278 
279  testVector.m_distance = 10.0;
280  testVector.m_isLos = false;
281  testVector.m_frequency = 5.0e9;
282  testVector.m_pt = 0.0;
283  testVector.m_pr = -82.5131;
284  m_testVectors.Add (testVector);
285 
286  testVector.m_distance = 100.0;
287  testVector.m_isLos = false;
288  testVector.m_frequency = 5.0e9;
289  testVector.m_pt = 0.0;
290  testVector.m_pr = -106.1356;
291  m_testVectors.Add (testVector);
292 
293  testVector.m_distance = 1000.0;
294  testVector.m_isLos = false;
295  testVector.m_frequency = 5.0e9;
296  testVector.m_pt = 0.0;
297  testVector.m_pr = -144.7641;
298  m_testVectors.Add (testVector);
299 
300  testVector.m_distance = 5000.0;
301  testVector.m_isLos = false;
302  testVector.m_frequency = 5.0e9;
303  testVector.m_pt = 0.0;
304  testVector.m_pr = -172.0753;
305  m_testVectors.Add (testVector);
306 
307  // Create the nodes for BS and UT
309  nodes.Create (2);
310 
311  // Create the mobility models
312  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
313  nodes.Get (0)->AggregateObject (a);
314  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
315  nodes.Get (1)->AggregateObject (b);
316 
317  // Use a deterministic channel condition model
318  Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel> ();
319  Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel> ();
320 
321  // Create the propagation loss model
322  Ptr<ThreeGppUmaPropagationLossModel> lossModel = CreateObject<ThreeGppUmaPropagationLossModel> ();
323  lossModel->SetAttribute ("ShadowingEnabled", BooleanValue (false)); // disable the shadow fading
324 
325  for (uint32_t i = 0; i < m_testVectors.GetN (); i++)
326  {
327  TestVector testVector = m_testVectors.Get (i);
328 
329  Vector posBs = Vector (0.0, 0.0, 25.0);
330  Vector posUt = Vector (testVector.m_distance, 0.0, 1.5);
331 
332  // set the LOS or NLOS condition
333  if (testVector.m_isLos)
334  {
335  lossModel->SetChannelConditionModel (losCondModel);
336  }
337  else
338  {
339  lossModel->SetChannelConditionModel (nlosCondModel);
340  }
341 
342  a->SetPosition (posBs);
343  b->SetPosition (posUt);
344 
345  lossModel->SetAttribute ("Frequency", DoubleValue (testVector.m_frequency));
346  NS_TEST_EXPECT_MSG_EQ_TOL (lossModel->CalcRxPower (testVector.m_pt, a, b), testVector.m_pr, m_tolerance, "Got unexpected rcv power");
347  }
348 
349  Simulator::Destroy ();
350 }
351 
358 {
359 public:
364 
369 
370 private:
374  virtual void DoRun (void);
375 
379  typedef struct
380  {
381  double m_distance;
382  bool m_isLos;
383  double m_frequency;
384  double m_pt;
385  double m_pr;
386  } TestVector;
387 
389  double m_tolerance;
390 };
391 
393  : TestCase ("Test for the ThreeGppUmiPropagationLossModel class"),
394  m_testVectors (),
395  m_tolerance (5e-2)
396 {
397 }
398 
400 {
401 }
402 
403 void
405 {
406  TestVector testVector;
407 
408  testVector.m_distance = 10.0;
409  testVector.m_isLos = true;
410  testVector.m_frequency = 5.0e9;
411  testVector.m_pt = 0.0;
412  testVector.m_pr = -69.8591;
413  m_testVectors.Add (testVector);
414 
415  testVector.m_distance = 100.0;
416  testVector.m_isLos = true;
417  testVector.m_frequency = 5.0e9;
418  testVector.m_pt = 0.0;
419  testVector.m_pr = -88.4122;
420  m_testVectors.Add (testVector);
421 
422  testVector.m_distance = 1000.0;
423  testVector.m_isLos = true;
424  testVector.m_frequency = 5.0e9;
425  testVector.m_pt = 0.0;
426  testVector.m_pr = -119.3114;
427 
428  testVector.m_distance = 5000.0;
429  testVector.m_isLos = true;
430  testVector.m_frequency = 5.0e9;
431  testVector.m_pt = 0.0;
432  testVector.m_pr = -147.2696;
433 
434  testVector.m_distance = 10.0;
435  testVector.m_isLos = false;
436  testVector.m_frequency = 5.0e9;
437  testVector.m_pt = 0.0;
438  testVector.m_pr = -76.7563;
439 
440  testVector.m_distance = 100.0;
441  testVector.m_isLos = false;
442  testVector.m_frequency = 5.0e9;
443  testVector.m_pt = 0.0;
444  testVector.m_pr = -107.9432;
445 
446  testVector.m_distance = 1000.0;
447  testVector.m_isLos = false;
448  testVector.m_frequency = 5.0e9;
449  testVector.m_pt = 0.0;
450  testVector.m_pr = -143.1886;
451 
452  testVector.m_distance = 5000.0;
453  testVector.m_isLos = false;
454  testVector.m_frequency = 5.0e9;
455  testVector.m_pt = 0.0;
456  testVector.m_pr = -167.8617;
457 
458  // Create the nodes for BS and UT
460  nodes.Create (2);
461 
462  // Create the mobility models
463  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
464  nodes.Get (0)->AggregateObject (a);
465  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
466  nodes.Get (1)->AggregateObject (b);
467 
468  // Use a deterministic channel condition model
469  Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel> ();
470  Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel> ();
471 
472  // Create the propagation loss model
473  Ptr<ThreeGppUmiStreetCanyonPropagationLossModel> lossModel = CreateObject<ThreeGppUmiStreetCanyonPropagationLossModel> ();
474  lossModel->SetAttribute ("ShadowingEnabled", BooleanValue (false)); // disable the shadow fading
475 
476  for (uint32_t i = 0; i < m_testVectors.GetN (); i++)
477  {
478  TestVector testVector = m_testVectors.Get (i);
479 
480  Vector posBs = Vector (0.0, 0.0, 10.0);
481  Vector posUt = Vector (testVector.m_distance, 0.0, 1.5);
482 
483  // set the LOS or NLOS condition
484  if (testVector.m_isLos)
485  {
486  lossModel->SetChannelConditionModel (losCondModel);
487  }
488  else
489  {
490  lossModel->SetChannelConditionModel (nlosCondModel);
491  }
492 
493  a->SetPosition (posBs);
494  b->SetPosition (posUt);
495 
496  lossModel->SetAttribute ("Frequency", DoubleValue (testVector.m_frequency));
497  NS_TEST_EXPECT_MSG_EQ_TOL (lossModel->CalcRxPower (testVector.m_pt, a, b), testVector.m_pr, m_tolerance, "Got unexpected rcv power");
498  }
499 
500  Simulator::Destroy ();
501 }
502 
509 {
510 public:
515 
520 
521 private:
525  virtual void DoRun (void);
526 
530  typedef struct
531  {
532  double m_distance;
533  bool m_isLos;
534  double m_frequency;
535  double m_pt;
536  double m_pr;
537  } TestVector;
538 
540  double m_tolerance;
541 };
542 
544  : TestCase ("Test for the ThreeGppIndoorOfficePropagationLossModel class"),
545  m_testVectors (),
546  m_tolerance (5e-2)
547 {
548 }
549 
551 {
552 }
553 
554 void
556 {
557  TestVector testVector;
558 
559  testVector.m_distance = 1.0;
560  testVector.m_isLos = true;
561  testVector.m_frequency = 5.0e9;
562  testVector.m_pt = 0.0;
563  testVector.m_pr = -50.8072;
564  m_testVectors.Add (testVector);
565 
566  testVector.m_distance = 10.0;
567  testVector.m_isLos = true;
568  testVector.m_frequency = 5.0e9;
569  testVector.m_pt = 0.0;
570  testVector.m_pr = -63.7630;
571  m_testVectors.Add (testVector);
572 
573  testVector.m_distance = 50.0;
574  testVector.m_isLos = true;
575  testVector.m_frequency = 5.0e9;
576  testVector.m_pt = 0.0;
577  testVector.m_pr = -75.7750;
578  m_testVectors.Add (testVector);
579 
580  testVector.m_distance = 100.0;
581  testVector.m_isLos = true;
582  testVector.m_frequency = 5.0e9;
583  testVector.m_pt = 0.0;
584  testVector.m_pr = -80.9802;
585  m_testVectors.Add (testVector);
586 
587  testVector.m_distance = 1.0;
588  testVector.m_isLos = false;
589  testVector.m_frequency = 5.0e9;
590  testVector.m_pt = 0.0;
591  testVector.m_pr = -50.8072;
592  m_testVectors.Add (testVector);
593 
594  testVector.m_distance = 10.0;
595  testVector.m_isLos = false;
596  testVector.m_frequency = 5.0e9;
597  testVector.m_pt = 0.0;
598  testVector.m_pr = -73.1894;
599  m_testVectors.Add (testVector);
600 
601  testVector.m_distance = 50.0;
602  testVector.m_isLos = false;
603  testVector.m_frequency = 5.0e9;
604  testVector.m_pt = 0.0;
605  testVector.m_pr = -99.7824;
606  m_testVectors.Add (testVector);
607 
608  testVector.m_distance = 100.0;
609  testVector.m_isLos = false;
610  testVector.m_frequency = 5.0e9;
611  testVector.m_pt = 0.0;
612  testVector.m_pr = -111.3062;
613  m_testVectors.Add (testVector);
614 
615  // Create the nodes for BS and UT
617  nodes.Create (2);
618 
619  // Create the mobility models
620  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
621  nodes.Get (0)->AggregateObject (a);
622  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
623  nodes.Get (1)->AggregateObject (b);
624 
625  // Use a deterministic channel condition model
626  Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel> ();
627  Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel> ();
628 
629  // Create the propagation loss model
630  Ptr<ThreeGppIndoorOfficePropagationLossModel> lossModel = CreateObject<ThreeGppIndoorOfficePropagationLossModel> ();
631  lossModel->SetAttribute ("ShadowingEnabled", BooleanValue (false)); // disable the shadow fading
632 
633  for (uint32_t i = 0; i < m_testVectors.GetN (); i++)
634  {
635  TestVector testVector = m_testVectors.Get (i);
636 
637  Vector posBs = Vector (0.0, 0.0, 3.0);
638  Vector posUt = Vector (testVector.m_distance, 0.0, 1.5);
639 
640  // set the LOS or NLOS condition
641  if (testVector.m_isLos)
642  {
643  lossModel->SetChannelConditionModel (losCondModel);
644  }
645  else
646  {
647  lossModel->SetChannelConditionModel (nlosCondModel);
648  }
649 
650  a->SetPosition (posBs);
651  b->SetPosition (posUt);
652 
653  lossModel->SetAttribute ("Frequency", DoubleValue (testVector.m_frequency));
654  NS_TEST_EXPECT_MSG_EQ_TOL (lossModel->CalcRxPower (testVector.m_pt, a, b), testVector.m_pr, m_tolerance, "Got unexpected rcv power");
655  }
656 
657  Simulator::Destroy ();
658 }
659 
676 {
677 public:
682 
687 
688 private:
692  virtual void DoRun (void);
693 
697  typedef struct
698  {
699  double m_distance;
700  bool m_isLos;
701  double m_frequency;
702  double m_pt;
703  double m_pr;
704  } TestVector;
705 
707  double m_tolerance;
708 };
709 
711  : TestCase ("Test for the ThreeGppV2vUrbanPropagationLossModel class."),
712  m_testVectors (),
713  m_tolerance (5e-2)
714 {
715 }
716 
718 {
719 }
720 
721 void
723 {
724  TestVector testVector;
725 
726  testVector.m_distance = 10.0;
727  testVector.m_isLos = true;
728  testVector.m_frequency = 5.0e9;
729  testVector.m_pt = 0.0;
730  testVector.m_pr = -68.1913;
731  m_testVectors.Add (testVector);
732 
733  testVector.m_distance = 100.0;
734  testVector.m_isLos = true;
735  testVector.m_frequency = 5.0e9;
736  testVector.m_pt = 0.0;
737  testVector.m_pr = -84.8913;
738  m_testVectors.Add (testVector);
739 
740  testVector.m_distance = 1000.0;
741  testVector.m_isLos = true;
742  testVector.m_frequency = 5.0e9;
743  testVector.m_pt = 0.0;
744  testVector.m_pr = -101.5913;
745  m_testVectors.Add (testVector);
746 
747  testVector.m_distance = 10.0;
748  testVector.m_isLos = false;
749  testVector.m_frequency = 5.0e9;
750  testVector.m_pt = 0.0;
751  testVector.m_pr = -80.0605;
752  m_testVectors.Add (testVector);
753 
754  testVector.m_distance = 100.0;
755  testVector.m_isLos = false;
756  testVector.m_frequency = 5.0e9;
757  testVector.m_pt = 0.0;
758  testVector.m_pr = -110.0605;
759  m_testVectors.Add (testVector);
760 
761  testVector.m_distance = 1000.0;
762  testVector.m_isLos = false;
763  testVector.m_frequency = 5.0e9;
764  testVector.m_pt = 0.0;
765  testVector.m_pr = -140.0605;
766  m_testVectors.Add (testVector);
767 
768  // Create the nodes for BS and UT
770  nodes.Create (2);
771 
772  // Create the mobility models
773  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
774  nodes.Get (0)->AggregateObject (a);
775  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
776  nodes.Get (1)->AggregateObject (b);
777 
778  // Use a deterministic channel condition model
779  Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel> ();
780  Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel> ();
781 
782  // Create the propagation loss model
783  Ptr<ThreeGppPropagationLossModel> lossModel = CreateObject<ThreeGppV2vUrbanPropagationLossModel> ();
784  lossModel->SetAttribute ("ShadowingEnabled", BooleanValue (false)); // disable the shadow fading
785 
786  for (uint32_t i = 0; i < m_testVectors.GetN (); i++)
787  {
788  TestVector testVector = m_testVectors.Get (i);
789 
790  Vector posUe1 = Vector (0.0, 0.0, 1.6);
791  Vector posUe2 = Vector (testVector.m_distance, 0.0, 1.6);
792 
793  // set the LOS or NLOS condition
794  if (testVector.m_isLos)
795  {
796  lossModel->SetChannelConditionModel (losCondModel);
797  }
798  else
799  {
800  lossModel->SetChannelConditionModel (nlosCondModel);
801  }
802 
803  a->SetPosition (posUe1);
804  b->SetPosition (posUe2);
805 
806  lossModel->SetAttribute ("Frequency", DoubleValue (testVector.m_frequency));
807  NS_TEST_EXPECT_MSG_EQ_TOL (lossModel->CalcRxPower (testVector.m_pt, a, b), testVector.m_pr, m_tolerance, "Got unexpected rcv power");
808  }
809 
810  Simulator::Destroy ();
811 }
812 
829 {
830 public:
835 
840 
841 private:
845  virtual void DoRun (void);
846 
850  typedef struct
851  {
852  double m_distance;
853  bool m_isLos;
854  double m_frequency;
855  double m_pt;
856  double m_pr;
857  } TestVector;
858 
860  double m_tolerance;
861 };
862 
864  : TestCase ("Test for the ThreeGppV2vHighwayPropagationLossModel"),
865  m_testVectors (),
866  m_tolerance (5e-2)
867 {
868 }
869 
871 {
872 }
873 
874 void
876 {
877  TestVector testVector;
878 
879  testVector.m_distance = 10.0;
880  testVector.m_isLos = true;
881  testVector.m_frequency = 5.0e9;
882  testVector.m_pt = 0.0;
883  testVector.m_pr = -66.3794;
884  m_testVectors.Add (testVector);
885 
886  testVector.m_distance = 100.0;
887  testVector.m_isLos = true;
888  testVector.m_frequency = 5.0e9;
889  testVector.m_pt = 0.0;
890  testVector.m_pr = -86.3794;
891  m_testVectors.Add (testVector);
892 
893  testVector.m_distance = 1000.0;
894  testVector.m_isLos = true;
895  testVector.m_frequency = 5.0e9;
896  testVector.m_pt = 0.0;
897  testVector.m_pr = -106.3794;
898  m_testVectors.Add (testVector);
899 
900  testVector.m_distance = 10.0;
901  testVector.m_isLos = false;
902  testVector.m_frequency = 5.0e9;
903  testVector.m_pt = 0.0;
904  testVector.m_pr = -80.0605;
905  m_testVectors.Add (testVector);
906 
907  testVector.m_distance = 100.0;
908  testVector.m_isLos = false;
909  testVector.m_frequency = 5.0e9;
910  testVector.m_pt = 0.0;
911  testVector.m_pr = -110.0605;
912  m_testVectors.Add (testVector);
913 
914  testVector.m_distance = 1000.0;
915  testVector.m_isLos = false;
916  testVector.m_frequency = 5.0e9;
917  testVector.m_pt = 0.0;
918  testVector.m_pr = -140.0605;
919  m_testVectors.Add (testVector);
920 
921  // Create the nodes for BS and UT
923  nodes.Create (2);
924 
925  // Create the mobility models
926  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
927  nodes.Get (0)->AggregateObject (a);
928  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
929  nodes.Get (1)->AggregateObject (b);
930 
931  // Use a deterministic channel condition model
932  Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel> ();
933  Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel> ();
934 
935  // Create the propagation loss model
936  Ptr<ThreeGppPropagationLossModel> lossModel = CreateObject<ThreeGppV2vHighwayPropagationLossModel> ();
937  lossModel->SetAttribute ("ShadowingEnabled", BooleanValue (false)); // disable the shadow fading
938 
939  for (uint32_t i = 0; i < m_testVectors.GetN (); i++)
940  {
941  TestVector testVector = m_testVectors.Get (i);
942 
943  Vector posUe1 = Vector (0.0, 0.0, 1.6);
944  Vector posUe2 = Vector (testVector.m_distance, 0.0, 1.6);
945 
946  // set the LOS or NLOS condition
947  if (testVector.m_isLos)
948  {
949  lossModel->SetChannelConditionModel (losCondModel);
950  }
951  else
952  {
953  lossModel->SetChannelConditionModel (nlosCondModel);
954  }
955 
956  a->SetPosition (posUe1);
957  b->SetPosition (posUe2);
958 
959  lossModel->SetAttribute ("Frequency", DoubleValue (testVector.m_frequency));
960  NS_TEST_EXPECT_MSG_EQ_TOL (lossModel->CalcRxPower (testVector.m_pt, a, b), testVector.m_pr, m_tolerance, "Got unexpected rcv power");
961  }
962 
963  Simulator::Destroy ();
964 }
965 
966 // Test to check if the shadowing fading is correctly computed
968 {
969 public:
971  virtual ~ThreeGppShadowingTestCase ();
972 
973 private:
974  virtual void DoRun (void);
975 
985  void RunTest (uint16_t testNum, std::string propagationLossModelType, double hBs, double hUt, double distance, bool shadowingEnabled);
986 
987 
994  void EvaluateLoss (Ptr<MobilityModel> a, Ptr<MobilityModel> b, uint8_t testNum);
995 
997 
1001  typedef struct
1002  {
1004  double m_hBs;
1005  double m_hUt;
1006  double m_distance;
1009  } TestVector;
1010 
1013  std::map<uint16_t /* index of experiment */, std::vector<double> /* loss in dB for each run */> m_results;
1014 };
1015 
1017  : TestCase ("Test to check if the shadow fading is correctly computed")
1018 {
1019 }
1020 
1022 {
1023 }
1024 
1025 void
1027 {
1028  double loss = m_lossModel->CalcRxPower (0, a, b);
1029  m_results.at (testNum).push_back (loss);
1030 }
1031 
1032 void
1034 {
1036 }
1037 
1038 void
1039 ThreeGppShadowingTestCase::RunTest (uint16_t testNum, std::string propagationLossModelType, double hBs, double hUt, double distance, bool shadowingEnabled)
1040 {
1041  // Add a new entry for this test in the results map
1042  m_results [testNum] = std::vector<double> ();
1043 
1044  // Create the nodes for BS and UT
1046  nodes.Create (2);
1047 
1048  // Create the mobility models
1049  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
1050  a->SetPosition (Vector (0.0, 0.0, hBs));
1051  nodes.Get (0)->AggregateObject (a);
1052 
1053  Ptr<ConstantVelocityMobilityModel> b = CreateObject<ConstantVelocityMobilityModel> ();
1054  nodes.Get (1)->AggregateObject (b);
1055  b->SetPosition (Vector (0.0, distance, hUt));
1056  b->SetVelocity (Vector (1.0, 0.0, 0.0));
1057 
1058  // Create the propagation loss model
1059  ObjectFactory propagationLossModelFactory = ObjectFactory (propagationLossModelType);
1060  m_lossModel = propagationLossModelFactory.Create<ThreeGppPropagationLossModel> ();
1061  m_lossModel->SetAttribute ("Frequency", DoubleValue (3.5e9));
1062  m_lossModel->SetAttribute ("ShadowingEnabled", BooleanValue (shadowingEnabled)); // enable the shadow fading
1063 
1064  // Set the channel condition to LOS
1065  Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel> ();
1066  m_lossModel->SetChannelConditionModel (losCondModel);
1067  // Schedule a transition to NLOS
1068  Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel> ();
1069  Simulator::Schedule (Seconds (99.5), &ThreeGppShadowingTestCase::ChangeChannelCondition, this, nlosCondModel);
1070 
1071  // Schedule multiple calls to EvaluateLoss. Use both EvaluateLoss (a,b) and
1072  // EvaluateLoss (b,a) to check if the reciprocity holds.
1073  for (int i = 0; i < 200; i++)
1074  {
1075  if (i % 2 == 0)
1076  Simulator::Schedule (MilliSeconds (1000 * i), &ThreeGppShadowingTestCase::EvaluateLoss, this, a, b, testNum);
1077  else
1078  Simulator::Schedule (MilliSeconds (1000 * i), &ThreeGppShadowingTestCase::EvaluateLoss, this, b, a, testNum);
1079  }
1080 
1081  Simulator::Run ();
1082  Simulator::Destroy ();
1083 }
1084 
1085 void
1087 {
1088  // The test scenario is composed of two nodes, one fixed
1089  // at position (0,0) and the other moving with constant velocity from
1090  // position (0,50) to position (200,50).
1091  // The channel condition changes from LOS to NLOS when the second node
1092  // reaches position (100,50).
1093  // Each experiment computes the propagation loss between the two nodes
1094  // every second, until the final position is reached, and saves the
1095  // results in an entry of the map m_results.
1096  // We run numSamples experiments and estimate the mean propagation loss in
1097  // each position by averaging among the samples.
1098  // Then, we perform the null hypothesis test with a significance level of
1099  // 0.05.
1100  // This procedure is repeated for all the 3GPP propagation scenarios, i.e.,
1101  // RMa, UMa, UMi and Indoor-Office.
1102 
1103  TestVector testVector;
1104  testVector.m_propagationLossModelType = "ns3::ThreeGppRmaPropagationLossModel";
1105  testVector.m_hBs = 25;
1106  testVector.m_hUt = 1.6;
1107  testVector.m_distance = 100;
1108  testVector.m_shadowingStdLos = 4;
1109  testVector.m_shadowingStdNlos = 8;
1110  m_testVectors.Add (testVector);
1111 
1112  testVector.m_propagationLossModelType = "ns3::ThreeGppRmaPropagationLossModel";
1113  testVector.m_hBs = 25;
1114  testVector.m_hUt = 1.6;
1115  testVector.m_distance = 4000; // beyond the breakpoint distance
1116  testVector.m_shadowingStdLos = 6;
1117  testVector.m_shadowingStdNlos = 8;
1118  m_testVectors.Add (testVector);
1119 
1120  testVector.m_propagationLossModelType = "ns3::ThreeGppUmaPropagationLossModel";
1121  testVector.m_hBs = 25;
1122  testVector.m_hUt = 1.6;
1123  testVector.m_distance = 100;
1124  testVector.m_shadowingStdLos = 4;
1125  testVector.m_shadowingStdNlos = 6;
1126  m_testVectors.Add (testVector);
1127 
1128  testVector.m_propagationLossModelType = "ns3::ThreeGppUmiStreetCanyonPropagationLossModel";
1129  testVector.m_hBs = 10;
1130  testVector.m_hUt = 1.6;
1131  testVector.m_distance = 100;
1132  testVector.m_shadowingStdLos = 4;
1133  testVector.m_shadowingStdNlos = 7.82;
1134  m_testVectors.Add (testVector);
1135 
1136  testVector.m_propagationLossModelType = "ns3::ThreeGppIndoorOfficePropagationLossModel";
1137  testVector.m_hBs = 3;
1138  testVector.m_hUt = 1;
1139  testVector.m_distance = 50;
1140  testVector.m_shadowingStdLos = 3;
1141  testVector.m_shadowingStdNlos = 8.03;
1142  m_testVectors.Add (testVector);
1143 
1144  testVector.m_propagationLossModelType = "ns3::ThreeGppV2vUrbanPropagationLossModel";
1145  testVector.m_hBs = 1.6;
1146  testVector.m_hUt = 1.6;
1147  testVector.m_distance = 50;
1148  testVector.m_shadowingStdLos = 3;
1149  testVector.m_shadowingStdNlos = 4;
1150  m_testVectors.Add (testVector);
1151 
1152  testVector.m_propagationLossModelType = "ns3::ThreeGppV2vHighwayPropagationLossModel";
1153  testVector.m_hBs = 1.6;
1154  testVector.m_hUt = 1.6;
1155  testVector.m_distance = 50;
1156  testVector.m_shadowingStdLos = 3;
1157  testVector.m_shadowingStdNlos = 4;
1158  m_testVectors.Add (testVector);
1159 
1160  uint16_t numSamples = 250;
1161 
1162  for (uint16_t tvIndex = 0; tvIndex < m_testVectors.GetN (); tvIndex++)
1163  {
1164  TestVector tv = m_testVectors.Get (tvIndex);
1165 
1166  // run the experiments.
1167  for (uint16_t sampleIndex = 0; sampleIndex < numSamples; sampleIndex++)
1168  {
1169  RunTest (sampleIndex, tv.m_propagationLossModelType, tv.m_hBs, tv.m_hUt, tv.m_distance, true);
1170  }
1171 
1172  // analyze the results
1173  std::vector<double> mean_vector; // the vector containing the mean propagation loss for each position (sample mean)
1174 
1175  uint16_t numPositions = m_results.at (0).size ();
1176  for (uint16_t k = 0; k < numPositions; k++)
1177  {
1178  // compute the mean propagation loss in position k
1179  double mean = 0.0;
1180  for (auto resIt : m_results)
1181  {
1182  mean += resIt.second.at (k);
1183  }
1184  mean /= m_results.size ();
1185  mean_vector.push_back (mean);
1186  }
1187 
1188  // compute the true mean - just the pathloss, without the shadowing component
1189  RunTest (numSamples, tv.m_propagationLossModelType, tv.m_hBs, tv.m_hUt, tv.m_distance, false);
1190  std::vector<double> true_mean = m_results.at (numSamples); // the result of the last test is the true mean
1191 
1192  // perform the null hypothesis test for the LOS case
1193  // positions from (0, 50) to (99, 50) are LOS
1194  for (uint16_t i = 0; i < mean_vector.size () / 2; i++)
1195  {
1196  double z = (mean_vector.at (i) - true_mean.at (i)) / (tv.m_shadowingStdLos / std::sqrt (mean_vector.size () / 2));
1197  NS_TEST_EXPECT_MSG_EQ_TOL (z, 0.0, 1.96, "Null hypothesis test (LOS case) for the shadowing component rejected");
1198  }
1199 
1200  // perform the null hypothesis test for the NLOS case
1201  // positions from (100, 50) to (199, 50) are NLOS
1202  for (uint16_t i = mean_vector.size () / 2; i < mean_vector.size (); i++)
1203  {
1204  double z = (mean_vector.at (i) - true_mean.at (i)) / (tv.m_shadowingStdNlos / std::sqrt (mean_vector.size () / 2));
1205  NS_TEST_EXPECT_MSG_EQ_TOL (z, 0.0, 1.96, "Null hypothesis test (NLOS case) for the shadowing component rejected");
1206  }
1207  }
1208 }
1209 
1211 {
1212 public:
1214 };
1215 
1217  : TestSuite ("three-gpp-propagation-loss-model", UNIT)
1218 {
1225  AddTestCase (new ThreeGppShadowingTestCase, TestCase::QUICK);
1226 }
1227 
virtual void DoRun(void)
Build the simulation scenario and run the tests.
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...
AttributeValue implementation for Boolean.
Definition: boolean.h:36
Test case for the class ThreeGppIndoorOfficePropagationLossModel.
TestVectors< TestVector > m_testVectors
array containing all the test vectors
Test case for the class ThreeGppRmaPropagationLossModel.
A suite of tests to run.
Definition: test.h:1343
double m_shadowingStdNlos
the standard deviation of the shadowing component in the NLOS case in dB
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1297
virtual void DoRun(void)
Build the simulation scenario and run the tests.
void ChangeChannelCondition(Ptr< ChannelConditionModel > ccm)
encapsulates test code
Definition: test.h:1153
virtual void DoRun(void)
Build the simulation scenario and run the tests.
Ptr< ThreeGppPropagationLossModel > m_lossModel
the propagation loss model
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1406
nodes
Definition: first.py:32
Ptr< Object > Create(void) const
Create an Object instance of the configured TypeId.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
TestVectors< TestVector > m_testVectors
array containing all the test vectors
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.
virtual void DoRun(void)
Build the simulation scenario and run the tests.
void EvaluateLoss(Ptr< MobilityModel > a, Ptr< MobilityModel > b, uint8_t testNum)
Compute the propagation loss.
TestVectors< TestVector > m_testVectors
array containing all the test vectors
Test case for the class ThreeGppV2vUrbanPropagationLossModel.
virtual void DoRun(void)
Implementation to actually run this TestCase.
double m_distance
the initial 2D distance in meters between BS and UT in meters
#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:563
std::string m_propagationLossModelType
the propagation loss model type id
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
Struct containing the parameters for each test.
virtual void DoRun(void)
Build the simulation scenario and run the tests.
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 ThreeGppUmiStreetCanyonPropagationLossModel.
TestVectors< TestVector > m_testVectors
array containing all the test vectors
Test case for the class ThreeGppV2vHighwayPropagationLossModel.
double m_shadowingStdLos
the standard deviation of the shadowing component in the LOS case in dB
void SetPosition(const Vector &position)
Instantiate subclasses of ns3::Object.
static ThreeGppPropagationLossModelsTestSuite propagationLossModelsTestSuite
std::map< uint16_t, std::vector< double > > m_results
used to store the test results
void SetChannelConditionModel(Ptr< ChannelConditionModel > model)
Set the channel condition model used to determine the channel state (e.g., the LOS/NLOS condition) ...
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
Test case for the class ThreeGppUmaPropagationLossModel.
TestVectors< TestVector > m_testVectors
array containing all the test vectors
Base class for the 3GPP propagation models.
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185