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