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.
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:70
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:580
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:125
static void Run()
Run the simulation.
Definition simulator.cc:161
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:296
@ QUICK
Fast test.
Definition test.h:1057
TestCase(const TestCase &)=delete
Caller graph was not generated because of its size.
Type
Type of test.
Definition test.h:1271
TestSuite(std::string name, Type type=Type::UNIT)
Construct a new test suite.
Definition test.cc:494
A simple way to store test vectors (for stimulus or from responses).
Definition test.h:1328
Base class for the 3GPP propagation models.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:627
#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:1273
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1290
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