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 (std::size_t i = 0; i < m_testVectors.GetN(); i++)
171 {
172 TestVector testVector = m_testVectors.Get(i);
173
174 Vector posBs = Vector(0.0, 0.0, 35.0);
175 Vector posUt = Vector(testVector.m_distance, 0.0, 1.5);
176
177 // set the LOS or NLOS condition
178 if (testVector.m_isLos)
179 {
180 lossModel->SetChannelConditionModel(losCondModel);
181 }
182 else
183 {
184 lossModel->SetChannelConditionModel(nlosCondModel);
185 }
186
187 a->SetPosition(posBs);
188 b->SetPosition(posUt);
189
190 lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
191 NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
192 testVector.m_pr,
194 "Got unexpected rcv power");
195 }
196
198}
199
200/**
201 * \ingroup propagation-tests
202 *
203 * Test case for the class ThreeGppUmaPropagationLossModel.
204 * It computes the pathloss between two nodes and compares it with the value
205 * obtained using the formula in 3GPP TR 38.901, Table 7.4.1-1.
206 */
208{
209 public:
210 /**
211 * Constructor
212 */
214
215 /**
216 * Destructor
217 */
219
220 private:
221 /**
222 * Build the simulation scenario and run the tests
223 */
224 void DoRun() override;
225
226 /**
227 * Struct containing the parameters for each test
228 */
230 {
231 double m_distance; //!< 2D distance between UT and BS in meters
232 bool m_isLos; //!< if true LOS, if false NLOS
233 double m_frequency; //!< carrier frequency in Hz
234 double m_pt; //!< transmitted power in dBm
235 double m_pr; //!< received power in dBm
236 };
237
238 TestVectors<TestVector> m_testVectors; //!< array containing all the test vectors
239 double m_tolerance; //!< tolerance
240};
241
243 : TestCase("Test for the ThreeGppUmaPropagationLossModel class"),
244 m_testVectors(),
245 m_tolerance(5e-2)
246{
247}
248
250{
251}
252
253void
255{
256 TestVector testVector;
257
258 testVector.m_distance = 10.0;
259 testVector.m_isLos = true;
260 testVector.m_frequency = 5.0e9;
261 testVector.m_pt = 0.0;
262 testVector.m_pr = -72.9380;
263 m_testVectors.Add(testVector);
264
265 testVector.m_distance = 100.0;
266 testVector.m_isLos = true;
267 testVector.m_frequency = 5.0e9;
268 testVector.m_pt = 0.0;
269 testVector.m_pr = -86.2362;
270 m_testVectors.Add(testVector);
271
272 testVector.m_distance = 1000.0;
273 testVector.m_isLos = true;
274 testVector.m_frequency = 5.0e9;
275 testVector.m_pt = 0.0;
276 testVector.m_pr = -109.7252;
277 m_testVectors.Add(testVector);
278
279 testVector.m_distance = 5000.0;
280 testVector.m_isLos = true;
281 testVector.m_frequency = 5.0e9;
282 testVector.m_pt = 0.0;
283 testVector.m_pr = -137.6794;
284 m_testVectors.Add(testVector);
285
286 testVector.m_distance = 10.0;
287 testVector.m_isLos = false;
288 testVector.m_frequency = 5.0e9;
289 testVector.m_pt = 0.0;
290 testVector.m_pr = -82.5131;
291 m_testVectors.Add(testVector);
292
293 testVector.m_distance = 100.0;
294 testVector.m_isLos = false;
295 testVector.m_frequency = 5.0e9;
296 testVector.m_pt = 0.0;
297 testVector.m_pr = -106.1356;
298 m_testVectors.Add(testVector);
299
300 testVector.m_distance = 1000.0;
301 testVector.m_isLos = false;
302 testVector.m_frequency = 5.0e9;
303 testVector.m_pt = 0.0;
304 testVector.m_pr = -144.7641;
305 m_testVectors.Add(testVector);
306
307 testVector.m_distance = 5000.0;
308 testVector.m_isLos = false;
309 testVector.m_frequency = 5.0e9;
310 testVector.m_pt = 0.0;
311 testVector.m_pr = -172.0753;
312 m_testVectors.Add(testVector);
313
314 // Create the nodes for BS and UT
316 nodes.Create(2);
317
318 // Create the mobility models
319 Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
321 Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
323
324 // Use a deterministic channel condition model
325 Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel>();
326 Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel>();
327
328 // Create the propagation loss model
330 CreateObject<ThreeGppUmaPropagationLossModel>();
331 lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
332
333 for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
334 {
335 TestVector testVector = m_testVectors.Get(i);
336
337 Vector posBs = Vector(0.0, 0.0, 25.0);
338 Vector posUt = Vector(testVector.m_distance, 0.0, 1.5);
339
340 // set the LOS or NLOS condition
341 if (testVector.m_isLos)
342 {
343 lossModel->SetChannelConditionModel(losCondModel);
344 }
345 else
346 {
347 lossModel->SetChannelConditionModel(nlosCondModel);
348 }
349
350 a->SetPosition(posBs);
351 b->SetPosition(posUt);
352
353 lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
354 NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
355 testVector.m_pr,
357 "Got unexpected rcv power");
358 }
359
361}
362
363/**
364 * \ingroup propagation-tests
365 *
366 * Test case for the class ThreeGppUmiStreetCanyonPropagationLossModel.
367 * It computes the pathloss between two nodes and compares it with the value
368 * obtained using the formula in 3GPP TR 38.901, Table 7.4.1-1.
369 */
371{
372 public:
373 /**
374 * Constructor
375 */
377
378 /**
379 * Destructor
380 */
382
383 private:
384 /**
385 * Build the simulation scenario and run the tests
386 */
387 void DoRun() override;
388
389 /**
390 * Struct containing the parameters for each test
391 */
393 {
394 double m_distance; //!< 2D distance between UT and BS in meters
395 bool m_isLos; //!< if true LOS, if false NLOS
396 double m_frequency; //!< carrier frequency in Hz
397 double m_pt; //!< transmitted power in dBm
398 double m_pr; //!< received power in dBm
399 };
400
401 TestVectors<TestVector> m_testVectors; //!< array containing all the test vectors
402 double m_tolerance; //!< tolerance
403};
404
406 : TestCase("Test for the ThreeGppUmiPropagationLossModel class"),
407 m_testVectors(),
408 m_tolerance(5e-2)
409{
410}
411
413{
414}
415
416void
418{
419 TestVector testVector;
420
421 testVector.m_distance = 10.0;
422 testVector.m_isLos = true;
423 testVector.m_frequency = 5.0e9;
424 testVector.m_pt = 0.0;
425 testVector.m_pr = -69.8591;
426 m_testVectors.Add(testVector);
427
428 testVector.m_distance = 100.0;
429 testVector.m_isLos = true;
430 testVector.m_frequency = 5.0e9;
431 testVector.m_pt = 0.0;
432 testVector.m_pr = -88.4122;
433 m_testVectors.Add(testVector);
434
435 testVector.m_distance = 1000.0;
436 testVector.m_isLos = true;
437 testVector.m_frequency = 5.0e9;
438 testVector.m_pt = 0.0;
439 testVector.m_pr = -119.3114;
440
441 testVector.m_distance = 5000.0;
442 testVector.m_isLos = true;
443 testVector.m_frequency = 5.0e9;
444 testVector.m_pt = 0.0;
445 testVector.m_pr = -147.2696;
446
447 testVector.m_distance = 10.0;
448 testVector.m_isLos = false;
449 testVector.m_frequency = 5.0e9;
450 testVector.m_pt = 0.0;
451 testVector.m_pr = -76.7563;
452
453 testVector.m_distance = 100.0;
454 testVector.m_isLos = false;
455 testVector.m_frequency = 5.0e9;
456 testVector.m_pt = 0.0;
457 testVector.m_pr = -107.9432;
458
459 testVector.m_distance = 1000.0;
460 testVector.m_isLos = false;
461 testVector.m_frequency = 5.0e9;
462 testVector.m_pt = 0.0;
463 testVector.m_pr = -143.1886;
464
465 testVector.m_distance = 5000.0;
466 testVector.m_isLos = false;
467 testVector.m_frequency = 5.0e9;
468 testVector.m_pt = 0.0;
469 testVector.m_pr = -167.8617;
470
471 // Create the nodes for BS and UT
473 nodes.Create(2);
474
475 // Create the mobility models
476 Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
478 Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
480
481 // Use a deterministic channel condition model
482 Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel>();
483 Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel>();
484
485 // Create the propagation loss model
487 CreateObject<ThreeGppUmiStreetCanyonPropagationLossModel>();
488 lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
489
490 for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
491 {
492 TestVector testVector = m_testVectors.Get(i);
493
494 Vector posBs = Vector(0.0, 0.0, 10.0);
495 Vector posUt = Vector(testVector.m_distance, 0.0, 1.5);
496
497 // set the LOS or NLOS condition
498 if (testVector.m_isLos)
499 {
500 lossModel->SetChannelConditionModel(losCondModel);
501 }
502 else
503 {
504 lossModel->SetChannelConditionModel(nlosCondModel);
505 }
506
507 a->SetPosition(posBs);
508 b->SetPosition(posUt);
509
510 lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
511 NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
512 testVector.m_pr,
514 "Got unexpected rcv power");
515 }
516
518}
519
520/**
521 * \ingroup propagation-tests
522 *
523 * Test case for the class ThreeGppIndoorOfficePropagationLossModel.
524 * It computes the pathloss between two nodes and compares it with the value
525 * obtained using the formula in 3GPP TR 38.901, Table 7.4.1-1.
526 */
528{
529 public:
530 /**
531 * Constructor
532 */
534
535 /**
536 * Destructor
537 */
539
540 private:
541 /**
542 * Build the simulation scenario and run the tests
543 */
544 void DoRun() override;
545
546 /**
547 * Struct containing the parameters for each test
548 */
550 {
551 double m_distance; //!< 2D distance between UT and BS in meters
552 bool m_isLos; //!< if true LOS, if false NLOS
553 double m_frequency; //!< carrier frequency in Hz
554 double m_pt; //!< transmitted power in dBm
555 double m_pr; //!< received power in dBm
556 };
557
558 TestVectors<TestVector> m_testVectors; //!< array containing all the test vectors
559 double m_tolerance; //!< tolerance
560};
561
563 : TestCase("Test for the ThreeGppIndoorOfficePropagationLossModel class"),
564 m_testVectors(),
565 m_tolerance(5e-2)
566{
567}
568
571{
572}
573
574void
576{
577 TestVector testVector;
578
579 testVector.m_distance = 1.0;
580 testVector.m_isLos = true;
581 testVector.m_frequency = 5.0e9;
582 testVector.m_pt = 0.0;
583 testVector.m_pr = -50.8072;
584 m_testVectors.Add(testVector);
585
586 testVector.m_distance = 10.0;
587 testVector.m_isLos = true;
588 testVector.m_frequency = 5.0e9;
589 testVector.m_pt = 0.0;
590 testVector.m_pr = -63.7630;
591 m_testVectors.Add(testVector);
592
593 testVector.m_distance = 50.0;
594 testVector.m_isLos = true;
595 testVector.m_frequency = 5.0e9;
596 testVector.m_pt = 0.0;
597 testVector.m_pr = -75.7750;
598 m_testVectors.Add(testVector);
599
600 testVector.m_distance = 100.0;
601 testVector.m_isLos = true;
602 testVector.m_frequency = 5.0e9;
603 testVector.m_pt = 0.0;
604 testVector.m_pr = -80.9802;
605 m_testVectors.Add(testVector);
606
607 testVector.m_distance = 1.0;
608 testVector.m_isLos = false;
609 testVector.m_frequency = 5.0e9;
610 testVector.m_pt = 0.0;
611 testVector.m_pr = -50.8072;
612 m_testVectors.Add(testVector);
613
614 testVector.m_distance = 10.0;
615 testVector.m_isLos = false;
616 testVector.m_frequency = 5.0e9;
617 testVector.m_pt = 0.0;
618 testVector.m_pr = -73.1894;
619 m_testVectors.Add(testVector);
620
621 testVector.m_distance = 50.0;
622 testVector.m_isLos = false;
623 testVector.m_frequency = 5.0e9;
624 testVector.m_pt = 0.0;
625 testVector.m_pr = -99.7824;
626 m_testVectors.Add(testVector);
627
628 testVector.m_distance = 100.0;
629 testVector.m_isLos = false;
630 testVector.m_frequency = 5.0e9;
631 testVector.m_pt = 0.0;
632 testVector.m_pr = -111.3062;
633 m_testVectors.Add(testVector);
634
635 // Create the nodes for BS and UT
637 nodes.Create(2);
638
639 // Create the mobility models
640 Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
642 Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
644
645 // Use a deterministic channel condition model
646 Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel>();
647 Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel>();
648
649 // Create the propagation loss model
651 CreateObject<ThreeGppIndoorOfficePropagationLossModel>();
652 lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
653
654 for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
655 {
656 TestVector testVector = m_testVectors.Get(i);
657
658 Vector posBs = Vector(0.0, 0.0, 3.0);
659 Vector posUt = Vector(testVector.m_distance, 0.0, 1.5);
660
661 // set the LOS or NLOS condition
662 if (testVector.m_isLos)
663 {
664 lossModel->SetChannelConditionModel(losCondModel);
665 }
666 else
667 {
668 lossModel->SetChannelConditionModel(nlosCondModel);
669 }
670
671 a->SetPosition(posBs);
672 b->SetPosition(posUt);
673
674 lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
675 NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
676 testVector.m_pr,
678 "Got unexpected rcv power");
679 }
680
682}
683
684/**
685 * \ingroup propagation-tests
686 *
687 * Test case for the class ThreeGppV2vUrbanPropagationLossModel.
688 * It computes the pathloss between two nodes and compares it with the value
689 * obtained using the formula in 3GPP TR 37.885 Table 6.2.1-1 for v2v
690 * communications (sidelink).
691 *
692 * Note that 3GPP TR 37.885 defines 3 different channel states for vehicular
693 * environments: LOS, NLOS, and NLOSv, the latter representing the case in which
694 * the LOS path is blocked by other vehicles in the scenario. However, for
695 * computing the pathloss, only the two states are considered: LOS/NLOSv or NLOS
696 * (see TR 37.885 Section 6.2.1). In case of NLOSv, an additional vehicle
697 * blockage loss may be added, according to a log-normal random variable.
698 * Here, we test both conditions: LOS/NLOSv (without vehicle blockage
699 * loss) and NLOS.
700 */
702{
703 public:
704 /**
705 * Constructor
706 */
708
709 /**
710 * Destructor
711 */
713
714 private:
715 /**
716 * Build the simulation scenario and run the tests
717 */
718 void DoRun() override;
719
720 /**
721 * Struct containing the parameters for each test
722 */
724 {
725 double m_distance; //!< 2D distance between UT and BS in meters
726 bool m_isLos; //!< if true LOS/NLOSv, if false NLOS
727 double m_frequency; //!< carrier frequency in Hz
728 double m_pt; //!< transmitted power in dBm
729 double m_pr; //!< received power in dBm
730 };
731
732 TestVectors<TestVector> m_testVectors; //!< array containing all the test vectors
733 double m_tolerance; //!< tolerance
734};
735
737 : TestCase("Test for the ThreeGppV2vUrbanPropagationLossModel class."),
738 m_testVectors(),
739 m_tolerance(5e-2)
740{
741}
742
744{
745}
746
747void
749{
750 TestVector testVector;
751
752 testVector.m_distance = 10.0;
753 testVector.m_isLos = true;
754 testVector.m_frequency = 5.0e9;
755 testVector.m_pt = 0.0;
756 testVector.m_pr = -68.1913;
757 m_testVectors.Add(testVector);
758
759 testVector.m_distance = 100.0;
760 testVector.m_isLos = true;
761 testVector.m_frequency = 5.0e9;
762 testVector.m_pt = 0.0;
763 testVector.m_pr = -84.8913;
764 m_testVectors.Add(testVector);
765
766 testVector.m_distance = 1000.0;
767 testVector.m_isLos = true;
768 testVector.m_frequency = 5.0e9;
769 testVector.m_pt = 0.0;
770 testVector.m_pr = -101.5913;
771 m_testVectors.Add(testVector);
772
773 testVector.m_distance = 10.0;
774 testVector.m_isLos = false;
775 testVector.m_frequency = 5.0e9;
776 testVector.m_pt = 0.0;
777 testVector.m_pr = -80.0605;
778 m_testVectors.Add(testVector);
779
780 testVector.m_distance = 100.0;
781 testVector.m_isLos = false;
782 testVector.m_frequency = 5.0e9;
783 testVector.m_pt = 0.0;
784 testVector.m_pr = -110.0605;
785 m_testVectors.Add(testVector);
786
787 testVector.m_distance = 1000.0;
788 testVector.m_isLos = false;
789 testVector.m_frequency = 5.0e9;
790 testVector.m_pt = 0.0;
791 testVector.m_pr = -140.0605;
792 m_testVectors.Add(testVector);
793
794 // Create the nodes for BS and UT
796 nodes.Create(2);
797
798 // Create the mobility models
799 Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
801 Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
803
804 // Use a deterministic channel condition model
805 Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel>();
806 Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel>();
807
808 // Create the propagation loss model
810 CreateObject<ThreeGppV2vUrbanPropagationLossModel>();
811 lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
812
813 for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
814 {
815 TestVector testVector = m_testVectors.Get(i);
816
817 Vector posUe1 = Vector(0.0, 0.0, 1.6);
818 Vector posUe2 = Vector(testVector.m_distance, 0.0, 1.6);
819
820 // set the LOS or NLOS condition
821 if (testVector.m_isLos)
822 {
823 lossModel->SetChannelConditionModel(losCondModel);
824 }
825 else
826 {
827 lossModel->SetChannelConditionModel(nlosCondModel);
828 }
829
830 a->SetPosition(posUe1);
831 b->SetPosition(posUe2);
832
833 lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
834 NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
835 testVector.m_pr,
837 "Got unexpected rcv power");
838 }
839
841}
842
843/**
844 * \ingroup propagation-tests
845 *
846 * Test case for the class ThreeGppV2vHighwayPropagationLossModel.
847 * It computes the pathloss between two nodes and compares it with the value
848 * obtained using the formula in 3GPP TR 37.885 Table 6.2.1-1 for v2v
849 * communications (sidelink).
850 *
851 * Note that 3GPP TR 37.885 defines 3 different channel states for vehicular
852 * environments: LOS, NLOS and NLOSv, the latter representing the case in which
853 * the LOS path is blocked by other vehicles in the scenario. However, for
854 * computing the pathloss, only two states are considered: LOS/NLOSv or NLOS
855 * (see TR 37.885 Section 6.2.1). In case of NLOSv, an additional vehicle
856 * blockage loss may be added, according to a log-normal random variable.
857 * Here, we test both conditions: LOS/NLOSv (without vehicle blockage
858 * loss) and NLOS.
859 */
861{
862 public:
863 /**
864 * Constructor
865 */
867
868 /**
869 * Destructor
870 */
872
873 private:
874 /**
875 * Build the simulation scenario and run the tests
876 */
877 void DoRun() override;
878
879 /**
880 * Struct containing the parameters for each test
881 */
883 {
884 double m_distance; //!< 2D distance between UT and BS in meters
885 bool m_isLos; //!< if true LOS/NLOSv, if false NLOS
886 double m_frequency; //!< carrier frequency in Hz
887 double m_pt; //!< transmitted power in dBm
888 double m_pr; //!< received power in dBm
889 };
890
891 TestVectors<TestVector> m_testVectors; //!< array containing all the test vectors
892 double m_tolerance; //!< tolerance
893};
894
896 : TestCase("Test for the ThreeGppV2vHighwayPropagationLossModel"),
897 m_testVectors(),
898 m_tolerance(5e-2)
899{
900}
901
903{
904}
905
906void
908{
909 TestVector testVector;
910
911 testVector.m_distance = 10.0;
912 testVector.m_isLos = true;
913 testVector.m_frequency = 5.0e9;
914 testVector.m_pt = 0.0;
915 testVector.m_pr = -66.3794;
916 m_testVectors.Add(testVector);
917
918 testVector.m_distance = 100.0;
919 testVector.m_isLos = true;
920 testVector.m_frequency = 5.0e9;
921 testVector.m_pt = 0.0;
922 testVector.m_pr = -86.3794;
923 m_testVectors.Add(testVector);
924
925 testVector.m_distance = 1000.0;
926 testVector.m_isLos = true;
927 testVector.m_frequency = 5.0e9;
928 testVector.m_pt = 0.0;
929 testVector.m_pr = -106.3794;
930 m_testVectors.Add(testVector);
931
932 testVector.m_distance = 10.0;
933 testVector.m_isLos = false;
934 testVector.m_frequency = 5.0e9;
935 testVector.m_pt = 0.0;
936 testVector.m_pr = -80.0605;
937 m_testVectors.Add(testVector);
938
939 testVector.m_distance = 100.0;
940 testVector.m_isLos = false;
941 testVector.m_frequency = 5.0e9;
942 testVector.m_pt = 0.0;
943 testVector.m_pr = -110.0605;
944 m_testVectors.Add(testVector);
945
946 testVector.m_distance = 1000.0;
947 testVector.m_isLos = false;
948 testVector.m_frequency = 5.0e9;
949 testVector.m_pt = 0.0;
950 testVector.m_pr = -140.0605;
951 m_testVectors.Add(testVector);
952
953 // Create the nodes for BS and UT
955 nodes.Create(2);
956
957 // Create the mobility models
958 Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
960 Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
962
963 // Use a deterministic channel condition model
964 Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel>();
965 Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel>();
966
967 // Create the propagation loss model
969 CreateObject<ThreeGppV2vHighwayPropagationLossModel>();
970 lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
971
972 for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
973 {
974 TestVector testVector = m_testVectors.Get(i);
975
976 Vector posUe1 = Vector(0.0, 0.0, 1.6);
977 Vector posUe2 = Vector(testVector.m_distance, 0.0, 1.6);
978
979 // set the LOS or NLOS condition
980 if (testVector.m_isLos)
981 {
982 lossModel->SetChannelConditionModel(losCondModel);
983 }
984 else
985 {
986 lossModel->SetChannelConditionModel(nlosCondModel);
987 }
988
989 a->SetPosition(posUe1);
990 b->SetPosition(posUe2);
991
992 lossModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
993 NS_TEST_EXPECT_MSG_EQ_TOL(lossModel->CalcRxPower(testVector.m_pt, a, b),
994 testVector.m_pr,
996 "Got unexpected rcv power");
997 }
998
1000}
1001
1002/**
1003 * \ingroup propagation-tests
1004 *
1005 * Test to check if the shadowing fading is correctly computed
1006 */
1008{
1009 public:
1011 ~ThreeGppShadowingTestCase() override;
1012
1013 private:
1014 void DoRun() override;
1015
1016 /**
1017 * Run the experiment
1018 * \param testNum the index of the experiment
1019 * \param propagationLossModelType the type id of the propagation loss model
1020 * to be used
1021 * \param hBs the BS height in meters
1022 * \param hUt the UT height in meters
1023 * \param distance the initial distance between the BS and the UT
1024 * \param shadowingEnabled true if shadowging must be enabled
1025 */
1026 void RunTest(uint16_t testNum,
1027 std::string propagationLossModelType,
1028 double hBs,
1029 double hUt,
1030 double distance,
1031 bool shadowingEnabled);
1032
1033 /**
1034 * Compute the propagation loss
1035 * \param a the first mobility model
1036 * \param b the second mobility model
1037 * \param testNum the index of the experiment
1038 */
1039 void EvaluateLoss(Ptr<MobilityModel> a, Ptr<MobilityModel> b, uint8_t testNum);
1040
1041 /**
1042 * Change the channel condition model
1043 * \param ccm the new ChannelConditionModel
1044 */
1046
1047 /**
1048 * Struct containing the parameters for each test
1049 */
1051 {
1052 std::string m_propagationLossModelType; //!< the propagation loss model type id
1053 double m_hBs; //!< the BS height in meters
1054 double m_hUt; //!< the UT height in meters
1055 double m_distance; //!< the initial 2D distance in meters between BS and UT in meters
1056 double m_shadowingStdLos; //!< the standard deviation of the shadowing component in the LOS
1057 //!< case in dB
1058 double m_shadowingStdNlos; //!< the standard deviation of the shadowing component in the
1059 //!< NLOS case in dB
1060 };
1061
1062 TestVectors<TestVector> m_testVectors; //!< array containing all the test vectors
1063 Ptr<ThreeGppPropagationLossModel> m_lossModel; //!< the propagation loss model
1064 std::map<uint16_t /* index of experiment */, std::vector<double> /* loss in dB for each run */>
1065 m_results; //!< used to store the test results
1066};
1067
1069 : TestCase("Test to check if the shadow fading is correctly computed")
1070{
1071}
1072
1074{
1075}
1076
1077void
1079{
1080 double loss = m_lossModel->CalcRxPower(0, a, b);
1081 m_results.at(testNum).push_back(loss);
1082}
1083
1084void
1086{
1088}
1089
1090void
1092 std::string propagationLossModelType,
1093 double hBs,
1094 double hUt,
1095 double distance,
1096 bool shadowingEnabled)
1097{
1098 // Add a new entry for this test in the results map
1099 m_results[testNum] = std::vector<double>();
1100
1101 // Create the nodes for BS and UT
1103 nodes.Create(2);
1104
1105 // Create the mobility models
1106 Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
1107 a->SetPosition(Vector(0.0, 0.0, hBs));
1108 nodes.Get(0)->AggregateObject(a);
1109
1110 Ptr<ConstantVelocityMobilityModel> b = CreateObject<ConstantVelocityMobilityModel>();
1111 nodes.Get(1)->AggregateObject(b);
1112 b->SetPosition(Vector(0.0, distance, hUt));
1113 b->SetVelocity(Vector(1.0, 0.0, 0.0));
1114
1115 // Create the propagation loss model
1116 ObjectFactory propagationLossModelFactory = ObjectFactory(propagationLossModelType);
1117 m_lossModel = propagationLossModelFactory.Create<ThreeGppPropagationLossModel>();
1118 m_lossModel->SetAttribute("Frequency", DoubleValue(3.5e9));
1119 m_lossModel->SetAttribute("ShadowingEnabled",
1120 BooleanValue(shadowingEnabled)); // enable the shadow fading
1121
1122 // Set the channel condition to LOS
1123 Ptr<ChannelConditionModel> losCondModel = CreateObject<AlwaysLosChannelConditionModel>();
1125 // Schedule a transition to NLOS
1126 Ptr<ChannelConditionModel> nlosCondModel = CreateObject<NeverLosChannelConditionModel>();
1129 this,
1130 nlosCondModel);
1131
1132 // Schedule multiple calls to EvaluateLoss. Use both EvaluateLoss (a,b) and
1133 // EvaluateLoss (b,a) to check if the reciprocity holds.
1134 for (int i = 0; i < 200; i++)
1135 {
1136 if (i % 2 == 0)
1137 {
1140 this,
1141 a,
1142 b,
1143 testNum);
1144 }
1145 else
1146 {
1149 this,
1150 b,
1151 a,
1152 testNum);
1153 }
1154 }
1155
1158}
1159
1160void
1162{
1163 // The test scenario is composed of two nodes, one fixed
1164 // at position (0,0) and the other moving with constant velocity from
1165 // position (0,50) to position (200,50).
1166 // The channel condition changes from LOS to NLOS when the second node
1167 // reaches position (100,50).
1168 // Each experiment computes the propagation loss between the two nodes
1169 // every second, until the final position is reached, and saves the
1170 // results in an entry of the map m_results.
1171 // We run numSamples experiments and estimate the mean propagation loss in
1172 // each position by averaging among the samples.
1173 // Then, we perform the null hypothesis test with a significance level of
1174 // 0.05.
1175 // This procedure is repeated for all the 3GPP propagation scenarios, i.e.,
1176 // RMa, UMa, UMi and Indoor-Office.
1177
1178 TestVector testVector;
1179 testVector.m_propagationLossModelType = "ns3::ThreeGppRmaPropagationLossModel";
1180 testVector.m_hBs = 25;
1181 testVector.m_hUt = 1.6;
1182 testVector.m_distance = 100;
1183 testVector.m_shadowingStdLos = 4;
1184 testVector.m_shadowingStdNlos = 8;
1185 m_testVectors.Add(testVector);
1186
1187 testVector.m_propagationLossModelType = "ns3::ThreeGppRmaPropagationLossModel";
1188 testVector.m_hBs = 25;
1189 testVector.m_hUt = 1.6;
1190 testVector.m_distance = 4000; // beyond the breakpoint distance
1191 testVector.m_shadowingStdLos = 6;
1192 testVector.m_shadowingStdNlos = 8;
1193 m_testVectors.Add(testVector);
1194
1195 testVector.m_propagationLossModelType = "ns3::ThreeGppUmaPropagationLossModel";
1196 testVector.m_hBs = 25;
1197 testVector.m_hUt = 1.6;
1198 testVector.m_distance = 100;
1199 testVector.m_shadowingStdLos = 4;
1200 testVector.m_shadowingStdNlos = 6;
1201 m_testVectors.Add(testVector);
1202
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_propagationLossModelType = "ns3::ThreeGppIndoorOfficePropagationLossModel";
1212 testVector.m_hBs = 3;
1213 testVector.m_hUt = 1;
1214 testVector.m_distance = 50;
1215 testVector.m_shadowingStdLos = 3;
1216 testVector.m_shadowingStdNlos = 8.03;
1217 m_testVectors.Add(testVector);
1218
1219 testVector.m_propagationLossModelType = "ns3::ThreeGppV2vUrbanPropagationLossModel";
1220 testVector.m_hBs = 1.6;
1221 testVector.m_hUt = 1.6;
1222 testVector.m_distance = 50;
1223 testVector.m_shadowingStdLos = 3;
1224 testVector.m_shadowingStdNlos = 4;
1225 m_testVectors.Add(testVector);
1226
1227 testVector.m_propagationLossModelType = "ns3::ThreeGppV2vHighwayPropagationLossModel";
1228 testVector.m_hBs = 1.6;
1229 testVector.m_hUt = 1.6;
1230 testVector.m_distance = 50;
1231 testVector.m_shadowingStdLos = 3;
1232 testVector.m_shadowingStdNlos = 4;
1233 m_testVectors.Add(testVector);
1234
1235 uint16_t numSamples = 250;
1236
1237 for (std::size_t tvIndex = 0; tvIndex < m_testVectors.GetN(); tvIndex++)
1238 {
1239 TestVector tv = m_testVectors.Get(tvIndex);
1240
1241 // run the experiments.
1242 for (uint16_t sampleIndex = 0; sampleIndex < numSamples; sampleIndex++)
1243 {
1244 RunTest(sampleIndex,
1246 tv.m_hBs,
1247 tv.m_hUt,
1248 tv.m_distance,
1249 true);
1250 }
1251
1252 // analyze the results
1253 std::vector<double> mean_vector; // the vector containing the mean propagation loss for each
1254 // position (sample mean)
1255
1256 uint16_t numPositions = m_results.at(0).size();
1257 for (uint16_t k = 0; k < numPositions; k++)
1258 {
1259 // compute the mean propagation loss in position k
1260 double mean = 0.0;
1261 for (auto resIt : m_results)
1262 {
1263 mean += resIt.second.at(k);
1264 }
1265 mean /= m_results.size();
1266 mean_vector.push_back(mean);
1267 }
1268
1269 // compute the true mean - just the pathloss, without the shadowing component
1270 RunTest(numSamples,
1272 tv.m_hBs,
1273 tv.m_hUt,
1274 tv.m_distance,
1275 false);
1276 std::vector<double> true_mean =
1277 m_results.at(numSamples); // the result of the last test is the true mean
1278
1279 // perform the null hypothesis test for the LOS case
1280 // positions from (0, 50) to (99, 50) are LOS
1281 for (std::size_t i = 0; i < mean_vector.size() / 2; i++)
1282 {
1283 double z = (mean_vector.at(i) - true_mean.at(i)) /
1284 (tv.m_shadowingStdLos / std::sqrt(mean_vector.size() / 2));
1286 z,
1287 0.0,
1288 1.96,
1289 "Null hypothesis test (LOS case) for the shadowing component rejected");
1290 }
1291
1292 // perform the null hypothesis test for the NLOS case
1293 // positions from (100, 50) to (199, 50) are NLOS
1294 for (std::size_t i = mean_vector.size() / 2; i < mean_vector.size(); i++)
1295 {
1296 double z = (mean_vector.at(i) - true_mean.at(i)) /
1297 (tv.m_shadowingStdNlos / std::sqrt(mean_vector.size() / 2));
1299 z,
1300 0.0,
1301 1.96,
1302 "Null hypothesis test (NLOS case) for the shadowing component rejected");
1303 }
1304 }
1305}
1306
1307/**
1308 * \ingroup propagation-tests
1309 *
1310 * \brief 3GPP Propagation models TestSuite
1311 *
1312 * This TestSuite tests the following models:
1313 * - ThreeGppRmaPropagationLossModel
1314 * - ThreeGppUmaPropagationLossModel
1315 * - ThreeGppUmiPropagationLossModel
1316 * - ThreeGppIndoorOfficePropagationLossModel
1317 * - ThreeGppV2vUrbanPropagationLossModel
1318 * - ThreeGppV2vHighwayPropagationLossModel
1319 * - ThreeGppShadowing
1320 */
1322{
1323 public:
1325};
1326
1328 : TestSuite("three-gpp-propagation-loss-model", Type::UNIT)
1329{
1330 AddTestCase(new ThreeGppRmaPropagationLossModelTestCase, TestCase::Duration::QUICK);
1331 AddTestCase(new ThreeGppUmaPropagationLossModelTestCase, TestCase::Duration::QUICK);
1332 AddTestCase(new ThreeGppUmiPropagationLossModelTestCase, TestCase::Duration::QUICK);
1333 AddTestCase(new ThreeGppIndoorOfficePropagationLossModelTestCase, TestCase::Duration::QUICK);
1334 AddTestCase(new ThreeGppV2vUrbanPropagationLossModelTestCase, TestCase::Duration::QUICK);
1335 AddTestCase(new ThreeGppV2vHighwayPropagationLossModelTestCase, TestCase::Duration::QUICK);
1336 AddTestCase(new ThreeGppShadowingTestCase, TestCase::Duration::QUICK);
1337}
1338
1339/// 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:301
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1342
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:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
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.