PropagationLossModel::GetLoss -> CalcRxPower. Add ThreeLogDistancePropagationLossModel.
authorTimo Bingmann <timo.bingmann@student.kit.edu>
Fri, 09 Jan 2009 09:39:42 +0100
changeset 4059 251351372d8d
parent 4058 5c7df2c1cfc5
child 4060 200676be351f
PropagationLossModel::GetLoss -> CalcRxPower. Add ThreeLogDistancePropagationLossModel.
samples/main-propagation-loss.cc
src/devices/wifi/jakes-propagation-loss-model.cc
src/devices/wifi/jakes-propagation-loss-model.h
src/devices/wifi/propagation-loss-model.cc
src/devices/wifi/propagation-loss-model.h
src/devices/wifi/yans-wifi-channel.cc
--- a/samples/main-propagation-loss.cc	Fri Jan 09 09:13:02 2009 +0100
+++ b/samples/main-propagation-loss.cc	Fri Jan 09 09:39:42 2009 +0100
@@ -40,7 +40,7 @@
       std::cout << x << " ";
       for (double txpower = minTxpower; txpower < maxTxpower; txpower += stepTxpower)
         {
-          double rxPowerDbm = txpower + model->GetLoss (a, b);
+          double rxPowerDbm = model->CalcRxPower (txpower, a, b);
           std::cout << rxPowerDbm << " ";
         }
       std::cout << std::endl;
--- a/src/devices/wifi/jakes-propagation-loss-model.cc	Fri Jan 09 09:13:02 2009 +0100
+++ b/src/devices/wifi/jakes-propagation-loss-model.cc	Fri Jan 09 09:39:42 2009 +0100
@@ -207,9 +207,10 @@
   m_nOscillators = nOscillators;
 }
 
-double
-JakesPropagationLossModel::DoGetLoss (Ptr<MobilityModel> a,
-				    Ptr<MobilityModel> b) const
+double 
+JakesPropagationLossModel::DoCalcRxPower (double txPowerDbm,
+                                          Ptr<MobilityModel> a,
+                                          Ptr<MobilityModel> b) const
 {
   PathsList::iterator i = m_paths.end ();
   while (i != m_paths.begin ()) 
@@ -227,12 +228,12 @@
                 {
                   ps->receivers.erase (r);
                   ps->receivers.push_back (pc);
-                  return pc->GetLoss ();
+                  return txPowerDbm + pc->GetLoss ();
                 }
             }
           PathCoefficients *pc = new PathCoefficients (this, b, m_nRays, m_nOscillators);
           ps->receivers.push_back (pc);
-          return pc->GetLoss ();
+          return txPowerDbm + pc->GetLoss ();
         }
     }
   PathsSet *ps = new PathsSet;
@@ -240,7 +241,7 @@
   PathCoefficients *pc = new PathCoefficients (this, b, m_nRays, m_nOscillators);
   ps->receivers.push_back (pc);
   m_paths.push_back (ps);
-  return pc->GetLoss ();
+  return txPowerDbm + pc->GetLoss ();
 }
 
 } // namespace ns3
--- a/src/devices/wifi/jakes-propagation-loss-model.h	Fri Jan 09 09:13:02 2009 +0100
+++ b/src/devices/wifi/jakes-propagation-loss-model.h	Fri Jan 09 09:39:42 2009 +0100
@@ -100,9 +100,9 @@
   JakesPropagationLossModel (const JakesPropagationLossModel &o);
   JakesPropagationLossModel & operator = (const JakesPropagationLossModel &o);
   void DoConstruct (void);
