A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
three-gpp-propagation-loss-model.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2019 SIGNET Lab, Department of Information Engineering,
3 * University of Padova
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 */
7
9
11
12#include "ns3/boolean.h"
13#include "ns3/double.h"
14#include "ns3/geocentric-constant-position-mobility-model.h"
15#include "ns3/log.h"
16#include "ns3/mobility-model.h"
17#include "ns3/node.h"
18#include "ns3/pointer.h"
19#include "ns3/simulator.h"
20
21#include <cmath>
22
23namespace
24{
25/**
26 * The enumerator used for code clarity when performing parameter assignment in the GetLoss Methods
27 */
37
38/**
39 * The map containing the 3GPP value regarding Shadow Fading and Clutter Loss tables for the
40 * NTN Dense Urban scenario
41 */
42const std::map<int, std::vector<float>> SFCL_DenseUrban{
43 {10, {3.5, 15.5, 34.3, 2.9, 17.1, 44.3}},
44 {20, {3.4, 13.9, 30.9, 2.4, 17.1, 39.9}},
45 {30, {2.9, 12.4, 29.0, 2.7, 15.6, 37.5}},
46 {40, {3.0, 11.7, 27.7, 2.4, 14.6, 35.8}},
47 {50, {3.1, 10.6, 26.8, 2.4, 14.2, 34.6}},
48 {60, {2.7, 10.5, 26.2, 2.7, 12.6, 33.8}},
49 {70, {2.5, 10.1, 25.8, 2.6, 12.1, 33.3}},
50 {80, {2.3, 9.2, 25.5, 2.8, 12.3, 33.0}},
51 {90, {1.2, 9.2, 25.5, 0.6, 12.3, 32.9}},
52};
53
54/**
55 * The map containing the 3GPP value regarding Shadow Fading and Clutter Loss tables for the
56 * NTN Urban scenario
57 */
58const std::map<int, std::vector<float>> SFCL_Urban{
59 {10, {4, 6, 34.3, 4, 6, 44.3}},
60 {20, {4, 6, 30.9, 4, 6, 39.9}},
61 {30, {4, 6, 29.0, 4, 6, 37.5}},
62 {40, {4, 6, 27.7, 4, 6, 35.8}},
63 {50, {4, 6, 26.8, 4, 6, 34.6}},
64 {60, {4, 6, 26.2, 4, 6, 33.8}},
65 {70, {4, 6, 25.8, 4, 6, 33.3}},
66 {80, {4, 6, 25.5, 4, 6, 33.0}},
67 {90, {4, 6, 25.5, 4, 6, 32.9}},
68};
69
70/**
71 * The map containing the 3GPP value regarding Shadow Fading and Clutter Loss tables for the
72 * NTN Suburban and Rural scenarios
73 */
74const std::map<int, std::vector<float>> SFCL_SuburbanRural{
75 {10, {1.79, 8.93, 19.52, 1.9, 10.7, 29.5}},
76 {20, {1.14, 9.08, 18.17, 1.6, 10.0, 24.6}},
77 {30, {1.14, 8.78, 18.42, 1.9, 11.2, 21.9}},
78 {40, {0.92, 10.25, 18.28, 2.3, 11.6, 20.0}},
79 {50, {1.42, 10.56, 18.63, 2.7, 11.8, 18.7}},
80 {60, {1.56, 10.74, 17.68, 3.1, 10.8, 17.8}},
81 {70, {0.85, 10.17, 16.5, 3.0, 10.8, 17.2}},
82 {80, {0.72, 11.52, 16.3, 3.6, 10.8, 16.9}},
83 {90, {0.72, 11.52, 16.3, 0.4, 10.8, 16.8}},
84};
85
86/**
87 * Array containing the attenuation given by atmospheric absorption. 100 samples are selected for
88 * frequencies from 1GHz to 100GHz. In order to get the atmospheric absorption loss for a given
89 * frequency f: 1- round f to the closest integer between 0 and 100. 2- use the obtained integer to
90 * access the corresponding element in the array, that will give the attenuation at that frequency.
91 * Data is obtained form ITU-R P.676 Figure 6.
92 */
93const double atmosphericAbsorption[101] = {
94 0, 0.0300, 0.0350, 0.0380, 0.0390, 0.0410, 0.0420, 0.0450, 0.0480, 0.0500,
95 0.0530, 0.0587, 0.0674, 0.0789, 0.0935, 0.1113, 0.1322, 0.1565, 0.1841, 0.2153,
96 0.2500, 0.3362, 0.4581, 0.5200, 0.5200, 0.5000, 0.4500, 0.3850, 0.3200, 0.2700,
97 0.2500, 0.2517, 0.2568, 0.2651, 0.2765, 0.2907, 0.3077, 0.3273, 0.3493, 0.3736,
98 0.4000, 0.4375, 0.4966, 0.5795, 0.6881, 0.8247, 0.9912, 1.1900, 1.4229, 1.6922,
99 2.0000, 4.2654, 10.1504, 19.2717, 31.2457, 45.6890, 62.2182, 80.4496, 100.0000, 140.0205,
100 170.0000, 100.0000, 78.1682, 59.3955, 43.5434, 30.4733, 20.0465, 12.1244, 6.5683, 3.2397,
101 2.0000, 1.7708, 1.5660, 1.3858, 1.2298, 1.0981, 0.9905, 0.9070, 0.8475, 0.8119,
102 0.8000, 0.8000, 0.8000, 0.8000, 0.8000, 0.8000, 0.8000, 0.8000, 0.8000, 0.8000,
103 0.8000, 0.8029, 0.8112, 0.8243, 0.8416, 0.8625, 0.8864, 0.9127, 0.9408, 0.9701,
104 1.0000};
105
106/**
107 * Map containing the Tropospheric attenuation in dB with 99% probability at 20 GHz in Toulouse
108 * used for tropospheric scintillation losses. From Table 6.6.6.2.1-1 of 3GPP TR 38.811.
109 */
110const std::map<int, float> troposphericScintillationLoss{
111 {10, {1.08}},
112 {20, {0.48}},
113 {30, {0.30}},
114 {40, {0.22}},
115 {50, {0.17}},
116 {60, {0.13}},
117 {70, {0.12}},
118 {80, {0.12}},
119 {90, {0.12}},
120};
121
122/**
123 * @brief Get the base station and user terminal relative distances and heights
124 *
125 * @param a the mobility model of terminal a
126 * @param b the mobility model of terminal b
127 *
128 * @return The tuple [dist2D, dist3D, hBs, hUt], where dist2D and dist3D
129 * are the 2D and 3D distances between a and b, respectively, hBs is the bigger
130 * height and hUt the smallest.
131 */
132std::tuple<double, double, double, double>
135{
136 auto aPos = a->GetPosition();
137 auto bPos = b->GetPosition();
138 double distance2D = ns3::ThreeGppChannelConditionModel::Calculate2dDistance(aPos, bPos);
139 double distance3D = ns3::CalculateDistance(aPos, bPos);
140 double hBs = std::max(aPos.z, bPos.z);
141 double hUt = std::min(aPos.z, bPos.z);
142 return std::make_tuple(distance2D, distance3D, hBs, hUt);
143};
144
145/**
146 * @brief Get the base station and user terminal heights for the UmiStreetCanyon scenario
147 *
148 * @param heightA the first height in meters
149 * @param heightB the second height in meters
150 *
151 * @return The tuple [hBs, hUt], where hBs is assumed to be = 10 and hUt other height.
152 */
153std::tuple<double, double>
154GetBsUtHeightsUmiStreetCanyon(double heightA, double heightB)
155{
156 double hBs = (heightA == 10) ? heightA : heightB;
157 double hUt = (heightA == 10) ? heightB : heightA;
158 return std::make_tuple(hBs, hUt);
159};
160
161/**
162 * @brief Computes the free-space path loss using the formula described in 3GPP TR 38.811,
163 * Table 6.6.2
164 *
165 * @param freq the operating frequency
166 * @param dist3d the 3D distance between the communicating nodes
167 *
168 * @return the path loss for NTN scenarios
169 */
170double
171ComputeNtnPathloss(double freq, double dist3d)
172{
173 return 32.45 + 20 * log10(freq / 1e9) + 20 * log10(dist3d);
174};
175
176/**
177 * @brief Computes the atmospheric absorption loss using the formula described in 3GPP TR 38.811,
178 * Sec 6.6.4
179 *
180 * @param freq the operating frequency
181 * @param elevAngle the elevation angle between the communicating nodes
182 *
183 * @return the atmospheric absorption loss for NTN scenarios
184 */
185double
186ComputeAtmosphericAbsorptionLoss(double freq, double elevAngle)
187{
188 double loss = 0;
189 if ((elevAngle < 10 && freq > 1e9) || freq >= 10e9)
190 {
191 int roundedFreq = round(freq / 10e8);
192 loss += atmosphericAbsorption[roundedFreq] / sin(elevAngle * (M_PI / 180));
193 }
194
195 return loss;
196};
197
198/**
199 * @brief Computes the ionospheric plus tropospheric scintillation loss using the formulas
200 * described in 3GPP TR 38.811, Sec 6.6.6.1-4 and 6.6.6.2, respectively.
201 *
202 * @param freq the operating frequency
203 * @param elevAngleQuantized the quantized elevation angle between the communicating nodes
204 *
205 * @return the ionospheric plus tropospheric scintillation loss for NTN scenarios
206 */
207double
208ComputeIonosphericPlusTroposphericScintillationLoss(double freq, double elevAngleQuantized)
209{
210 double loss = 0;
211 if (freq < 6e9)
212 {
213 // Ionospheric
214 loss = 6.22 / (pow(freq / 1e9, 1.5));
215 }
216 else
217 {
218 // Tropospheric
219 loss = troposphericScintillationLoss.at(elevAngleQuantized);
220 }
221 return loss;
222};
223
224/**
225 * @brief Computes the clutter loss using the formula
226 * described in 3GPP TR 38.811, Sec 6.6.6.1-4 and 6.6.6.2, respectively.
227 *
228 * @param freq the operating frequency
229 * @param elevAngleQuantized the quantized elevation angle between the communicating nodes
230 * @param sfcl the nested map containing the Shadow Fading and
231 * Clutter Loss values for the NTN Suburban and Rural scenario
232 *
233 * @return the clutter loss for NTN scenarios
234 */
235double
237 const std::map<int, std::vector<float>>* sfcl,
238 double elevAngleQuantized)
239{
240 double loss = 0;
241 if (freq < 13.0e9)
242 {
243 loss += (*sfcl).at(elevAngleQuantized)[SFCL_params::S_NLOS_CL]; // Get the Clutter Loss for
244 // the S Band
245 }
246 else
247 {
248 loss += (*sfcl).at(elevAngleQuantized)[SFCL_params::Ka_NLOS_CL]; // Get the Clutter Loss for
249 // the Ka Band
250 }
251
252 return loss;
253};
254
255constexpr double M_C = 3.0e8; //!< propagation velocity in free space
256
257} // namespace
258
259namespace ns3
260{
261
262NS_LOG_COMPONENT_DEFINE("ThreeGppPropagationLossModel");
263
264NS_OBJECT_ENSURE_REGISTERED(ThreeGppPropagationLossModel);
265
266TypeId
268{
269 static TypeId tid =
270 TypeId("ns3::ThreeGppPropagationLossModel")
272 .SetGroupName("Propagation")
273 .AddAttribute("Frequency",
274 "The centre frequency in Hz.",
275 DoubleValue(500.0e6),
279 .AddAttribute("ShadowingEnabled",
280 "Enable/disable shadowing.",
281 BooleanValue(true),
284 .AddAttribute(
285 "ChannelConditionModel",
286 "Pointer to the channel condition model.",
287 PointerValue(),
291 .AddAttribute("EnforceParameterRanges",
292 "Whether to strictly enforce TR38.901 applicability ranges",
293 BooleanValue(false),
296 .AddAttribute(
297 "BuildingPenetrationLossesEnabled",
298 "Enable/disable Building Penetration Losses.",
299 BooleanValue(true),
302 return tid;
303}
304
326
331
332void
339
340void
346
353
354void
356{
357 NS_LOG_FUNCTION(this);
358 NS_ASSERT_MSG(f >= 500.0e6 && f <= 100.0e9,
359 "Frequency should be between 0.5 and 100 GHz but is " << f);
360 m_frequency = f;
361}
362
363double
369
370bool
375
376double
379 Ptr<MobilityModel> b) const
380{
381 NS_LOG_FUNCTION(this);
382
383 // check if the model is initialized
384 NS_ASSERT_MSG(m_frequency != 0.0, "First set the centre frequency");
385
386 // retrieve the channel condition
387 NS_ASSERT_MSG(m_channelConditionModel, "First set the channel condition model");
388 Ptr<ChannelCondition> cond = m_channelConditionModel->GetChannelCondition(a, b);
389
390 double rxPow = txPowerDbm;
391 rxPow -= GetLoss(cond, a, b);
392
394 {
395 rxPow -= GetShadowing(a, b, cond->GetLosCondition());
396 }
397
398 // get o2i losses
400 ((cond->GetO2iCondition() == ChannelCondition::O2iConditionValue::O2I) ||
401 (cond->GetO2iCondition() == ChannelCondition::O2iConditionValue::I2I &&
402 cond->GetLosCondition() == ChannelCondition::LosConditionValue::NLOS)))
403 {
404 if (IsO2iLowPenetrationLoss(cond))
405 {
406 rxPow -= GetO2iLowPenetrationLoss(a, b, cond->GetLosCondition());
407 }
408 else
409 {
410 rxPow -= GetO2iHighPenetrationLoss(a, b, cond->GetLosCondition());
411 }
412 }
413
414 return rxPow;
415}
416
417double
420 Ptr<MobilityModel> b) const
421{
422 NS_LOG_FUNCTION(this);
423
424 double loss = 0;
425 switch (cond->GetLosCondition())
426 {
428 loss = GetLossLos(a, b);
429 break;
431 loss = GetLossNlosv(a, b);
432 break;
434 loss = GetLossNlos(a, b);
435 break;
436 default:
437 NS_FATAL_ERROR("Unknown channel condition");
438 }
439
440 return loss;
441}
442
443double
448{
449 NS_LOG_FUNCTION(this);
450
451 double o2iLossValue = 0;
452 double lowLossTw = 0;
453 double lossIn = 0;
454 double lowlossNormalVariate = 0;
455 double lGlass = 0;
456 double lConcrete = 0;
457
458 // compute the channel key
459 uint32_t key = GetKey(a, b);
460
461 bool notFound = false; // indicates if the o2iLoss value has not been computed yet
462 bool newCondition = false; // indicates if the channel condition has changed
463
464 auto it = m_o2iLossMap.end(); // the o2iLoss map iterator
465 if (m_o2iLossMap.find(key) != m_o2iLossMap.end())
466 {
467 // found the o2iLoss value in the map
468 it = m_o2iLossMap.find(key);
469 newCondition = (it->second.m_condition != cond); // true if the condition changed
470 }
471 else
472 {
473 notFound = true;
474 // add a new entry in the map and update the iterator
475 O2iLossMapItem newItem;
476 it = m_o2iLossMap.insert(it, std::make_pair(key, newItem));
477 }
478
479 if (notFound || newCondition)
480 {
481 // distance2dIn is minimum of two independently generated uniformly distributed
482 // variables between 0 and 25 m for UMa and UMi-Street Canyon, and between 0 and
483 // 10 m for RMa. 2D−in d shall be UT-specifically generated.
484 double distance2dIn = GetO2iDistance2dIn();
485
486 // calculate material penetration losses, see TR 38.901 Table 7.4.3-1
487 lGlass = 2 + 0.2 * m_frequency / 1e9; // m_frequency is operation frequency in Hz
488 lConcrete = 5 + 4 * m_frequency / 1e9;
489
490 lowLossTw =
491 5 - 10 * log10(0.3 * std::pow(10, -lGlass / 10) + 0.7 * std::pow(10, -lConcrete / 10));
492
493 // calculate indoor loss
494 lossIn = 0.5 * distance2dIn;
495
496 // calculate low loss standard deviation
497 lowlossNormalVariate = m_normalO2iLowLossVar->GetValue();
498
499 o2iLossValue = lowLossTw + lossIn + lowlossNormalVariate;
500 }
501 else
502 {
503 o2iLossValue = it->second.m_o2iLoss;
504 }
505
506 // update the entry in the map
507 it->second.m_o2iLoss = o2iLossValue;
508 it->second.m_condition = cond;
509
510 return o2iLossValue;
511}
512
513double
518{
519 NS_LOG_FUNCTION(this);
520
521 double o2iLossValue = 0;
522 double highLossTw = 0;
523 double lossIn = 0;
524 double highlossNormalVariate = 0;
525 double lIIRGlass = 0;
526 double lConcrete = 0;
527
528 // compute the channel key
529 uint32_t key = GetKey(a, b);
530
531 bool notFound = false; // indicates if the o2iLoss value has not been computed yet
532 bool newCondition = false; // indicates if the channel condition has changed
533
534 auto it = m_o2iLossMap.end(); // the o2iLoss map iterator
535 if (m_o2iLossMap.find(key) != m_o2iLossMap.end())
536 {
537 // found the o2iLoss value in the map
538 it = m_o2iLossMap.find(key);
539 newCondition = (it->second.m_condition != cond); // true if the condition changed
540 }
541 else
542 {
543 notFound = true;
544 // add a new entry in the map and update the iterator
545 O2iLossMapItem newItem;
546 it = m_o2iLossMap.insert(it, std::make_pair(key, newItem));
547 }
548
549 if (notFound || newCondition)
550 {
551 // generate a new independent realization
552
553 // distance2dIn is minimum of two independently generated uniformly distributed
554 // variables between 0 and 25 m for UMa and UMi-Street Canyon, and between 0 and
555 // 10 m for RMa. 2D−in d shall be UT-specifically generated.
556 double distance2dIn = GetO2iDistance2dIn();
557
558 // calculate material penetration losses, see TR 38.901 Table 7.4.3-1
559 lIIRGlass = 23 + 0.3 * m_frequency / 1e9;
560 lConcrete = 5 + 4 * m_frequency / 1e9;
561
562 highLossTw = 5 - 10 * log10(0.7 * std::pow(10, -lIIRGlass / 10) +
563 0.3 * std::pow(10, -lConcrete / 10));
564
565 // calculate indoor loss
566 lossIn = 0.5 * distance2dIn;
567
568 // calculate low loss standard deviation
569 highlossNormalVariate = m_normalO2iHighLossVar->GetValue();
570
571 o2iLossValue = highLossTw + lossIn + highlossNormalVariate;
572 }
573 else
574 {
575 o2iLossValue = it->second.m_o2iLoss;
576 }
577
578 // update the entry in the map
579 it->second.m_o2iLoss = o2iLossValue;
580 it->second.m_condition = cond;
581
582 return o2iLossValue;
583}
584
585bool
587{
588 if (cond->GetO2iLowHighCondition() == ChannelCondition::O2iLowHighConditionValue::LOW)
589 {
590 return true;
591 }
592 else if (cond->GetO2iLowHighCondition() == ChannelCondition::O2iLowHighConditionValue::HIGH)
593 {
594 return false;
595 }
596 else
597 {
598 NS_ABORT_MSG("If we have set the O2I condition, we shouldn't be here");
599 }
600}
601
602double
604{
605 NS_LOG_FUNCTION(this);
606 NS_FATAL_ERROR("Unsupported channel condition (NLOSv)");
607 return 0;
608}
609
610double
614{
615 NS_LOG_FUNCTION(this);
616
617 double shadowingValue;
618
619 // compute the channel key
620 uint32_t key = GetKey(a, b);
621
622 bool notFound = false; // indicates if the shadowing value has not been computed yet
623 bool newCondition = false; // indicates if the channel condition has changed
624 Vector newDistance; // the distance vector, that is not a distance but a difference
625 auto it = m_shadowingMap.end(); // the shadowing map iterator
626 if (m_shadowingMap.find(key) != m_shadowingMap.end())
627 {
628 // found the shadowing value in the map
629 it = m_shadowingMap.find(key);
630 newDistance = GetVectorDifference(a, b);
631 newCondition = (it->second.m_condition != cond); // true if the condition changed
632 }
633 else
634 {
635 notFound = true;
636
637 // add a new entry in the map and update the iterator
638 ShadowingMapItem newItem;
639 it = m_shadowingMap.insert(it, std::make_pair(key, newItem));
640 }
641
642 if (notFound || newCondition)
643 {
644 // generate a new independent realization
645 shadowingValue = m_normRandomVariable->GetValue() * GetShadowingStd(a, b, cond);
646 }
647 else
648 {
649 // compute a new correlated shadowing loss
650 Vector2D displacement(newDistance.x - it->second.m_distance.x,
651 newDistance.y - it->second.m_distance.y);
652 double R = exp(-1 * displacement.GetLength() / GetShadowingCorrelationDistance(cond));
653 shadowingValue = R * it->second.m_shadowing + sqrt(1 - R * R) *
654 m_normRandomVariable->GetValue() *
655 GetShadowingStd(a, b, cond);
656 }
657
658 // update the entry in the map
659 it->second.m_shadowing = shadowingValue;
660 it->second.m_distance = newDistance; // Save the (0,0,0) vector in case it's the first time we
661 // are calculating this value
662 it->second.m_condition = cond;
663
664 return shadowingValue;
665}
666
667int64_t
669{
670 NS_LOG_FUNCTION(this);
671
672 m_normRandomVariable->SetStream(stream);
673 m_randomO2iVar1->SetStream(stream + 1);
674 m_randomO2iVar2->SetStream(stream + 2);
675 m_normalO2iLowLossVar->SetStream(stream + 3);
676 m_normalO2iHighLossVar->SetStream(stream + 4);
677
678 return 5;
679}
680
681double
683{
684 double x = a.x - b.x;
685 double y = a.y - b.y;
686 double distance2D = sqrt(x * x + y * y);
687
688 return distance2D;
689}
690
693{
694 // use the nodes ids to obtain an unique key for the channel between a and b
695 // sort the nodes ids so that the key is reciprocal
696 uint32_t x1 = std::min(a->GetObject<Node>()->GetId(), b->GetObject<Node>()->GetId());
697 uint32_t x2 = std::max(a->GetObject<Node>()->GetId(), b->GetObject<Node>()->GetId());
698
699 // use the cantor function to obtain the key
700 uint32_t key = (((x1 + x2) * (x1 + x2 + 1)) / 2) + x2;
701
702 return key;
703}
704
705Vector
707{
708 uint32_t x1 = a->GetObject<Node>()->GetId();
709 uint32_t x2 = b->GetObject<Node>()->GetId();
710
711 if (x1 < x2)
712 {
713 return b->GetPosition() - a->GetPosition();
714 }
715 else
716 {
717 return a->GetPosition() - b->GetPosition();
718 }
719}
720
721// ------------------------------------------------------------------------- //
722
724
725TypeId
727{
728 static TypeId tid = TypeId("ns3::ThreeGppRmaPropagationLossModel")
730 .SetGroupName("Propagation")
731 .AddConstructor<ThreeGppRmaPropagationLossModel>()
732 .AddAttribute("AvgBuildingHeight",
733 "The average building height in meters.",
734 DoubleValue(5.0),
736 MakeDoubleChecker<double>(5.0, 50.0))
737 .AddAttribute("AvgStreetWidth",
738 "The average street width in meters.",
739 DoubleValue(20.0),
741 MakeDoubleChecker<double>(5.0, 50.0));
742 return tid;
743}
744
753
758
759double
761{
762 // distance2dIn is minimum of two independently generated uniformly distributed variables
763 // between 0 and 10 m for RMa. 2D−in d shall be UT-specifically generated.
764 return std::min(m_randomO2iVar1->GetValue(0, 10), m_randomO2iVar2->GetValue(0, 10));
765}
766
767bool
769 [[maybe_unused]]) const
770{
771 // Based on 3GPP 38.901 7.4.3.1 in RMa only low losses are applied.
772 // Therefore enforce low losses.
773 return true;
774}
775
776double
778{
779 NS_LOG_FUNCTION(this);
780 NS_ASSERT_MSG(m_frequency <= 30.0e9,
781 "RMa scenario is valid for frequencies between 0.5 and 30 GHz.");
782
783 auto [distance2D, distance3D, hBs, hUt] = GetBsUtDistancesAndHeights(a, b);
784
785 // check if hBS and hUT are within the specified validity range
786 if (hUt < 1.0 || hUt > 10.0)
787 {
788 NS_ABORT_MSG_IF(m_enforceRanges, "Rma UT height out of range");
790 "The height of the UT should be between 1 and 10 m (see TR 38.901, Table 7.4.1-1)");
791 }
792
793 if (hBs < 10.0 || hBs > 150.0)
794 {
795 NS_ABORT_MSG_IF(m_enforceRanges, "Rma BS height out of range");
797 "The height of the BS should be between 10 and 150 m (see TR 38.901, Table 7.4.1-1)");
798 }
799
800 // NOTE The model is intended to be used for BS-UT links, however we may need to
801 // compute the pathloss between two BSs or UTs, e.g., to evaluate the
802 // interference. In order to apply the model, we need to retrieve the values of
803 // hBS and hUT, but in these cases one of the two falls outside the validity
804 // range and the warning message is printed (hBS for the UT-UT case and hUT
805 // for the BS-BS case).
806
807 double distanceBp = GetBpDistance(m_frequency, hBs, hUt);
808 NS_LOG_DEBUG("breakpoint distance " << distanceBp);
810 distanceBp > 0,
811 "Breakpoint distance is zero (divide-by-zero below); are either hBs or hUt = 0?");
812
813 // check if the distance is outside the validity range
814 if (distance2D < 10.0 || distance2D > 10.0e3)
815 {
816 NS_ABORT_MSG_IF(m_enforceRanges, "Rma distance2D out of range");
817 NS_LOG_WARN("The 2D distance is outside the validity range, the pathloss value may not be "
818 "accurate");
819 }
820
821 // compute the pathloss (see 3GPP TR 38.901, Table 7.4.1-1)
822 double loss = 0;
823 if (distance2D <= distanceBp)
824 {
825 // use PL1
826 loss = Pl1(m_frequency, distance3D, m_h, m_w);
827 }
828 else
829 {
830 // use PL2
831 loss = Pl1(m_frequency, distanceBp, m_h, m_w) + 40 * log10(distance3D / distanceBp);
832 }
833
834 NS_LOG_DEBUG("Loss " << loss);
835
836 return loss;
837}
838
839double
841{
842 NS_LOG_FUNCTION(this);
843 NS_ASSERT_MSG(m_frequency <= 30.0e9,
844 "RMa scenario is valid for frequencies between 0.5 and 30 GHz.");
845
846 auto [distance2D, distance3D, hBs, hUt] = GetBsUtDistancesAndHeights(a, b);
847
848 // check if hBs and hUt are within the validity range
849 if (hUt < 1.0 || hUt > 10.0)
850 {
851 NS_ABORT_MSG_IF(m_enforceRanges, "Rma UT height out of range");
853 "The height of the UT should be between 1 and 10 m (see TR 38.901, Table 7.4.1-1)");
854 }
855
856 if (hBs < 10.0 || hBs > 150.0)
857 {
858 NS_ABORT_MSG_IF(m_enforceRanges, "Rma BS height out of range");
860 "The height of the BS should be between 10 and 150 m (see TR 38.901, Table 7.4.1-1)");
861 }
862
863 // NOTE The model is intended to be used for BS-UT links, however we may need to
864 // compute the pathloss between two BSs or UTs, e.g., to evaluate the
865 // interference. In order to apply the model, we need to retrieve the values of
866 // hBS and hUT, but in these cases one of the two falls outside the validity
867 // range and the warning message is printed (hBS for the UT-UT case and hUT
868 // for the BS-BS case).
869
870 // check if the distance is outside the validity range
871 if (distance2D < 10.0 || distance2D > 5.0e3)
872 {
873 NS_ABORT_MSG_IF(m_enforceRanges, "distance2D out of range");
874 NS_LOG_WARN("The 2D distance is outside the validity range, the pathloss value may not be "
875 "accurate");
876 }
877
878 // compute the pathloss
879 double plNlos = 161.04 - 7.1 * log10(m_w) + 7.5 * log10(m_h) -
880 (24.37 - 3.7 * pow((m_h / hBs), 2)) * log10(hBs) +
881 (43.42 - 3.1 * log10(hBs)) * (log10(distance3D) - 3.0) +
882 20.0 * log10(m_frequency / 1e9) - (3.2 * pow(log10(11.75 * hUt), 2) - 4.97);
883
884 double loss = std::max(GetLossLos(a, b), plNlos);
885
886 NS_LOG_DEBUG("Loss " << loss);
887
888 return loss;
889}
890
891double
895{
896 NS_LOG_FUNCTION(this);
897 double shadowingStd;
898
900 {
901 // compute the 2D distance between the two nodes
902 double distance2d = Calculate2dDistance(a->GetPosition(), b->GetPosition());
903
904 // compute the breakpoint distance (see 3GPP TR 38.901, Table 7.4.1-1, note 5)
905 double distanceBp = GetBpDistance(m_frequency, a->GetPosition().z, b->GetPosition().z);
906
907 if (distance2d <= distanceBp)
908 {
909 shadowingStd = 4.0;
910 }
911 else
912 {
913 shadowingStd = 6.0;
914 }
915 }
917 {
918 shadowingStd = 8.0;
919 }
920 else
921 {
922 NS_FATAL_ERROR("Unknown channel condition");
923 }
924
925 return shadowingStd;
926}
927
928double
931{
932 NS_LOG_FUNCTION(this);
933 double correlationDistance;
934
935 // See 3GPP TR 38.901, Table 7.5-6
937 {
938 correlationDistance = 37;
939 }
941 {
942 correlationDistance = 120;
943 }
944 else
945 {
946 NS_FATAL_ERROR("Unknown channel condition");
947 }
948
949 return correlationDistance;
950}
951
952double
953ThreeGppRmaPropagationLossModel::Pl1(double frequency, double distance3D, double h, double /* w */)
954{
955 double loss = 20.0 * log10(40.0 * M_PI * distance3D * frequency / 1e9 / 3.0) +
956 std::min(0.03 * pow(h, 1.72), 10.0) * log10(distance3D) -
957 std::min(0.044 * pow(h, 1.72), 14.77) + 0.002 * log10(h) * distance3D;
958 return loss;
959}
960
961double
962ThreeGppRmaPropagationLossModel::GetBpDistance(double frequency, double hA, double hB)
963{
964 double distanceBp = 2.0 * M_PI * hA * hB * frequency / M_C;
965 return distanceBp;
966}
967
968// ------------------------------------------------------------------------- //
969
971
972TypeId
974{
975 static TypeId tid = TypeId("ns3::ThreeGppUmaPropagationLossModel")
977 .SetGroupName("Propagation")
978 .AddConstructor<ThreeGppUmaPropagationLossModel>();
979 return tid;
980}
981
990
995
996double
997ThreeGppUmaPropagationLossModel::GetBpDistance(double hUt, double hBs, double distance2D) const
998{
999 NS_LOG_FUNCTION(this);
1000
1001 // compute g (d2D) (see 3GPP TR 38.901, Table 7.4.1-1, Note 1)
1002 double g = 0.0;
1003 if (distance2D > 18.0)
1004 {
1005 g = 5.0 / 4.0 * pow(distance2D / 100.0, 3) * exp(-distance2D / 150.0);
1006 }
1007
1008 // compute C (hUt, d2D) (see 3GPP TR 38.901, Table 7.4.1-1, Note 1)
1009 double c = 0.0;
1010 if (hUt >= 13.0)
1011 {
1012 c = pow((hUt - 13.0) / 10.0, 1.5) * g;
1013 }
1014
1015 // compute hE (see 3GPP TR 38.901, Table 7.4.1-1, Note 1)
1016 double prob = 1.0 / (1.0 + c);
1017 double hE = 0.0;
1018 if (m_uniformVar->GetValue() < prob)
1019 {
1020 hE = 1.0;
1021 }
1022 else
1023 {
1024 int random = m_uniformVar->GetInteger(12, std::max(12, (int)(hUt - 1.5)));
1025 hE = (double)floor(random / 3.0) * 3.0;
1026 }
1027
1028 // compute dBP' (see 3GPP TR 38.901, Table 7.4.1-1, Note 1)
1029 double distanceBp = 4 * (hBs - hE) * (hUt - hE) * m_frequency / M_C;
1030
1031 return distanceBp;
1032}
1033
1034double
1036{
1037 NS_LOG_FUNCTION(this);
1038
1039 auto [distance2D, distance3D, hBs, hUt] = GetBsUtDistancesAndHeights(a, b);
1040
1041 // check if hBS and hUT are within the validity range
1042 if (hUt < 1.5 || hUt > 22.5)
1043 {
1044 NS_ABORT_MSG_IF(m_enforceRanges, "Uma UT height out of range");
1046 "The height of the UT should be between 1.5 and 22.5 m (see TR 38.901, Table 7.4.1-1)");
1047 }
1048
1049 if (hBs != 25.0)
1050 {
1051 NS_ABORT_MSG_IF(m_enforceRanges, "Uma BS height out of range");
1052 NS_LOG_WARN("The height of the BS should be equal to 25 m (see TR 38.901, Table 7.4.1-1)");
1053 }
1054
1055 // NOTE The model is intended to be used for BS-UT links, however we may need to
1056 // compute the pathloss between two BSs or UTs, e.g., to evaluate the
1057 // interference. In order to apply the model, we need to retrieve the values of
1058 // hBS and hUT, but in these cases one of the two falls outside the validity
1059 // range and the warning message is printed (hBS for the UT-UT case and hUT
1060 // for the BS-BS case).
1061
1062 // compute the breakpoint distance (see 3GPP TR 38.901, Table 7.4.1-1, note 1)
1063 double distanceBp = GetBpDistance(hUt, hBs, distance2D);
1064 NS_LOG_DEBUG("breakpoint distance " << distanceBp);
1065
1066 // check if the distance is outside the validity range
1067 if (distance2D < 10.0 || distance2D > 5.0e3)
1068 {
1069 NS_ABORT_MSG_IF(m_enforceRanges, "Uma 2D distance out of range");
1070 NS_LOG_WARN("The 2D distance is outside the validity range, the pathloss value may not be "
1071 "accurate");
1072 }
1073
1074 // compute the pathloss (see 3GPP TR 38.901, Table 7.4.1-1)
1075 double loss = 0;
1076 if (distance2D <= distanceBp)
1077 {
1078 // use PL1
1079 loss = 28.0 + 22.0 * log10(distance3D) + 20.0 * log10(m_frequency / 1e9);
1080 }
1081 else
1082 {
1083 // use PL2
1084 loss = 28.0 + 40.0 * log10(distance3D) + 20.0 * log10(m_frequency / 1e9) -
1085 9.0 * log10(pow(distanceBp, 2) + pow(hBs - hUt, 2));
1086 }
1087
1088 NS_LOG_DEBUG("Loss " << loss);
1089
1090 return loss;
1091}
1092
1093double
1095{
1096 // distance2dIn is minimum of two independently generated uniformly distributed variables
1097 // between 0 and 25 m for UMa and UMi-Street Canyon. 2D−in d shall be UT-specifically generated.
1098 return std::min(m_randomO2iVar1->GetValue(0, 25), m_randomO2iVar2->GetValue(0, 25));
1099}
1100
1101double
1103{
1104 NS_LOG_FUNCTION(this);
1105
1106 auto [distance2D, distance3D, hBs, hUt] = GetBsUtDistancesAndHeights(a, b);
1107
1108 // check if hBS and hUT are within the validity range
1109 if (hUt < 1.5 || hUt > 22.5)
1110 {
1111 NS_ABORT_MSG_IF(m_enforceRanges, "Uma UT height out of range");
1113 "The height of the UT should be between 1.5 and 22.5 m (see TR 38.901, Table 7.4.1-1)");
1114 }
1115
1116 if (hBs != 25.0)
1117 {
1118 NS_ABORT_MSG_IF(m_enforceRanges, "Uma BS height out of range");
1119 NS_LOG_WARN("The height of the BS should be equal to 25 m (see TR 38.901, Table 7.4.1-1)");
1120 }
1121
1122 // NOTE The model is intended to be used for BS-UT links, however we may need to
1123 // compute the pathloss between two BSs or UTs, e.g., to evaluate the
1124 // interference. In order to apply the model, we need to retrieve the values of
1125 // hBS and hUT, but in these cases one of the two falls outside the validity
1126 // range and the warning message is printed (hBS for the UT-UT case and hUT
1127 // for the BS-BS case).
1128
1129 // check if the distance is outside the validity range
1130 if (distance2D < 10.0 || distance2D > 5.0e3)
1131 {
1132 NS_ABORT_MSG_IF(m_enforceRanges, "Uma 2D distance out of range");
1133 NS_LOG_WARN("The 2D distance is outside the validity range, the pathloss value may not be "
1134 "accurate");
1135 }
1136
1137 // compute the pathloss
1138 double plNlos =
1139 13.54 + 39.08 * log10(distance3D) + 20.0 * log10(m_frequency / 1e9) - 0.6 * (hUt - 1.5);
1140 double loss = std::max(GetLossLos(a, b), plNlos);
1141 NS_LOG_DEBUG("Loss " << loss);
1142
1143 return loss;
1144}
1145
1146double
1148 Ptr<MobilityModel> /* b */,
1150{
1151 NS_LOG_FUNCTION(this);
1152 double shadowingStd;
1153
1155 {
1156 shadowingStd = 4.0;
1157 }
1159 {
1160 shadowingStd = 6.0;
1161 }
1162 else
1163 {
1164 NS_FATAL_ERROR("Unknown channel condition");
1165 }
1166
1167 return shadowingStd;
1168}
1169
1170double
1173{
1174 NS_LOG_FUNCTION(this);
1175 double correlationDistance;
1176
1177 // See 3GPP TR 38.901, Table 7.5-6
1179 {
1180 correlationDistance = 37;
1181 }
1183 {
1184 correlationDistance = 50;
1185 }
1186 else
1187 {
1188 NS_FATAL_ERROR("Unknown channel condition");
1189 }
1190
1191 return correlationDistance;
1192}
1193
1194int64_t
1196{
1197 NS_LOG_FUNCTION(this);
1198
1199 m_normRandomVariable->SetStream(stream);
1200 m_uniformVar->SetStream(stream + 1);
1201 return 2;
1202}
1203
1204// ------------------------------------------------------------------------- //
1205
1207
1208TypeId
1210{
1211 static TypeId tid = TypeId("ns3::ThreeGppUmiStreetCanyonPropagationLossModel")
1213 .SetGroupName("Propagation")
1215 return tid;
1216}
1217
1226
1231
1232double
1234 double hBs,
1235 double /* distance2D */) const
1236{
1237 NS_LOG_FUNCTION(this);
1238
1239 // compute hE (see 3GPP TR 38.901, Table 7.4.1-1, Note 1)
1240 double hE = 1.0;
1241
1242 // compute dBP' (see 3GPP TR 38.901, Table 7.4.1-1, Note 1)
1243 double distanceBp = 4 * (hBs - hE) * (hUt - hE) * m_frequency / M_C;
1244
1245 return distanceBp;
1246}
1247
1248double
1250{
1251 // distance2dIn is minimum of two independently generated uniformly distributed variables
1252 // between 0 and 25 m for UMa and UMi-Street Canyon. 2D−in d shall be UT-specifically generated.
1253 return std::min(m_randomO2iVar1->GetValue(0, 25), m_randomO2iVar2->GetValue(0, 25));
1254}
1255
1256double
1258 Ptr<MobilityModel> b) const
1259{
1260 NS_LOG_FUNCTION(this);
1261
1262 double distance2D = Calculate2dDistance(a->GetPosition(), b->GetPosition());
1263 double distance3D = CalculateDistance(a->GetPosition(), b->GetPosition());
1264 auto [hBs, hUt] = GetBsUtHeightsUmiStreetCanyon(a->GetPosition().z, b->GetPosition().z);
1265
1266 // check if hBS and hUT are within the validity range
1267 if (hUt < 1.5 || hUt >= 10.0)
1268 {
1269 NS_ABORT_MSG_IF(m_enforceRanges, "UmiStreetCanyon UT height out of range");
1271 "The height of the UT should be between 1.5 and 22.5 m (see TR 38.901, Table 7.4.1-1). "
1272 "We further assume hUT < hBS, then hUT is upper bounded by hBS, which should be 10 m");
1273 }
1274
1275 if (hBs != 10.0)
1276 {
1277 NS_ABORT_MSG_IF(m_enforceRanges, "UmiStreetCanyon BS height out of range");
1278 NS_LOG_WARN("The height of the BS should be equal to 10 m (see TR 38.901, Table 7.4.1-1)");
1279 }
1280
1281 // NOTE The model is intended to be used for BS-UT links, however we may need to
1282 // compute the pathloss between two BSs or UTs, e.g., to evaluate the
1283 // interference. In order to apply the model, we need to retrieve the values of
1284 // hBS and hUT, but in these cases one of the two falls outside the validity
1285 // range and the warning message is printed (hBS for the UT-UT case and hUT
1286 // for the BS-BS case).
1287
1288 // compute the breakpoint distance (see 3GPP TR 38.901, Table 7.4.1-1, note 1)
1289 double distanceBp = GetBpDistance(hUt, hBs, distance2D);
1290 NS_LOG_DEBUG("breakpoint distance " << distanceBp);
1291
1292 // check if the distance is outside the validity range
1293 if (distance2D < 10.0 || distance2D > 5.0e3)
1294 {
1295 NS_ABORT_MSG_IF(m_enforceRanges, "UmiStreetCanyon 2D distance out of range");
1296 NS_LOG_WARN("The 2D distance is outside the validity range, the pathloss value may not be "
1297 "accurate");
1298 }
1299
1300 // compute the pathloss (see 3GPP TR 38.901, Table 7.4.1-1)
1301 double loss = 0;
1302 if (distance2D <= distanceBp)
1303 {
1304 // use PL1
1305 loss = 32.4 + 21.0 * log10(distance3D) + 20.0 * log10(m_frequency / 1e9);
1306 }
1307 else
1308 {
1309 // use PL2
1310 loss = 32.4 + 40.0 * log10(distance3D) + 20.0 * log10(m_frequency / 1e9) -
1311 9.5 * log10(pow(distanceBp, 2) + pow(hBs - hUt, 2));
1312 }
1313
1314 NS_LOG_DEBUG("Loss " << loss);
1315
1316 return loss;
1317}
1318
1319double
1321 Ptr<MobilityModel> b) const
1322{
1323 NS_LOG_FUNCTION(this);
1324
1325 double distance2D = Calculate2dDistance(a->GetPosition(), b->GetPosition());
1326 double distance3D = CalculateDistance(a->GetPosition(), b->GetPosition());
1327 auto [hBs, hUt] = GetBsUtHeightsUmiStreetCanyon(a->GetPosition().z, b->GetPosition().z);
1328
1329 // check if hBS and hUT are within the validity range
1330 if (hUt < 1.5 || hUt >= 10.0)
1331 {
1332 NS_ABORT_MSG_IF(m_enforceRanges, "UmiStreetCanyon UT height out of range");
1334 "The height of the UT should be between 1.5 and 22.5 m (see TR 38.901, Table 7.4.1-1). "
1335 "We further assume hUT < hBS, then hUT is upper bounded by hBS, which should be 10 m");
1336 }
1337
1338 if (hBs != 10.0)
1339 {
1340 NS_ABORT_MSG_IF(m_enforceRanges, "UmiStreetCanyon BS height out of range");
1341 NS_LOG_WARN("The height of the BS should be equal to 10 m (see TR 38.901, Table 7.4.1-1)");
1342 }
1343
1344 // NOTE The model is intended to be used for BS-UT links, however we may need to
1345 // compute the pathloss between two BSs or UTs, e.g., to evaluate the
1346 // interference. In order to apply the model, we need to retrieve the values of
1347 // hBS and hUT, but in these cases one of the two falls outside the validity
1348 // range and the warning message is printed (hBS for the UT-UT case and hUT
1349 // for the BS-BS case).
1350
1351 // check if the distance is outside the validity range
1352 if (distance2D < 10.0 || distance2D > 5.0e3)
1353 {
1354 NS_ABORT_MSG_IF(m_enforceRanges, "UmiStreetCanyon 2D distance out of range");
1355 NS_LOG_WARN("The 2D distance is outside the validity range, the pathloss value may not be "
1356 "accurate");
1357 }
1358
1359 // compute the pathloss
1360 double plNlos =
1361 22.4 + 35.3 * log10(distance3D) + 21.3 * log10(m_frequency / 1e9) - 0.3 * (hUt - 1.5);
1362 double loss = std::max(GetLossLos(a, b), plNlos);
1363 NS_LOG_DEBUG("Loss " << loss);
1364
1365 return loss;
1366}
1367
1368double
1370 Ptr<MobilityModel> /* a */,
1371 Ptr<MobilityModel> /* b */,
1373{
1374 NS_LOG_FUNCTION(this);
1375 double shadowingStd;
1376
1378 {
1379 shadowingStd = 4.0;
1380 }
1382 {
1383 shadowingStd = 7.82;
1384 }
1385 else
1386 {
1387 NS_FATAL_ERROR("Unknown channel condition");
1388 }
1389
1390 return shadowingStd;
1391}
1392
1393double
1396{
1397 NS_LOG_FUNCTION(this);
1398 double correlationDistance;
1399
1400 // See 3GPP TR 38.901, Table 7.5-6
1402 {
1403 correlationDistance = 10;
1404 }
1406 {
1407 correlationDistance = 13;
1408 }
1409 else
1410 {
1411 NS_FATAL_ERROR("Unknown channel condition");
1412 }
1413
1414 return correlationDistance;
1415}
1416
1417// ------------------------------------------------------------------------- //
1418
1420
1421TypeId
1423{
1424 static TypeId tid = TypeId("ns3::ThreeGppIndoorOfficePropagationLossModel")
1426 .SetGroupName("Propagation")
1428 return tid;
1429}
1430
1439
1444
1445double
1450
1451double
1453 Ptr<MobilityModel> b) const
1454{
1455 NS_LOG_FUNCTION(this);
1456
1457 double distance3D = CalculateDistance(a->GetPosition(), b->GetPosition());
1458
1459 // check if the distance is outside the validity range
1460 if (distance3D < 1.0 || distance3D > 150.0)
1461 {
1462 NS_ABORT_MSG_IF(m_enforceRanges, "IndoorOffice 3D distance out of range");
1463 NS_LOG_WARN("The 3D distance is outside the validity range, the pathloss value may not be "
1464 "accurate");
1465 }
1466
1467 // compute the pathloss (see 3GPP TR 38.901, Table 7.4.1-1)
1468 double loss = 32.4 + 17.3 * log10(distance3D) + 20.0 * log10(m_frequency / 1e9);
1469
1470 NS_LOG_DEBUG("Loss " << loss);
1471
1472 return loss;
1473}
1474
1475double
1477 Ptr<MobilityModel> b) const
1478{
1479 NS_LOG_FUNCTION(this);
1480
1481 double distance3D = CalculateDistance(a->GetPosition(), b->GetPosition());
1482
1483 // check if the distance is outside the validity range
1484 if (distance3D < 1.0 || distance3D > 150.0)
1485 {
1486 NS_ABORT_MSG_IF(m_enforceRanges, "IndoorOffice 3D distance out of range");
1487 NS_LOG_WARN("The 3D distance is outside the validity range, the pathloss value may not be "
1488 "accurate");
1489 }
1490
1491 // compute the pathloss
1492 double plNlos = 17.3 + 38.3 * log10(distance3D) + 24.9 * log10(m_frequency / 1e9);
1493 double loss = std::max(GetLossLos(a, b), plNlos);
1494
1495 NS_LOG_DEBUG("Loss " << loss);
1496
1497 return loss;
1498}
1499
1500double
1502 Ptr<MobilityModel> /* a */,
1503 Ptr<MobilityModel> /* b */,
1505{
1506 NS_LOG_FUNCTION(this);
1507 double shadowingStd;
1508
1510 {
1511 shadowingStd = 3.0;
1512 }
1514 {
1515 shadowingStd = 8.03;
1516 }
1517 else
1518 {
1519 NS_FATAL_ERROR("Unknown channel condition");
1520 }
1521
1522 return shadowingStd;
1523}
1524
1525double
1528{
1529 NS_LOG_FUNCTION(this);
1530
1531 // See 3GPP TR 38.901, Table 7.5-6
1532 double correlationDistance;
1533
1535 {
1536 correlationDistance = 10;
1537 }
1539 {
1540 correlationDistance = 6;
1541 }
1542 else
1543 {
1544 NS_FATAL_ERROR("Unknown channel condition");
1545 }
1546
1547 return correlationDistance;
1548}
1549
1551
1552TypeId
1554{
1555 static TypeId tid = TypeId("ns3::ThreeGppNTNDenseUrbanPropagationLossModel")
1557 .SetGroupName("Propagation")
1559 return tid;
1560}
1561
1569
1574
1575double
1580
1581double
1583 Ptr<MobilityModel> b) const
1584{
1585 NS_LOG_FUNCTION(this);
1586 NS_ASSERT_MSG(m_frequency <= 100.0e9,
1587 "NTN communications are valid for frequencies between 0.5 and 100 GHz.");
1588
1589 double distance3D = CalculateDistance(a->GetPosition(), b->GetPosition());
1590 auto [elevAngle, elevAngleQuantized] =
1592
1593 // compute the pathloss (see 3GPP TR 38.811, Table 6.6.2)
1594 double loss = ComputeNtnPathloss(m_frequency, distance3D);
1595
1596 // Apply Atmospheric Absorption Loss 3GPP 38.811 6.6.4
1597 loss += ComputeAtmosphericAbsorptionLoss(m_frequency, elevAngle);
1598
1599 // Apply Ionospheric plus Tropospheric Scintillation Loss
1600 loss += ComputeIonosphericPlusTroposphericScintillationLoss(m_frequency, elevAngleQuantized);
1601
1602 NS_LOG_DEBUG("Loss " << loss);
1603 return loss;
1604}
1605
1606double
1608 Ptr<MobilityModel> b) const
1609{
1610 NS_LOG_FUNCTION(this);
1611 NS_ASSERT_MSG(m_frequency <= 100.0e9,
1612 "NTN communications are valid for frequencies between 0.5 and 100 GHz.");
1613
1614 double distance3D = CalculateDistance(a->GetPosition(), b->GetPosition());
1615 auto [elevAngle, elevAngleQuantized] =
1617
1618 // compute the pathloss (see 3GPP TR 38.811, Table 6.6.2)
1619 double loss = ComputeNtnPathloss(m_frequency, distance3D);
1620
1621 // Apply Clutter Loss
1622 loss += ComputeClutterLoss(m_frequency, m_SFCL_DenseUrban, elevAngleQuantized);
1623
1624 // Apply Atmospheric Absorption Loss 3GPP 38.811 6.6.4
1625 loss += ComputeAtmosphericAbsorptionLoss(m_frequency, elevAngle);
1626
1627 // Apply Ionospheric plus Tropospheric Scintillation Loss
1628 loss += ComputeIonosphericPlusTroposphericScintillationLoss(m_frequency, elevAngleQuantized);
1629
1630 NS_LOG_DEBUG("Loss " << loss);
1631 return loss;
1632}
1633
1634double
1639{
1640 NS_LOG_FUNCTION(this);
1641 double shadowingStd;
1642
1643 std::string freqBand = (m_frequency < 13.0e9) ? "S" : "Ka";
1644 auto [elevAngle, elevAngleQuantized] =
1646
1647 // Assign Shadowing Standard Deviation according to table 6.6.2-1
1648 if (cond == ChannelCondition::LosConditionValue::LOS && freqBand == "S")
1649 {
1650 shadowingStd = (*m_SFCL_DenseUrban).at(elevAngleQuantized)[SFCL_params::S_LOS_sigF];
1651 }
1652 else if (cond == ChannelCondition::LosConditionValue::LOS && freqBand == "Ka")
1653 {
1654 shadowingStd = (*m_SFCL_DenseUrban).at(elevAngleQuantized)[SFCL_params::Ka_LOS_sigF];
1655 }
1656 else if (cond == ChannelCondition::LosConditionValue::NLOS && freqBand == "S")
1657 {
1658 shadowingStd = (*m_SFCL_DenseUrban).at(elevAngleQuantized)[SFCL_params::S_NLOS_sigF];
1659 }
1660 else if (cond == ChannelCondition::LosConditionValue::NLOS && freqBand == "Ka")
1661 {
1662 shadowingStd = (*m_SFCL_DenseUrban).at(elevAngleQuantized)[SFCL_params::Ka_NLOS_sigF];
1663 }
1664 else
1665 {
1666 NS_FATAL_ERROR("Unknown channel condition");
1667 }
1668
1669 return shadowingStd;
1670}
1671
1672double
1675{
1676 NS_LOG_FUNCTION(this);
1677 double correlationDistance;
1678
1679 // See 3GPP TR 38.811, Table 6.7.2-1a/b and Table 6.7.2-2a/b
1681 {
1682 correlationDistance = 37;
1683 }
1685 {
1686 correlationDistance = 50;
1687 }
1688 else
1689 {
1690 NS_FATAL_ERROR("Unknown channel condition");
1691 }
1692
1693 return correlationDistance;
1694}
1695
1696// ------------------------------------------------------------------------- //
1697
1699
1700TypeId
1702{
1703 static TypeId tid = TypeId("ns3::ThreeGppNTNUrbanPropagationLossModel")
1705 .SetGroupName("Propagation")
1706 .AddConstructor<ThreeGppNTNUrbanPropagationLossModel>();
1707 return tid;
1708}
1709
1717
1722
1723double
1728
1729double
1731{
1732 NS_LOG_FUNCTION(this);
1733 NS_ASSERT_MSG(m_frequency <= 100.0e9,
1734 "NTN communications are valid for frequencies between 0.5 and 100 GHz.");
1735
1736 double distance3D = CalculateDistance(a->GetPosition(), b->GetPosition());
1737 auto [elevAngle, elevAngleQuantized] =
1739
1740 // compute the pathloss (see 3GPP TR 38.811, Table 6.6.2)
1741 double loss = ComputeNtnPathloss(m_frequency, distance3D);
1742
1743 // Apply Atmospheric Absorption Loss 3GPP 38.811 6.6.4
1744 loss += ComputeAtmosphericAbsorptionLoss(m_frequency, elevAngle);
1745
1746 // Apply Ionospheric plus Tropospheric Scintillation Loss
1747 loss += ComputeIonosphericPlusTroposphericScintillationLoss(m_frequency, elevAngleQuantized);
1748
1749 NS_LOG_DEBUG("Loss " << loss);
1750 return loss;
1751}
1752
1753double
1755{
1756 NS_LOG_FUNCTION(this);
1757 NS_ASSERT_MSG(m_frequency <= 100.0e9,
1758 "NTN communications are valid for frequencies between 0.5 and 100 GHz.");
1759
1760 double distance3D = CalculateDistance(a->GetPosition(), b->GetPosition());
1761 auto [elevAngle, elevAngleQuantized] =
1763
1764 // compute the pathloss (see 3GPP TR 38.811, Table 6.6.2)
1765 double loss = ComputeNtnPathloss(m_frequency, distance3D);
1766
1767 // Apply Clutter Loss
1768 loss += ComputeClutterLoss(m_frequency, m_SFCL_Urban, elevAngleQuantized);
1769
1770 // Apply Atmospheric Absorption Loss 3GPP 38.811 6.6.4
1771 loss += ComputeAtmosphericAbsorptionLoss(m_frequency, elevAngle);
1772
1773 // Apply Ionospheric plus Tropospheric Scintillation Loss
1774 loss += ComputeIonosphericPlusTroposphericScintillationLoss(m_frequency, elevAngleQuantized);
1775
1776 NS_LOG_DEBUG("Loss " << loss);
1777 return loss;
1778}
1779
1780double
1785{
1786 NS_LOG_FUNCTION(this);
1787 double shadowingStd;
1788
1789 std::string freqBand = (m_frequency < 13.0e9) ? "S" : "Ka";
1790 auto [elevAngle, elevAngleQuantized] =
1792
1793 // Assign Shadowing Standard Deviation according to table 6.6.2-1
1794 if (cond == ChannelCondition::LosConditionValue::LOS && freqBand == "S")
1795 {
1796 shadowingStd = (*m_SFCL_Urban).at(elevAngleQuantized)[SFCL_params::S_LOS_sigF];
1797 }
1798 else if (cond == ChannelCondition::LosConditionValue::LOS && freqBand == "Ka")
1799 {
1800 shadowingStd = (*m_SFCL_Urban).at(elevAngleQuantized)[SFCL_params::Ka_LOS_sigF];
1801 }
1802 else if (cond == ChannelCondition::LosConditionValue::NLOS && freqBand == "S")
1803 {
1804 shadowingStd = (*m_SFCL_Urban).at(elevAngleQuantized)[SFCL_params::S_NLOS_sigF];
1805 }
1806 else if (cond == ChannelCondition::LosConditionValue::NLOS && freqBand == "Ka")
1807 {
1808 shadowingStd = (*m_SFCL_Urban).at(elevAngleQuantized)[SFCL_params::Ka_NLOS_sigF];
1809 }
1810 else
1811 {
1812 NS_FATAL_ERROR("Unknown channel condition");
1813 }
1814
1815 return shadowingStd;
1816}
1817
1818double
1821{
1822 NS_LOG_FUNCTION(this);
1823 double correlationDistance;
1824
1825 // See 3GPP TR 38.811, Table 6.7.2-3a/b and Table 6.7.2-3a/b
1827 {
1828 correlationDistance = 37;
1829 }
1831 {
1832 correlationDistance = 50;
1833 }
1834 else
1835 {
1836 NS_FATAL_ERROR("Unknown channel condition");
1837 }
1838
1839 return correlationDistance;
1840}
1841
1842// ------------------------------------------------------------------------- //
1843
1845
1846TypeId
1848{
1849 static TypeId tid = TypeId("ns3::ThreeGppNTNSuburbanPropagationLossModel")
1851 .SetGroupName("Propagation")
1852 .AddConstructor<ThreeGppNTNSuburbanPropagationLossModel>();
1853 return tid;
1854}
1855
1863
1868
1869double
1874
1875double
1877 Ptr<MobilityModel> b) const
1878{
1879 NS_LOG_FUNCTION(this);
1880 NS_ASSERT_MSG(m_frequency <= 100.0e9,
1881 "NTN communications are valid for frequencies between 0.5 and 100 GHz.");
1882
1883 double distance3D = CalculateDistance(a->GetPosition(), b->GetPosition());
1884 auto [elevAngle, elevAngleQuantized] =
1886
1887 // compute the pathloss (see 3GPP TR 38.811, Table 6.6.2)
1888 double loss = ComputeNtnPathloss(m_frequency, distance3D);
1889
1890 // Apply Atmospheric Absorption Loss 3GPP 38.811 6.6.4
1891 loss += ComputeAtmosphericAbsorptionLoss(m_frequency, elevAngle);
1892
1893 // Apply Ionospheric plus Tropospheric Scintillation Loss
1894 loss += ComputeIonosphericPlusTroposphericScintillationLoss(m_frequency, elevAngleQuantized);
1895
1896 NS_LOG_DEBUG("Loss " << loss);
1897
1898 return loss;
1899}
1900
1901double
1903 Ptr<MobilityModel> b) const
1904{
1905 NS_LOG_FUNCTION(this);
1906 NS_ASSERT_MSG(m_frequency <= 100.0e9,
1907 "NTN communications are valid for frequencies between 0.5 and 100 GHz.");
1908
1909 double distance3D = CalculateDistance(a->GetPosition(), b->GetPosition());
1910 auto [elevAngle, elevAngleQuantized] =
1912
1913 // compute the pathloss (see 3GPP TR 38.811, Table 6.6.2)
1914 double loss = ComputeNtnPathloss(m_frequency, distance3D);
1915
1916 // Apply Clutter Loss
1917 loss += ComputeClutterLoss(m_frequency, m_SFCL_SuburbanRural, elevAngleQuantized);
1918
1919 // Apply Atmospheric Absorption Loss 3GPP 38.811 6.6.4
1920 loss += ComputeAtmosphericAbsorptionLoss(m_frequency, elevAngle);
1921
1922 // Apply Ionospheric plus Tropospheric Scintillation Loss
1923 loss += ComputeIonosphericPlusTroposphericScintillationLoss(m_frequency, elevAngleQuantized);
1924
1925 NS_LOG_DEBUG("Loss " << loss);
1926 return loss;
1927}
1928
1929double
1934{
1935 NS_LOG_FUNCTION(this);
1936 double shadowingStd;
1937
1938 std::string freqBand = (m_frequency < 13.0e9) ? "S" : "Ka";
1939 auto [elevAngle, elevAngleQuantized] =
1941
1942 // Assign Shadowing Standard Deviation according to table 6.6.2-1
1943 if (cond == ChannelCondition::LosConditionValue::LOS && freqBand == "S")
1944 {
1945 shadowingStd = (*m_SFCL_SuburbanRural).at(elevAngleQuantized)[SFCL_params::S_LOS_sigF];
1946 }
1947 else if (cond == ChannelCondition::LosConditionValue::LOS && freqBand == "Ka")
1948 {
1949 shadowingStd = (*m_SFCL_SuburbanRural).at(elevAngleQuantized)[SFCL_params::Ka_LOS_sigF];
1950 }
1951 else if (cond == ChannelCondition::LosConditionValue::NLOS && freqBand == "S")
1952 {
1953 shadowingStd = (*m_SFCL_SuburbanRural).at(elevAngleQuantized)[SFCL_params::S_NLOS_sigF];
1954 }
1955 else if (cond == ChannelCondition::LosConditionValue::NLOS && freqBand == "Ka")
1956 {
1957 shadowingStd = (*m_SFCL_SuburbanRural).at(elevAngleQuantized)[SFCL_params::Ka_NLOS_sigF];
1958 }
1959 else
1960 {
1961 NS_FATAL_ERROR("Unknown channel condition");
1962 }
1963
1964 return shadowingStd;
1965}
1966
1967double
1970{
1971 NS_LOG_FUNCTION(this);
1972 double correlationDistance;
1973
1974 // See 3GPP TR 38.811, Table 6.7.2-5a/b and Table 6.7.2-6a/b
1976 {
1977 correlationDistance = 37;
1978 }
1980 {
1981 correlationDistance = 50;
1982 }
1983 else
1984 {
1985 NS_FATAL_ERROR("Unknown channel condition");
1986 }
1987
1988 return correlationDistance;
1989}
1990
1991// ------------------------------------------------------------------------- //
1992
1994
1995TypeId
1997{
1998 static TypeId tid = TypeId("ns3::ThreeGppNTNRuralPropagationLossModel")
2000 .SetGroupName("Propagation")
2001 .AddConstructor<ThreeGppNTNRuralPropagationLossModel>();
2002 return tid;
2003}
2004
2012
2017
2018double
2023
2024double
2026{
2027 NS_LOG_FUNCTION(this);
2028 NS_ASSERT_MSG(m_frequency <= 100.0e9,
2029 "NTN communications are valid for frequencies between 0.5 and 100 GHz.");
2030
2031 double distance3D = CalculateDistance(a->GetPosition(), b->GetPosition());
2032 auto [elevAngle, elevAngleQuantized] =
2034
2035 // compute the pathloss (see 3GPP TR 38.811, Table 6.6.2)
2036 double loss = ComputeNtnPathloss(m_frequency, distance3D);
2037
2038 // Apply Atmospheric Absorption Loss 3GPP 38.811 6.6.4
2039 loss += ComputeAtmosphericAbsorptionLoss(m_frequency, elevAngle);
2040
2041 // Apply Ionospheric plus Tropospheric Scintillation Loss
2042 loss += ComputeIonosphericPlusTroposphericScintillationLoss(m_frequency, elevAngleQuantized);
2043
2044 NS_LOG_DEBUG("Loss " << loss);
2045 return loss;
2046}
2047
2048double
2050{
2051 NS_LOG_FUNCTION(this);
2052 NS_ASSERT_MSG(m_frequency <= 100.0e9,
2053 "NTN communications are valid for frequencies between 0.5 and 100 GHz.");
2054
2055 double distance3D = CalculateDistance(a->GetPosition(), b->GetPosition());
2056 auto [elevAngle, elevAngleQuantized] =
2058
2059 // compute the pathloss (see 3GPP TR 38.811, Table 6.6.2)
2060 double loss = ComputeNtnPathloss(m_frequency, distance3D);
2061
2062 // Apply Clutter Loss
2063 loss += ComputeClutterLoss(m_frequency, m_SFCL_SuburbanRural, elevAngleQuantized);
2064
2065 // Apply Atmospheric Absorption Loss 3GPP 38.811 6.6.4
2066 loss += ComputeAtmosphericAbsorptionLoss(m_frequency, elevAngle);
2067
2068 // Apply Ionospheric plus Tropospheric Scintillation Loss
2069 loss += ComputeIonosphericPlusTroposphericScintillationLoss(m_frequency, elevAngleQuantized);
2070
2071 NS_LOG_DEBUG("Loss " << loss);
2072 return loss;
2073}
2074
2075double
2080{
2081 NS_LOG_FUNCTION(this);
2082 double shadowingStd;
2083
2084 std::string freqBand = (m_frequency < 13.0e9) ? "S" : "Ka";
2085 auto [elevAngle, elevAngleQuantized] =
2087
2088 // Assign Shadowing Standard Deviation according to table 6.6.2-1
2089 if (cond == ChannelCondition::LosConditionValue::LOS && freqBand == "S")
2090 {
2091 shadowingStd = (*m_SFCL_SuburbanRural).at(elevAngleQuantized)[SFCL_params::S_LOS_sigF];
2092 }
2093 else if (cond == ChannelCondition::LosConditionValue::LOS && freqBand == "Ka")
2094 {
2095 shadowingStd = (*m_SFCL_SuburbanRural).at(elevAngleQuantized)[SFCL_params::Ka_LOS_sigF];
2096 }
2097 else if (cond == ChannelCondition::LosConditionValue::NLOS && freqBand == "S")
2098 {
2099 shadowingStd = (*m_SFCL_SuburbanRural).at(elevAngleQuantized)[SFCL_params::S_NLOS_sigF];
2100 }
2101 else if (cond == ChannelCondition::LosConditionValue::NLOS && freqBand == "Ka")
2102 {
2103 shadowingStd = (*m_SFCL_SuburbanRural).at(elevAngleQuantized)[SFCL_params::Ka_NLOS_sigF];
2104 }
2105 else
2106 {
2107 NS_FATAL_ERROR("Unknown channel condition");
2108 }
2109
2110 return shadowingStd;
2111}
2112
2113double
2116{
2117 NS_LOG_FUNCTION(this);
2118 double correlationDistance;
2119
2120 // See 3GPP TR 38.811, Table 6.7.2-7a/b and Table 6.7.2-8a/b
2122 {
2123 correlationDistance = 37;
2124 }
2126 {
2127 correlationDistance = 120;
2128 }
2129 else
2130 {
2131 NS_FATAL_ERROR("Unknown channel condition");
2132 }
2133
2134 return correlationDistance;
2135}
2136
2137} // namespace ns3
@ LOW
Low Penetration Losses.
@ HIGH
High Penetration Losses.
LosConditionValue
Possible values for Line-of-Sight condition.
@ NLOSv
Non Line of Sight due to a vehicle.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
A network Node.
Definition node.h:46
uint32_t GetId() const
Definition node.cc:106
AttributeValue implementation for Pointer.
Models the propagation loss through a transmission medium.
Smart pointer class similar to boost::intrusive_ptr.
static double Calculate2dDistance(const Vector &a, const Vector &b)
Computes the 2D distance between two 3D vectors.
static std::tuple< double, double > GetQuantizedElevationAngle(Ptr< const MobilityModel > a, Ptr< const MobilityModel > b)
Computes and quantizes the elevation angle to a two-digits integer in [10, 90].
Implements the pathloss model defined in 3GPP TR 38.901, Table 7.4.1-1 for the Indoor Office scenario...
double GetShadowingCorrelationDistance(ChannelCondition::LosConditionValue cond) const override
Returns the shadow fading correlation distance.
double GetShadowingStd(Ptr< MobilityModel > a, Ptr< MobilityModel > b, ChannelCondition::LosConditionValue cond) const override
Returns the shadow fading standard deviation.
double GetO2iDistance2dIn() const override
Returns the minimum of the two independently generated distances according to the uniform distributio...
double GetLossNlos(Ptr< MobilityModel > a, Ptr< MobilityModel > b) const override
Computes the pathloss between a and b considering that the line of sight is obstructed.
double GetLossLos(Ptr< MobilityModel > a, Ptr< MobilityModel > b) const override
Computes the pathloss between a and b considering that the line of sight is not obstructed.
Implements the pathloss model defined in 3GPP TR 38.811, Table ???? for the NTN Dense Urban scenario.
double GetShadowingStd(Ptr< MobilityModel > a, Ptr< MobilityModel > b, ChannelCondition::LosConditionValue cond) const override
Returns the shadow fading standard deviation.
double GetO2iDistance2dIn() const override
Returns the minimum of the two independently generated distances according to the uniform distributio...
double GetLossLos(Ptr< MobilityModel > a, Ptr< MobilityModel > b) const override
Computes the pathloss between a and b considering that the line of sight is not obstructed.
const std::map< int, std::vector< float > > * m_SFCL_DenseUrban
The nested map containing the Shadow Fading and Clutter Loss values for the NTN Dense Urban scenario.
double GetShadowingCorrelationDistance(ChannelCondition::LosConditionValue cond) const override
Returns the shadow fading correlation distance.
double GetLossNlos(Ptr< MobilityModel > a, Ptr< MobilityModel > b) const override
Computes the pathloss between a and b considering that the line of sight is obstructed.
Implements the pathloss model defined in 3GPP TR 38.811, Table ???? for the NTN Rural scenario.
const std::map< int, std::vector< float > > * m_SFCL_SuburbanRural
The nested map containing the Shadow Fading and Clutter Loss values for the NTN Suburban and Rural sc...
double GetO2iDistance2dIn() const override
Returns the minimum of the two independently generated distances according to the uniform distributio...
double GetLossNlos(Ptr< MobilityModel > a, Ptr< MobilityModel > b) const override
Computes the pathloss between a and b considering that the line of sight is obstructed.
double GetShadowingCorrelationDistance(ChannelCondition::LosConditionValue cond) const override
Returns the shadow fading correlation distance.
double GetShadowingStd(Ptr< MobilityModel > a, Ptr< MobilityModel > b, ChannelCondition::LosConditionValue cond) const override
Returns the shadow fading standard deviation.
double GetLossLos(Ptr< MobilityModel > a, Ptr< MobilityModel > b) const override
Computes the pathloss between a and b considering that the line of sight is not obstructed.
Implements the pathloss model defined in 3GPP TR 38.811, Table ???? for the NTN Suburban scenario.
double GetShadowingCorrelationDistance(ChannelCondition::LosConditionValue cond) const override
Returns the shadow fading correlation distance.
const std::map< int, std::vector< float > > * m_SFCL_SuburbanRural
The nested map containing the Shadow Fading and Clutter Loss values for the NTN Suburban and Rural sc...
double GetO2iDistance2dIn() const override
Returns the minimum of the two independently generated distances according to the uniform distributio...
double GetShadowingStd(Ptr< MobilityModel > a, Ptr< MobilityModel > b, ChannelCondition::LosConditionValue cond) const override
Returns the shadow fading standard deviation.
double GetLossLos(Ptr< MobilityModel > a, Ptr< MobilityModel > b) const override
Computes the pathloss between a and b considering that the line of sight is not obstructed.
double GetLossNlos(Ptr< MobilityModel > a, Ptr< MobilityModel > b) const override
Computes the pathloss between a and b considering that the line of sight is obstructed.
Implements the pathloss model defined in 3GPP TR 38.811, Table ???? for the NTN Urban scenario.
double GetLossNlos(Ptr< MobilityModel > a, Ptr< MobilityModel > b) const override
Computes the pathloss between a and b considering that the line of sight is obstructed.
const std::map< int, std::vector< float > > * m_SFCL_Urban
The nested map containing the Shadow Fading and Clutter Loss values for the NTN Urban scenario.
double GetShadowingCorrelationDistance(ChannelCondition::LosConditionValue cond) const override
Returns the shadow fading correlation distance.
double GetLossLos(Ptr< MobilityModel > a, Ptr< MobilityModel > b) const override
Computes the pathloss between a and b considering that the line of sight is not obstructed.
double GetO2iDistance2dIn() const override
Returns the minimum of the two independently generated distances according to the uniform distributio...
double GetShadowingStd(Ptr< MobilityModel > a, Ptr< MobilityModel > b, ChannelCondition::LosConditionValue cond) const override
Returns the shadow fading standard deviation.
Base class for the 3GPP propagation models.
Ptr< ChannelConditionModel > GetChannelConditionModel() const
Returns the associated channel condition model.
virtual double GetO2iLowPenetrationLoss(Ptr< MobilityModel > a, Ptr< MobilityModel > b, ChannelCondition::LosConditionValue cond) const
Retrieves the o2i building penetration loss value by looking at m_o2iLossMap.
Ptr< UniformRandomVariable > m_randomO2iVar2
a uniform random variable for the calculation of the indoor loss, see TR38.901 Table 7....
double GetFrequency() const
Return the current central frequency.
double GetLoss(Ptr< ChannelCondition > cond, Ptr< MobilityModel > a, Ptr< MobilityModel > b) const
Computes the pathloss between a and b.
Ptr< UniformRandomVariable > m_randomO2iVar1
a uniform random variable for the calculation of the indoor loss, see TR38.901 Table 7....
double GetShadowing(Ptr< MobilityModel > a, Ptr< MobilityModel > b, ChannelCondition::LosConditionValue cond) const
Retrieves the shadowing value by looking at m_shadowingMap.
static double Calculate2dDistance(Vector a, Vector b)
Computes the 2D distance between two 3D vectors.
void SetChannelConditionModel(Ptr< ChannelConditionModel > model)
Set the channel condition model used to determine the channel state (e.g., the LOS/NLOS condition)
std::unordered_map< uint32_t, ShadowingMapItem > m_shadowingMap
map to store the shadowing values
virtual double GetLossNlos(Ptr< MobilityModel > a, Ptr< MobilityModel > b) const =0
Computes the pathloss between a and b considering that the line of sight is obstructed.
virtual bool DoIsO2iLowPenetrationLoss(Ptr< const ChannelCondition > cond) const
Indicates the condition of the o2i building penetration loss (defined in 3GPP TR 38....
int64_t DoAssignStreams(int64_t stream) override
Assign a fixed random variable stream number to the random variables used by this model.
virtual double GetLossNlosv(Ptr< MobilityModel > a, Ptr< MobilityModel > b) const
Computes the pathloss between a and b considering that the line of sight is obstructed by a vehicle.
virtual double GetShadowingCorrelationDistance(ChannelCondition::LosConditionValue cond) const =0
Returns the shadow fading correlation distance.
Ptr< NormalRandomVariable > m_normRandomVariable
normal random variable
Ptr< ChannelConditionModel > m_channelConditionModel
pointer to the channel condition model
std::unordered_map< uint32_t, O2iLossMapItem > m_o2iLossMap
map to store the o2i Loss values
virtual double GetO2iDistance2dIn() const =0
Returns the minimum of the two independently generated distances according to the uniform distributio...
virtual double GetO2iHighPenetrationLoss(Ptr< MobilityModel > a, Ptr< MobilityModel > b, ChannelCondition::LosConditionValue cond) const
Retrieves the o2i building penetration loss value by looking at m_o2iLossMap.
bool IsO2iLowPenetrationLoss(Ptr< const ChannelCondition > cond) const
Return true if the O2I Building Penetration loss corresponds to a low loss condition.
void SetFrequency(double f)
Set the central frequency of the model.
void DoDispose() override
Destructor implementation.
static uint32_t GetKey(Ptr< MobilityModel > a, Ptr< MobilityModel > b)
Returns an unique key for the channel between a and b.
Ptr< NormalRandomVariable > m_normalO2iLowLossVar
a normal random variable for the calculation of 02i low loss, see TR38.901 Table 7....
bool m_enforceRanges
strictly enforce TR 38.901 parameter ranges
virtual double GetShadowingStd(Ptr< MobilityModel > a, Ptr< MobilityModel > b, ChannelCondition::LosConditionValue cond) const =0
Returns the shadow fading standard deviation.
Ptr< NormalRandomVariable > m_normalO2iHighLossVar
a normal random variable for the calculation of 02i high loss, see TR38.901 Table 7....
double DoCalcRxPower(double txPowerDbm, Ptr< MobilityModel > a, Ptr< MobilityModel > b) const override
Computes the received power by applying the pathloss model described in 3GPP TR 38....
static Vector GetVectorDifference(Ptr< MobilityModel > a, Ptr< MobilityModel > b)
Get the difference between the node position.
bool m_buildingPenLossesEnabled
enable/disable building penetration losses
virtual double GetLossLos(Ptr< MobilityModel > a, Ptr< MobilityModel > b) const =0
Computes the pathloss between a and b considering that the line of sight is not obstructed.
Implements the pathloss model defined in 3GPP TR 38.901, Table 7.4.1-1 for the RMa scenario.
double GetLossNlos(Ptr< MobilityModel > a, Ptr< MobilityModel > b) const override
Computes the pathloss between a and b considering that the line of sight is obstructed.
double GetShadowingStd(Ptr< MobilityModel > a, Ptr< MobilityModel > b, ChannelCondition::LosConditionValue cond) const override
Returns the shadow fading standard deviation.
static double Pl1(double frequency, double distance3D, double h, double w)
Computes the PL1 formula for the RMa scenario.
double GetLossLos(Ptr< MobilityModel > a, Ptr< MobilityModel > b) const override
Computes the pathloss between a and b considering that the line of sight is not obstructed.
double GetO2iDistance2dIn() const override
Returns the minimum of the two independently generated distances according to the uniform distributio...
double GetShadowingCorrelationDistance(ChannelCondition::LosConditionValue cond) const override
Returns the shadow fading correlation distance.
double m_h
average building height in meters
static double GetBpDistance(double frequency, double hA, double hB)
Computes the breakpoint distance for the RMa scenario.
bool DoIsO2iLowPenetrationLoss(Ptr< const ChannelCondition > cond) const override
Indicates the condition of the o2i building penetration loss (defined in 3GPP TR 38....
Implements the pathloss model defined in 3GPP TR 38.901, Table 7.4.1-1 for the UMa scenario.
double GetLossNlos(Ptr< MobilityModel > a, Ptr< MobilityModel > b) const override
Computes the pathloss between a and b considering that the line of sight is obstructed.
double GetBpDistance(double hUt, double hBs, double distance2D) const
Computes the breakpoint distance.
int64_t DoAssignStreams(int64_t stream) override
Assign a fixed random variable stream number to the random variables used by this model.
double GetLossLos(Ptr< MobilityModel > a, Ptr< MobilityModel > b) const override
Computes the pathloss between a and b considering that the line of sight is not obstructed.
double GetO2iDistance2dIn() const override
Returns the minimum of the two independently generated distances according to the uniform distributio...
Ptr< UniformRandomVariable > m_uniformVar
a uniform random variable used for the computation of the breakpoint distance
double GetShadowingStd(Ptr< MobilityModel > a, Ptr< MobilityModel > b, ChannelCondition::LosConditionValue cond) const override
Returns the shadow fading standard deviation.
double GetShadowingCorrelationDistance(ChannelCondition::LosConditionValue cond) const override
Returns the shadow fading correlation distance.
Implements the pathloss model defined in 3GPP TR 38.901, Table 7.4.1-1 for the UMi-Street Canyon scen...
double GetLossNlos(Ptr< MobilityModel > a, Ptr< MobilityModel > b) const override
Computes the pathloss between a and b considering that the line of sight is obstructed.
double GetShadowingStd(Ptr< MobilityModel > a, Ptr< MobilityModel > b, ChannelCondition::LosConditionValue cond) const override
Returns the shadow fading standard deviation.
double GetBpDistance(double hUt, double hBs, double distance2D) const
Computes the breakpoint distance.
double GetO2iDistance2dIn() const override
Returns the minimum of the two independently generated distances according to the uniform distributio...
double GetLossLos(Ptr< MobilityModel > a, Ptr< MobilityModel > b) const override
Computes the pathloss between a and b considering that the line of sight is not obstructed.
double GetShadowingCorrelationDistance(ChannelCondition::LosConditionValue cond) const override
Returns the shadow fading correlation distance.
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
a 2d vector
Definition vector.h:196
double GetLength() const
Compute the length (magnitude) of the vector.
Definition vector.cc:77
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition pointer.h:248
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:269
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition abort.h:133
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition log.h:250
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
const std::map< int, std::vector< float > > SFCL_SuburbanRural
The map containing the 3GPP value regarding Shadow Fading and Clutter Loss tables for the NTN Suburba...
double ComputeIonosphericPlusTroposphericScintillationLoss(double freq, double elevAngleQuantized)
Computes the ionospheric plus tropospheric scintillation loss using the formulas described in 3GPP TR...
std::tuple< double, double, double, double > GetBsUtDistancesAndHeights(ns3::Ptr< const ns3::MobilityModel > a, ns3::Ptr< const ns3::MobilityModel > b)
Get the base station and user terminal relative distances and heights.
double ComputeAtmosphericAbsorptionLoss(double freq, double elevAngle)
Computes the atmospheric absorption loss using the formula described in 3GPP TR 38....
double ComputeNtnPathloss(double freq, double dist3d)
Computes the free-space path loss using the formula described in 3GPP TR 38.811, Table 6....
const double atmosphericAbsorption[101]
Array containing the attenuation given by atmospheric absorption.
const std::map< int, float > troposphericScintillationLoss
Map containing the Tropospheric attenuation in dB with 99% probability at 20 GHz in Toulouse used for...
const std::map< int, std::vector< float > > SFCL_Urban
The map containing the 3GPP value regarding Shadow Fading and Clutter Loss tables for the NTN Urban s...
double ComputeClutterLoss(double freq, const std::map< int, std::vector< float > > *sfcl, double elevAngleQuantized)
Computes the clutter loss using the formula described in 3GPP TR 38.811, Sec 6.6.6....
SFCL_params
The enumerator used for code clarity when performing parameter assignment in the GetLoss Methods.
std::tuple< double, double > GetBsUtHeightsUmiStreetCanyon(double heightA, double heightB)
Get the base station and user terminal heights for the UmiStreetCanyon scenario.
const std::map< int, std::vector< float > > SFCL_DenseUrban
The map containing the 3GPP value regarding Shadow Fading and Clutter Loss tables for the NTN Dense U...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition boolean.cc:113
Ptr< const AttributeChecker > MakeDoubleChecker()
Definition double.h:82
double CalculateDistance(const Vector3D &a, const Vector3D &b)
Definition vector.cc:98
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition boolean.h:70
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition double.h:32