A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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 * SPDX-License-Identifier: GPL-2.0-only
6 */
7
8#include "ns3/abort.h"
9#include "ns3/boolean.h"
10#include "ns3/channel-condition-model.h"
11#include "ns3/config.h"
12#include "ns3/constant-position-mobility-model.h"
13#include "ns3/constant-velocity-mobility-model.h"
14#include "ns3/double.h"
15#include "ns3/log.h"
16#include "ns3/mobility-helper.h"
17#include "ns3/simulator.h"
18#include "ns3/test.h"
19#include "ns3/three-gpp-propagation-loss-model.h"
20#include "ns3/three-gpp-v2v-propagation-loss-model.h"
21
22using namespace ns3;
23
24NS_LOG_COMPONENT_DEFINE("ThreeGppPropagationLossModelsTest");
25
26/**
27 * @ingroup propagation-tests
28 *
29 * Test case for the class ThreeGppRmaPropagationLossModel.
30 * It computes the pathloss between two nodes and compares it with the value
31 * obtained using the formula in 3GPP TR 38.901, Table 7.4.1-1.
32 */
34{
35 public:
36 /**
37 * Constructor
38 */
40
41 /**
42 * Destructor
43 */
45
46 private:
47 /**
48 * Build the simulation scenario and run the tests
49 */
50 void DoRun() override;
51
52 /**
53 * Struct containing the parameters for each test
54 */
56 {
57 double m_distance; //!< 2D distance between UT and BS in meters
58 bool m_isLos; //!< if true LOS, if false NLOS
59 double m_frequency; //!< carrier frequency in Hz
60 double m_pt; //!< transmitted power in dBm
61 double m_pr; //!< received power in dBm
62 };
63
64 TestVectors<TestVector> m_testVectors; //!< array containing all the test vectors
65 double m_tolerance; //!< tolerance
66};
67
69 : TestCase("Test for the ThreeGppRmaPropagationLossModel class"),
71 m_tolerance(5e-2)
72{
73}
74
78
79void
81{
82 TestVector testVector;
83
84 testVector.m_distance = 10.0;
85 testVector.m_isLos = true;
86 testVector.m_frequency = 5.0e9;
87 testVector.m_pt = 0.0;
88 testVector.m_pr = -77.3784;
89 m_testVectors.Add(testVector);
90
91 testVector.m_distance = 100.0;
92 testVector.m_isLos = true;
93 testVector.m_frequency = 5.0e9;
94 testVector.m_pt = 0.0;
95 testVector.m_pr = -87.2965;
96 m_testVectors.Add(testVector);
97
98 testVector.m_distance = 1000.0;
99 testVector.m_isLos = true;
100 testVector.m_frequency = 5.0e9;
101 testVector.m_pt = 0.0;
102 testVector.m_pr = -108.5577;
103 m_testVectors.Add(testVector);
104
105 testVector.m_distance = 10000.0;
106 testVector.m_isLos = true;
107 testVector.m_frequency = 5.0e9;
108 testVector.m_pt = 0.0;
109 testVector.m_pr = -140.3896;
110 m_testVectors.Add(testVector);
111
112 testVector.m_distance = 10.0;
113 testVector.m_isLos = false;
114 testVector.m_frequency = 5.0e9;
115 testVector.m_pt = 0.0;
116 testVector.m_pr = -77.3784;
117 m_testVectors.Add(testVector);
118
119 testVector.m_distance = 100.0;
120 testVector.m_isLos = false;
121 testVector.m_frequency = 5.0e9;
122 testVector.m_pt = 0.0;
123 testVector.m_pr = -95.7718;
124 m_testVectors.Add(testVector);
125
126 testVector.m_distance = 1000.0;
127 testVector.m_isLos = false;
128 testVector.m_frequency = 5.0e9;
129 testVector.m_pt = 0.0;
130 testVector.m_pr = -133.5223;
131 m_testVectors.Add(testVector);
132
133 testVector.m_distance = 5000.0;
134 testVector.m_isLos = false;
135 testVector.m_frequency = 5.0e9;
136 testVector.m_pt = 0.0;
137 testVector.m_pr = -160.5169;
138 m_testVectors.Add(testVector);
139
140 // Create the nodes for BS and UT
142 nodes.Create(2);
143
144 // Create the mobility models
146 nodes.Get(0)->AggregateObject(a);
148 nodes.Get(1)->AggregateObject(b);
149
150 // Use a deterministic channel condition model
153
154 // Create the propagation loss model
157 lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
158
159 for (const auto& testVector : m_testVectors)
160 {
161 Vector posBs = Vector(0.0, 0.0, 35.0);
162 Vector posUt = Vector(testVector.m_distance, 0.0, 1.5);
163
164 // set the LOS or NLOS condition
165 if (testVector.m_isLos)
166 {
167 lossModel->SetChannelConditionModel(losCondModel);
168 }
169 else
170 {
171 lossModel->SetChannelConditionModel(nlosCondModel);
172 }
173
174 a->SetPosition(posBs);
175 b->SetPosition(posUt);
176
177 lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
178 NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
179 testVector.m_pr,
181 "Got unexpected rcv power");
182 }
183
185}
186
187/**
188 * @ingroup propagation-tests
189 *
190 * Test case for the class ThreeGppUmaPropagationLossModel.
191 * It computes the pathloss between two nodes and compares it with the value
192 * obtained using the formula in 3GPP TR 38.901, Table 7.4.1-1.
193 */
195{
196 public:
197 /**
198 * Constructor
199 */
201
202 /**
203 * Destructor
204 */
206
207 private:
208 /**
209 * Build the simulation scenario and run the tests
210 */
211 void DoRun() override;
212
213 /**
214 * Struct containing the parameters for each test
215 */
217 {
218 double m_distance; //!< 2D distance between UT and BS in meters
219 bool m_isLos; //!< if true LOS, if false NLOS
220 double m_frequency; //!< carrier frequency in Hz
221 double m_pt; //!< transmitted power in dBm
222 double m_pr; //!< received power in dBm
223 };
224
225 TestVectors<TestVector> m_testVectors; //!< array containing all the test vectors
226 double m_tolerance; //!< tolerance
227};
228
230 : TestCase("Test for the ThreeGppUmaPropagationLossModel class"),
232 m_tolerance(5e-2)
233{
234}
235
239
240void
242{
243 TestVector testVector;
244
245 testVector.m_distance = 10.0;
246 testVector.m_isLos = true;
247 testVector.m_frequency = 5.0e9;
248 testVector.m_pt = 0.0;
249 testVector.m_pr = -72.9380;
250 m_testVectors.Add(testVector);
251
252 testVector.m_distance = 100.0;
253 testVector.m_isLos = true;
254 testVector.m_frequency = 5.0e9;
255 testVector.m_pt = 0.0;
256 testVector.m_pr = -86.2362;
257 m_testVectors.Add(testVector);
258
259 testVector.m_distance = 1000.0;
260 testVector.m_isLos = true;
261 testVector.m_frequency = 5.0e9;
262 testVector.m_pt = 0.0;
263 testVector.m_pr = -109.7252;
264 m_testVectors.Add(testVector);
265
266 testVector.m_distance = 5000.0;
267 testVector.m_isLos = true;
268 testVector.m_frequency = 5.0e9;
269 testVector.m_pt = 0.0;
270 testVector.m_pr = -137.6794;
271 m_testVectors.Add(testVector);
272
273 testVector.m_distance = 10.0;
274 testVector.m_isLos = false;
275 testVector.m_frequency = 5.0e9;
276 testVector.m_pt = 0.0;
277 testVector.m_pr = -82.5131;
278 m_testVectors.Add(testVector);
279
280 testVector.m_distance = 100.0;
281 testVector.m_isLos = false;
282 testVector.m_frequency = 5.0e9;
283 testVector.m_pt = 0.0;
284 testVector.m_pr = -106.1356;
285 m_testVectors.Add(testVector);
286
287 testVector.m_distance = 1000.0;
288 testVector.m_isLos = false;
289 testVector.m_frequency = 5.0e9;
290 testVector.m_pt = 0.0;
291 testVector.m_pr = -144.7641;
292 m_testVectors.Add(testVector);
293
294 testVector.m_distance = 5000.0;
295 testVector.m_isLos = false;
296 testVector.m_frequency = 5.0e9;
297 testVector.m_pt = 0.0;
298 testVector.m_pr = -172.0753;
299 m_testVectors.Add(testVector);
300
301 // Create the nodes for BS and UT
303 nodes.Create(2);
304
305 // Create the mobility models
307 nodes.Get(0)->AggregateObject(a);
309 nodes.Get(1)->AggregateObject(b);
310
311 // Use a deterministic channel condition model
314
315 // Create the propagation loss model
318 lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
319
320 for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
321 {
322 TestVector testVector = m_testVectors.Get(i);
323
324 Vector posBs = Vector(0.0, 0.0, 25.0);
325 Vector posUt = Vector(testVector.m_distance, 0.0, 1.5);
326
327 // set the LOS or NLOS condition
328 if (testVector.m_isLos)
329 {
330 lossModel->SetChannelConditionModel(losCondModel);
331 }
332 else
333 {
334 lossModel->SetChannelConditionModel(nlosCondModel);
335 }
336
337 a->SetPosition(posBs);
338 b->SetPosition(posUt);
339
340 lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
341 NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
342 testVector.m_pr,
344 "Got unexpected rcv power");
345 }
346
348}
349
350/**
351 * @ingroup propagation-tests
352 *
353 * Test case for the class ThreeGppUmiStreetCanyonPropagationLossModel.
354 * It computes the pathloss between two nodes and compares it with the value
355 * obtained using the formula in 3GPP TR 38.901, Table 7.4.1-1.
356 */
358{
359 public:
360 /**
361 * Constructor
362 */
364
365 /**
366 * Destructor
367 */
369
370 private:
371 /**
372 * Build the simulation scenario and run the tests
373 */
374 void DoRun() override;
375
376 /**
377 * Struct containing the parameters for each test
378 */
380 {
381 double m_distance; //!< 2D distance between UT and BS in meters
382 bool m_isLos; //!< if true LOS, if false NLOS
383 double m_frequency; //!< carrier frequency in Hz
384 double m_pt; //!< transmitted power in dBm
385 double m_pr; //!< received power in dBm
386 };
387
388 TestVectors<TestVector> m_testVectors; //!< array containing all the test vectors
389 double m_tolerance; //!< tolerance
390};
391
393 : TestCase("Test for the ThreeGppUmiPropagationLossModel class"),
395 m_tolerance(5e-2)
396{
397}
398
402
403void
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
464 nodes.Get(0)->AggregateObject(a);
466 nodes.Get(1)->AggregateObject(b);
467
468 // Use a deterministic channel condition model
471
472 // Create the propagation loss model
475 lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
476
477 for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
478 {
479 TestVector testVector = m_testVectors.Get(i);
480
481 Vector posBs = Vector(0.0, 0.0, 10.0);
482 Vector posUt = Vector(testVector.m_distance, 0.0, 1.5);
483
484 // set the LOS or NLOS condition
485 if (testVector.m_isLos)
486 {
487 lossModel->SetChannelConditionModel(losCondModel);
488 }
489 else
490 {
491 lossModel->SetChannelConditionModel(nlosCondModel);
492 }
493
494 a->SetPosition(posBs);
495 b->SetPosition(posUt);
496
497 lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
498 NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
499 testVector.m_pr,
501 "Got unexpected rcv power");
502 }
503
505}
506
507/**
508 * @ingroup propagation-tests
509 *
510 * Test case for the class ThreeGppIndoorOfficePropagationLossModel.
511 * It computes the pathloss between two nodes and compares it with the value
512 * obtained using the formula in 3GPP TR 38.901, Table 7.4.1-1.
513 */
515{
516 public:
517 /**
518 * Constructor
519 */
521
522 /**
523 * Destructor
524 */
526
527 private:
528 /**
529 * Build the simulation scenario and run the tests
530 */
531 void DoRun() override;
532
533 /**
534 * Struct containing the parameters for each test
535 */
537 {
538 double m_distance; //!< 2D distance between UT and BS in meters
539 bool m_isLos; //!< if true LOS, if false NLOS
540 double m_frequency; //!< carrier frequency in Hz
541 double m_pt; //!< transmitted power in dBm
542 double m_pr; //!< received power in dBm
543 };
544
545 TestVectors<TestVector> m_testVectors; //!< array containing all the test vectors
546 double m_tolerance; //!< tolerance
547};
548
550 : TestCase("Test for the ThreeGppIndoorOfficePropagationLossModel class"),
552 m_tolerance(5e-2)
553{
554}
555
560
561void
563{
564 TestVector testVector;
565
566 testVector.m_distance = 1.0;
567 testVector.m_isLos = true;
568 testVector.m_frequency = 5.0e9;
569 testVector.m_pt = 0.0;
570 testVector.m_pr = -50.8072;
571 m_testVectors.Add(testVector);
572
573 testVector.m_distance = 10.0;
574 testVector.m_isLos = true;
575 testVector.m_frequency = 5.0e9;
576 testVector.m_pt = 0.0;
577 testVector.m_pr = -63.7630;
578 m_testVectors.Add(testVector);
579
580 testVector.m_distance = 50.0;
581 testVector.m_isLos = true;
582 testVector.m_frequency = 5.0e9;
583 testVector.m_pt = 0.0;
584 testVector.m_pr = -75.7750;
585 m_testVectors.Add(testVector);
586
587 testVector.m_distance = 100.0;
588 testVector.m_isLos = true;
589 testVector.m_frequency = 5.0e9;
590 testVector.m_pt = 0.0;
591 testVector.m_pr = -80.9802;
592 m_testVectors.Add(testVector);
593
594 testVector.m_distance = 1.0;
595 testVector.m_isLos = false;
596 testVector.m_frequency = 5.0e9;
597 testVector.m_pt = 0.0;
598 testVector.m_pr = -50.8072;
599 m_testVectors.Add(testVector);
600
601 testVector.m_distance = 10.0;
602 testVector.m_isLos = false;
603 testVector.m_frequency = 5.0e9;
604 testVector.m_pt = 0.0;
605 testVector.m_pr = -73.1894;
606 m_testVectors.Add(testVector);
607
608 testVector.m_distance = 50.0;
609 testVector.m_isLos = false;
610 testVector.m_frequency = 5.0e9;
611 testVector.m_pt = 0.0;
612 testVector.m_pr = -99.7824;
613 m_testVectors.Add(testVector);
614
615 testVector.m_distance = 100.0;
616 testVector.m_isLos = false;
617 testVector.m_frequency = 5.0e9;
618 testVector.m_pt = 0.0;
619 testVector.m_pr = -111.3062;
620 m_testVectors.Add(testVector);
621
622 // Create the nodes for BS and UT
624 nodes.Create(2);
625
626 // Create the mobility models
628 nodes.Get(0)->AggregateObject(a);
630 nodes.Get(1)->AggregateObject(b);
631
632 // Use a deterministic channel condition model
635
636 // Create the propagation loss model
639 lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
640
641 for (std::size_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),
663 testVector.m_pr,
665 "Got unexpected rcv power");
666 }
667
669}
670
671/**
672 * @ingroup propagation-tests
673 *
674 * Test case for the class ThreeGppV2vUrbanPropagationLossModel.
675 * It computes the pathloss between two nodes and compares it with the value
676 * obtained using the formula in 3GPP TR 37.885 Table 6.2.1-1 for v2v
677 * communications (sidelink).
678 *
679 * Note that 3GPP TR 37.885 defines 3 different channel states for vehicular
680 * environments: LOS, NLOS, and NLOSv, the latter representing the case in which
681 * the LOS path is blocked by other vehicles in the scenario. However, for
682 * computing the pathloss, only the two states are considered: LOS/NLOSv or NLOS
683 * (see TR 37.885 Section 6.2.1). In case of NLOSv, an additional vehicle
684 * blockage loss may be added, according to a log-normal random variable.
685 * Here, we test both conditions: LOS/NLOSv (without vehicle blockage
686 * loss) and NLOS.
687 */
689{
690 public:
691 /**
692 * Constructor
693 */
695
696 /**
697 * Destructor
698 */
700
701 private:
702 /**
703 * Build the simulation scenario and run the tests
704 */
705 void DoRun() override;
706
707 /**
708 * Struct containing the parameters for each test
709 */
711 {
712 double m_distance; //!< 2D distance between UT and BS in meters
713 bool m_isLos; //!< if true LOS/NLOSv, if false NLOS
714 double m_frequency; //!< carrier frequency in Hz
715 double m_pt; //!< transmitted power in dBm
716 double m_pr; //!< received power in dBm
717 };
718
719 TestVectors<TestVector> m_testVectors; //!< array containing all the test vectors
720 double m_tolerance; //!< tolerance
721};
722
724 : TestCase("Test for the ThreeGppV2vUrbanPropagationLossModel class."),
726 m_tolerance(5e-2)
727{
728}
729
733
734void
736{
737 TestVector testVector;
738
739 testVector.m_distance = 10.0;
740 testVector.m_isLos = true;
741 testVector.m_frequency = 5.0e9;
742 testVector.m_pt = 0.0;
743 testVector.m_pr = -68.1913;
744 m_testVectors.Add(testVector);
745
746 testVector.m_distance = 100.0;
747 testVector.m_isLos = true;
748 testVector.m_frequency = 5.0e9;
749 testVector.m_pt = 0.0;
750 testVector.m_pr = -84.8913;
751 m_testVectors.Add(testVector);
752
753 testVector.m_distance = 1000.0;
754 testVector.m_isLos = true;
755 testVector.m_frequency = 5.0e9;
756 testVector.m_pt = 0.0;
757 testVector.m_pr = -101.5913;
758 m_testVectors.Add(testVector);
759
760 testVector.m_distance = 10.0;
761 testVector.m_isLos = false;
762 testVector.m_frequency = 5.0e9;
763 testVector.m_pt = 0.0;
764 testVector.m_pr = -80.0605;
765 m_testVectors.Add(testVector);
766
767 testVector.m_distance = 100.0;
768 testVector.m_isLos = false;
769 testVector.m_frequency = 5.0e9;
770 testVector.m_pt = 0.0;
771 testVector.m_pr = -110.0605;
772 m_testVectors.Add(testVector);
773
774 testVector.m_distance = 1000.0;
775 testVector.m_isLos = false;
776 testVector.m_frequency = 5.0e9;
777 testVector.m_pt = 0.0;
778 testVector.m_pr = -140.0605;
779 m_testVectors.Add(testVector);
780
781 // Create the nodes for BS and UT
783 nodes.Create(2);
784
785 // Create the mobility models
787 nodes.Get(0)->AggregateObject(a);
789 nodes.Get(1)->AggregateObject(b);
790
791 // Use a deterministic channel condition model
794
795 // Create the propagation loss model
798 lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
799
800 for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
801 {
802 TestVector testVector = m_testVectors.Get(i);
803
804 Vector posUe1 = Vector(0.0, 0.0, 1.6);
805 Vector posUe2 = Vector(testVector.m_distance, 0.0, 1.6);
806
807 // set the LOS or NLOS condition
808 if (testVector.m_isLos)
809 {
810 lossModel->SetChannelConditionModel(losCondModel);
811 }
812 else
813 {
814 lossModel->SetChannelConditionModel(nlosCondModel);
815 }
816
817 a->SetPosition(posUe1);
818 b->SetPosition(posUe2);
819
820 lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
821 NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
822 testVector.m_pr,
824 "Got unexpected rcv power");
825 }
826
828}
829
830/**
831 * @ingroup propagation-tests
832 *
833 * Test case for the class ThreeGppV2vHighwayPropagationLossModel.
834 * It computes the pathloss between two nodes and compares it with the value
835 * obtained using the formula in 3GPP TR 37.885 Table 6.2.1-1 for v2v
836 * communications (sidelink).
837 *
838 * Note that 3GPP TR 37.885 defines 3 different channel states for vehicular
839 * environments: LOS, NLOS and NLOSv, the latter representing the case in which
840 * the LOS path is blocked by other vehicles in the scenario. However, for
841 * computing the pathloss, only two states are considered: LOS/NLOSv or NLOS
842 * (see TR 37.885 Section 6.2.1). In case of NLOSv, an additional vehicle
843 * blockage loss may be added, according to a log-normal random variable.
844 * Here, we test both conditions: LOS/NLOSv (without vehicle blockage
845 * loss) and NLOS.
846 */
848{
849 public:
850 /**
851 * Constructor
852 */
854
855 /**
856 * Destructor
857 */
859
860 private:
861 /**
862 * Build the simulation scenario and run the tests
863 */
864 void DoRun() override;
865
866 /**
867 * Struct containing the parameters for each test
868 */
870 {
871 double m_distance; //!< 2D distance between UT and BS in meters
872 bool m_isLos; //!< if true LOS/NLOSv, if false NLOS
873 double m_frequency; //!< carrier frequency in Hz
874 double m_pt; //!< transmitted power in dBm
875 double m_pr; //!< received power in dBm
876 };
877
878 TestVectors<TestVector> m_testVectors; //!< array containing all the test vectors
879 double m_tolerance; //!< tolerance
880};
881
883 : TestCase("Test for the ThreeGppV2vHighwayPropagationLossModel"),
885 m_tolerance(5e-2)
886{
887}
888
892
893void
895{
896 TestVector testVector;
897
898 testVector.m_distance = 10.0;
899 testVector.m_isLos = true;
900 testVector.m_frequency = 5.0e9;
901 testVector.m_pt = 0.0;
902 testVector.m_pr = -66.3794;
903 m_testVectors.Add(testVector);
904
905 testVector.m_distance = 100.0;
906 testVector.m_isLos = true;
907 testVector.m_frequency = 5.0e9;
908 testVector.m_pt = 0.0;
909 testVector.m_pr = -86.3794;
910 m_testVectors.Add(testVector);
911
912 testVector.m_distance = 1000.0;
913 testVector.m_isLos = true;
914 testVector.m_frequency = 5.0e9;
915 testVector.m_pt = 0.0;
916 testVector.m_pr = -106.3794;
917 m_testVectors.Add(testVector);
918
919 testVector.m_distance = 10.0;
920 testVector.m_isLos = false;
921 testVector.m_frequency = 5.0e9;
922 testVector.m_pt = 0.0;
923 testVector.m_pr = -80.0605;
924 m_testVectors.Add(testVector);
925
926 testVector.m_distance = 100.0;
927 testVector.m_isLos = false;
928 testVector.m_frequency = 5.0e9;
929 testVector.m_pt = 0.0;
930 testVector.m_pr = -110.0605;
931 m_testVectors.Add(testVector);
932
933 testVector.m_distance = 1000.0;
934 testVector.m_isLos = false;
935 testVector.m_frequency = 5.0e9;
936 testVector.m_pt = 0.0;
937 testVector.m_pr = -140.0605;
938 m_testVectors.Add(testVector);
939
940 // Create the nodes for BS and UT
942 nodes.Create(2);
943
944 // Create the mobility models
946 nodes.Get(0)->AggregateObject(a);
948 nodes.Get(1)->AggregateObject(b);
949
950 // Use a deterministic channel condition model
953
954 // Create the propagation loss model
957 lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
958
959 for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
960 {
961 TestVector testVector = m_testVectors.Get(i);
962
963 Vector posUe1 = Vector(0.0, 0.0, 1.6);
964 Vector posUe2 = Vector(testVector.m_distance, 0.0, 1.6);
965
966 // set the LOS or NLOS condition
967 if (testVector.m_isLos)
968 {
969 lossModel->SetChannelConditionModel(losCondModel);
970 }
971 else
972 {
973 lossModel->SetChannelConditionModel(nlosCondModel);
974 }
975
976 a->SetPosition(posUe1);
977 b->SetPosition(posUe2);
978
979 lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
980 NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
981 testVector.m_pr,
983 "Got unexpected rcv power");
984 }
985
987}
988
989/**
990 * @ingroup propagation-tests
991 *
992 * Test to check if the shadowing fading is correctly computed
993 */
995{
996 public:
999
1000 private:
1001 void DoRun() override;
1002
1003 /**
1004 * Run the experiment
1005 * @param testNum the index of the experiment
1006 * @param propagationLossModelType the type id of the propagation loss model
1007 * to be used
1008 * @param hBs the BS height in meters
1009 * @param hUt the UT height in meters
1010 * @param distance the initial distance between the BS and the UT
1011 * @param shadowingEnabled true if shadowing must be enabled
1012 * @param frequency channel frequency
1013 */
1014 void RunTest(uint16_t testNum,
1015 std::string propagationLossModelType,
1016 double hBs,
1017 double hUt,
1018 double distance,
1019 bool shadowingEnabled,
1020 double frequency);
1021
1022 /**
1023 * Compute the propagation loss
1024 * @param a the first mobility model
1025 * @param b the second mobility model
1026 * @param testNum the index of the experiment
1027 */
1028 void EvaluateLoss(Ptr<MobilityModel> a, Ptr<MobilityModel> b, uint16_t testNum);
1029
1030 /**
1031 * Change the channel condition model
1032 * @param ccm the new ChannelConditionModel
1033 */
1035
1036 /**
1037 * Struct containing the parameters for each test
1038 */
1040 {
1041 std::string m_propagationLossModelType; //!< the propagation loss model type id
1042 double m_hBs; //!< the BS height in meters
1043 double m_hUt; //!< the UT height in meters
1044 double m_distance; //!< the initial 2D distance in meters between BS and UT in meters
1045 double m_shadowingStdLos; //!< the standard deviation of the shadowing component in the LOS
1046 //!< case in dB
1047 double m_shadowingStdNlos; //!< the standard deviation of the shadowing component in the
1048 //!< NLOS case in dB
1049 double m_frequency; //!< channel frequency
1050 };
1051
1052 TestVectors<TestVector> m_testVectors; //!< array containing all the test vectors
1053 Ptr<ThreeGppPropagationLossModel> m_lossModel; //!< the propagation loss model
1054 std::map<uint16_t /* index of experiment */, std::vector<double> /* loss in dB for each run */>
1055 m_results; //!< used to store the test results
1056};
1057
1059 : TestCase("Test to check if the shadow fading is correctly computed")
1060{
1061}
1062
1066
1067void
1070 uint16_t testNum)
1071{
1072 double loss = m_lossModel->CalcRxPower(0, a, b);
1073 m_results.at(testNum).push_back(loss);
1074}
1075
1076void
1081
1082void
1084 std::string propagationLossModelType,
1085 double hBs,
1086 double hUt,
1087 double distance,
1088 bool shadowingEnabled,
1089 double frequency)
1090{
1091 // Add a new entry for this test in the results map
1092 m_results[testNum] = std::vector<double>();
1093
1094 // Create the nodes for BS and UT
1096 nodes.Create(2);
1097
1098 // Create the mobility models
1100 a->SetPosition(Vector(0.0, 0.0, hBs));
1101 nodes.Get(0)->AggregateObject(a);
1102
1104 nodes.Get(1)->AggregateObject(b);
1105 b->SetPosition(Vector(0.0, distance, hUt));
1106 b->SetVelocity(Vector(1.0, 0.0, 0.0));
1107
1108 // Create the propagation loss model
1109 ObjectFactory propagationLossModelFactory = ObjectFactory(propagationLossModelType);
1110 m_lossModel = propagationLossModelFactory.Create<ThreeGppPropagationLossModel>();
1111 m_lossModel->SetAttribute("Frequency", DoubleValue(frequency));
1112 m_lossModel->SetAttribute("ShadowingEnabled",
1113 BooleanValue(shadowingEnabled)); // enable the shadow fading
1114 m_lossModel->AssignStreams(testNum);
1115
1116 // Set the channel condition to LOS
1118 m_lossModel->SetChannelConditionModel(losCondModel);
1119 // Schedule a transition to NLOS
1123 this,
1124 nlosCondModel);
1125
1126 // Schedule multiple calls to EvaluateLoss. Use both EvaluateLoss (a,b) and
1127 // EvaluateLoss (b,a) to check if the reciprocity holds.
1128 for (int i = 0; i < 200; i++)
1129 {
1130 if (i % 2 == 0)
1131 {
1134 this,
1135 a,
1136 b,
1137 testNum);
1138 }
1139 else
1140 {
1143 this,
1144 b,
1145 a,
1146 testNum);
1147 }
1148 }
1149
1152}
1153
1154void
1156{
1157 // The test scenario is composed of two nodes, one fixed
1158 // at position (0,0) and the other moving with constant velocity from
1159 // position (0,50) to position (200,50).
1160 // The channel condition changes from LOS to NLOS when the second node
1161 // reaches position (100,50).
1162 // Each experiment computes the propagation loss between the two nodes
1163 // every second, until the final position is reached, and saves the
1164 // results in an entry of the map m_results.
1165 // We run numSamples experiments and estimate the mean propagation loss in
1166 // each position by averaging among the samples.
1167 // Then, we perform the null hypothesis test with a significance level of
1168 // 0.05.
1169 // This procedure is repeated for all the 3GPP propagation scenarios, i.e.,
1170 // RMa, UMa, UMi and Indoor-Office.
1171
1172 TestVector testVector;
1173
1174 // Above 6GHz
1175 testVector.m_frequency = 6e9;
1176 testVector.m_propagationLossModelType = "ns3::ThreeGppRmaPropagationLossModel";
1177 testVector.m_hBs = 25;
1178 testVector.m_hUt = 1.6;
1179 testVector.m_distance = 100;
1180 testVector.m_shadowingStdLos = 4;
1181 testVector.m_shadowingStdNlos = 8;
1182 m_testVectors.Add(testVector);
1183
1184 testVector.m_frequency = 6e9;
1185 testVector.m_propagationLossModelType = "ns3::ThreeGppRmaPropagationLossModel";
1186 testVector.m_hBs = 25;
1187 testVector.m_hUt = 1.6;
1188 testVector.m_distance = 4000; // beyond the breakpoint distance
1189 testVector.m_shadowingStdLos = 6;
1190 testVector.m_shadowingStdNlos = 8;
1191 m_testVectors.Add(testVector);
1192
1193 testVector.m_frequency = 6e9;
1194 testVector.m_propagationLossModelType = "ns3::ThreeGppUmaPropagationLossModel";
1195 testVector.m_hBs = 25;
1196 testVector.m_hUt = 1.6;
1197 testVector.m_distance = 100;
1198 testVector.m_shadowingStdLos = 4;
1199 testVector.m_shadowingStdNlos = 6;
1200 m_testVectors.Add(testVector);
1201
1202 testVector.m_frequency = 6e9;
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_frequency = 6e9;
1212 testVector.m_propagationLossModelType = "ns3::ThreeGppIndoorOfficePropagationLossModel";
1213 testVector.m_hBs = 3;
1214 testVector.m_hUt = 1;
1215 testVector.m_distance = 50;
1216 testVector.m_shadowingStdLos = 3;
1217 testVector.m_shadowingStdNlos = 8.03;
1218 m_testVectors.Add(testVector);
1219
1220 testVector.m_frequency = 6e9;
1221 testVector.m_propagationLossModelType = "ns3::ThreeGppV2vUrbanPropagationLossModel";
1222 testVector.m_hBs = 1.6;
1223 testVector.m_hUt = 1.6;
1224 testVector.m_distance = 50;
1225 testVector.m_shadowingStdLos = 3;
1226 testVector.m_shadowingStdNlos = 4;
1227 m_testVectors.Add(testVector);
1228
1229 testVector.m_frequency = 6e9;
1230 testVector.m_propagationLossModelType = "ns3::ThreeGppV2vHighwayPropagationLossModel";
1231 testVector.m_hBs = 1.6;
1232 testVector.m_hUt = 1.6;
1233 testVector.m_distance = 50;
1234 testVector.m_shadowingStdLos = 3;
1235 testVector.m_shadowingStdNlos = 4;
1236 m_testVectors.Add(testVector);
1237
1238 // Sub 6GHz
1239 testVector.m_frequency = 3.5e9;
1240 testVector.m_propagationLossModelType = "ns3::ThreeGppUmaPropagationLossModel";
1241 testVector.m_hBs = 25;
1242 testVector.m_hUt = 1.6;
1243 testVector.m_distance = 100;
1244 testVector.m_shadowingStdLos = 7;
1245 testVector.m_shadowingStdNlos = 7;
1246 m_testVectors.Add(testVector);
1247
1248 testVector.m_frequency = 3.5e9;
1249 testVector.m_propagationLossModelType = "ns3::ThreeGppUmiStreetCanyonPropagationLossModel";
1250 testVector.m_hBs = 10;
1251 testVector.m_hUt = 1.6;
1252 testVector.m_distance = 100;
1253 testVector.m_shadowingStdLos = 7;
1254 testVector.m_shadowingStdNlos = 7;
1255 m_testVectors.Add(testVector);
1256
1257 uint16_t numSamples = 400;
1258
1259 for (std::size_t tvIndex = 0; tvIndex < m_testVectors.GetN(); tvIndex++)
1260 {
1261 TestVector tv = m_testVectors.Get(tvIndex);
1262
1263 // run the experiments.
1264 for (uint16_t sampleIndex = 0; sampleIndex < numSamples; sampleIndex++)
1265 {
1266 RunTest(sampleIndex,
1268 tv.m_hBs,
1269 tv.m_hUt,
1270 tv.m_distance,
1271 true,
1272 tv.m_frequency);
1273 }
1274
1275 // analyze the results
1276 std::vector<double> mean_vector; // the vector containing the mean propagation loss for
1277 // each position (sample mean)
1278
1279 uint16_t numPositions = m_results.at(0).size();
1280 for (uint16_t k = 0; k < numPositions; k++)
1281 {
1282 // compute the mean propagation loss in position k
1283 double mean = 0.0;
1284 for (auto resIt : m_results)
1285 {
1286 mean += resIt.second.at(k);
1287 }
1288 mean /= m_results.size();
1289 mean_vector.push_back(mean);
1290 }
1291
1292 // compute the true mean - just the pathloss, without the shadowing component
1293 RunTest(numSamples,
1295 tv.m_hBs,
1296 tv.m_hUt,
1297 tv.m_distance,
1298 false,
1299 tv.m_frequency);
1300 std::vector<double> true_mean =
1301 m_results.at(numSamples); // the result of the last test is the true mean
1302
1303 // perform the null hypothesis test for the LOS case
1304 // positions from (0, 50) to (99, 50) are LOS
1305 for (std::size_t i = 0; i < mean_vector.size() / 2; i++)
1306 {
1307 double z = (mean_vector.at(i) - true_mean.at(i)) /
1308 (tv.m_shadowingStdLos / std::sqrt(mean_vector.size() / 2));
1310 z,
1311 0.0,
1312 1.96,
1313 "Null hypothesis test (LOS case) for the shadowing component rejected");
1314 }
1315
1316 // perform the null hypothesis test for the NLOS case
1317 // positions from (100, 50) to (199, 50) are NLOS
1318 for (std::size_t i = mean_vector.size() / 2; i < mean_vector.size(); i++)
1319 {
1320 double z = (mean_vector.at(i) - true_mean.at(i)) /
1321 (tv.m_shadowingStdNlos / std::sqrt(mean_vector.size() / 2));
1323 z,
1324 0.0,
1325 1.96,
1326 "Null hypothesis test (NLOS case) for the shadowing component rejected");
1327 }
1328 }
1329}
1330
1331/**
1332 * @ingroup propagation-tests
1333 *
1334 * @brief 3GPP Propagation models TestSuite
1335 *
1336 * This TestSuite tests the following models:
1337 * - ThreeGppRmaPropagationLossModel
1338 * - ThreeGppUmaPropagationLossModel
1339 * - ThreeGppUmiPropagationLossModel
1340 * - ThreeGppIndoorOfficePropagationLossModel
1341 * - ThreeGppV2vUrbanPropagationLossModel
1342 * - ThreeGppV2vHighwayPropagationLossModel
1343 * - ThreeGppShadowing
1344 */
1350
1362
1363/// Static variable for test initialization
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 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, double frequency)
Run the experiment.
void EvaluateLoss(Ptr< MobilityModel > a, Ptr< MobilityModel > b, uint16_t testNum)
Compute the propagation loss.
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:26
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
keep track of a set of node pointers.
Instantiate subclasses of ns3::Object.
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:67
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:561
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static void Run()
Run the simulation.
Definition simulator.cc:167
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:293
@ QUICK
Fast test.
Definition test.h:1054
TestCase(const TestCase &)=delete
Type
Type of test.
Definition test.h:1257
TestSuite(std::string name, Type type=Type::UNIT)
Construct a new test suite.
Definition test.cc:491
A simple way to store test vectors (for stimulus or from responses).
Definition test.h:1313
Base class for the 3GPP propagation models.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#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:499
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1369
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1381
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static PropagationLossModelsTestSuite g_propagationLossModelsTestSuite
Static variable for test initialization.
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