A Discrete-Event Network Simulator
API
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 * 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
20
21#include "ns3/boolean.h"
22#include "ns3/channel-condition-model.h"
23#include "ns3/double.h"
24#include "ns3/log.h"
25#include "ns3/mobility-model.h"
26#include "ns3/node.h"
27#include "ns3/pointer.h"
28#include "ns3/simulator.h"
29
30#include <cmath>
31
32namespace ns3
33{
34
35NS_LOG_COMPONENT_DEFINE("ThreeGppPropagationLossModel");
36
37static const double M_C = 3.0e8;
38
39// ------------------------------------------------------------------------- //
40
42
45{
46 static TypeId tid =
47 TypeId("ns3::ThreeGppPropagationLossModel")
49 .SetGroupName("Propagation")
50 .AddAttribute("Frequency",
51 "The centre frequency in Hz.",
52 DoubleValue(500.0e6),
55 MakeDoubleChecker<double>())
56 .AddAttribute("ShadowingEnabled",
57 "Enable/disable shadowing.",
58 BooleanValue(true),
61 .AddAttribute(
62 "ChannelConditionModel",
63 "Pointer to the channel condition model.",
67 MakePointerChecker<ChannelConditionModel>())
68 .AddAttribute("EnforceParameterRanges",
69 "Whether to strictly enforce TR38.901 applicability ranges",
70 BooleanValue(false),
73 .AddAttribute(
74 "BuildingPenetrationLossesEnabled",
75 "Enable/disable Building Penetration Losses.",
76 BooleanValue(true),
79 return tid;
80}
81
84{
85 NS_LOG_FUNCTION(this);
86
87 // initialize the normal random variables
88 m_normRandomVariable = CreateObject<NormalRandomVariable>();
89 m_normRandomVariable->SetAttribute("Mean", DoubleValue(0));
90 m_normRandomVariable->SetAttribute("Variance", DoubleValue(1));
91
92 m_randomO2iVar1 = CreateObject<UniformRandomVariable>();
93 m_randomO2iVar2 = CreateObject<UniformRandomVariable>();
94
95 m_normalO2iLowLossVar = CreateObject<NormalRandomVariable>();
96 m_normalO2iLowLossVar->SetAttribute("Mean", DoubleValue(0));
97 m_normalO2iLowLossVar->SetAttribute("Variance", DoubleValue(4.4));
98
99 m_normalO2iHighLossVar = CreateObject<NormalRandomVariable>();
100 m_normalO2iHighLossVar->SetAttribute("Mean", DoubleValue(0));
101 m_normalO2iHighLossVar->SetAttribute("Variance", DoubleValue(6.5));
102}
103
105{
106 NS_LOG_FUNCTION(this);
107}
108
109void
111{
112 m_channelConditionModel->Dispose();
113 m_channelConditionModel = nullptr;
114 m_shadowingMap.clear();
115}
116
117void
119{
120 NS_LOG_FUNCTION(this);
122}
123
126{
127 NS_LOG_FUNCTION(this);
129}
130
131void
133{
134 NS_LOG_FUNCTION(this);
135 NS_ASSERT_MSG(f >= 500.0e6 && f <= 100.0e9,
136 "Frequency should be between 0.5 and 100 GHz but is " << f);
137 m_frequency = f;
138}
139
140double
142{
143 NS_LOG_FUNCTION(this);
144 return m_frequency;
145}
146
147double
150 Ptr<MobilityModel> b) const
151{
152 NS_LOG_FUNCTION(this);
153
154 // check if the model is initialized
155 NS_ASSERT_MSG(m_frequency != 0.0, "First set the centre frequency");
156
157 // retrieve the channel condition
158 NS_ASSERT_MSG(m_channelConditionModel, "First set the channel condition model");
159 Ptr<ChannelCondition> cond = m_channelConditionModel->GetChannelCondition(a, b);
160
161 // compute the 2D distance between a and b
162 double distance2d = Calculate2dDistance(a->GetPosition(), b->GetPosition());
163
164 // compute the 3D distance between a and b
165 double distance3d = CalculateDistance(a->GetPosition(), b->GetPosition());
166
167 // compute hUT and hBS
168 std::pair<double, double> heights = GetUtAndBsHeights(a->GetPosition().z, b->GetPosition().z);
169
170 double rxPow = txPowerDbm;
171 rxPow -= GetLoss(cond, distance2d, distance3d, heights.first, heights.second);
172
174 {
175 rxPow -= GetShadowing(a, b, cond->GetLosCondition());
176 }
177
178 // get o2i losses
179 if (cond->GetO2iCondition() == ChannelCondition::O2iConditionValue::O2I &&
181 {
182 if (cond->GetO2iLowHighCondition() == ChannelCondition::O2iLowHighConditionValue::LOW)
183 {
184 rxPow -= GetO2iLowPenetrationLoss(a, b, cond->GetLosCondition());
185 }
186 else if (cond->GetO2iLowHighCondition() == ChannelCondition::O2iLowHighConditionValue::HIGH)
187 {
188 rxPow -= GetO2iHighPenetrationLoss(a, b, cond->GetLosCondition());
189 }
190 else
191 {
192 NS_ABORT_MSG("If we have set the O2I condition, we shouldn't be here");
193 }
194 }
195
196 return rxPow;
197}
198
199double
201 double distance2d,
202 double distance3d,
203 double hUt,
204 double hBs) const
205{
206 NS_LOG_FUNCTION(this);
207
208 double loss = 0;
209 if (cond->GetLosCondition() == ChannelCondition::LosConditionValue::LOS)
210 {
211 loss = GetLossLos(distance2d, distance3d, hUt, hBs);
212 }
213 else if (cond->GetLosCondition() == ChannelCondition::LosConditionValue::NLOSv)
214 {
215 loss = GetLossNlosv(distance2d, distance3d, hUt, hBs);
216 }
217 else if (cond->GetLosCondition() == ChannelCondition::LosConditionValue::NLOS)
218 {
219 loss = GetLossNlos(distance2d, distance3d, hUt, hBs);
220 }
221 else
222 {
223 NS_FATAL_ERROR("Unknown channel condition");
224 }
225
226 return loss;
227}
228
229double
234{
235 NS_LOG_FUNCTION(this);
236
237 double o2iLossValue = 0;
238 double lowLossTw = 0;
239 double lossIn = 0;
240 double lowlossNormalVariate = 0;
241 double lGlass = 0;
242 double lConcrete = 0;
243
244 // compute the channel key
245 uint32_t key = GetKey(a, b);
246
247 bool notFound = false; // indicates if the o2iLoss value has not been computed yet
248 bool newCondition = false; // indicates if the channel condition has changed
249
250 auto it = m_o2iLossMap.end(); // the o2iLoss map iterator
251 if (m_o2iLossMap.find(key) != m_o2iLossMap.end())
252 {
253 // found the o2iLoss value in the map
254 it = m_o2iLossMap.find(key);
255 newCondition = (it->second.m_condition != cond); // true if the condition changed
256 }
257 else
258 {
259 notFound = true;
260 // add a new entry in the map and update the iterator
261 O2iLossMapItem newItem;
262 it = m_o2iLossMap.insert(it, std::make_pair(key, newItem));
263 }
264
265 if (notFound || newCondition)
266 {
267 // distance2dIn is minimum of two independently generated uniformly distributed
268 // variables between 0 and 25 m for UMa and UMi-Street Canyon, and between 0 and
269 // 10 m for RMa. 2D−in d shall be UT-specifically generated.
270 double distance2dIn = GetO2iDistance2dIn();
271
272 // calculate material penetration losses, see TR 38.901 Table 7.4.3-1
273 lGlass = 2 + 0.2 * m_frequency / 1e9; // m_frequency is operation frequency in Hz
274 lConcrete = 5 + 4 * m_frequency / 1e9;
275
276 lowLossTw =
277 5 - 10 * log10(0.3 * std::pow(10, -lGlass / 10) + 0.7 * std::pow(10, -lConcrete / 10));
278
279 // calculate indoor loss
280 lossIn = 0.5 * distance2dIn;
281
282 // calculate low loss standard deviation
283 lowlossNormalVariate = m_normalO2iLowLossVar->GetValue();
284
285 o2iLossValue = lowLossTw + lossIn + lowlossNormalVariate;
286 }
287 else
288 {
289 o2iLossValue = it->second.m_o2iLoss;
290 }
291
292 // update the entry in the map
293 it->second.m_o2iLoss = o2iLossValue;
294 it->second.m_condition = cond;
295
296 return o2iLossValue;
297}
298
299double
304{
305 NS_LOG_FUNCTION(this);
306
307 double o2iLossValue = 0;
308 double highLossTw = 0;
309 double lossIn = 0;
310 double highlossNormalVariate = 0;
311 double lIIRGlass = 0;
312 double lConcrete = 0;
313
314 // compute the channel key
315 uint32_t key = GetKey(a, b);
316
317 bool notFound = false; // indicates if the o2iLoss value has not been computed yet
318 bool newCondition = false; // indicates if the channel condition has changed
319
320 auto it = m_o2iLossMap.end(); // the o2iLoss map iterator
321 if (m_o2iLossMap.find(key) != m_o2iLossMap.end())
322 {
323 // found the o2iLoss value in the map
324 it = m_o2iLossMap.find(key);
325 newCondition = (it->second.m_condition != cond); // true if the condition changed
326 }
327 else
328 {
329 notFound = true;
330 // add a new entry in the map and update the iterator
331 O2iLossMapItem newItem;
332 it = m_o2iLossMap.insert(it, std::make_pair(key, newItem));
333 }
334
335 if (notFound || newCondition)
336 {
337 // generate a new independent realization
338
339 // distance2dIn is minimum of two independently generated uniformly distributed
340 // variables between 0 and 25 m for UMa and UMi-Street Canyon, and between 0 and
341 // 10 m for RMa. 2D−in d shall be UT-specifically generated.
342 double distance2dIn = GetO2iDistance2dIn();
343
344 // calculate material penetration losses, see TR 38.901 Table 7.4.3-1
345 lIIRGlass = 23 + 0.3 * m_frequency / 1e9;
346 lConcrete = 5 + 4 * m_frequency / 1e9;
347
348 highLossTw = 5 - 10 * log10(0.7 * std::pow(10, -lIIRGlass / 10) +
349 0.3 * std::pow(10, -lConcrete / 10));
350
351 // calculate indoor loss
352 lossIn = 0.5 * distance2dIn;
353
354 // calculate low loss standard deviation
355 highlossNormalVariate = m_normalO2iHighLossVar->GetValue();
356
357 o2iLossValue = highLossTw + lossIn + highlossNormalVariate;
358 }
359 else
360 {
361 o2iLossValue = it->second.m_o2iLoss;
362 }
363
364 // update the entry in the map
365 it->second.m_o2iLoss = o2iLossValue;
366 it->second.m_condition = cond;
367
368 return o2iLossValue;
369}
370
371double
373 double distance3D,
374 double hUt,
375 double hBs) const
376{
377 NS_LOG_FUNCTION(this);
378 NS_FATAL_ERROR("Unsupported channel condition (NLOSv)");
379 return 0;
380}
381
382double
386{
387 NS_LOG_FUNCTION(this);
388
389 double shadowingValue;
390
391 // compute the channel key
392 uint32_t key = GetKey(a, b);
393
394 bool notFound = false; // indicates if the shadowing value has not been computed yet
395 bool newCondition = false; // indicates if the channel condition has changed
396 Vector newDistance; // the distance vector, that is not a distance but a difference
397 auto it = m_shadowingMap.end(); // the shadowing map iterator
398 if (m_shadowingMap.find(key) != m_shadowingMap.end())
399 {
400 // found the shadowing value in the map
401 it = m_shadowingMap.find(key);
402 newDistance = GetVectorDifference(a, b);
403 newCondition = (it->second.m_condition != cond); // true if the condition changed
404 }
405 else
406 {
407 notFound = true;
408
409 // add a new entry in the map and update the iterator
410 ShadowingMapItem newItem;
411 it = m_shadowingMap.insert(it, std::make_pair(key, newItem));
412 }
413
414 if (notFound || newCondition)
415 {
416 // generate a new independent realization
417 shadowingValue = m_normRandomVariable->GetValue() * GetShadowingStd(a, b, cond);
418 }
419 else
420 {
421 // compute a new correlated shadowing loss
422 Vector2D displacement(newDistance.x - it->second.m_distance.x,
423 newDistance.y - it->second.m_distance.y);
424 double R = exp(-1 * displacement.GetLength() / GetShadowingCorrelationDistance(cond));
425 shadowingValue = R * it->second.m_shadowing + sqrt(1 - R * R) *
426 m_normRandomVariable->GetValue() *
427 GetShadowingStd(a, b, cond);
428 }
429
430 // update the entry in the map
431 it->second.m_shadowing = shadowingValue;
432 it->second.m_distance = newDistance; // Save the (0,0,0) vector in case it's the first time we
433 // are calculating this value
434 it->second.m_condition = cond;
435
436 return shadowingValue;
437}
438
439std::pair<double, double>
441{
442 // The default implementation assumes that the tallest node is the BS and the
443 // smallest is the UT.
444 double hUt = std::min(za, zb);
445 double hBs = std::max(za, zb);
446
447 return std::pair<double, double>(hUt, hBs);
448}
449
450int64_t
452{
453 NS_LOG_FUNCTION(this);
454
455 m_normRandomVariable->SetStream(stream);
456 m_randomO2iVar1->SetStream(stream + 1);
457 m_randomO2iVar2->SetStream(stream + 2);
458 m_normalO2iLowLossVar->SetStream(stream + 3);
459 m_normalO2iHighLossVar->SetStream(stream + 4);
460
461 return 5;
462}
463
464double
466{
467 double x = a.x - b.x;
468 double y = a.y - b.y;
469 double distance2D = sqrt(x * x + y * y);
470
471 return distance2D;
472}
473
476{
477 // use the nodes ids to obtain an unique key for the channel between a and b
478 // sort the nodes ids so that the key is reciprocal
479 uint32_t x1 = std::min(a->GetObject<Node>()->GetId(), b->GetObject<Node>()->GetId());
480 uint32_t x2 = std::max(a->GetObject<Node>()->GetId(), b->GetObject<Node>()->GetId());
481
482 // use the cantor function to obtain the key
483 uint32_t key = (((x1 + x2) * (x1 + x2 + 1)) / 2) + x2;
484
485 return key;
486}
487
488Vector
490{
491 uint32_t x1 = a->GetObject<Node>()->GetId();
492 uint32_t x2 = b->GetObject<Node>()->GetId();
493
494 if (x1 < x2)
495 {
496 return b->GetPosition() - a->GetPosition();
497 }
498 else
499 {
500 return a->GetPosition() - b->GetPosition();
501 }
502}
503
504// ------------------------------------------------------------------------- //
505
507
508TypeId
510{
511 static TypeId tid = TypeId("ns3::ThreeGppRmaPropagationLossModel")
513 .SetGroupName("Propagation")
514 .AddConstructor<ThreeGppRmaPropagationLossModel>()
515 .AddAttribute("AvgBuildingHeight",
516 "The average building height in meters.",
517 DoubleValue(5.0),
519 MakeDoubleChecker<double>(5.0, 50.0))
520 .AddAttribute("AvgStreetWidth",
521 "The average street width in meters.",
522 DoubleValue(20.0),
524 MakeDoubleChecker<double>(5.0, 50.0));
525 return tid;
526}
527
530{
531 NS_LOG_FUNCTION(this);
532
533 // set a default channel condition model
534 m_channelConditionModel = CreateObject<ThreeGppRmaChannelConditionModel>();
535}
536
538{
539 NS_LOG_FUNCTION(this);
540}
541
542double
544{
545 // distance2dIn is minimum of two independently generated uniformly distributed variables
546 // between 0 and 10 m for RMa. 2D−in d shall be UT-specifically generated.
548}
549
550double
552 double distance3D,
553 double hUt,
554 double hBs) const
555{
556 NS_LOG_FUNCTION(this);
557 NS_ASSERT_MSG(m_frequency <= 30.0e9,
558 "RMa scenario is valid for frequencies between 0.5 and 30 GHz.");
559
560 // check if hBS and hUT are within the specified validity range
561 if (hUt < 1.0 || hUt > 10.0)
562 {
563 NS_ABORT_MSG_IF(m_enforceRanges, "Rma UT height out of range");
565 "The height of the UT should be between 1 and 10 m (see TR 38.901, Table 7.4.1-1)");
566 }
567
568 if (hBs < 10.0 || hBs > 150.0)
569 {
570 NS_ABORT_MSG_IF(m_enforceRanges, "Rma BS height out of range");
572 "The height of the BS should be between 10 and 150 m (see TR 38.901, Table 7.4.1-1)");
573 }
574
575 // NOTE The model is intended to be used for BS-UT links, however we may need to
576 // compute the pathloss between two BSs or UTs, e.g., to evaluate the
577 // interference. In order to apply the model, we need to retrieve the values of
578 // hBS and hUT, but in these cases one of the two falls outside the validity
579 // range and the warning message is printed (hBS for the UT-UT case and hUT
580 // for the BS-BS case).
581
582 double distanceBp = GetBpDistance(m_frequency, hBs, hUt);
583 NS_LOG_DEBUG("breakpoint distance " << distanceBp);
585 distanceBp > 0,
586 "Breakpoint distance is zero (divide-by-zero below); are either hBs or hUt = 0?");
587
588 // check if the distance is outside the validity range
589 if (distance2D < 10.0 || distance2D > 10.0e3)
590 {
591 NS_ABORT_MSG_IF(m_enforceRanges, "Rma distance2D out of range");
592 NS_LOG_WARN("The 2D distance is outside the validity range, the pathloss value may not be "
593 "accurate");
594 }
595
596 // compute the pathloss (see 3GPP TR 38.901, Table 7.4.1-1)
597 double loss = 0;
598 if (distance2D <= distanceBp)
599 {
600 // use PL1
601 loss = Pl1(m_frequency, distance3D, m_h, m_w);
602 }
603 else
604 {
605 // use PL2
606 loss = Pl1(m_frequency, distanceBp, m_h, m_w) + 40 * log10(distance3D / distanceBp);
607 }
608
609 NS_LOG_DEBUG("Loss " << loss);
610
611 return loss;
612}
613
614double
616 double distance3D,
617 double hUt,
618 double hBs) const
619{
620 NS_LOG_FUNCTION(this);
621 NS_ASSERT_MSG(m_frequency <= 30.0e9,
622 "RMa scenario is valid for frequencies between 0.5 and 30 GHz.");
623
624 // check if hBs and hUt are within the validity range
625 if (hUt < 1.0 || hUt > 10.0)
626 {
627 NS_ABORT_MSG_IF(m_enforceRanges, "Rma UT height out of range");
629 "The height of the UT should be between 1 and 10 m (see TR 38.901, Table 7.4.1-1)");
630 }
631
632 if (hBs < 10.0 || hBs > 150.0)
633 {
634 NS_ABORT_MSG_IF(m_enforceRanges, "Rma BS height out of range");
636 "The height of the BS should be between 10 and 150 m (see TR 38.901, Table 7.4.1-1)");
637 }
638
639 // NOTE The model is intended to be used for BS-UT links, however we may need to
640 // compute the pathloss between two BSs or UTs, e.g., to evaluate the
641 // interference. In order to apply the model, we need to retrieve the values of
642 // hBS and hUT, but in these cases one of the two falls outside the validity
643 // range and the warning message is printed (hBS for the UT-UT case and hUT
644 // for the BS-BS case).
645
646 // check if the distance is outside the validity range
647 if (distance2D < 10.0 || distance2D > 5.0e3)
648 {
649 NS_ABORT_MSG_IF(m_enforceRanges, "distance2D out of range");
650 NS_LOG_WARN("The 2D distance is outside the validity range, the pathloss value may not be "
651 "accurate");
652 }
653
654 // compute the pathloss
655 double plNlos = 161.04 - 7.1 * log10(m_w) + 7.5 * log10(m_h) -
656 (24.37 - 3.7 * pow((m_h / hBs), 2)) * log10(hBs) +
657 (43.42 - 3.1 * log10(hBs)) * (log10(distance3D) - 3.0) +
658 20.0 * log10(m_frequency / 1e9) - (3.2 * pow(log10(11.75 * hUt), 2) - 4.97);
659
660 double loss = std::max(GetLossLos(distance2D, distance3D, hUt, hBs), plNlos);
661
662 NS_LOG_DEBUG("Loss " << loss);
663
664 return loss;
665}
666
667double
671{
672 NS_LOG_FUNCTION(this);
673 double shadowingStd;
674
675 if (cond == ChannelCondition::LosConditionValue::LOS)
676 {
677 // compute the 2D distance between the two nodes
678 double distance2d = Calculate2dDistance(a->GetPosition(), b->GetPosition());
679
680 // compute the breakpoint distance (see 3GPP TR 38.901, Table 7.4.1-1, note 5)
681 double distanceBp = GetBpDistance(m_frequency, a->GetPosition().z, b->GetPosition().z);
682
683 if (distance2d <= distanceBp)
684 {
685 shadowingStd = 4.0;
686 }
687 else
688 {
689 shadowingStd = 6.0;
690 }
691 }
692 else if (cond == ChannelCondition::LosConditionValue::NLOS)
693 {
694 shadowingStd = 8.0;
695 }
696 else
697 {
698 NS_FATAL_ERROR("Unknown channel condition");
699 }
700
701 return shadowingStd;
702}
703
704double
707{
708 NS_LOG_FUNCTION(this);
709 double correlationDistance;
710
711 // See 3GPP TR 38.901, Table 7.5-6
712 if (cond == ChannelCondition::LosConditionValue::LOS)
713 {
714 correlationDistance = 37;
715 }
716 else if (cond == ChannelCondition::LosConditionValue::NLOS)
717 {
718 correlationDistance = 120;
719 }
720 else
721 {
722 NS_FATAL_ERROR("Unknown channel condition");
723 }
724
725 return correlationDistance;
726}
727
728double
729ThreeGppRmaPropagationLossModel::Pl1(double frequency, double distance3D, double h, double /* w */)
730{
731 double loss = 20.0 * log10(40.0 * M_PI * distance3D * frequency / 1e9 / 3.0) +
732 std::min(0.03 * pow(h, 1.72), 10.0) * log10(distance3D) -
733 std::min(0.044 * pow(h, 1.72), 14.77) + 0.002 * log10(h) * distance3D;
734 return loss;
735}
736
737double
738ThreeGppRmaPropagationLossModel::GetBpDistance(double frequency, double hA, double hB)
739{
740 double distanceBp = 2.0 * M_PI * hA * hB * frequency / M_C;
741 return distanceBp;
742}
743
744// ------------------------------------------------------------------------- //
745
747
748TypeId
750{
751 static TypeId tid = TypeId("ns3::ThreeGppUmaPropagationLossModel")
753 .SetGroupName("Propagation")
754 .AddConstructor<ThreeGppUmaPropagationLossModel>();
755 return tid;
756}
757
760{
761 NS_LOG_FUNCTION(this);
762 m_uniformVar = CreateObject<UniformRandomVariable>();
763 // set a default channel condition model
764 m_channelConditionModel = CreateObject<ThreeGppUmaChannelConditionModel>();
765}
766
768{
769 NS_LOG_FUNCTION(this);
770}
771
772double
773ThreeGppUmaPropagationLossModel::GetBpDistance(double hUt, double hBs, double distance2D) const
774{
775 NS_LOG_FUNCTION(this);
776
777 // compute g (d2D) (see 3GPP TR 38.901, Table 7.4.1-1, Note 1)
778 double g = 0.0;
779 if (distance2D > 18.0)
780 {
781 g = 5.0 / 4.0 * pow(distance2D / 100.0, 3) * exp(-distance2D / 150.0);
782 }
783
784 // compute C (hUt, d2D) (see 3GPP TR 38.901, Table 7.4.1-1, Note 1)
785 double c = 0.0;
786 if (hUt >= 13.0)
787 {
788 c = pow((hUt - 13.0) / 10.0, 1.5) * g;
789 }
790
791 // compute hE (see 3GPP TR 38.901, Table 7.4.1-1, Note 1)
792 double prob = 1.0 / (1.0 + c);
793 double hE = 0.0;
794 if (m_uniformVar->GetValue() < prob)
795 {
796 hE = 1.0;
797 }
798 else
799 {
800 int random = m_uniformVar->GetInteger(12, std::max(12, (int)(hUt - 1.5)));
801 hE = (double)floor(random / 3.0) * 3.0;
802 }
803
804 // compute dBP' (see 3GPP TR 38.901, Table 7.4.1-1, Note 1)
805 double distanceBp = 4 * (hBs - hE) * (hUt - hE) * m_frequency / M_C;
806
807 return distanceBp;
808}
809
810double
812 double distance3D,
813 double hUt,
814 double hBs) const
815{
816 NS_LOG_FUNCTION(this);
817
818 // check if hBS and hUT are within the validity range
819 if (hUt < 1.5 || hUt > 22.5)
820 {
821 NS_ABORT_MSG_IF(m_enforceRanges, "Uma UT height out of range");
823 "The height of the UT should be between 1.5 and 22.5 m (see TR 38.901, Table 7.4.1-1)");
824 }
825
826 if (hBs != 25.0)
827 {
828 NS_ABORT_MSG_IF(m_enforceRanges, "Uma BS height out of range");
829 NS_LOG_WARN("The height of the BS should be equal to 25 m (see TR 38.901, Table 7.4.1-1)");
830 }
831
832 // NOTE The model is intended to be used for BS-UT links, however we may need to
833 // compute the pathloss between two BSs or UTs, e.g., to evaluate the
834 // interference. In order to apply the model, we need to retrieve the values of
835 // hBS and hUT, but in these cases one of the two falls outside the validity
836 // range and the warning message is printed (hBS for the UT-UT case and hUT
837 // for the BS-BS case).
838
839 // compute the breakpoint distance (see 3GPP TR 38.901, Table 7.4.1-1, note 1)
840 double distanceBp = GetBpDistance(hUt, hBs, distance2D);
841 NS_LOG_DEBUG("breakpoint distance " << distanceBp);
842
843 // check if the distance is outside the validity range
844 if (distance2D < 10.0 || distance2D > 5.0e3)
845 {
846 NS_ABORT_MSG_IF(m_enforceRanges, "Uma 2D distance out of range");
847 NS_LOG_WARN("The 2D distance is outside the validity range, the pathloss value may not be "
848 "accurate");
849 }
850
851 // compute the pathloss (see 3GPP TR 38.901, Table 7.4.1-1)
852 double loss = 0;
853 if (distance2D <= distanceBp)
854 {
855 // use PL1
856 loss = 28.0 + 22.0 * log10(distance3D) + 20.0 * log10(m_frequency / 1e9);
857 }
858 else
859 {
860 // use PL2
861 loss = 28.0 + 40.0 * log10(distance3D) + 20.0 * log10(m_frequency / 1e9) -
862 9.0 * log10(pow(distanceBp, 2) + pow(hBs - hUt, 2));
863 }
864
865 NS_LOG_DEBUG("Loss " << loss);
866
867 return loss;
868}
869
870double
872{
873 // distance2dIn is minimum of two independently generated uniformly distributed variables
874 // between 0 and 25 m for UMa and UMi-Street Canyon. 2D−in d shall be UT-specifically generated.
876}
877
878double
880 double distance3D,
881 double hUt,
882 double hBs) const
883{
884 NS_LOG_FUNCTION(this);
885
886 // check if hBS and hUT are within the vaalidity range
887 if (hUt < 1.5 || hUt > 22.5)
888 {
889 NS_ABORT_MSG_IF(m_enforceRanges, "Uma UT height out of range");
891 "The height of the UT should be between 1.5 and 22.5 m (see TR 38.901, Table 7.4.1-1)");
892 }
893
894 if (hBs != 25.0)
895 {
896 NS_ABORT_MSG_IF(m_enforceRanges, "Uma BS height out of range");
897 NS_LOG_WARN("The height of the BS should be equal to 25 m (see TR 38.901, Table 7.4.1-1)");
898 }
899
900 // NOTE The model is intended to be used for BS-UT links, however we may need to
901 // compute the pathloss between two BSs or UTs, e.g., to evaluate the
902 // interference. In order to apply the model, we need to retrieve the values of
903 // hBS and hUT, but in these cases one of the two falls outside the validity
904 // range and the warning message is printed (hBS for the UT-UT case and hUT
905 // for the BS-BS case).
906
907 // check if the distance is outside the validity range
908 if (distance2D < 10.0 || distance2D > 5.0e3)
909 {
910 NS_ABORT_MSG_IF(m_enforceRanges, "Uma 2D distance out of range");
911 NS_LOG_WARN("The 2D distance is outside the validity range, the pathloss value may not be "
912 "accurate");
913 }
914
915 // compute the pathloss
916 double plNlos =
917 13.54 + 39.08 * log10(distance3D) + 20.0 * log10(m_frequency / 1e9) - 0.6 * (hUt - 1.5);
918 double loss = std::max(GetLossLos(distance2D, distance3D, hUt, hBs), plNlos);
919 NS_LOG_DEBUG("Loss " << loss);
920
921 return loss;
922}
923
924double
926 Ptr<MobilityModel> /* b */,
928{
929 NS_LOG_FUNCTION(this);
930 double shadowingStd;
931
932 if (cond == ChannelCondition::LosConditionValue::LOS)
933 {
934 shadowingStd = 4.0;
935 }
936 else if (cond == ChannelCondition::LosConditionValue::NLOS)
937 {
938 shadowingStd = 6.0;
939 }
940 else
941 {
942 NS_FATAL_ERROR("Unknown channel condition");
943 }
944
945 return shadowingStd;
946}
947
948double
951{
952 NS_LOG_FUNCTION(this);
953 double correlationDistance;
954
955 // See 3GPP TR 38.901, Table 7.5-6
956 if (cond == ChannelCondition::LosConditionValue::LOS)
957 {
958 correlationDistance = 37;
959 }
960 else if (cond == ChannelCondition::LosConditionValue::NLOS)
961 {
962 correlationDistance = 50;
963 }
964 else
965 {
966 NS_FATAL_ERROR("Unknown channel condition");
967 }
968
969 return correlationDistance;
970}
971
972int64_t
974{
975 NS_LOG_FUNCTION(this);
976
977 m_normRandomVariable->SetStream(stream);
978 m_uniformVar->SetStream(stream + 1);
979 return 2;
980}
981
982// ------------------------------------------------------------------------- //
983
985
986TypeId
988{
989 static TypeId tid = TypeId("ns3::ThreeGppUmiStreetCanyonPropagationLossModel")
991 .SetGroupName("Propagation")
993 return tid;
994}
995
998{
999 NS_LOG_FUNCTION(this);
1000
1001 // set a default channel condition model
1002 m_channelConditionModel = CreateObject<ThreeGppUmiStreetCanyonChannelConditionModel>();
1003}
1004
1006{
1007 NS_LOG_FUNCTION(this);
1008}
1009
1010double
1012 double hBs,
1013 double /* distance2D */) const
1014{
1015 NS_LOG_FUNCTION(this);
1016
1017 // compute hE (see 3GPP TR 38.901, Table 7.4.1-1, Note 1)
1018 double hE = 1.0;
1019
1020 // compute dBP' (see 3GPP TR 38.901, Table 7.4.1-1, Note 1)
1021 double distanceBp = 4 * (hBs - hE) * (hUt - hE) * m_frequency / M_C;
1022
1023 return distanceBp;
1024}
1025
1026double
1028{
1029 // distance2dIn is minimum of two independently generated uniformly distributed variables
1030 // between 0 and 25 m for UMa and UMi-Street Canyon. 2D−in d shall be UT-specifically generated.
1031 return std::min(m_randomO2iVar1->GetValue(0, 25), m_randomO2iVar2->GetValue(0, 25));
1032}
1033
1034double
1036 double distance3D,
1037 double hUt,
1038 double hBs) const
1039{
1040 NS_LOG_FUNCTION(this);
1041
1042 // check if hBS and hUT are within the validity range
1043 if (hUt < 1.5 || hUt >= 10.0)
1044 {
1045 NS_ABORT_MSG_IF(m_enforceRanges, "UmiStreetCanyon UT height out of range");
1047 "The height of the UT should be between 1.5 and 22.5 m (see TR 38.901, Table 7.4.1-1). "
1048 "We further assume hUT < hBS, then hUT is upper bounded by hBS, which should be 10 m");
1049 }
1050
1051 if (hBs != 10.0)
1052 {
1053 NS_ABORT_MSG_IF(m_enforceRanges, "UmiStreetCanyon BS height out of range");
1054 NS_LOG_WARN("The height of the BS should be equal to 10 m (see TR 38.901, Table 7.4.1-1)");
1055 }
1056
1057 // NOTE The model is intended to be used for BS-UT links, however we may need to
1058 // compute the pathloss between two BSs or UTs, e.g., to evaluate the
1059 // interference. In order to apply the model, we need to retrieve the values of
1060 // hBS and hUT, but in these cases one of the two falls outside the validity
1061 // range and the warning message is printed (hBS for the UT-UT case and hUT
1062 // for the BS-BS case).
1063
1064 // compute the breakpoint distance (see 3GPP TR 38.901, Table 7.4.1-1, note 1)
1065 double distanceBp = GetBpDistance(hUt, hBs, distance2D);
1066 NS_LOG_DEBUG("breakpoint distance " << distanceBp);
1067
1068 // check if the distance is outside the validity range
1069 if (distance2D < 10.0 || distance2D > 5.0e3)
1070 {
1071 NS_ABORT_MSG_IF(m_enforceRanges, "UmiStreetCanyon 2D distance out of range");
1072 NS_LOG_WARN("The 2D distance is outside the validity range, the pathloss value may not be "
1073 "accurate");
1074 }
1075
1076 // compute the pathloss (see 3GPP TR 38.901, Table 7.4.1-1)
1077 double loss = 0;
1078 if (distance2D <= distanceBp)
1079 {
1080 // use PL1
1081 loss = 32.4 + 21.0 * log10(distance3D) + 20.0 * log10(m_frequency / 1e9);
1082 }
1083 else
1084 {
1085 // use PL2
1086 loss = 32.4 + 40.0 * log10(distance3D) + 20.0 * log10(m_frequency / 1e9) -
1087 9.5 * log10(pow(distanceBp, 2) + pow(hBs - hUt, 2));
1088 }
1089
1090 NS_LOG_DEBUG("Loss " << loss);
1091
1092 return loss;
1093}
1094
1095double
1097 double distance3D,
1098 double hUt,
1099 double hBs) const
1100{
1101 NS_LOG_FUNCTION(this);
1102
1103 // check if hBS and hUT are within the validity range
1104 if (hUt < 1.5 || hUt >= 10.0)
1105 {
1106 NS_ABORT_MSG_IF(m_enforceRanges, "UmiStreetCanyon UT height out of range");
1108 "The height of the UT should be between 1.5 and 22.5 m (see TR 38.901, Table 7.4.1-1). "
1109 "We further assume hUT < hBS, then hUT is upper bounded by hBS, which should be 10 m");
1110 }
1111
1112 if (hBs != 10.0)
1113 {
1114 NS_ABORT_MSG_IF(m_enforceRanges, "UmiStreetCanyon BS height out of range");
1115 NS_LOG_WARN("The height of the BS should be equal to 10 m (see TR 38.901, Table 7.4.1-1)");
1116 }
1117
1118 // NOTE The model is intended to be used for BS-UT links, however we may need to
1119 // compute the pathloss between two BSs or UTs, e.g., to evaluate the
1120 // interference. In order to apply the model, we need to retrieve the values of
1121 // hBS and hUT, but in these cases one of the two falls outside the validity
1122 // range and the warning message is printed (hBS for the UT-UT case and hUT
1123 // for the BS-BS case).
1124
1125 // check if the distance is outside the validity range
1126 if (distance2D < 10.0 || distance2D > 5.0e3)
1127 {
1128 NS_ABORT_MSG_IF(m_enforceRanges, "UmiStreetCanyon 2D distance out of range");
1129 NS_LOG_WARN("The 2D distance is outside the validity range, the pathloss value may not be "
1130 "accurate");
1131 }
1132
1133 // compute the pathloss
1134 double plNlos =
1135 22.4 + 35.3 * log10(distance3D) + 21.3 * log10(m_frequency / 1e9) - 0.3 * (hUt - 1.5);
1136 double loss = std::max(GetLossLos(distance2D, distance3D, hUt, hBs), plNlos);
1137 NS_LOG_DEBUG("Loss " << loss);
1138
1139 return loss;
1140}
1141
1142std::pair<double, double>
1144{
1145 NS_LOG_FUNCTION(this);
1146 // TR 38.901 specifies hBS = 10 m and 1.5 <= hUT <= 22.5
1147 double hBs;
1148 double hUt;
1149 if (za == 10.0)
1150 {
1151 // node A is the BS and node B is the UT
1152 hBs = za;
1153 hUt = zb;
1154 }
1155 else if (zb == 10.0)
1156 {
1157 // node B is the BS and node A is the UT
1158 hBs = zb;
1159 hUt = za;
1160 }
1161 else
1162 {
1163 // We cannot know who is the BS and who is the UT, we assume that the
1164 // tallest node is the BS and the smallest is the UT
1165 hBs = std::max(za, zb);
1166 hUt = std::min(za, za);
1167 }
1168
1169 return std::pair<double, double>(hUt, hBs);
1170}
1171
1172double
1174 Ptr<MobilityModel> /* a */,
1175 Ptr<MobilityModel> /* b */,
1177{
1178 NS_LOG_FUNCTION(this);
1179 double shadowingStd;
1180
1181 if (cond == ChannelCondition::LosConditionValue::LOS)
1182 {
1183 shadowingStd = 4.0;
1184 }
1185 else if (cond == ChannelCondition::LosConditionValue::NLOS)
1186 {
1187 shadowingStd = 7.82;
1188 }
1189 else
1190 {
1191 NS_FATAL_ERROR("Unknown channel condition");
1192 }
1193
1194 return shadowingStd;
1195}
1196
1197double
1200{
1201 NS_LOG_FUNCTION(this);
1202 double correlationDistance;
1203
1204 // See 3GPP TR 38.901, Table 7.5-6
1205 if (cond == ChannelCondition::LosConditionValue::LOS)
1206 {
1207 correlationDistance = 10;
1208 }
1209 else if (cond == ChannelCondition::LosConditionValue::NLOS)
1210 {
1211 correlationDistance = 13;
1212 }
1213 else
1214 {
1215 NS_FATAL_ERROR("Unknown channel condition");
1216 }
1217
1218 return correlationDistance;
1219}
1220
1221// ------------------------------------------------------------------------- //
1222
1224
1225TypeId
1227{
1228 static TypeId tid = TypeId("ns3::ThreeGppIndoorOfficePropagationLossModel")
1230 .SetGroupName("Propagation")
1232 return tid;
1233}
1234
1237{
1238 NS_LOG_FUNCTION(this);
1239
1240 // set a default channel condition model
1241 m_channelConditionModel = CreateObject<ThreeGppIndoorOpenOfficeChannelConditionModel>();
1242}
1243
1245{
1246 NS_LOG_FUNCTION(this);
1247}
1248
1249double
1251{
1252 return 0;
1253}
1254
1255double
1257 double distance3D,
1258 double /* hUt */,
1259 double /* hBs */) const
1260{
1261 NS_LOG_FUNCTION(this);
1262
1263 // check if the distance is outside the validity range
1264 if (distance3D < 1.0 || distance3D > 150.0)
1265 {
1266 NS_ABORT_MSG_IF(m_enforceRanges, "IndoorOffice 3D distance out of range");
1267 NS_LOG_WARN("The 3D distance is outside the validity range, the pathloss value may not be "
1268 "accurate");
1269 }
1270
1271 // compute the pathloss (see 3GPP TR 38.901, Table 7.4.1-1)
1272 double loss = 32.4 + 17.3 * log10(distance3D) + 20.0 * log10(m_frequency / 1e9);
1273
1274 NS_LOG_DEBUG("Loss " << loss);
1275
1276 return loss;
1277}
1278
1279double
1281 double distance3D,
1282 double hUt,
1283 double hBs) const
1284{
1285 NS_LOG_FUNCTION(this);
1286
1287 // check if the distance is outside the validity range
1288 if (distance3D < 1.0 || distance3D > 150.0)
1289 {
1290 NS_ABORT_MSG_IF(m_enforceRanges, "IndoorOffice 3D distance out of range");
1291 NS_LOG_WARN("The 3D distance is outside the validity range, the pathloss value may not be "
1292 "accurate");
1293 }
1294
1295 // compute the pathloss
1296 double plNlos = 17.3 + 38.3 * log10(distance3D) + 24.9 * log10(m_frequency / 1e9);
1297 double loss = std::max(GetLossLos(distance2D, distance3D, hUt, hBs), plNlos);
1298
1299 NS_LOG_DEBUG("Loss " << loss);
1300
1301 return loss;
1302}
1303
1304double
1306 Ptr<MobilityModel> /* a */,
1307 Ptr<MobilityModel> /* b */,
1309{
1310 NS_LOG_FUNCTION(this);
1311 double shadowingStd;
1312
1313 if (cond == ChannelCondition::LosConditionValue::LOS)
1314 {
1315 shadowingStd = 3.0;
1316 }
1317 else if (cond == ChannelCondition::LosConditionValue::NLOS)
1318 {
1319 shadowingStd = 8.03;
1320 }
1321 else
1322 {
1323 NS_FATAL_ERROR("Unknown channel condition");
1324 }
1325
1326 return shadowingStd;
1327}
1328
1329double
1332{
1333 NS_LOG_FUNCTION(this);
1334
1335 // See 3GPP TR 38.901, Table 7.5-6
1336 double correlationDistance;
1337
1338 if (cond == ChannelCondition::LosConditionValue::LOS)
1339 {
1340 correlationDistance = 10;
1341 }
1342 else if (cond == ChannelCondition::LosConditionValue::NLOS)
1343 {
1344 correlationDistance = 6;
1345 }
1346 else
1347 {
1348 NS_FATAL_ERROR("Unknown channel condition");
1349 }
1350
1351 return correlationDistance;
1352}
1353
1354} // namespace ns3
#define min(a, b)
Definition: 80211b.c:42
double f(double x, void *params)
Definition: 80211b.c:71
#define max(a, b)
Definition: 80211b.c:43
AttributeValue implementation for Boolean.
Definition: boolean.h:37
LosConditionValue
Possible values for Line-of-Sight condition.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
Vector GetPosition() const
A network Node.
Definition: node.h:56
uint32_t GetId() const
Definition: node.cc:117
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Models the propagation loss through a transmission medium.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
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(double distance2D, double distance3D, double hUt, double hBs) const override
Computes the pathloss between a and b considering that the line of sight is obstructed.
double GetLossLos(double distance2D, double distance3D, double hUt, double hBs) const override
Computes the pathloss between a and b considering that the line of sight is not obstructed.
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.
double GetLoss(Ptr< ChannelCondition > cond, double distance2D, double distance3D, double hUt, double hBs) const
Computes the pathloss between a and b.
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.
Ptr< UniformRandomVariable > m_randomO2iVar1
a uniform random variable for the calculation of the indoor loss, see TR38.901 Table 7....
virtual double GetLossNlos(double distance2D, double distance3D, double hUt, double hBs) const =0
Computes the pathloss between a and b considering that the line of sight is obstructed.
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 GetLossLos(double distance2D, double distance3D, double hUt, double hBs) const =0
Computes the pathloss between a and b considering that the line of sight is not obstructed.
int64_t DoAssignStreams(int64_t stream) override
Assign a fixed random variable stream number to the random variables used by this model.
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.
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.
virtual double GetLossNlosv(double distance2D, double distance3D, double hUt, double hBs) const
Computes the pathloss between a and b considering that the line of sight is obstructed by a vehicle.
Ptr< NormalRandomVariable > m_normalO2iHighLossVar
a normal random variable for the calculation of 02i high loss, see TR38.901 Table 7....
virtual std::pair< double, double > GetUtAndBsHeights(double za, double zb) const
Determines hUT and hBS.
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
Implements the pathloss model defined in 3GPP TR 38.901, Table 7.4.1-1 for the RMa scenario.
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 GetO2iDistance2dIn() const override
Returns the minimum of the two independently generated distances according to the uniform distributio...
double GetLossLos(double distance2D, double distance3D, double hUt, double hBs) const override
Computes the pathloss between a and b considering that the line of sight is not obstructed.
double GetLossNlos(double distance2D, double distance3D, double hUt, double hBs) 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 m_h
average building height in meters
static double GetBpDistance(double frequency, double hA, double hB)
Computes the breakpoint distance for the RMa scenario.
Implements the pathloss model defined in 3GPP TR 38.901, Table 7.4.1-1 for the UMa scenario.
double GetLossLos(double distance2D, double distance3D, double hUt, double hBs) const override
Computes the pathloss between a and b considering that the line of sight is not 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 GetLossNlos(double distance2D, double distance3D, double hUt, double hBs) const override
Computes the pathloss between a and b considering that the line of sight is 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...
std::pair< double, double > GetUtAndBsHeights(double za, double zb) const override
Determines hUT and hBS.
double GetLossNlos(double distance2D, double distance3D, double hUt, double hBs) 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(double distance2D, double distance3D, double hUt, double hBs) 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:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
uint32_t GetInteger(uint32_t min, uint32_t max)
Get the next random value, as an unsigned integer in the specified range .
a 2d vector
Definition: vector.h:183
double GetLength() const
Compute the length (magnitude) of the vector.
Definition: vector.cc:88
#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:86
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:230
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:160
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#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:261
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static const double M_C
propagation velocity in free space
double CalculateDistance(const Vector3D &a, const Vector3D &b)
Definition: vector.cc:109