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