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