src/devices/wifi/jakes-propagation-loss-model.cc
changeset 6068 a2127017ecb4
parent 6067 ccbdc2b19ea5
parent 6062 f62b76f5c92a
child 6069 c21754b56036
equal deleted inserted replaced
6067:ccbdc2b19ea5 6068:a2127017ecb4
     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: Federico Maguolo <maguolof@dei.unipd.it>
       
    19  */
       
    20 
       
    21 #include "ns3/simulator.h"
       
    22 #include "ns3/uinteger.h"
       
    23 #include "ns3/double.h"
       
    24 #include "ns3/random-variable.h"
       
    25 #include "ns3/mobility-model.h"
       
    26 #include "ns3/log.h"
       
    27 #include "jakes-propagation-loss-model.h"
       
    28 #include <math.h>
       
    29 
       
    30 NS_LOG_COMPONENT_DEFINE ("Jakes");
       
    31 
       
    32 namespace ns3 {
       
    33 
       
    34 class JakesPropagationLossModel::PathCoefficients 
       
    35 {
       
    36 public:
       
    37   PathCoefficients (Ptr<const JakesPropagationLossModel> jakes,
       
    38                     Ptr<MobilityModel> receiver, 
       
    39                     uint8_t nRays, 
       
    40                     uint8_t nOscillators);
       
    41   ~PathCoefficients ();
       
    42   double GetLoss (void);
       
    43   Ptr<MobilityModel> GetReceiver (void);
       
    44 private:
       
    45   void DoConstruct (void);
       
    46   Ptr<MobilityModel> m_receiver;
       
    47   uint8_t m_nOscillators;
       
    48   uint8_t m_nRays;
       
    49   double **m_phases;
       
    50   Time m_lastUpdate;
       
    51   Ptr<const JakesPropagationLossModel> m_jakes;
       
    52 };
       
    53 
       
    54 
       
    55 JakesPropagationLossModel::PathCoefficients::PathCoefficients (Ptr<const JakesPropagationLossModel> jakes, 
       
    56                                                            Ptr<MobilityModel> receiver, 
       
    57                                                            uint8_t nRays, 
       
    58 							   uint8_t nOscillators)
       
    59   : m_receiver (receiver),
       
    60     m_nOscillators (nOscillators),
       
    61     m_nRays (nRays),
       
    62     m_jakes(jakes)
       
    63 {
       
    64   DoConstruct ();
       
    65 }
       
    66 
       
    67 JakesPropagationLossModel::PathCoefficients::~PathCoefficients ()
       
    68 {
       
    69   for (uint8_t i = 0; i < m_nRays; i++) 
       
    70     {
       
    71       delete [] m_phases[i];
       
    72     }
       
    73   delete [] m_phases;
       
    74 }
       
    75 
       
    76 void
       
    77 JakesPropagationLossModel::PathCoefficients::DoConstruct ()
       
    78 {
       
    79   m_phases = new double*[m_nRays];
       
    80   for (uint8_t i = 0; i < m_nRays; i++) 
       
    81     {
       
    82       m_phases[i] = new double[m_nOscillators + 1];
       
    83       for (uint8_t j = 0; j <= m_nOscillators; j++) 
       
    84         {
       
    85           m_phases[i][j] = 2.0 * JakesPropagationLossModel::PI * m_jakes->m_variable.GetValue ();
       
    86         }
       
    87     }
       
    88   m_lastUpdate = Simulator::Now ();
       
    89 }
       
    90 
       
    91 Ptr<MobilityModel>
       
    92 JakesPropagationLossModel::PathCoefficients::GetReceiver ()
       
    93 {
       
    94   return m_receiver;
       
    95 }
       
    96 
       
    97 double
       
    98 JakesPropagationLossModel::PathCoefficients::GetLoss (void)
       
    99 {
       
   100   uint16_t N = 4 * m_nOscillators + 2;
       
   101   Time interval = Simulator::Now () - m_lastUpdate;
       
   102   ComplexNumber coef= {0.0, 0.0};
       
   103   ComplexNumber fading;
       
   104   double norm = 0.0;
       
   105   for (uint8_t i = 0; i < m_nRays; i++) 
       
   106     {
       
   107       fading.real = 0.0;
       
   108       fading.imag = 0.0;
       
   109       for (uint8_t j = 0; j <= m_nOscillators; j++) 
       
   110         {
       
   111           m_phases[i][j] += 2.0 * JakesPropagationLossModel::PI * 
       
   112             cos (2.0 * JakesPropagationLossModel::PI * j / N) * m_jakes->m_fd * interval.GetSeconds ();
       
   113           m_phases[i][j] -= 2.0 * JakesPropagationLossModel::PI * 
       
   114             floor (m_phases[i][j] / 2.0 / JakesPropagationLossModel::PI);
       
   115           fading.real += m_jakes->m_amp[j].real * cos (m_phases[i][j]);
       
   116           fading.imag += m_jakes->m_amp[j].imag * cos (m_phases[i][j]);
       
   117           norm += sqrt(pow (m_jakes->m_amp[j].real, 2) + pow(m_jakes->m_amp[j].imag, 2));
       
   118         }
       
   119     coef.real += fading.real;
       
   120     coef.imag += fading.imag;
       
   121     }
       
   122   m_lastUpdate = Simulator::Now ();
       
   123   double k = sqrt (pow (coef.real, 2) + pow (coef.imag, 2)) / norm;
       
   124   NS_LOG_DEBUG ("Jakes coef "<< k << " (" << 10 * log10 (k) << "dB)");
       
   125   return 10 * log10 (k);
       
   126 }
       
   127 
       
   128 NS_OBJECT_ENSURE_REGISTERED (JakesPropagationLossModel);
       
   129 
       
   130 const double JakesPropagationLossModel::PI = 3.14159265358979323846;
       
   131 
       
   132 TypeId
       
   133 JakesPropagationLossModel::GetTypeId (void)
       
   134 {
       
   135   static TypeId tid = TypeId ("ns3::JakesPropagationLossModel")
       
   136     .SetParent<PropagationLossModel> ()
       
   137     .AddConstructor<JakesPropagationLossModel> ()
       
   138     .AddAttribute ("NumberOfRaysPerPath",
       
   139                    "The number of rays to use by default for compute the fading coeficent for a given path (default is 1)",
       
   140                    UintegerValue (1),
       
   141 		   MakeUintegerAccessor (&JakesPropagationLossModel::SetNRays,
       
   142                                          &JakesPropagationLossModel::GetNRays),
       
   143 		   MakeUintegerChecker<uint8_t> ())
       
   144     .AddAttribute ("NumberOfOscillatorsPerRay",
       
   145                    "The number of oscillators to use by default for compute the coeficent for a given ray of a given "
       
   146                    "path (default is 4)",
       
   147                    UintegerValue (4),
       
   148 		   MakeUintegerAccessor (&JakesPropagationLossModel::SetNOscillators,
       
   149                                          &JakesPropagationLossModel::GetNOscillators),
       
   150 		   MakeUintegerChecker<uint8_t> ())
       
   151     .AddAttribute ("DopplerFreq",
       
   152                    "The doppler frequency in Hz (f_d = v / lambda = v * f / c), the default is 0)",
       
   153                    DoubleValue (0.0),
       
   154 		   MakeDoubleAccessor (&JakesPropagationLossModel::m_fd),
       
   155 		   MakeDoubleChecker<double> ())
       
   156     .AddAttribute ("Distribution",
       
   157                    "The distribution to choose the initial phases.",
       
   158                    RandomVariableValue (ConstantVariable (1.0)),
       
   159                    MakeRandomVariableAccessor (&JakesPropagationLossModel::m_variable),
       
   160                    MakeRandomVariableChecker ())
       
   161     ;
       
   162   return tid;
       
   163 }
       
   164 
       
   165 JakesPropagationLossModel::JakesPropagationLossModel ()
       
   166   : m_amp (0),
       
   167     m_nRays (0),
       
   168     m_nOscillators (0)
       
   169 {}
       
   170 
       
   171 JakesPropagationLossModel::~JakesPropagationLossModel ()
       
   172 {
       
   173   delete [] m_amp;
       
   174   for (PathsList::iterator i = m_paths.end (); i != m_paths.begin (); i--) 
       
   175     {
       
   176       PathsSet *ps = *i;
       
   177       for (DestinationList::iterator r = ps->receivers.begin (); r != ps->receivers.end (); r++) 
       
   178         {
       
   179           PathCoefficients *pc = *r;
       
   180           delete pc;
       
   181         }
       
   182       delete ps;
       
   183     }
       
   184 }
       
   185 
       
   186 void
       
   187 JakesPropagationLossModel::SetNRays (uint8_t nRays)
       
   188 {
       
   189   m_nRays = nRays;
       
   190 }
       
   191 
       
   192 void
       
   193 JakesPropagationLossModel::SetNOscillators (uint8_t nOscillators)
       
   194 {
       
   195   m_nOscillators = nOscillators;
       
   196   delete [] m_amp;
       
   197   uint16_t N = 4 * m_nOscillators + 2;
       
   198   m_amp = new ComplexNumber[m_nOscillators + 1];
       
   199   m_amp[0].real = 2.0 * sqrt(2.0 / N) * cos (PI / 4.0);
       
   200   m_amp[0].imag = 2.0 * sqrt(2.0 / N) * sin (PI / 4.0);
       
   201   for (uint8_t i = 1; i <= m_nOscillators; i++) 
       
   202     {
       
   203       double beta = PI * (double)i / m_nOscillators;
       
   204       m_amp[i].real = 4.0 * cos (beta) / sqrt(N);
       
   205       m_amp[i].imag = 4.0 * sin (beta) / sqrt(N);
       
   206     }
       
   207 }
       
   208 
       
   209 uint8_t 
       
   210 JakesPropagationLossModel::GetNRays (void) const
       
   211 {
       
   212   return m_nRays;
       
   213 }
       
   214 uint8_t 
       
   215 JakesPropagationLossModel::GetNOscillators (void) const
       
   216 {
       
   217   return m_nOscillators;
       
   218 }
       
   219 
       
   220 
       
   221 double 
       
   222 JakesPropagationLossModel::DoCalcRxPower (double txPowerDbm,
       
   223                                           Ptr<MobilityModel> a,
       
   224                                           Ptr<MobilityModel> b) const
       
   225 {
       
   226   PathsList::iterator i = m_paths.end ();
       
   227   while (i != m_paths.begin ()) 
       
   228     {
       
   229       i--;
       
   230       PathsSet *ps = *i;
       
   231       if (ps->sender == a) 
       
   232         {
       
   233           m_paths.erase (i);
       
   234           m_paths.push_back (ps);
       
   235           for (DestinationList::iterator r = ps->receivers.begin (); r != ps->receivers.end (); r++) 
       
   236             {
       
   237               PathCoefficients *pc = *r;
       
   238               if (pc->GetReceiver () == b) 
       
   239                 {
       
   240                   ps->receivers.erase (r);
       
   241                   ps->receivers.push_back (pc);
       
   242                   return txPowerDbm + pc->GetLoss ();
       
   243                 }
       
   244             }
       
   245           PathCoefficients *pc = new PathCoefficients (this, b, m_nRays, m_nOscillators);
       
   246           ps->receivers.push_back (pc);
       
   247           return txPowerDbm + pc->GetLoss ();
       
   248         }
       
   249     }
       
   250   PathsSet *ps = new PathsSet;
       
   251   ps->sender = a;
       
   252   PathCoefficients *pc = new PathCoefficients (this, b, m_nRays, m_nOscillators);
       
   253   ps->receivers.push_back (pc);
       
   254   m_paths.push_back (ps);
       
   255   return txPowerDbm + pc->GetLoss ();
       
   256 }
       
   257 
       
   258 } // namespace ns3
       
   259