1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * Copyright (c) 2005,2006,2007 INRIA
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 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19 * Contributions: Timo Bingmann <timo.bingmann@student.kit.edu>
20 * Contributions: Tom Hewer <tomhewer@mac.com> for Two Ray Ground Model
21 * Pavel Boyko <boyko@iitp.ru> for matrix
22 */
23
24 #include "propagation-loss-model.h"
25 #include "ns3/log.h"
26 #include "ns3/mobility-model.h"
27 #include "ns3/boolean.h"
28 #include "ns3/double.h"
29 #include "ns3/string.h"
30 #include "ns3/pointer.h"
31 #include <cmath>
32
33 namespace ns3 {
34
35 NS_LOG_COMPONENT_DEFINE ("PropagationLossModel");
36
37 // ------------------------------------------------------------------------- //
38
39 NS_OBJECT_ENSURE_REGISTERED (PropagationLossModel);
40
41 TypeId
GetTypeId(void)42 PropagationLossModel::GetTypeId (void)
43 {
44 static TypeId tid = TypeId ("ns3::PropagationLossModel")
45 .SetParent<Object> ()
46 .SetGroupName ("Propagation")
47 ;
48 return tid;
49 }
50
PropagationLossModel()51 PropagationLossModel::PropagationLossModel ()
52 : m_next (0)
53 {
54 }
55
~PropagationLossModel()56 PropagationLossModel::~PropagationLossModel ()
57 {
58 }
59
60 void
SetNext(Ptr<PropagationLossModel> next)61 PropagationLossModel::SetNext (Ptr<PropagationLossModel> next)
62 {
63 m_next = next;
64 }
65
66 Ptr<PropagationLossModel>
GetNext()67 PropagationLossModel::GetNext ()
68 {
69 return m_next;
70 }
71
72 double
CalcRxPower(double txPowerDbm,Ptr<MobilityModel> a,Ptr<MobilityModel> b) const73 PropagationLossModel::CalcRxPower (double txPowerDbm,
74 Ptr<MobilityModel> a,
75 Ptr<MobilityModel> b) const
76 {
77 double self = DoCalcRxPower (txPowerDbm, a, b);
78 if (m_next != 0)
79 {
80 self = m_next->CalcRxPower (self, a, b);
81 }
82 return self;
83 }
84
85 int64_t
AssignStreams(int64_t stream)86 PropagationLossModel::AssignStreams (int64_t stream)
87 {
88 int64_t currentStream = stream;
89 currentStream += DoAssignStreams (stream);
90 if (m_next != 0)
91 {
92 currentStream += m_next->AssignStreams (currentStream);
93 }
94 return (currentStream - stream);
95 }
96
97 // ------------------------------------------------------------------------- //
98
99 NS_OBJECT_ENSURE_REGISTERED (RandomPropagationLossModel);
100
101 TypeId
GetTypeId(void)102 RandomPropagationLossModel::GetTypeId (void)
103 {
104 static TypeId tid = TypeId ("ns3::RandomPropagationLossModel")
105 .SetParent<PropagationLossModel> ()
106 .SetGroupName ("Propagation")
107 .AddConstructor<RandomPropagationLossModel> ()
108 .AddAttribute ("Variable", "The random variable used to pick a loss every time CalcRxPower is invoked.",
109 StringValue ("ns3::ConstantRandomVariable[Constant=1.0]"),
110 MakePointerAccessor (&RandomPropagationLossModel::m_variable),
111 MakePointerChecker<RandomVariableStream> ())
112 ;
113 return tid;
114 }
RandomPropagationLossModel()115 RandomPropagationLossModel::RandomPropagationLossModel ()
116 : PropagationLossModel ()
117 {
118 }
119
~RandomPropagationLossModel()120 RandomPropagationLossModel::~RandomPropagationLossModel ()
121 {
122 }
123
124 double
DoCalcRxPower(double txPowerDbm,Ptr<MobilityModel> a,Ptr<MobilityModel> b) const125 RandomPropagationLossModel::DoCalcRxPower (double txPowerDbm,
126 Ptr<MobilityModel> a,
127 Ptr<MobilityModel> b) const
128 {
129 double rxc = -m_variable->GetValue ();
130 NS_LOG_DEBUG ("attenuation coefficient="<<rxc<<"Db");
131 return txPowerDbm + rxc;
132 }
133
134 int64_t
DoAssignStreams(int64_t stream)135 RandomPropagationLossModel::DoAssignStreams (int64_t stream)
136 {
137 m_variable->SetStream (stream);
138 return 1;
139 }
140
141 // ------------------------------------------------------------------------- //
142
143 NS_OBJECT_ENSURE_REGISTERED (FriisPropagationLossModel);
144
145 TypeId
GetTypeId(void)146 FriisPropagationLossModel::GetTypeId (void)
147 {
148 static TypeId tid = TypeId ("ns3::FriisPropagationLossModel")
149 .SetParent<PropagationLossModel> ()
150 .SetGroupName ("Propagation")
151 .AddConstructor<FriisPropagationLossModel> ()
152 .AddAttribute ("Frequency",
153 "The carrier frequency (in Hz) at which propagation occurs (default is 5.15 GHz).",
154 DoubleValue (5.150e9),
155 MakeDoubleAccessor (&FriisPropagationLossModel::SetFrequency,
156 &FriisPropagationLossModel::GetFrequency),
157 MakeDoubleChecker<double> ())
158 .AddAttribute ("SystemLoss", "The system loss",
159 DoubleValue (1.0),
160 MakeDoubleAccessor (&FriisPropagationLossModel::m_systemLoss),
161 MakeDoubleChecker<double> ())
162 .AddAttribute ("MinLoss",
163 "The minimum value (dB) of the total loss, used at short ranges. Note: ",
164 DoubleValue (0.0),
165 MakeDoubleAccessor (&FriisPropagationLossModel::SetMinLoss,
166 &FriisPropagationLossModel::GetMinLoss),
167 MakeDoubleChecker<double> ())
168 ;
169 return tid;
170 }
171
FriisPropagationLossModel()172 FriisPropagationLossModel::FriisPropagationLossModel ()
173 {
174 }
175 void
SetSystemLoss(double systemLoss)176 FriisPropagationLossModel::SetSystemLoss (double systemLoss)
177 {
178 m_systemLoss = systemLoss;
179 }
180 double
GetSystemLoss(void) const181 FriisPropagationLossModel::GetSystemLoss (void) const
182 {
183 return m_systemLoss;
184 }
185 void
SetMinLoss(double minLoss)186 FriisPropagationLossModel::SetMinLoss (double minLoss)
187 {
188 m_minLoss = minLoss;
189 }
190 double
GetMinLoss(void) const191 FriisPropagationLossModel::GetMinLoss (void) const
192 {
193 return m_minLoss;
194 }
195
196 void
SetFrequency(double frequency)197 FriisPropagationLossModel::SetFrequency (double frequency)
198 {
199 m_frequency = frequency;
200 static const double C = 299792458.0; // speed of light in vacuum
201 m_lambda = C / frequency;
202 }
203
204 double
GetFrequency(void) const205 FriisPropagationLossModel::GetFrequency (void) const
206 {
207 return m_frequency;
208 }
209
210 double
DbmToW(double dbm) const211 FriisPropagationLossModel::DbmToW (double dbm) const
212 {
213 double mw = std::pow (10.0,dbm/10.0);
214 return mw / 1000.0;
215 }
216
217 double
DbmFromW(double w) const218 FriisPropagationLossModel::DbmFromW (double w) const
219 {
220 double dbm = std::log10 (w * 1000.0) * 10.0;
221 return dbm;
222 }
223
224 double
DoCalcRxPower(double txPowerDbm,Ptr<MobilityModel> a,Ptr<MobilityModel> b) const225 FriisPropagationLossModel::DoCalcRxPower (double txPowerDbm,
226 Ptr<MobilityModel> a,
227 Ptr<MobilityModel> b) const
228 {
229 /*
230 * Friis free space equation:
231 * where Pt, Gr, Gr and P are in Watt units
232 * L is in meter units.
233 *
234 * P Gt * Gr * (lambda^2)
235 * --- = ---------------------
236 * Pt (4 * pi * d)^2 * L
237 *
238 * Gt: tx gain (unit-less)
239 * Gr: rx gain (unit-less)
240 * Pt: tx power (W)
241 * d: distance (m)
242 * L: system loss
243 * lambda: wavelength (m)
244 *
245 * Here, we ignore tx and rx gain and the input and output values
246 * are in dB or dBm:
247 *
248 * lambda^2
249 * rx = tx + 10 log10 (-------------------)
250 * (4 * pi * d)^2 * L
251 *
252 * rx: rx power (dB)
253 * tx: tx power (dB)
254 * d: distance (m)
255 * L: system loss (unit-less)
256 * lambda: wavelength (m)
257 */
258 double distance = a->GetDistanceFrom (b);
259 if (distance < 3*m_lambda)
260 {
261 NS_LOG_WARN ("distance not within the far field region => inaccurate propagation loss value");
262 }
263 if (distance <= 0)
264 {
265 return txPowerDbm - m_minLoss;
266 }
267 double numerator = m_lambda * m_lambda;
268 double denominator = 16 * M_PI * M_PI * distance * distance * m_systemLoss;
269 double lossDb = -10 * log10 (numerator / denominator);
270 NS_LOG_DEBUG ("distance=" << distance<< "m, loss=" << lossDb <<"dB");
271 return txPowerDbm - std::max (lossDb, m_minLoss);
272 }
273
274 int64_t
DoAssignStreams(int64_t stream)275 FriisPropagationLossModel::DoAssignStreams (int64_t stream)
276 {
277 return 0;
278 }
279
280 // ------------------------------------------------------------------------- //
281 // -- Two-Ray Ground Model ported from NS-2 -- tomhewer@mac.com -- Nov09 //
282
283 NS_OBJECT_ENSURE_REGISTERED (TwoRayGroundPropagationLossModel);
284
285 TypeId
GetTypeId(void)286 TwoRayGroundPropagationLossModel::GetTypeId (void)
287 {
288 static TypeId tid = TypeId ("ns3::TwoRayGroundPropagationLossModel")
289 .SetParent<PropagationLossModel> ()
290 .SetGroupName ("Propagation")
291 .AddConstructor<TwoRayGroundPropagationLossModel> ()
292 .AddAttribute ("Frequency",
293 "The carrier frequency (in Hz) at which propagation occurs (default is 5.15 GHz).",
294 DoubleValue (5.150e9),
295 MakeDoubleAccessor (&TwoRayGroundPropagationLossModel::SetFrequency,
296 &TwoRayGroundPropagationLossModel::GetFrequency),
297 MakeDoubleChecker<double> ())
298 .AddAttribute ("SystemLoss", "The system loss",
299 DoubleValue (1.0),
300 MakeDoubleAccessor (&TwoRayGroundPropagationLossModel::m_systemLoss),
301 MakeDoubleChecker<double> ())
302 .AddAttribute ("MinDistance",
303 "The distance under which the propagation model refuses to give results (m)",
304 DoubleValue (0.5),
305 MakeDoubleAccessor (&TwoRayGroundPropagationLossModel::SetMinDistance,
306 &TwoRayGroundPropagationLossModel::GetMinDistance),
307 MakeDoubleChecker<double> ())
308 .AddAttribute ("HeightAboveZ",
309 "The height of the antenna (m) above the node's Z coordinate",
310 DoubleValue (0),
311 MakeDoubleAccessor (&TwoRayGroundPropagationLossModel::m_heightAboveZ),
312 MakeDoubleChecker<double> ())
313 ;
314 return tid;
315 }
316
TwoRayGroundPropagationLossModel()317 TwoRayGroundPropagationLossModel::TwoRayGroundPropagationLossModel ()
318 {
319 }
320 void
SetSystemLoss(double systemLoss)321 TwoRayGroundPropagationLossModel::SetSystemLoss (double systemLoss)
322 {
323 m_systemLoss = systemLoss;
324 }
325 double
GetSystemLoss(void) const326 TwoRayGroundPropagationLossModel::GetSystemLoss (void) const
327 {
328 return m_systemLoss;
329 }
330 void
SetMinDistance(double minDistance)331 TwoRayGroundPropagationLossModel::SetMinDistance (double minDistance)
332 {
333 m_minDistance = minDistance;
334 }
335 double
GetMinDistance(void) const336 TwoRayGroundPropagationLossModel::GetMinDistance (void) const
337 {
338 return m_minDistance;
339 }
340 void
SetHeightAboveZ(double heightAboveZ)341 TwoRayGroundPropagationLossModel::SetHeightAboveZ (double heightAboveZ)
342 {
343 m_heightAboveZ = heightAboveZ;
344 }
345
346 void
SetFrequency(double frequency)347 TwoRayGroundPropagationLossModel::SetFrequency (double frequency)
348 {
349 m_frequency = frequency;
350 static const double C = 299792458.0; // speed of light in vacuum
351 m_lambda = C / frequency;
352 }
353
354 double
GetFrequency(void) const355 TwoRayGroundPropagationLossModel::GetFrequency (void) const
356 {
357 return m_frequency;
358 }
359
360 double
DbmToW(double dbm) const361 TwoRayGroundPropagationLossModel::DbmToW (double dbm) const
362 {
363 double mw = std::pow (10.0,dbm / 10.0);
364 return mw / 1000.0;
365 }
366
367 double
DbmFromW(double w) const368 TwoRayGroundPropagationLossModel::DbmFromW (double w) const
369 {
370 double dbm = std::log10 (w * 1000.0) * 10.0;
371 return dbm;
372 }
373
374 double
DoCalcRxPower(double txPowerDbm,Ptr<MobilityModel> a,Ptr<MobilityModel> b) const375 TwoRayGroundPropagationLossModel::DoCalcRxPower (double txPowerDbm,
376 Ptr<MobilityModel> a,
377 Ptr<MobilityModel> b) const
378 {
379 /*
380 * Two-Ray Ground equation:
381 *
382 * where Pt, Gt and Gr are in dBm units
383 * L, Ht and Hr are in meter units.
384 *
385 * Pr Gt * Gr * (Ht^2 * Hr^2)
386 * -- = (-------------------------)
387 * Pt d^4 * L
388 *
389 * Gt: tx gain (unit-less)
390 * Gr: rx gain (unit-less)
391 * Pt: tx power (dBm)
392 * d: distance (m)
393 * L: system loss
394 * Ht: Tx antenna height (m)
395 * Hr: Rx antenna height (m)
396 * lambda: wavelength (m)
397 *
398 * As with the Friis model we ignore tx and rx gain and output values
399 * are in dB or dBm
400 *
401 * (Ht * Ht) * (Hr * Hr)
402 * rx = tx + 10 log10 (-----------------------)
403 * (d * d * d * d) * L
404 */
405 double distance = a->GetDistanceFrom (b);
406 if (distance <= m_minDistance)
407 {
408 return txPowerDbm;
409 }
410
411 // Set the height of the Tx and Rx antennae
412 double txAntHeight = a->GetPosition ().z + m_heightAboveZ;
413 double rxAntHeight = b->GetPosition ().z + m_heightAboveZ;
414
415 // Calculate a crossover distance, under which we use Friis
416 /*
417 *
418 * dCross = (4 * pi * Ht * Hr) / lambda
419 *
420 */
421
422 double dCross = (4 * M_PI * txAntHeight * rxAntHeight) / m_lambda;
423 double tmp = 0;
424 if (distance <= dCross)
425 {
426 // We use Friis
427 double numerator = m_lambda * m_lambda;
428 tmp = M_PI * distance;
429 double denominator = 16 * tmp * tmp * m_systemLoss;
430 double pr = 10 * std::log10 (numerator / denominator);
431 NS_LOG_DEBUG ("Receiver within crossover (" << dCross << "m) for Two_ray path; using Friis");
432 NS_LOG_DEBUG ("distance=" << distance << "m, attenuation coefficient=" << pr << "dB");
433 return txPowerDbm + pr;
434 }
435 else // Use Two-Ray Pathloss
436 {
437 tmp = txAntHeight * rxAntHeight;
438 double rayNumerator = tmp * tmp;
439 tmp = distance * distance;
440 double rayDenominator = tmp * tmp * m_systemLoss;
441 double rayPr = 10 * std::log10 (rayNumerator / rayDenominator);
442 NS_LOG_DEBUG ("distance=" << distance << "m, attenuation coefficient=" << rayPr << "dB");
443 return txPowerDbm + rayPr;
444
445 }
446 }
447
448 int64_t
DoAssignStreams(int64_t stream)449 TwoRayGroundPropagationLossModel::DoAssignStreams (int64_t stream)
450 {
451 return 0;
452 }
453
454 // ------------------------------------------------------------------------- //
455
456 NS_OBJECT_ENSURE_REGISTERED (LogDistancePropagationLossModel);
457
458 TypeId
GetTypeId(void)459 LogDistancePropagationLossModel::GetTypeId (void)
460 {
461 static TypeId tid = TypeId ("ns3::LogDistancePropagationLossModel")
462 .SetParent<PropagationLossModel> ()
463 .SetGroupName ("Propagation")
464 .AddConstructor<LogDistancePropagationLossModel> ()
465 .AddAttribute ("Exponent",
466 "The exponent of the Path Loss propagation model",
467 DoubleValue (3.0),
468 MakeDoubleAccessor (&LogDistancePropagationLossModel::m_exponent),
469 MakeDoubleChecker<double> ())
470 .AddAttribute ("ReferenceDistance",
471 "The distance at which the reference loss is calculated (m)",
472 DoubleValue (1.0),
473 MakeDoubleAccessor (&LogDistancePropagationLossModel::m_referenceDistance),
474 MakeDoubleChecker<double> ())
475 .AddAttribute ("ReferenceLoss",
476 "The reference loss at reference distance (dB). (Default is Friis at 1m with 5.15 GHz)",
477 DoubleValue (46.6777),
478 MakeDoubleAccessor (&LogDistancePropagationLossModel::m_referenceLoss),
479 MakeDoubleChecker<double> ())
480 ;
481 return tid;
482
483 }
484
LogDistancePropagationLossModel()485 LogDistancePropagationLossModel::LogDistancePropagationLossModel ()
486 {
487 }
488
489 void
SetPathLossExponent(double n)490 LogDistancePropagationLossModel::SetPathLossExponent (double n)
491 {
492 m_exponent = n;
493 }
494 void
SetReference(double referenceDistance,double referenceLoss)495 LogDistancePropagationLossModel::SetReference (double referenceDistance, double referenceLoss)
496 {
497 m_referenceDistance = referenceDistance;
498 m_referenceLoss = referenceLoss;
499 }
500 double
GetPathLossExponent(void) const501 LogDistancePropagationLossModel::GetPathLossExponent (void) const
502 {
503 return m_exponent;
504 }
505
506 double
DoCalcRxPower(double txPowerDbm,Ptr<MobilityModel> a,Ptr<MobilityModel> b) const507 LogDistancePropagationLossModel::DoCalcRxPower (double txPowerDbm,
508 Ptr<MobilityModel> a,
509 Ptr<MobilityModel> b) const
510 {
511 double distance = a->GetDistanceFrom (b);
512 if (distance <= m_referenceDistance)
513 {
514 return txPowerDbm - m_referenceLoss;
515 }
516 /**
517 * The formula is:
518 * rx = 10 * log (Pr0(tx)) - n * 10 * log (d/d0)
519 *
520 * Pr0: rx power at reference distance d0 (W)
521 * d0: reference distance: 1.0 (m)
522 * d: distance (m)
523 * tx: tx power (dB)
524 * rx: dB
525 *
526 * Which, in our case is:
527 *
528 * rx = rx0(tx) - 10 * n * log (d/d0)
529 */
530 double pathLossDb = 10 * m_exponent * std::log10 (distance / m_referenceDistance);
531 double rxc = -m_referenceLoss - pathLossDb;
532 NS_LOG_DEBUG ("distance="<<distance<<"m, reference-attenuation="<< -m_referenceLoss<<"dB, "<<
533 "attenuation coefficient="<<rxc<<"db");
534 return txPowerDbm + rxc;
535 }
536
537 int64_t
DoAssignStreams(int64_t stream)538 LogDistancePropagationLossModel::DoAssignStreams (int64_t stream)
539 {
540 return 0;
541 }
542
543 // ------------------------------------------------------------------------- //
544
545 NS_OBJECT_ENSURE_REGISTERED (ThreeLogDistancePropagationLossModel);
546
547 TypeId
GetTypeId(void)548 ThreeLogDistancePropagationLossModel::GetTypeId (void)
549 {
550 static TypeId tid = TypeId ("ns3::ThreeLogDistancePropagationLossModel")
551 .SetParent<PropagationLossModel> ()
552 .SetGroupName ("Propagation")
553 .AddConstructor<ThreeLogDistancePropagationLossModel> ()
554 .AddAttribute ("Distance0",
555 "Beginning of the first (near) distance field",
556 DoubleValue (1.0),
557 MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_distance0),
558 MakeDoubleChecker<double> ())
559 .AddAttribute ("Distance1",
560 "Beginning of the second (middle) distance field.",
561 DoubleValue (200.0),
562 MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_distance1),
563 MakeDoubleChecker<double> ())
564 .AddAttribute ("Distance2",
565 "Beginning of the third (far) distance field.",
566 DoubleValue (500.0),
567 MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_distance2),
568 MakeDoubleChecker<double> ())
569 .AddAttribute ("Exponent0",
570 "The exponent for the first field.",
571 DoubleValue (1.9),
572 MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_exponent0),
573 MakeDoubleChecker<double> ())
574 .AddAttribute ("Exponent1",
575 "The exponent for the second field.",
576 DoubleValue (3.8),
577 MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_exponent1),
578 MakeDoubleChecker<double> ())
579 .AddAttribute ("Exponent2",
580 "The exponent for the third field.",
581 DoubleValue (3.8),
582 MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_exponent2),
583 MakeDoubleChecker<double> ())
584 .AddAttribute ("ReferenceLoss",
585 "The reference loss at distance d0 (dB). (Default is Friis at 1m with 5.15 GHz)",
586 DoubleValue (46.6777),
587 MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_referenceLoss),
588 MakeDoubleChecker<double> ())
589 ;
590 return tid;
591
592 }
593
ThreeLogDistancePropagationLossModel()594 ThreeLogDistancePropagationLossModel::ThreeLogDistancePropagationLossModel ()
595 {
596 }
597
598 double
DoCalcRxPower(double txPowerDbm,Ptr<MobilityModel> a,Ptr<MobilityModel> b) const599 ThreeLogDistancePropagationLossModel::DoCalcRxPower (double txPowerDbm,
600 Ptr<MobilityModel> a,
601 Ptr<MobilityModel> b) const
602 {
603 double distance = a->GetDistanceFrom (b);
604 NS_ASSERT (distance >= 0);
605
606 // See doxygen comments for the formula and explanation
607
608 double pathLossDb;
609
610 if (distance < m_distance0)
611 {
612 pathLossDb = 0;
613 }
614 else if (distance < m_distance1)
615 {
616 pathLossDb = m_referenceLoss
617 + 10 * m_exponent0 * std::log10 (distance / m_distance0);
618 }
619 else if (distance < m_distance2)
620 {
621 pathLossDb = m_referenceLoss
622 + 10 * m_exponent0 * std::log10 (m_distance1 / m_distance0)
623 + 10 * m_exponent1 * std::log10 (distance / m_distance1);
624 }
625 else
626 {
627 pathLossDb = m_referenceLoss
628 + 10 * m_exponent0 * std::log10 (m_distance1 / m_distance0)
629 + 10 * m_exponent1 * std::log10 (m_distance2 / m_distance1)
630 + 10 * m_exponent2 * std::log10 (distance / m_distance2);
631 }
632
633 NS_LOG_DEBUG ("ThreeLogDistance distance=" << distance << "m, " <<
634 "attenuation=" << pathLossDb << "dB");
635
636 return txPowerDbm - pathLossDb;
637 }
638
639 int64_t
DoAssignStreams(int64_t stream)640 ThreeLogDistancePropagationLossModel::DoAssignStreams (int64_t stream)
641 {
642 return 0;
643 }
644
645 // ------------------------------------------------------------------------- //
646
647 NS_OBJECT_ENSURE_REGISTERED (NakagamiPropagationLossModel);
648
649 TypeId
GetTypeId(void)650 NakagamiPropagationLossModel::GetTypeId (void)
651 {
652 static TypeId tid = TypeId ("ns3::NakagamiPropagationLossModel")
653 .SetParent<PropagationLossModel> ()
654 .SetGroupName ("Propagation")
655 .AddConstructor<NakagamiPropagationLossModel> ()
656 .AddAttribute ("Distance1",
657 "Beginning of the second distance field. Default is 80m.",
658 DoubleValue (80.0),
659 MakeDoubleAccessor (&NakagamiPropagationLossModel::m_distance1),
660 MakeDoubleChecker<double> ())
661 .AddAttribute ("Distance2",
662 "Beginning of the third distance field. Default is 200m.",
663 DoubleValue (200.0),
664 MakeDoubleAccessor (&NakagamiPropagationLossModel::m_distance2),
665 MakeDoubleChecker<double> ())
666 .AddAttribute ("m0",
667 "m0 for distances smaller than Distance1. Default is 1.5.",
668 DoubleValue (1.5),
669 MakeDoubleAccessor (&NakagamiPropagationLossModel::m_m0),
670 MakeDoubleChecker<double> ())
671 .AddAttribute ("m1",
672 "m1 for distances smaller than Distance2. Default is 0.75.",
673 DoubleValue (0.75),
674 MakeDoubleAccessor (&NakagamiPropagationLossModel::m_m1),
675 MakeDoubleChecker<double> ())
676 .AddAttribute ("m2",
677 "m2 for distances greater than Distance2. Default is 0.75.",
678 DoubleValue (0.75),
679 MakeDoubleAccessor (&NakagamiPropagationLossModel::m_m2),
680 MakeDoubleChecker<double> ())
681 .AddAttribute ("ErlangRv",
682 "Access to the underlying ErlangRandomVariable",
683 StringValue ("ns3::ErlangRandomVariable"),
684 MakePointerAccessor (&NakagamiPropagationLossModel::m_erlangRandomVariable),
685 MakePointerChecker<ErlangRandomVariable> ())
686 .AddAttribute ("GammaRv",
687 "Access to the underlying GammaRandomVariable",
688 StringValue ("ns3::GammaRandomVariable"),
689 MakePointerAccessor (&NakagamiPropagationLossModel::m_gammaRandomVariable),
690 MakePointerChecker<GammaRandomVariable> ());
691 ;
692 return tid;
693
694 }
695
NakagamiPropagationLossModel()696 NakagamiPropagationLossModel::NakagamiPropagationLossModel ()
697 {
698 }
699
700 double
DoCalcRxPower(double txPowerDbm,Ptr<MobilityModel> a,Ptr<MobilityModel> b) const701 NakagamiPropagationLossModel::DoCalcRxPower (double txPowerDbm,
702 Ptr<MobilityModel> a,
703 Ptr<MobilityModel> b) const
704 {
705 // select m parameter
706
707 double distance = a->GetDistanceFrom (b);
708 NS_ASSERT (distance >= 0);
709
710 double m;
711 if (distance < m_distance1)
712 {
713 m = m_m0;
714 }
715 else if (distance < m_distance2)
716 {
717 m = m_m1;
718 }
719 else
720 {
721 m = m_m2;
722 }
723
724 // the current power unit is dBm, but Watt is put into the Nakagami /
725 // Rayleigh distribution.
726 double powerW = std::pow (10, (txPowerDbm - 30) / 10);
727
728 double resultPowerW;
729
730 // switch between Erlang- and Gamma distributions: this is only for
731 // speed. (Gamma is equal to Erlang for any positive integer m.)
732 unsigned int int_m = static_cast<unsigned int>(std::floor (m));
733
734 if (int_m == m)
735 {
736 resultPowerW = m_erlangRandomVariable->GetValue (int_m, powerW / m);
737 }
738 else
739 {
740 resultPowerW = m_gammaRandomVariable->GetValue (m, powerW / m);
741 }
742
743 double resultPowerDbm = 10 * std::log10 (resultPowerW) + 30;
744
745 NS_LOG_DEBUG ("Nakagami distance=" << distance << "m, " <<
746 "power=" << powerW <<"W, " <<
747 "resultPower=" << resultPowerW << "W=" << resultPowerDbm << "dBm");
748
749 return resultPowerDbm;
750 }
751
752 int64_t
DoAssignStreams(int64_t stream)753 NakagamiPropagationLossModel::DoAssignStreams (int64_t stream)
754 {
755 m_erlangRandomVariable->SetStream (stream);
756 m_gammaRandomVariable->SetStream (stream + 1);
757 return 2;
758 }
759
760 // ------------------------------------------------------------------------- //
761
762 NS_OBJECT_ENSURE_REGISTERED (FixedRssLossModel);
763
764 TypeId
GetTypeId(void)765 FixedRssLossModel::GetTypeId (void)
766 {
767 static TypeId tid = TypeId ("ns3::FixedRssLossModel")
768 .SetParent<PropagationLossModel> ()
769 .SetGroupName ("Propagation")
770 .AddConstructor<FixedRssLossModel> ()
771 .AddAttribute ("Rss", "The fixed receiver Rss.",
772 DoubleValue (-150.0),
773 MakeDoubleAccessor (&FixedRssLossModel::m_rss),
774 MakeDoubleChecker<double> ())
775 ;
776 return tid;
777 }
FixedRssLossModel()778 FixedRssLossModel::FixedRssLossModel ()
779 : PropagationLossModel ()
780 {
781 }
782
~FixedRssLossModel()783 FixedRssLossModel::~FixedRssLossModel ()
784 {
785 }
786
787 void
SetRss(double rss)788 FixedRssLossModel::SetRss (double rss)
789 {
790 m_rss = rss;
791 }
792
793 double
DoCalcRxPower(double txPowerDbm,Ptr<MobilityModel> a,Ptr<MobilityModel> b) const794 FixedRssLossModel::DoCalcRxPower (double txPowerDbm,
795 Ptr<MobilityModel> a,
796 Ptr<MobilityModel> b) const
797 {
798 return m_rss;
799 }
800
801 int64_t
DoAssignStreams(int64_t stream)802 FixedRssLossModel::DoAssignStreams (int64_t stream)
803 {
804 return 0;
805 }
806
807 // ------------------------------------------------------------------------- //
808
809 NS_OBJECT_ENSURE_REGISTERED (MatrixPropagationLossModel);
810
811 TypeId
GetTypeId(void)812 MatrixPropagationLossModel::GetTypeId (void)
813 {
814 static TypeId tid = TypeId ("ns3::MatrixPropagationLossModel")
815 .SetParent<PropagationLossModel> ()
816 .SetGroupName ("Propagation")
817 .AddConstructor<MatrixPropagationLossModel> ()
818 .AddAttribute ("DefaultLoss", "The default value for propagation loss, dB.",
819 DoubleValue (std::numeric_limits<double>::max ()),
820 MakeDoubleAccessor (&MatrixPropagationLossModel::m_default),
821 MakeDoubleChecker<double> ())
822 ;
823 return tid;
824 }
825
MatrixPropagationLossModel()826 MatrixPropagationLossModel::MatrixPropagationLossModel ()
827 : PropagationLossModel (), m_default (std::numeric_limits<double>::max ())
828 {
829 }
830
~MatrixPropagationLossModel()831 MatrixPropagationLossModel::~MatrixPropagationLossModel ()
832 {
833 }
834
835 void
SetDefaultLoss(double loss)836 MatrixPropagationLossModel::SetDefaultLoss (double loss)
837 {
838 m_default = loss;
839 }
840
841 void
SetLoss(Ptr<MobilityModel> ma,Ptr<MobilityModel> mb,double loss,bool symmetric)842 MatrixPropagationLossModel::SetLoss (Ptr<MobilityModel> ma, Ptr<MobilityModel> mb, double loss, bool symmetric)
843 {
844 NS_ASSERT (ma != 0 && mb != 0);
845
846 MobilityPair p = std::make_pair (ma, mb);
847 std::map<MobilityPair, double>::iterator i = m_loss.find (p);
848
849 if (i == m_loss.end ())
850 {
851 m_loss.insert (std::make_pair (p, loss));
852 }
853 else
854 {
855 i->second = loss;
856 }
857
858 if (symmetric)
859 {
860 SetLoss (mb, ma, loss, false);
861 }
862 }
863
864 double
DoCalcRxPower(double txPowerDbm,Ptr<MobilityModel> a,Ptr<MobilityModel> b) const865 MatrixPropagationLossModel::DoCalcRxPower (double txPowerDbm,
866 Ptr<MobilityModel> a,
867 Ptr<MobilityModel> b) const
868 {
869 std::map<MobilityPair, double>::const_iterator i = m_loss.find (std::make_pair (a, b));
870
871 if (i != m_loss.end ())
872 {
873 return txPowerDbm - i->second;
874 }
875 else
876 {
877 return txPowerDbm - m_default;
878 }
879 }
880
881 int64_t
DoAssignStreams(int64_t stream)882 MatrixPropagationLossModel::DoAssignStreams (int64_t stream)
883 {
884 return 0;
885 }
886
887 // ------------------------------------------------------------------------- //
888
889 NS_OBJECT_ENSURE_REGISTERED (RangePropagationLossModel);
890
891 TypeId
GetTypeId(void)892 RangePropagationLossModel::GetTypeId (void)
893 {
894 static TypeId tid = TypeId ("ns3::RangePropagationLossModel")
895 .SetParent<PropagationLossModel> ()
896 .SetGroupName ("Propagation")
897 .AddConstructor<RangePropagationLossModel> ()
898 .AddAttribute ("MaxRange",
899 "Maximum Transmission Range (meters)",
900 DoubleValue (250),
901 MakeDoubleAccessor (&RangePropagationLossModel::m_range),
902 MakeDoubleChecker<double> ())
903 ;
904 return tid;
905 }
906
RangePropagationLossModel()907 RangePropagationLossModel::RangePropagationLossModel ()
908 {
909 }
910
911 double
DoCalcRxPower(double txPowerDbm,Ptr<MobilityModel> a,Ptr<MobilityModel> b) const912 RangePropagationLossModel::DoCalcRxPower (double txPowerDbm,
913 Ptr<MobilityModel> a,
914 Ptr<MobilityModel> b) const
915 {
916 double distance = a->GetDistanceFrom (b);
917 if (distance <= m_range)
918 {
919 return txPowerDbm;
920 }
921 else
922 {
923 return -1000;
924 }
925 }
926
927 int64_t
DoAssignStreams(int64_t stream)928 RangePropagationLossModel::DoAssignStreams (int64_t stream)
929 {
930 return 0;
931 }
932
933 // ------------------------------------------------------------------------- //
934
935 } // namespace ns3
936