-  virtual double DoGetLoss (Ptr<MobilityModel> a,
-			  Ptr<MobilityModel> b) const;
-
+  virtual double DoCalcRxPower (double txPowerDbm,
+                                Ptr<MobilityModel> a,
+                                Ptr<MobilityModel> b) const;
 
   class PathCoefficients;
   struct ComplexNumber {
--- a/src/devices/wifi/propagation-loss-model.cc	Fri Jan 09 09:13:02 2009 +0100
+++ b/src/devices/wifi/propagation-loss-model.cc	Fri Jan 09 09:39:42 2009 +0100
@@ -16,21 +16,22 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Contributions: Timo Bingmann <timo.bingmann@student.kit.edu>
  */
+
 #include "propagation-loss-model.h"
 #include "ns3/log.h"
 #include "ns3/mobility-model.h"
 #include "ns3/static-mobility-model.h"
+#include "ns3/boolean.h"
 #include "ns3/double.h"
-#include "ns3/pointer.h"
 #include <math.h>
 
 NS_LOG_COMPONENT_DEFINE ("PropagationLossModel");
 
 namespace ns3 {
 
-
-const double FriisPropagationLossModel::PI = 3.1415;
+// ------------------------------------------------------------------------- //
 
 NS_OBJECT_ENSURE_REGISTERED (PropagationLossModel);
 
@@ -57,17 +58,19 @@
 }
 
 double 
-PropagationLossModel::GetLoss (Ptr<MobilityModel> a,
-                               Ptr<MobilityModel> b) const
+PropagationLossModel::CalcRxPower (double txPowerDbm,
+                                   Ptr<MobilityModel> a,
+                                   Ptr<MobilityModel> b) const
 {
-  double self = DoGetLoss (a, b);
+  double self = DoCalcRxPower (txPowerDbm, a, b);
   if (m_next != 0)
     {
-      self += m_next->GetLoss (a, b);
+      self = m_next->CalcRxPower (self, a, b);
     }
   return self;
 }
 
+// ------------------------------------------------------------------------- //
 
 NS_OBJECT_ENSURE_REGISTERED (RandomPropagationLossModel);
 
@@ -77,7 +80,7 @@
   static TypeId tid = TypeId ("ns3::RandomPropagationLossModel")
     .SetParent<PropagationLossModel> ()
     .AddConstructor<RandomPropagationLossModel> ()
-    .AddAttribute ("Variable", "The random variable used to pick a loss everytime GetLoss is invoked.",
+    .AddAttribute ("Variable", "The random variable used to pick a loss everytime CalcRxPower is invoked.",
                    RandomVariableValue (ConstantVariable (1.0)),
                    MakeRandomVariableAccessor (&RandomPropagationLossModel::m_variable),
                    MakeRandomVariableChecker ())
@@ -92,16 +95,21 @@
 {}
 
 double 
-RandomPropagationLossModel::DoGetLoss (Ptr<MobilityModel> a,
-                                       Ptr<MobilityModel> b) const
+RandomPropagationLossModel::DoCalcRxPower (double txPowerDbm,
+                                           Ptr<MobilityModel> a,
+                                           Ptr<MobilityModel> b) const
 {
   double rxc = -m_variable.GetValue ();
   NS_LOG_DEBUG ("attenuation coefficent="<<rxc<<"Db");
-  return rxc;
+  return txPowerDbm + rxc;
 }
 
+// ------------------------------------------------------------------------- //
+
 NS_OBJECT_ENSURE_REGISTERED (FriisPropagationLossModel);
 
+const double FriisPropagationLossModel::PI = 3.1415;
+
 TypeId 
 FriisPropagationLossModel::GetTypeId (void)
 {
@@ -179,10 +187,10 @@
   return dbm;
 }
 
-
 double 
-FriisPropagationLossModel::DoGetLoss (Ptr<MobilityModel> a,
-				    Ptr<MobilityModel> b) const
+FriisPropagationLossModel::DoCalcRxPower (double txPowerDbm,
+                                          Ptr<MobilityModel> a,
+                                          Ptr<MobilityModel> b) const
 {
   /*
    * Friis free space equation:
@@ -201,30 +209,32 @@
    * lambda: wavelength (m)
    *
    * Here, we ignore tx and rx gain and the input and output values 
-   * are in dbm:
+   * are in dB or dBm:
    *
    *                           lambda^2
    * rx = tx +  10 log10 (-------------------)
    *                       (4 * pi * d)^2 * L
    *
-   * rx: rx power (dbm)
-   * tx: tx power (dbm)
+   * rx: rx power (dB)
+   * tx: tx power (dB)
    * d: distance (m)
-   * L: system loss
+   * L: system loss (unit-less)
    * lambda: wavelength (m)
    */
   double distance = a->GetDistanceFrom (b);
   if (distance <= m_minDistance)
     {
-      return 0.0;
+      return txPowerDbm;
     }
   double numerator = m_lambda * m_lambda;
   double denominator = 16 * PI * PI * distance * distance * m_systemLoss;
   double pr = 10 * log10 (numerator / denominator);
   NS_LOG_DEBUG ("distance="<<distance<<"m, attenuation coefficient="<<pr<<"dB");
-  return pr;
+  return txPowerDbm + pr;
 }
 
+// ------------------------------------------------------------------------- //
+
 NS_OBJECT_ENSURE_REGISTERED (LogDistancePropagationLossModel);
 
 TypeId
@@ -244,7 +254,7 @@
                    MakeDoubleAccessor (&LogDistancePropagationLossModel::m_referenceDistance),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("ReferenceLoss",
-                   "The reference loss at reference distance",
+                   "The reference loss at reference distance (dB). (Default is Friis at 1m with 5.15 GHz)",
                    DoubleValue (46.6777),
                    MakeDoubleAccessor (&LogDistancePropagationLossModel::m_referenceLoss),
                    MakeDoubleChecker<double> ())
@@ -274,13 +284,14 @@
 }
   
 double 
-LogDistancePropagationLossModel::DoGetLoss (Ptr<MobilityModel> a,
-                                          Ptr<MobilityModel> b) const
+LogDistancePropagationLossModel::DoCalcRxPower (double txPowerDbm,
+                                                Ptr<MobilityModel> a,
+                                                Ptr<MobilityModel> b) const
 {
   double distance = a->GetDistanceFrom (b);
   if (distance <= m_referenceDistance)
     {
-      return 0.0;
+      return txPowerDbm;
     }
   /**
    * The formula is:
@@ -289,18 +300,114 @@
    * Pr0: rx power at reference distance d0 (W)
    * d0: reference distance: 1.0 (m)
    * d: distance (m)
-   * tx: tx power (db)
-   * rx: db
+   * tx: tx power (dB)
+   * rx: dB
    *
    * Which, in our case is:
-   *      
+   *
    * rx = rx0(tx) - 10 * n * log (d/d0)
    */
   double pathLossDb = 10 * m_exponent * log10 (distance / m_referenceDistance);
   double rxc = -m_referenceLoss - pathLossDb;
   NS_LOG_DEBUG ("distance="<<distance<<"m, reference-attenuation="<<-m_referenceLoss<<"dB, "<<
 		"attenuation coefficient="<<rxc<<"db");
-  return rxc;
+  return txPowerDbm + rxc;
 }
 
+// ------------------------------------------------------------------------- //
+
+NS_OBJECT_ENSURE_REGISTERED (ThreeLogDistancePropagationLossModel);
+
+TypeId
+ThreeLogDistancePropagationLossModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::ThreeLogDistancePropagationLossModel")
+    .SetParent<PropagationLossModel> ()
+    .AddConstructor<ThreeLogDistancePropagationLossModel> ()
+    .AddAttribute ("Distance0",
+                   "Beginning of the first (near) distance field",
+                   DoubleValue (1.0),
+                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_distance0),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("Distance1",
+                   "Beginning of the second (middle) distance field.",
+                   DoubleValue (200.0),
+                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_distance1),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("Distance2",
+                   "Beginning of the third (far) distance field.",
+                   DoubleValue (500.0),
+                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_distance2),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("Exponent0",
+                   "The exponent for the first field.",
+                   DoubleValue (1.9),
+                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_exponent0),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("Exponent1",
+                   "The exponent for the second field.",
+                   DoubleValue (3.8),
+                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_exponent1),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("Exponent2",
+                   "The exponent for the third field.",
+                   DoubleValue (3.8),
+                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_exponent2),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("ReferenceLoss",
+                   "The reference loss at distance d0 (dB). (Default is Friis at 1m with 5.15 GHz)",
+                   DoubleValue (46.6777),
+                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_referenceLoss),
+                   MakeDoubleChecker<double> ())
+    ;
+  return tid;
+                   
+}
+
+ThreeLogDistancePropagationLossModel::ThreeLogDistancePropagationLossModel ()
+{
+}
+
+double 
+ThreeLogDistancePropagationLossModel::DoCalcRxPower (double txPowerDbm,
+                                                     Ptr<MobilityModel> a,
+                                                     Ptr<MobilityModel> b) const
+{
+  double distance = a->GetDistanceFrom (b);
+  NS_ASSERT(distance >= 0);
+
+  // See doxygen comments for the formula and explanation
+
+  double pathLossDb;
+
+  if (distance < m_distance0)
+    {
+      pathLossDb = 0;
+    }
+  else if (distance < m_distance1)
+    {
+      pathLossDb = m_referenceLoss
+        + 10 * m_exponent0 * log10(distance / m_distance0);
+    }
+  else if (distance < m_distance2)
+    {
+      pathLossDb = m_referenceLoss
+        + 10 * m_exponent0 * log10(m_distance1 / m_distance0)
+        + 10 * m_exponent1 * log10(distance / m_distance1);
+    }
+  else
+    {
+      pathLossDb = m_referenceLoss
+        + 10 * m_exponent0 * log10(m_distance1 / m_distance0)
+        + 10 * m_exponent1 * log10(m_distance2 / m_distance1)
+        + 10 * m_exponent2 * log10(distance / m_distance2);
+    }
+
+  NS_LOG_DEBUG ("ThreeLogDistance distance=" << distance << "m, " <<
+                "attenuation=" << pathLossDb << "dB");
+
+  return txPowerDbm - pathLossDb;
+}
+
+
 } // namespace ns3
