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 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19#include "ns3/abort.h"
20#include "ns3/boolean.h"
21#include "ns3/channel-condition-model.h"
22#include "ns3/config.h"
23#include "ns3/constant-position-mobility-model.h"
24#include "ns3/constant-velocity-mobility-model.h"
25#include "ns3/double.h"
26#include "ns3/log.h"
27#include "ns3/mobility-helper.h"
28#include "ns3/simulator.h"
29#include "ns3/test.h"
30#include "ns3/three-gpp-propagation-loss-model.h"
31#include "ns3/three-gpp-v2v-propagation-loss-model.h"
32
33using namespace ns3;
34
35NS_LOG_COMPONENT_DEFINE("ThreeGppPropagationLossModelsTest");
36
37/**
38 * \ingroup propagation-tests
39 *
40 * Test case for the class ThreeGppRmaPropagationLossModel.
41 * It computes the pathloss between two nodes and compares it with the value
42 * obtained using the formula in 3GPP TR 38.901, Table 7.4.1-1.
43 */
45{
46 public:
47 /**
48 * Constructor
49 */
51
52 /**
53 * Destructor
54 */
56
57 private:
58 /**
59 * Build the simulation scenario and run the tests
60 */
61 void DoRun() override;
62
63 /**
64 * Struct containing the parameters for each test
65 */
67 {
68 double m_distance; //!< 2D distance between UT and BS in meters
69 bool m_isLos; //!< if true LOS, if false NLOS
70 double m_frequency; //!< carrier frequency in Hz
71 double m_pt; //!< transmitted power in dBm
72 double m_pr; //!< received power in dBm
73 };
74
75 TestVectors<TestVector> m_testVectors; //!< array containing all the test vectors
76 double m_tolerance; //!< tolerance
77};
78
80 : TestCase("Test for the ThreeGppRmaPropagationLossModel class"),
81 m_testVectors(),
82 m_tolerance(5e-2)
83{
84}
85
87{
88}
89
90void
92{
93 TestVector testVector;
94
95 testVector.m_distance = 10.0;
96 testVector.m_isLos = true;
97 testVector.m_frequency = 5.0e9;
98 testVector.m_pt = 0.0;
99 testVector.m_pr = -77.3784;
100 m_testVectors.Add(testVector);
101
102 testVector.m_distance = 100.0;
103 testVector.m_isLos = true;
104 testVector.m_frequency = 5.0e9;
105 testVector.m_pt = 0.0;
106 testVector.m_pr = -87.2965;
107 m_testVectors.Add(testVector);
108
109 testVector.m_distance = 1000.0;
110 testVector.m_isLos = true;
111 testVector.m_frequency = 5.0e9;
112 testVector.m_pt = 0.0;
113 testVector.m_pr = -108.5577;
114 m_testVectors.Add(testVector);
115
116 testVector.m_distance = 10000.0;
117 testVector.m_isLos = true;
118 testVector.m_frequency = 5.0e9;
119 testVector.m_pt = 0.0;
120 testVector.m_pr = -140.3896;
121 m_testVectors.Add(testVector);
122
123 testVector.m_distance = 10.0;
124 testVector.m_isLos = false;
125 testVector.m_frequency = 5.0e9;
126 testVector.m_pt = 0.0;
127 testVector.m_pr = -77.3784;
128 m_testVectors.Add(testVector);
129
130 testVector.m_distance = 100.0;
131 testVector.m_isLos = false;
132 testVector.m_frequency = 5.0e9;
133 testVector.m_pt = 0.0;
134 testVector.m_pr = -95.7718;
135 m_testVectors.Add(testVector);
136
137 testVector.m_distance = 1000.0;
138 testVector.m_isLos = false;
139 testVector.m_frequency = 5.0e9;
140 testVector.m_pt = 0.0;
141 testVector.m_pr = -133.5223;
142 m_testVectors.Add(testVector);
143
144 testVector.m_distance = 5000.0;
145 testVector.m_isLos = false;
146 testVector.m_frequency = 5.0e9;
147 testVector.m_pt = 0.0;
148 testVector.m_pr = -160.5169;
149 m_testVectors.Add(testVector);
150
151 // Create the nodes for BS and UT
153 nodes.Create(2);
154
155 // Create the mobility models
156 Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
158 Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
160
161 // Use a deterministic channel condition model
162 Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel>();
163 Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel>();
164
165 // Create the propagation loss model
167 CreateObject<ThreeGppRmaPropagationLossModel>();
168 lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
169
170 for (const auto& testVector : m_testVectors)
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),
190 testVector.m_pr,
192 "Got unexpected rcv power");
193 }
194
196}
197
198/**
199 * \ingroup propagation-tests
200 *
201 * Test case for the class ThreeGppUmaPropagationLossModel.
202 * It computes the pathloss between two nodes and compares it with the value
203 * obtained using the formula in 3GPP TR 38.901, Table 7.4.1-1.
204 */
206{
207 public:
208 /**
209 * Constructor
210 */
212
213 /**
214 * Destructor
215 */
217
218 private:
219 /**
220 * Build the simulation scenario and run the tests
221 */
222 void DoRun() override;
223
224 /**
225 * Struct containing the parameters for each test
226 */
228 {
229 double m_distance; //!< 2D distance between UT and BS in meters
230 bool m_isLos; //!< if true LOS, if false NLOS
231 double m_frequency; //!< carrier frequency in Hz
232 double m_pt; //!< transmitted power in dBm
233 double m_pr; //!< received power in dBm
234 };
235
236 TestVectors<TestVector> m_testVectors; //!< array containing all the test vectors
237 double m_tolerance; //!< tolerance
238};
239
241 : TestCase("Test for the ThreeGppUmaPropagationLossModel class"),
242 m_testVectors(),
243 m_tolerance(5e-2)
244{
245}
246
248{
249}
250
251void
253{
254 TestVector testVector;
255
256 testVector.m_distance = 10.0;
257 testVector.m_isLos = true;
258 testVector.m_frequency = 5.0e9;
259 testVector.m_pt = 0.0;
260 testVector.m_pr = -72.9380;
261 m_testVectors.Add(testVector);
262
263 testVector.m_distance = 100.0;
264 testVector.m_isLos = true;
265 testVector.m_frequency = 5.0e9;
266 testVector.m_pt = 0.0;
267 testVector.m_pr = -86.2362;
268 m_testVectors.Add(testVector);
269
270 testVector.m_distance = 1000.0;
271 testVector.m_isLos = true;
272 testVector.m_frequency = 5.0e9;
273 testVector.m_pt = 0.0;
274 testVector.m_pr = -109.7252;
275 m_testVectors.Add(testVector);
276
277 testVector.m_distance = 5000.0;
278 testVector.m_isLos = true;
279 testVector.m_frequency = 5.0e9;
280 testVector.m_pt = 0.0;
281 testVector.m_pr = -137.6794;
282 m_testVectors.Add(testVector);
283
284 testVector.m_distance = 10.0;
285 testVector.m_isLos = false;
286 testVector.m_frequency = 5.0e9;
287 testVector.m_pt = 0.0;
288 testVector.m_pr = -82.5131;
289 m_testVectors.Add(testVector);
290
291 testVector.m_distance = 100.0;
292 testVector.m_isLos = false;
293 testVector.m_frequency = 5.0e9;
294 testVector.m_pt = 0.0;
295 testVector.m_pr = -106.1356;
296 m_testVectors.Add(testVector);
297
298 testVector.m_distance = 1000.0;
299 testVector.m_isLos = false;
300 testVector.m_frequency = 5.0e9;
301 testVector.m_pt = 0.0;
302 testVector.m_pr = -144.7641;
303 m_testVectors.Add(testVector);
304
305 testVector.m_distance = 5000.0;
306 testVector.m_isLos = false;
307 testVector.m_frequency = 5.0e9;
308 testVector.m_pt = 0.0;
309 testVector.m_pr = -172.0753;
310 m_testVectors.Add(testVector);
311
312 // Create the nodes for BS and UT
314 nodes.Create(2);
315
316 // Create the mobility models
317 Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
319 Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
321
322 // Use a deterministic channel condition model
323 Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel>();
324 Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel>();
325
326 // Create the propagation loss model
328 CreateObject<ThreeGppUmaPropagationLossModel>();
329 lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
330
331 for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
332 {
333 TestVector testVector = m_testVectors.Get(i);
334
335 Vector posBs = Vector(0.0, 0.0, 25.0);
336 Vector posUt = Vector(testVector.m_distance, 0.0, 1.5);
337
338 // set the LOS or NLOS condition
339 if (testVector.m_isLos)
340 {
341 lossModel->SetChannelConditionModel(losCondModel);
342 }
343 else
344 {
345 lossModel->SetChannelConditionModel(nlosCondModel);
346 }
347
348 a->SetPosition(posBs);
349 b->SetPosition(posUt);
350
351 lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
352 NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
353 testVector.m_pr,
355 "Got unexpected rcv power");
356 }
357
359}
360
361/**
362 * \ingroup propagation-tests
363 *
364 * Test case for the class ThreeGppUmiStreetCanyonPropagationLossModel.
365 * It computes the pathloss between two nodes and compares it with the value
366 * obtained using the formula in 3GPP TR 38.901, Table 7.4.1-1.
367 */
369{
370 public:
371 /**
372 * Constructor
373 */
375
376 /**
377 * Destructor
378 */
380
381 private:
382 /**
383 * Build the simulation scenario and run the tests
384 */
385 void DoRun() override;
386
387 /**
388 * Struct containing the parameters for each test
389 */
391 {
392 double m_distance; //!< 2D distance between UT and BS in meters
393 bool m_isLos; //!< if true LOS, if false NLOS
394 double m_frequency; //!< carrier frequency in Hz
395 double m_pt; //!< transmitted power in dBm
396 double m_pr; //!< received power in dBm
397 };
398
399 TestVectors<TestVector> m_testVectors; //!< array containing all the test vectors
400 double m_tolerance; //!< tolerance
401};
402
404 : TestCase("Test for the ThreeGppUmiPropagationLossModel class"),
405 m_testVectors(),
406 m_tolerance(5e-2)
407{
408}
409
411{
412}
413
414void
416{
417 TestVector testVector;
418
419 testVector.m_distance = 10.0;
420 testVector.m_isLos = true;
421 testVector.m_frequency = 5.0e9;
422 testVector.m_pt = 0.0;
423 testVector.m_pr = -69.8591;
424 m_testVectors.Add(testVector);
425
426 testVector.m_distance = 100.0;
427 testVector.m_isLos = true;
428 testVector.m_frequency = 5.0e9;
429 testVector.m_pt = 0.0;
430 testVector.m_pr = -88.4122;
431 m_testVectors.Add(testVector);
432
433 testVector.m_distance = 1000.0;
434 testVector.m_isLos = true;
435 testVector.m_frequency = 5.0e9;
436 testVector.m_pt = 0.0;
437 testVector.m_pr = -119.3114;
438
439 testVector.m_distance = 5000.0;
440 testVector.m_isLos = true;
441 testVector.m_frequency = 5.0e9;
442 testVector.m_pt = 0.0;
443 testVector.m_pr = -147.2696;
444
445 testVector.m_distance = 10.0;
446 testVector.m_isLos = false;
447 testVector.m_frequency = 5.0e9;
448 testVector.m_pt = 0.0;
449 testVector.m_pr = -76.7563;
450
451 testVector.m_distance = 100.0;
452 testVector.m_isLos = false;
453 testVector.m_frequency = 5.0e9;
454 testVector.m_pt = 0.0;
455 testVector.m_pr = -107.9432;
456
457 testVector.m_distance = 1000.0;
458 testVector.m_isLos = false;
459 testVector.m_frequency = 5.0e9;
460 testVector.m_pt = 0.0;
461 testVector.m_pr = -143.1886;
462
463 testVector.m_distance = 5000.0;
464 testVector.m_isLos = false;
465 testVector.m_frequency = 5.0e9;
466 testVector.m_pt = 0.0;
467 testVector.m_pr = -167.8617;
468
469 // Create the nodes for BS and UT
471 nodes.Create(2);
472
473 // Create the mobility models
474 Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
476 Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
478
479 // Use a deterministic channel condition model
480 Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel>();
481 Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel>();
482
483 // Create the propagation loss model
485 CreateObject<ThreeGppUmiStreetCanyonPropagationLossModel>();
486 lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
487
488 for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
489 {
490 TestVector testVector = m_testVectors.Get(i);
491
492 Vector posBs = Vector(0.0, 0.0, 10.0);
493 Vector posUt = Vector(testVector.m_distance, 0.0, 1.5);
494
495 // set the LOS or NLOS condition
496 if (testVector.m_isLos)
497 {
498 lossModel->SetChannelConditionModel(losCondModel);
499 }
500 else
501 {
502 lossModel->SetChannelConditionModel(nlosCondModel);
503 }
504
505 a->SetPosition(posBs);
506 b->SetPosition(posUt);
507
508 lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
509 NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
510 testVector.m_pr,
512 "Got unexpected rcv power");
513 }
514
516}
517
518/**
519 * \ingroup propagation-tests
520 *
521 * Test case for the class ThreeGppIndoorOfficePropagationLossModel.
522 * It computes the pathloss between two nodes and compares it with the value
523 * obtained using the formula in 3GPP TR 38.901, Table 7.4.1-1.
524 */
526{
527 public:
528 /**
529 * Constructor
530 */
532
533 /**
534 * Destructor
535 */
537
538 private:
539 /**
540 * Build the simulation scenario and run the tests
541 */
542 void DoRun() override;
543
544 /**
545 * Struct containing the parameters for each test
546 */
548 {
549 double m_distance; //!< 2D distance between UT and BS in meters
550 bool m_isLos; //!< if true LOS, if false NLOS
551 double m_frequency; //!< carrier frequency in Hz
552 double m_pt; //!< transmitted power in dBm
553 double m_pr; //!< received power in dBm
554 };
555
556 TestVectors<TestVector> m_testVectors; //!< array containing all the test vectors
557 double m_tolerance; //!< tolerance
558};
559
561 : TestCase("Test for the ThreeGppIndoorOfficePropagationLossModel class"),
562 m_testVectors(),
563 m_tolerance(5e-2)
564{
565}
566
569{
570}
571
572void
574{
575 TestVector testVector;
576
577 testVector.m_distance = 1.0;
578 testVector.m_isLos = true;
579 testVector.m_frequency = 5.0e9;
580 testVector.m_pt = 0.0;
581 testVector.m_pr = -50.8072;
582 m_testVectors.Add(testVector);
583
584 testVector.m_distance = 10.0;
585 testVector.m_isLos = true;
586 testVector.m_frequency = 5.0e9;
587 testVector.m_pt = 0.0;
588 testVector.m_pr = -63.7630;
589 m_testVectors.Add(testVector);
590
591 testVector.m_distance = 50.0;
592 testVector.m_isLos = true;
593 testVector.m_frequency = 5.0e9;
594 testVector.m_pt = 0.0;
595 testVector.m_pr = -75.7750;
596 m_testVectors.Add(testVector);
597
598 testVector.m_distance = 100.0;
599 testVector.m_isLos = true;
600 testVector.m_frequency = 5.0e9;
601 testVector.m_pt = 0.0;
602 testVector.m_pr = -80.9802;
603 m_testVectors.Add(testVector);
604
605 testVector.m_distance = 1.0;
606 testVector.m_isLos = false;
607 testVector.m_frequency = 5.0e9;
608 testVector.m_pt = 0.0;
609 testVector.m_pr = -50.8072;
610 m_testVectors.Add(testVector);
611
612 testVector.m_distance = 10.0;
613 testVector.m_isLos = false;
614 testVector.m_frequency = 5.0e9;
615 testVector.m_pt = 0.0;
616 testVector.m_pr = -73.1894;
617 m_testVectors.Add(testVector);
618
619 testVector.m_distance = 50.0;
620 testVector.m_isLos = false;
621 testVector.m_frequency = 5.0e9;
622 testVector.m_pt = 0.0;
623 testVector.m_pr = -99.7824;
624 m_testVectors.Add(testVector);
625
626 testVector.m_distance = 100.0;
627 testVector.m_isLos = false;
628 testVector.m_frequency = 5.0e9;
629 testVector.m_pt = 0.0;
630 testVector.m_pr = -111.3062;
631 m_testVectors.Add(testVector);
632
633 // Create the nodes for BS and UT
635 nodes.Create(2);
636
637 // Create the mobility models
638 Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
640 Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
642
643 // Use a deterministic channel condition model
644 Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel>();
645 Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel>();
646
647 // Create the propagation loss model
649 CreateObject<ThreeGppIndoorOfficePropagationLossModel>();
650 lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
651
652 for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
653 {
654 TestVector testVector = m_testVectors.Get(i);
655
656 Vector posBs = Vector(0.0, 0.0, 3.0);
657 Vector posUt = Vector(testVector.m_distance, 0.0, 1.5);
658
659 // set the LOS or NLOS condition
660 if (testVector.m_isLos)
661 {
662 lossModel->SetChannelConditionModel(losCondModel);
663 }
664 else
665 {
666 lossModel->SetChannelConditionModel(nlosCondModel);
667 }
668
669 a->SetPosition(posBs);
670 b->SetPosition(posUt);
671
672 lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
673 NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
674 testVector.m_pr,
676 "Got unexpected rcv power");
677 }
678
680}
681
682/**
683 * \ingroup propagation-tests
684 *
685 * Test case for the class ThreeGppV2vUrbanPropagationLossModel.
686 * It computes the pathloss between two nodes and compares it with the value
687 * obtained using the formula in 3GPP TR 37.885 Table 6.2.1-1 for v2v
688 * communications (sidelink).
689 *
690 * Note that 3GPP TR 37.885 defines 3 different channel states for vehicular
691 * environments: LOS, NLOS, and NLOSv, the latter representing the case in which
692 * the LOS path is blocked by other vehicles in the scenario. However, for
693 * computing the pathloss, only the two states are considered: LOS/NLOSv or NLOS
694 * (see TR 37.885 Section 6.2.1). In case of NLOSv, an additional vehicle
695 * blockage loss may be added, according to a log-normal random variable.
696 * Here, we test both conditions: LOS/NLOSv (without vehicle blockage
697 * loss) and NLOS.
698 */
700{
701 public:
702 /**
703 * Constructor
704 */
706
707 /**
708 * Destructor
709 */
711
712 private:
713 /**
714 * Build the simulation scenario and run the tests
715 */
716 void DoRun() override;
717
718 /**
719 * Struct containing the parameters for each test
720 */
722 {
723 double m_distance; //!< 2D distance between UT and BS in meters
724 bool m_isLos; //!< if true LOS/NLOSv, if false NLOS
725 double m_frequency; //!< carrier frequency in Hz
726 double m_pt; //!< transmitted power in dBm
727 double m_pr; //!< received power in dBm
728 };
729
730 TestVectors<TestVector> m_testVectors; //!< array containing all the test vectors
731 double m_tolerance; //!< tolerance
732};
733
735 : TestCase("Test for the ThreeGppV2vUrbanPropagationLossModel class."),
736 m_testVectors(),
737 m_tolerance(5e-2)
738{
739}
740
742{
743}
744
745void
747{
748 TestVector testVector;
749
750 testVector.m_distance = 10.0;
751 testVector.m_isLos = true;
752 testVector.m_frequency = 5.0e9;
753 testVector.m_pt = 0.0;
754 testVector.m_pr = -68.1913;
755 m_testVectors.Add(testVector);
756
757 testVector.m_distance = 100.0;
758 testVector.m_isLos = true;
759 testVector.m_frequency = 5.0e9;
760 testVector.m_pt = 0.0;
761 testVector.m_pr = -84.8913;
762 m_testVectors.Add(testVector);
763
764 testVector.m_distance = 1000.0;
765 testVector.m_isLos = true;
766 testVector.m_frequency = 5.0e9;
767 testVector.m_pt = 0.0;
768 testVector.m_pr = -101.5913;
769 m_testVectors.Add(testVector);
770
771 testVector.m_distance = 10.0;
772 testVector.m_isLos = false;
773 testVector.m_frequency = 5.0e9;
774 testVector.m_pt = 0.0;
775 testVector.m_pr = -80.0605;
776 m_testVectors.Add(testVector);
777
778 testVector.m_distance = 100.0;
779 testVector.m_isLos = false;
780 testVector.m_frequency = 5.0e9;
781 testVector.m_pt = 0.0;
782 testVector.m_pr = -110.0605;
783 m_testVectors.Add(testVector);
784
785 testVector.m_distance = 1000.0;
786 testVector.m_isLos = false;
787 testVector.m_frequency = 5.0e9;
788 testVector.m_pt = 0.0;
789 testVector.m_pr = -140.0605;
790 m_testVectors.Add(testVector);
791
792 // Create the nodes for BS and UT
794 nodes.Create(2);
795
796 // Create the mobility models
797 Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
799 Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
801
802 // Use a deterministic channel condition model
803 Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel>();
804 Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel>();
805
806 // Create the propagation loss model
808 CreateObject<ThreeGppV2vUrbanPropagationLossModel>();
809 lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
810
811 for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
812 {
813 TestVector testVector = m_testVectors.Get(i);
814
815 Vector posUe1 = Vector(0.0, 0.0, 1.6);
816 Vector posUe2 = Vector(testVector.m_distance, 0.0, 1.6);
817
818 // set the LOS or NLOS condition
819 if (testVector.m_isLos)
820 {
821 lossModel->SetChannelConditionModel(losCondModel);
822 }
823 else
824 {
825 lossModel->SetChannelConditionModel(nlosCondModel);
826 }
827
828 a->SetPosition(posUe1);
829 b->SetPosition(posUe2);
830
831 lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
832 NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
833 testVector.m_pr,
835 "Got unexpected rcv power");
836 }
837
839}
840
841/**
842 * \ingroup propagation-tests
843 *
844 * Test case for the class ThreeGppV2vHighwayPropagationLossModel.
845 * It computes the pathloss between two nodes and compares it with the value
846 * obtained using the formula in 3GPP TR 37.885 Table 6.2.1-1 for v2v
847 * communications (sidelink).
848 *
849 * Note that 3GPP TR 37.885 defines 3 different channel states for vehicular
850 * environments: LOS, NLOS and NLOSv, the latter representing the case in which
851 * the LOS path is blocked by other vehicles in the scenario. However, for
852 * computing the pathloss, only two states are considered: LOS/NLOSv or NLOS
853 * (see TR 37.885 Section 6.2.1). In case of NLOSv, an additional vehicle
854 * blockage loss may be added, according to a log-normal random variable.
855 * Here, we test both conditions: LOS/NLOSv (without vehicle blockage
856 * loss) and NLOS.
857 */
859{
860 public:
861 /**
862 * Constructor
863 */
865
866 /**
867 * Destructor
868 */
870
871 private:
872 /**
873 * Build the simulation scenario and run the tests
874 */
875 void DoRun() override;
876
877 /**
878 * Struct containing the parameters for each test
879 */
881 {
882 double m_distance; //!< 2D distance between UT and BS in meters
883 bool m_isLos; //!< if true LOS/NLOSv, if false NLOS
884 double m_frequency; //!< carrier frequency in Hz
885 double m_pt; //!< transmitted power in dBm
886 double m_pr; //!< received power in dBm
887 };
888
889 TestVectors<TestVector> m_testVectors; //!< array containing all the test vectors
890 double m_tolerance; //!< tolerance
891};
892
894 : TestCase("Test for the ThreeGppV2vHighwayPropagationLossModel"),
895 m_testVectors(),
896 m_tolerance(5e-2)
897{
898}
899
901{
902}
903
904void
906{
907 TestVector testVector;
908
909 testVector.m_distance = 10.0;
910 testVector.m_isLos = true;
911 testVector.m_frequency = 5.0e9;
912 testVector.m_pt = 0.0;
913 testVector.m_pr = -66.3794;
914 m_testVectors.Add(testVector);
915
916 testVector.m_distance = 100.0;
917 testVector.m_isLos = true;
918 testVector.m_frequency = 5.0e9;
919 testVector.m_pt = 0.0;
920 testVector.m_pr = -86.3794;
921 m_testVectors.Add(testVector);
922
923 testVector.m_distance = 1000.0;
924 testVector.m_isLos = true;
925 testVector.m_frequency = 5.0e9;
926 testVector.m_pt = 0.0;
927 testVector.m_pr = -106.3794;
928 m_testVectors.Add(testVector);
929
930 testVector.m_distance = 10.0;
931 testVector.m_isLos = false;
932 testVector.m_frequency = 5.0e9;
933 testVector.m_pt = 0.0;
934 testVector.m_pr = -80.0605;
935 m_testVectors.Add(testVector);
936
937 testVector.m_distance = 100.0;
938 testVector.m_isLos = false;
939 testVector.m_frequency = 5.0e9;
940 testVector.m_pt = 0.0;
941 testVector.m_pr = -110.0605;
942 m_testVectors.Add(testVector);
943
944 testVector.m_distance = 1000.0;
945 testVector.m_isLos = false;
946 testVector.m_frequency = 5.0e9;
947 testVector.m_pt = 0.0;
948 testVector.m_pr = -140.0605;
949 m_testVectors.Add(testVector);
950
951 // Create the nodes for BS and UT
953 nodes.Create(2);
954
955 // Create the mobility models
956 Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
958 Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
960
961 // Use a deterministic channel condition model
962 Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel>();
963 Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel>();
964
965 // Create the propagation loss model
967 CreateObject<ThreeGppV2vHighwayPropagationLossModel>();
968 lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
969
970 for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
971 {
972 TestVector testVector = m_testVectors.Get(i);
973
974 Vector posUe1 = Vector(0.0, 0.0, 1.6);
975 Vector posUe2 = Vector(testVector.m_distance, 0.0, 1.6);
976
977 // set the LOS or NLOS condition
978 if (testVector.m_isLos)
979 {
980 lossModel->SetChannelConditionModel(losCondModel);
981 }
982 else
983 {
984 lossModel->SetChannelConditionModel(nlosCondModel);
985 }
986
987 a->SetPosition(posUe1);
988 b->SetPosition(posUe2);
989
990 lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
991 NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
992 testVector.m_pr,
994 "Got unexpected rcv power");
995 }
996
998}
999
1000/**
1001 * \ingroup propagation-tests
1002 *
1003 * Test to check if the shadowing fading is correctly computed
1004 */
1006{
1007 public:
1009 ~ThreeGppShadowingTestCase() override;
1010
1011 private:
1012 void DoRun() override;
1013
1014 /**
1015 * Run the experiment
1016 * \param testNum the index of the experiment
1017 * \param propagationLossModelType the type id of the propagation loss model
1018 * to be used
1019 * \param hBs the BS height in meters
1020 * \param hUt the UT height in meters
1021 * \param distance the initial distance between the BS and the UT
1022 * \param shadowingEnabled true if shadowging must be enabled
1023 */
1024 void RunTest(uint16_t testNum,
1025 std::string propagationLossModelType,
1026 double hBs,
1027 double hUt,
1028 double distance,
1029 bool shadowingEnabled);
1030
1031 /**
1032 * Compute the propagation loss
1033 * \param a the first mobility model
1034 * \param b the second mobility model
1035 * \param testNum the index of the experiment
1036 */
1037 void EvaluateLoss(Ptr<MobilityModel> a, Ptr<MobilityModel> b, uint8_t testNum);
1038
1039 /**
1040 * Change the channel condition model
1041 * \param ccm the new ChannelConditionModel
1042 */
1044
1045 /**
1046 * Struct containing the parameters for each test
1047 */
1049 {
1050 std::string m_propagationLossModelType; //!< the propagation loss model type id
1051 double m_hBs; //!< the BS height in meters
1052 double m_hUt; //!< the UT height in meters
1053 double m_distance; //!< the initial 2D distance in meters between BS and UT in meters
1054 double m_shadowingStdLos; //!< the standard deviation of the shadowing component in the LOS
1055 //!< case in dB
1056 double m_shadowingStdNlos; //!< the standard deviation of the shadowing component in the
1057 //!< NLOS case in dB
1058 };
1059
1060 TestVectors<TestVector> m_testVectors; //!< array containing all the test vectors
1061 Ptr<ThreeGppPropagationLossModel> m_lossModel; //!< the propagation loss model
1062 std::map<uint16_t /* index of experiment */, std::vector<double> /* loss in dB for each run */>
1063 m_results; //!< used to store the test results
1064};
1065
1067 : TestCase("Test to check if the shadow fading is correctly computed")
1068{
1069}
1070
1072{
1073}
1074
1075void
1077{
1078 double loss = m_lossModel->CalcRxPower(0, a, b);
1079 m_results.at(testNum).push_back(loss);
1080}
1081
1082void
1084{
1086}
1087
1088void
1090 std::string propagationLossModelType,
1091 double hBs,
1092 double hUt,
1093 double distance,
1094 bool shadowingEnabled)
1095{
1096 // Add a new entry for this test in the results map
1097 m_results[testNum] = std::vector<double>();
1098
1099 // Create the nodes for BS and UT
1101 nodes.Create(2);
1102
1103 // Create the mobility models
1104 Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
1105 a->SetPosition(Vector(0.0, 0.0, hBs));
1106 nodes.Get(0)->AggregateObject(a);
1107
1108 Ptr<ConstantVelocityMobilityModel> b = CreateObject<ConstantVelocityMobilityModel>();
1109 nodes.Get(1)->AggregateObject(b);
1110 b->SetPosition(Vector(0.0, distance, hUt));
1111 b->SetVelocity(Vector(1.0, 0.0, 0.0));
1112
1113 // Create the propagation loss model
1114 ObjectFactory propagationLossModelFactory = ObjectFactory(propagationLossModelType);
1115 m_lossModel = propagationLossModelFactory.Create<ThreeGppPropagationLossModel>();
1116 m_lossModel->SetAttribute("Frequency", DoubleValue(3.5e9));
1117 m_lossModel->SetAttribute("ShadowingEnabled",
1118 BooleanValue(shadowingEnabled)); // enable the shadow fading
1119
1120 // Set the channel condition to LOS
1121 Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel>();
1123 // Schedule a transition to NLOS
1124 Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel>();
1127 this,
1128 nlosCondModel);
1129
1130 // Schedule multiple calls to EvaluateLoss. Use both EvaluateLoss (a,b) and
1131 // EvaluateLoss (b,a) to check if the reciprocity holds.
1132 for (int i = 0; i < 200; i++)
1133 {
1134 if (i % 2 == 0)
1135 {
1138 this,
1139 a,
1140 b,
1141 testNum);
1142 }
1143 else
1144 {
1147 this,
1148 b,
1149 a,
1150 testNum);
1151 }
1152 }
1153
1156}
1157
1158void
1160{
1161 // The test scenario is composed of two nodes, one fixed
1162 // at position (0,0) and the other moving with constant velocity from
1163 // position (0,50) to position (200,50).
1164 // The channel condition changes from LOS to NLOS when the second node
1165 // reaches position (100,50).
1166 // Each experiment computes the propagation loss between the two nodes
1167 // every second, until the final position is reached, and saves the
1168 // results in an entry of the map m_results.
1169 // We run numSamples experiments and estimate the mean propagation loss in
1170 // each position by averaging among the samples.
1171 // Then, we perform the null hypothesis test with a significance level of
1172 // 0.05.
1173 // This procedure is repeated for all the 3GPP propagation scenarios, i.e.,
1174 // RMa, UMa, UMi and Indoor-Office.
1175
1176 TestVector testVector;
1177 testVector.m_propagationLossModelType = "ns3::ThreeGppRmaPropagationLossModel";
1178 testVector.m_hBs = 25;
1179 testVector.m_hUt = 1.6;
1180 testVector.m_distance = 100;
1181 testVector.m_shadowingStdLos = 4;
1182 testVector.m_shadowingStdNlos = 8;
1183 m_testVectors.Add(testVector);
1184
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_propagationLossModelType = "ns3::ThreeGppUmaPropagationLossModel";
1194 testVector.m_hBs = 25;
1195 testVector.m_hUt = 1.6;
1196 testVector.m_distance = 100;
1197 testVector.m_shadowingStdLos = 4;
1198 testVector.m_shadowingStdNlos = 6;
1199 m_testVectors.Add(testVector);
1200
1201 testVector.m_propagationLossModelType = "ns3::ThreeGppUmiStreetCanyonPropagationLossModel";
1202 testVector.m_hBs = 10;
1203 testVector.m_hUt = 1.6;
1204 testVector.m_distance = 100;
1205 testVector.m_shadowingStdLos = 4;
1206 testVector.m_shadowingStdNlos = 7.82;
1207 m_testVectors.Add(testVector);
1208
1209 testVector.m_propagationLossModelType = "ns3::ThreeGppIndoorOfficePropagationLossModel";
1210 testVector.m_hBs = 3;
1211 testVector.m_hUt = 1;
1212 testVector.m_distance = 50;
1213 testVector.m_shadowingStdLos = 3;
1214 testVector.m_shadowingStdNlos = 8.03;
1215 m_testVectors.Add(testVector);
1216
1217 testVector.m_propagationLossModelType = "ns3::ThreeGppV2vUrbanPropagationLossModel";
1218 testVector.m_hBs = 1.6;
1219 testVector.m_hUt = 1.6;
1220 testVector.m_distance = 50;
1221 testVector.m_shadowingStdLos = 3;
1222 testVector.m_shadowingStdNlos = 4;
1223 m_testVectors.Add(testVector);
1224
1225 testVector.m_propagationLossModelType = "ns3::ThreeGppV2vHighwayPropagationLossModel";
1226 testVector.m_hBs = 1.6;
1227 testVector.m_hUt = 1.6;
1228 testVector.m_distance = 50;
1229 testVector.m_shadowingStdLos = 3;
1230 testVector.m_shadowingStdNlos = 4;
1231 m_testVectors.Add(testVector);
1232
1233 uint16_t numSamples = 250;
1234
1235 for (std::size_t tvIndex = 0; tvIndex < m_testVectors.GetN(); tvIndex++)
1236 {
1237 TestVector tv = m_testVectors.Get(tvIndex);
1238
1239 // run the experiments.
1240 for (uint16_t sampleIndex = 0; sampleIndex < numSamples; sampleIndex++)
1241 {
1242 RunTest(sampleIndex,
1244 tv.m_hBs,
1245 tv.m_hUt,
1246 tv.m_distance,
1247 true);
1248 }
1249
1250 // analyze the results
1251 std::vector<double> mean_vector; // the vector containing the mean propagation loss for each
1252 // position (sample mean)
1253
1254 uint16_t numPositions = m_results.at(0).size();
1255 for (uint16_t k = 0; k < numPositions; k++)
1256 {
1257 // compute the mean propagation loss in position k
1258 double mean = 0.0;
1259 for (auto resIt : m_results)
1260 {
1261 mean += resIt.second.at(k);
1262 }
1263 mean /= m_results.size();
1264 mean_vector.push_back(mean);
1265 }
1266
1267 // compute the true mean - just the pathloss, without the shadowing component
1268 RunTest(numSamples,
1270 tv.m_hBs,
1271 tv.m_hUt,
1272 tv.m_distance,
1273 false);
1274 std::vector<double> true_mean =
1275 m_results.at(numSamples); // the result of the last test is the true mean
1276
1277 // perform the null hypothesis test for the LOS case
1278 // positions from (0, 50) to (99, 50) are LOS
1279 for (std::size_t i = 0; i < mean_vector.size() / 2; i++)
1280 {
1281 double z = (mean_vector.at(i) - true_mean.at(i)) /
1282 (tv.m_shadowingStdLos / std::sqrt(mean_vector.size() / 2));
1284 z,
1285 0.0,
1286 1.96,
1287 "Null hypothesis test (LOS case) for the shadowing component rejected");
1288 }
1289
1290 // perform the null hypothesis test for the NLOS case
1291 // positions from (100, 50) to (199, 50) are NLOS
1292 for (std::size_t i = mean_vector.size() / 2; i < mean_vector.size(); i++)
1293 {
1294 double z = (mean_vector.at(i) - true_mean.at(i)) /
1295 (tv.m_shadowingStdNlos / std::sqrt(mean_vector.size() / 2));
1297 z,
1298 0.0,
1299 1.96,
1300 "Null hypothesis test (NLOS case) for the shadowing component rejected");
1301 }
1302 }
1303}
1304
1305/**
1306 * \ingroup propagation-tests
1307 *
1308 * \brief 3GPP Propagation models TestSuite
1309 *
1310 * This TestSuite tests the following models:
1311 * - ThreeGppRmaPropagationLossModel
1312 * - ThreeGppUmaPropagationLossModel
1313 * - ThreeGppUmiPropagationLossModel
1314 * - ThreeGppIndoorOfficePropagationLossModel
1315 * - ThreeGppV2vUrbanPropagationLossModel
1316 * - ThreeGppV2vHighwayPropagationLossModel
1317 * - ThreeGppShadowing
1318 */
1320{
1321 public:
1323};
1324
1326 : TestSuite("three-gpp-propagation-loss-model", Type::UNIT)
1327{
1328 AddTestCase(new ThreeGppRmaPropagationLossModelTestCase, TestCase::Duration::QUICK);
1329 AddTestCase(new ThreeGppUmaPropagationLossModelTestCase, TestCase::Duration::QUICK);
1330 AddTestCase(new ThreeGppUmiPropagationLossModelTestCase, TestCase::Duration::QUICK);
1331 AddTestCase(new ThreeGppIndoorOfficePropagationLossModelTestCase, TestCase::Duration::QUICK);
1332 AddTestCase(new ThreeGppV2vUrbanPropagationLossModelTestCase, TestCase::Duration::QUICK);
1333 AddTestCase(new ThreeGppV2vHighwayPropagationLossModelTestCase, TestCase::Duration::QUICK);
1334 AddTestCase(new ThreeGppShadowingTestCase, TestCase::Duration::QUICK);
1335}
1336
1337/// 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 EvaluateLoss(Ptr< MobilityModel > a, Ptr< MobilityModel > b, uint8_t testNum)
Compute the propagation loss.
void DoRun() override
Implementation to actually run this TestCase.
std::map< uint16_t, std::vector< double > > m_results
used to store the test results
void ChangeChannelCondition(Ptr< ChannelConditionModel > ccm)
Change the channel condition model.
Ptr< ThreeGppPropagationLossModel > m_lossModel
the propagation loss model
TestVectors< TestVector > m_testVectors
array containing all the test vectors
void RunTest(uint16_t testNum, std::string propagationLossModelType, double hBs, double hUt, double distance, bool shadowingEnabled)
Run the experiment.
Test case for the class ThreeGppUmaPropagationLossModel.
TestVectors< TestVector > m_testVectors
array containing all the test vectors
void DoRun() override
Build the simulation scenario and run the tests.
Test case for the class ThreeGppUmiStreetCanyonPropagationLossModel.
TestVectors< TestVector > m_testVectors
array containing all the test vectors
void DoRun() override
Build the simulation scenario and run the tests.
Test case for the class ThreeGppV2vHighwayPropagationLossModel.
TestVectors< TestVector > m_testVectors
array containing all the test vectors
void DoRun() override
Build the simulation scenario and run the tests.
Test case for the class ThreeGppV2vUrbanPropagationLossModel.
TestVectors< TestVector > m_testVectors
array containing all the test vectors
void DoRun() override
Build the simulation scenario and run the tests.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:211
Instantiate subclasses of ns3::Object.
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:309
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.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
encapsulates test code
Definition: test.h:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:302
A suite of tests to run.
Definition: test.h:1273
Type
Type of test.
Definition: test.h:1280
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1347
Base class for the 3GPP propagation models.
void SetChannelConditionModel(Ptr< ChannelConditionModel > model)
Set the channel condition model used to determine the channel state (e.g., the LOS/NLOS condition)
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_TEST_EXPECT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report if ...
Definition: test.h:511
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1331
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Struct containing the parameters for each test.
double m_distance
the initial 2D distance in meters between BS and UT in meters
std::string m_propagationLossModelType
the propagation loss model type id
double m_shadowingStdLos
the standard deviation of the shadowing component in the LOS case in dB
double m_shadowingStdNlos
the standard deviation of the shadowing component in the NLOS case in dB
static ThreeGppPropagationLossModelsTestSuite g_propagationLossModelsTestSuite
Static variable for test initialization.