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.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h: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.