--- a/src/devices/wifi/propagation-loss-model.h	Fri Jan 09 09:13:02 2009 +0100
+++ b/src/devices/wifi/propagation-loss-model.h	Fri Jan 09 09:39:42 2009 +0100
@@ -16,7 +16,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Contributions: Timo Bingmann <timo.bingmann@student.kit.edu>
  */
+
 #ifndef PROPAGATION_LOSS_MODEL_H
 #define PROPAGATION_LOSS_MODEL_H
 
@@ -30,8 +32,8 @@
 /**
  * \brief Modelize the propagation loss through a transmission medium
  *
- * Calculate the receive power (dbm) from a transmit power (dbm),
- * and, a mobility model for the source and destination positions.
+ * Calculate the receive power (dbm) from a transmit power (dbm)
+ * and a mobility model for the source and destination positions.
  */
 class PropagationLossModel : public Object
 {
@@ -44,23 +46,26 @@
   void SetNext (Ptr<PropagationLossModel> next);
 
   /**
+   * \param txPowerDbm current transmission power (in dBm)
    * \param a the mobility model of the source
    * \param b the mobility model of the destination
-   * \returns the attenuation coefficient (dB)
+   * \returns the reception power after adding/multiplying propagation loss (in dBm)
    */
-  double GetLoss (Ptr<MobilityModel> a,
-                  Ptr<MobilityModel> b) const;
+  double CalcRxPower (double txPowerDbm,
+                      Ptr<MobilityModel> a,
+                      Ptr<MobilityModel> b) const;
 private:
   PropagationLossModel (const PropagationLossModel &o);
   PropagationLossModel &operator = (const PropagationLossModel &o);
-  virtual double DoGetLoss (Ptr<MobilityModel> a,
-                            Ptr<MobilityModel> b) const = 0;
+  virtual double DoCalcRxPower (double txPowerDbm,
+                                Ptr<MobilityModel> a,
+                                Ptr<MobilityModel> b) const = 0;
 
   Ptr<PropagationLossModel> m_next;
 };
 
 /**
- * \brief The propagation loss is random
+ * \brief The propagation loss follows a random distribution.
  */ 
 class RandomPropagationLossModel : public PropagationLossModel
 {
@@ -73,8 +78,9 @@
 private:
   RandomPropagationLossModel (const RandomPropagationLossModel &o);
   RandomPropagationLossModel & operator = (const RandomPropagationLossModel &o);
-  virtual double DoGetLoss (Ptr<MobilityModel> a,
-                            Ptr<MobilityModel> b) const;
+  virtual double DoCalcRxPower (double txPowerDbm,
+                                Ptr<MobilityModel> a,
+                                Ptr<MobilityModel> b) const;
   RandomVariable m_variable;
 };
 
@@ -163,8 +169,9 @@
 private:
   FriisPropagationLossModel (const FriisPropagationLossModel &o);
   FriisPropagationLossModel & operator = (const FriisPropagationLossModel &o);
-  virtual double DoGetLoss (Ptr<MobilityModel> a,
-                            Ptr<MobilityModel> b) const;
+  virtual double DoCalcRxPower (double txPowerDbm,
+                                Ptr<MobilityModel> a,
+                                Ptr<MobilityModel> b) const;
   double DbmToW (double dbm) const;
   double DbmFromW (double w) const;
 
@@ -213,8 +220,9 @@
 private:
   LogDistancePropagationLossModel (const LogDistancePropagationLossModel &o);
   LogDistancePropagationLossModel & operator = (const LogDistancePropagationLossModel &o);
-  virtual double DoGetLoss (Ptr<MobilityModel> a,
-                            Ptr<MobilityModel> b) const;
+  virtual double DoCalcRxPower (double txPowerDbm,
+                                Ptr<MobilityModel> a,
+                                Ptr<MobilityModel> b) const;
   static Ptr<PropagationLossModel> CreateDefaultReference (void);
 
   double m_exponent;
@@ -222,6 +230,72 @@
   double m_referenceLoss;
 };
 
+/**
+ * \brief A log distance path loss propagation model with three distance
+ * fields. This model is the same as ns3::LogDistancePropagationLossModel
+ * except that it has three distance fields: near, middle and far with
+ * different exponents.
+ *
+ * Within each field the reception power is calculated using the log-distance
+ * propagation equation:
+ * \f[ L = L_0 + 10 \cdot n_0 log_{10}(\frac{d}{d_0})\f]
+ * Each field begins where the previous ends and all together form a continuous function.
+ *
+ * There are three valid distance fields: near, middle, far. Actually four: the
+ * first from 0 to the reference distance is invalid and returns txPowerDbm.
+ *
+ * \f[ \underbrace{0 \cdots\cdots}_{=0} \underbrace{d_0 \cdots\cdots}_{n_0} \underbrace{d_1 \cdots\cdots}_{n_1} \underbrace{d_2 \cdots\cdots}_{n_2} \infty \f]
+ *
+ * Complete formula for the path loss in dB:
+ *
+ * \f[\displaystyle L =
+\begin{cases}
+0 & d < d_0 \\
+L_0 + 10 \cdot n_0 \log_{10}(\frac{d}{d_0}) & d_0 \leq d < d_1 \\
+L_0 + 10 \cdot n_0 \log_{10}(\frac{d_1}{d_0}) + 10 \cdot n_1 \log_{10}(\frac{d}{d_1}) & d_1 \leq d < d_2 \\
+L_0 + 10 \cdot n_0 \log_{10}(\frac{d_1}{d_0}) + 10 \cdot n_1 \log_{10}(\frac{d_2}{d_1}) + 10 \cdot n_2 \log_{10}(\frac{d}{d_2})& d_2 \leq d
+\end{cases}\f]
+ *
+ * where:
+ *  - \f$ L \f$ : resulting path loss (dB)
+ *  - \f$ d \f$ : distance (m)
+ *  - \f$ d_0, d_1, d_2 \f$ : three distance fields (m)
+ *  - \f$ n_0, n_1, n_2 \f$ : path loss distance exponent for each field (unitless)
+ *  - \f$ L_0 \f$ : path loss at reference distance (dB)
+ *
+ * When the path loss is requested at a distance smaller than the reference
+ * distance \f$ d_0 \f$, the tx power (with no path loss) is returned. The
+ * reference distance defaults to 1m and reference loss defaults to
+ * ns3::FriisPropagationLossModel with 5.15 GHz and is thus \f$ L_0 \f$ = 46.67 dB.
+ */
+
+class ThreeLogDistancePropagationLossModel : public PropagationLossModel
+{
+public:
+  static TypeId GetTypeId (void);
+  ThreeLogDistancePropagationLossModel ();
+
+  // Parameters are all accessible via attributes.
+
+private:
+  ThreeLogDistancePropagationLossModel (const ThreeLogDistancePropagationLossModel& o);
+  ThreeLogDistancePropagationLossModel& operator= (const ThreeLogDistancePropagationLossModel& o);
+
+  virtual double DoCalcRxPower (double txPowerDbm,
+                                Ptr<MobilityModel> a,
+                                Ptr<MobilityModel> b) const;
+
+  double m_distance0;
+  double m_distance1;
+  double m_distance2;
+
+  double m_exponent0;
+  double m_exponent1;
+  double m_exponent2;
+
+  double m_referenceLoss;
+};
+
 } // namespace ns3
 
 #endif /* PROPAGATION_LOSS_MODEL_H */
--- a/src/devices/wifi/yans-wifi-channel.cc	Fri Jan 09 09:13:02 2009 +0100
+++ b/src/devices/wifi/yans-wifi-channel.cc	Fri Jan 09 09:39:42 2009 +0100
@@ -83,7 +83,7 @@
         {
           Ptr<MobilityModel> receiverMobility = (*i)->GetMobility ()->GetObject<MobilityModel> ();
           Time delay = m_delay->GetDelay (senderMobility, receiverMobility);
-          double rxPowerDbm = txPowerDbm + m_loss->GetLoss (senderMobility, receiverMobility);
+          double rxPowerDbm = m_loss->CalcRxPower (txPowerDbm, senderMobility, receiverMobility);
           NS_LOG_DEBUG ("propagation: txPower="<<txPowerDbm<<"dbm, rxPower="<<rxPowerDbm<<"dbm, "<<
                         "distance="<<senderMobility->GetDistanceFrom (receiverMobility)<<"m, delay="<<delay);
           Ptr<Packet> copy = packet->Copy ();