src/buildings/model/buildings-propagation-loss-model.cc
changeset 8248 986f7db9f056
parent 8244 ee25b5332a67
child 8252 cc60191ad0d4
child 8272 3969525083ca
equal deleted inserted replaced
8247:9cc847386565 8248:986f7db9f056
       
     1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
       
     2 /*
       
     3  * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
       
     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: Marco Miozzo  <marco.miozzo@cttc.es>
       
    19  * 
       
    20  */
       
    21 
       
    22 #include "ns3/propagation-loss-model.h"
       
    23 #include "ns3/log.h"
       
    24 #include "ns3/mobility-model.h"
       
    25 #include "ns3/double.h"
       
    26 #include "ns3/pointer.h"
       
    27 #include <math.h>
       
    28 #include "buildings-propagation-loss-model.h"
       
    29 #include "ns3/buildings-mobility-model.h"
       
    30 #include "ns3/enum.h"
       
    31 
       
    32 #include <ns3/shadowing-loss-model.h>
       
    33 #include <ns3/jakes-fading-loss-model.h>
       
    34 
       
    35 
       
    36 NS_LOG_COMPONENT_DEFINE ("BuildingsPropagationLossModel");
       
    37 
       
    38 namespace ns3 {
       
    39   
       
    40 NS_OBJECT_ENSURE_REGISTERED (BuildingsPropagationLossModel);
       
    41 
       
    42 
       
    43 
       
    44 class BuildingsPropagationLossModel::ShadowingLoss 
       
    45 {
       
    46   public:
       
    47   ShadowingLoss (double mean, double sigma);
       
    48   ~ShadowingLoss ();
       
    49   double GetLoss ();
       
    50   Ptr<MobilityModel> GetReceiver (void);
       
    51   private:
       
    52   Ptr<MobilityModel> m_receiver;
       
    53   NormalVariable m_randVariable;
       
    54   double m_shadowingValue;
       
    55 };
       
    56 
       
    57 
       
    58 BuildingsPropagationLossModel::ShadowingLoss::ShadowingLoss (double mean, double sigma) :
       
    59 m_randVariable (mean, sigma*sigma)  // NormalVariable class wants mean and variance (sigma is a standard deviation)
       
    60 {
       
    61   m_shadowingValue = m_randVariable.GetValue ();
       
    62   NS_LOG_INFO (this << " New Shadowing: sigma " << sigma << " value " << m_shadowingValue);
       
    63 }
       
    64 
       
    65 BuildingsPropagationLossModel::ShadowingLoss::~ShadowingLoss ()
       
    66 {
       
    67   
       
    68 }
       
    69   
       
    70 double
       
    71 BuildingsPropagationLossModel::ShadowingLoss::GetLoss ()
       
    72 {
       
    73   return (m_shadowingValue);
       
    74 }
       
    75 
       
    76 Ptr<MobilityModel>
       
    77 BuildingsPropagationLossModel::ShadowingLoss::GetReceiver ()
       
    78 {
       
    79   return m_receiver;
       
    80 }
       
    81 
       
    82 TypeId
       
    83 BuildingsPropagationLossModel::GetTypeId (void)
       
    84 {
       
    85   static TypeId tid = TypeId ("ns3::BuildingsPropagationLossModel")
       
    86 
       
    87     .SetParent<PropagationLossModel> ()
       
    88 
       
    89     .AddConstructor<BuildingsPropagationLossModel> ()
       
    90 
       
    91     .AddAttribute ("Lambda",
       
    92                    "The wavelength  (default is 2.106 GHz at 300 000 km/s).",
       
    93                    DoubleValue (300000000.0 / 2160e6),
       
    94                    MakeDoubleAccessor (&BuildingsPropagationLossModel::SetLambda, &BuildingsPropagationLossModel::GetLambda),
       
    95                    MakeDoubleChecker<double> ())
       
    96 
       
    97     .AddAttribute ("Frequency",
       
    98                    "The Frequency  (default is 2.106 GHz).",
       
    99                    DoubleValue (2160e6),
       
   100                    MakeDoubleAccessor (&BuildingsPropagationLossModel::m_frequency),
       
   101                    MakeDoubleChecker<double> ())
       
   102                    
       
   103      .AddAttribute ("ShadowSigmaOutdoor",
       
   104                     "Standard deviation of the normal distribution used for calculate the shadowing for outdoor nodes",
       
   105                       DoubleValue (7.0),
       
   106                      MakeDoubleAccessor (&BuildingsPropagationLossModel::m_shadowingSigmaOutdoor),
       
   107                       MakeDoubleChecker<double> ())
       
   108                       
       
   109       .AddAttribute ("ShadowSigmaIndoor",
       
   110                      "Standard deviation of the normal distribution used for calculate the shadowing for indoor nodes ",
       
   111                       DoubleValue (8.0),
       
   112                      MakeDoubleAccessor (&BuildingsPropagationLossModel::m_shadowingSigmaIndoor),
       
   113                       MakeDoubleChecker<double> ())
       
   114       .AddAttribute ("ShadowSigmaExtWalls",
       
   115                     "Standard deviation of the normal distribution used for calculate the shadowing due to ext walls ",
       
   116                     DoubleValue (5.0),
       
   117                     MakeDoubleAccessor (&BuildingsPropagationLossModel::m_shadowingSigmaExtWalls),
       
   118                     MakeDoubleChecker<double> ())
       
   119                    
       
   120     .AddAttribute ("RooftopLevel",
       
   121                   " The height of the rooftop [m].",
       
   122                   DoubleValue (20.0),
       
   123                   MakeDoubleAccessor (&BuildingsPropagationLossModel::m_rooftopHeight),
       
   124                   MakeDoubleChecker<double> ())
       
   125                   
       
   126     .AddAttribute ("Los2NlosThr",
       
   127                     " Threshold from LoS to NLoS in ITU 1411 [m].",
       
   128                     DoubleValue (200.0),
       
   129                     MakeDoubleAccessor (&BuildingsPropagationLossModel::m_itu1411NlosThreshold),
       
   130                     MakeDoubleChecker<double> ())
       
   131                     
       
   132     .AddAttribute ("ITU1411DistanceThr",
       
   133                     " Threshold for ITU 1411 [m].",
       
   134                     DoubleValue (2000.0),
       
   135                     MakeDoubleAccessor (&BuildingsPropagationLossModel::m_itu1411DistanceThreshold),
       
   136                     MakeDoubleChecker<double> ())
       
   137 
       
   138     .AddAttribute ("MinDistance",
       
   139                    "The distance under which the propagation model refuses to give results (m) ",
       
   140                    DoubleValue (0.5),
       
   141                    MakeDoubleAccessor (&BuildingsPropagationLossModel::SetMinDistance, &BuildingsPropagationLossModel::GetMinDistance),
       
   142                    MakeDoubleChecker<double> ())
       
   143                    
       
   144       .AddAttribute ("Environment", 
       
   145                     "Environment Scenario",
       
   146                     EnumValue (BuildingsPropagationLossModel::Urban),
       
   147                      MakeEnumAccessor (&BuildingsPropagationLossModel::SetEnvironment,
       
   148                      &BuildingsPropagationLossModel::GetEnvironment),
       
   149                     MakeEnumChecker (BuildingsPropagationLossModel::Urban, "Urban",
       
   150                                       BuildingsPropagationLossModel::SubUrban, "SubUrban",
       
   151                                       BuildingsPropagationLossModel::OpenAreas, "OpenAreas"))
       
   152 
       
   153       .AddAttribute ("CitySize", 
       
   154                       "Dimension of the city",
       
   155                       EnumValue (BuildingsPropagationLossModel::Large),
       
   156                      MakeEnumAccessor (&BuildingsPropagationLossModel::SetCitySize),
       
   157                       MakeEnumChecker (BuildingsPropagationLossModel::Small, "Small",
       
   158                                       BuildingsPropagationLossModel::Medium, "Medium",
       
   159                                       BuildingsPropagationLossModel::Large, "Large"));
       
   160 
       
   161     
       
   162   return tid;
       
   163 }
       
   164 
       
   165 BuildingsPropagationLossModel::BuildingsPropagationLossModel () :
       
   166   C (0),
       
   167   m_environment (Urban),
       
   168   m_citySize (Large),
       
   169   m_streetsOrientation (45.0),
       
   170   m_streetsWidth (20.0),
       
   171   m_buildingsExtend (80.0),
       
   172   m_buildingSeparation (50.0)
       
   173 {
       
   174 }
       
   175 
       
   176 BuildingsPropagationLossModel::~BuildingsPropagationLossModel ()
       
   177 {
       
   178   for (PairsList::reverse_iterator i = m_shadowingPairs.rbegin (); i != m_shadowingPairs.rend (); i++)
       
   179   {
       
   180     PairsSet *ps = *i;
       
   181     for (DestinationList::iterator r = ps->receivers.begin (); r != ps->receivers.end (); r++)
       
   182     {
       
   183       ShadowingLoss *pc = *r;
       
   184       delete pc;
       
   185     }
       
   186     ps->sender = 0;
       
   187     ps->receivers.clear ();
       
   188     delete ps;
       
   189   }
       
   190   m_shadowingPairs.clear ();
       
   191 }
       
   192 
       
   193 // void
       
   194 // BuildingsPropagationLossModel::SetLambda (double frequency, double speed)
       
   195 // {
       
   196 //   m_lambda = speed / frequency;
       
   197 //   m_frequency = frequency;
       
   198 // }
       
   199 
       
   200 void
       
   201 BuildingsPropagationLossModel::SetLambda (double lambda)
       
   202 {
       
   203   m_lambda = lambda;
       
   204   m_frequency = 300000000 / lambda;
       
   205 }
       
   206 
       
   207 double
       
   208 BuildingsPropagationLossModel::GetLambda (void) const
       
   209 {
       
   210   return m_lambda;
       
   211 }
       
   212 
       
   213 void
       
   214 BuildingsPropagationLossModel::SetMinDistance (double minDistance)
       
   215 {
       
   216   m_minDistance = minDistance;
       
   217 }
       
   218 double
       
   219 BuildingsPropagationLossModel::GetMinDistance (void) const
       
   220 {
       
   221   return m_minDistance;
       
   222 }
       
   223 
       
   224 void
       
   225 BuildingsPropagationLossModel::SetEnvironment (Environment env)
       
   226 {
       
   227 //   if (env==Urban)
       
   228 //   {
       
   229 //      NS_LOG_INFO (this << " Urban");
       
   230 //   }
       
   231 //   else if (env==SubUrban)
       
   232 //   {
       
   233 //     NS_LOG_INFO (this << " SubUrban");
       
   234 //   }
       
   235 //   else if (env==OpenAreas)
       
   236 //   {
       
   237 //     NS_LOG_INFO (this << " OpenAreas");
       
   238 //   }
       
   239   m_environment = env;
       
   240 }
       
   241 
       
   242 BuildingsPropagationLossModel::Environment
       
   243 BuildingsPropagationLossModel::GetEnvironment (void) const
       
   244 {
       
   245   return m_environment;
       
   246 }
       
   247 
       
   248 void
       
   249 BuildingsPropagationLossModel::SetCitySize (CitySize size)
       
   250 {
       
   251   m_citySize = size;
       
   252 }
       
   253 
       
   254 BuildingsPropagationLossModel::CitySize
       
   255 BuildingsPropagationLossModel::GetCitySize (void) const
       
   256 {
       
   257   return m_citySize;
       
   258 }
       
   259 
       
   260 
       
   261 
       
   262 double
       
   263 BuildingsPropagationLossModel::OkumuraHata (Ptr<BuildingsMobilityModel> a, Ptr<BuildingsMobilityModel> b) const
       
   264 {
       
   265   // Hp: a is the rooftop antenna (from GetLoss logic)
       
   266   double loss = 0.0;
       
   267   double fmhz = m_frequency/1e6;
       
   268   double dist = a->GetDistanceFrom (b) / 1000.0; 
       
   269   if (m_frequency<=1.500e9)
       
   270     {
       
   271       // standard Okumura Hata (from wikipedia)
       
   272       double log_f = log10 (fmhz);
       
   273       double hb = (a->GetPosition ().z>b->GetPosition ().z ? a->GetPosition ().z : b->GetPosition ().z);
       
   274       double hm = (a->GetPosition ().z< b->GetPosition ().z ? a->GetPosition ().z : b->GetPosition ().z);
       
   275       NS_ASSERT_MSG (hb > 0 && hm > 0, "nodes' height must be greater then 0");
       
   276       double log_aHeight = 13.82 * log10 (hb);
       
   277       double log_bHeight = 0.0;
       
   278       if (m_citySize == Large)
       
   279         {
       
   280           if (m_frequency<200)
       
   281             {
       
   282               log_bHeight = 8.29 * pow (log10 (1.54 * hm), 2) -  1.1;
       
   283             }
       
   284           else
       
   285             {
       
   286               log_bHeight = 3.2 * pow (log10 (11.75 * hm), 2) - 4.97;
       
   287             }
       
   288         }
       
   289       else
       
   290         {
       
   291           log_bHeight = 0.8 + (1.1*log_f - 0.7)*hm - 1.56*log_f;
       
   292         }
       
   293         
       
   294 //       NS_LOG_INFO (this << " logf " << 26.16 * log_f << " loga " << log_aHeight << " X " << (((44.9 - (6.55 * log10(hb)) ))*log10 (a->GetDistanceFrom (b))) << " logb " << log_bHeight);
       
   295       loss = 69.55 + (26.16 * log_f) - log_aHeight + (((44.9 - (6.55 * log10(hb)) ))*log10 (dist)) - log_bHeight;
       
   296       if (m_environment == SubUrban)
       
   297         {
       
   298           loss += - 2 * (pow(log10 (fmhz / 28), 2)) - 5.4;
       
   299         }
       
   300       else if (m_environment == OpenAreas)
       
   301         {
       
   302           loss += -4.70*pow(log10(fmhz),2) + 18.33*log10(fmhz) - 40.94;
       
   303         }
       
   304           
       
   305     }
       
   306   else if (m_frequency <= 2.170e9) // max 3GPP freq EUTRA band #1
       
   307     {
       
   308       // COST 231 Okumura model
       
   309       double log_f = log10 (fmhz);
       
   310       double hb = (a->GetPosition ().z>b->GetPosition ().z ? a->GetPosition ().z : b->GetPosition ().z);
       
   311       double hm = (a->GetPosition ().z< b->GetPosition ().z ? a->GetPosition ().z : b->GetPosition ().z);
       
   312       NS_ASSERT_MSG (hb > 0 && hm > 0, "nodes' height must be greater then 0");
       
   313       double log_aHeight = 13.82 * log10 (hb);
       
   314       double log_bHeight = 0.0;
       
   315       double C = 0.0;
       
   316         
       
   317       if (m_citySize == Large)
       
   318         {
       
   319           log_bHeight = 3.2 * pow ((log10(11.75 * hm)),2);
       
   320           C = 3;
       
   321         }
       
   322       else
       
   323         {
       
   324           log_bHeight = 1.1*log_f - 0.7*hm - (1.56*log_f - 0.8);
       
   325         }
       
   326       
       
   327       loss = 46.3 + (33.9 * log_f) - log_aHeight + (((44.9 - (6.55 * log10(hb)) ))*log10 (dist)) - log_bHeight + C;
       
   328     }
       
   329   else if (m_frequency <= 2.690e9) // max 3GPP freq EUTRA band #1
       
   330     {
       
   331       // Empirical model from
       
   332       // "Path Loss Models for Suburban Scenario at 2.3GHz, 2.6GHz and 3.5GHz"
       
   333       // Sun Kun, Wang Ping, Li Yingze
       
   334       // Antennas, Propagation and EM Theory, 2008. ISAPE 2008. 8th International Symposium on 
       
   335       loss = 36 + 26*log10(dist*1000);
       
   336     }
       
   337       
       
   338   return (loss);
       
   339 }
       
   340 
       
   341 
       
   342 
       
   343 double
       
   344 BuildingsPropagationLossModel::ItuR1411 (Ptr<BuildingsMobilityModel> a, Ptr<BuildingsMobilityModel> b) const
       
   345 {
       
   346   if (a->GetDistanceFrom (b) < m_itu1411NlosThreshold)
       
   347     {
       
   348       return (ItuR1411Los (a,b));
       
   349     }
       
   350   else
       
   351     {
       
   352       return (ItuR1411NlosOverRooftop (a,b));
       
   353     }
       
   354 }
       
   355 
       
   356 
       
   357 double
       
   358 BuildingsPropagationLossModel::ItuR1411Los (Ptr<BuildingsMobilityModel> a, Ptr<BuildingsMobilityModel> b) const
       
   359 {
       
   360   NS_LOG_INFO (this);
       
   361   double dist = a->GetDistanceFrom (b);
       
   362   double lossLow = 0.0;
       
   363   double lossUp = 0.0;
       
   364   double pi = 3.141592653589793;
       
   365   NS_ASSERT_MSG (a->GetPosition ().z > 0 && b->GetPosition ().z > 0, "nodes' height must be greater then 0");
       
   366   double Lbp = fabs (20*log10 ((m_lambda*m_lambda)/(8*pi*a->GetPosition ().z*b->GetPosition ().z)));
       
   367   double Rbp = (4 * a->GetPosition ().z * b->GetPosition ().z) / m_lambda;
       
   368 //   NS_LOG_INFO (this << " Lbp " << Lbp << " Rbp " << Rbp << " lambda " << m_lambda);
       
   369   if (dist <= Rbp)
       
   370   {
       
   371     lossLow = Lbp + 20*log10(dist/Rbp);
       
   372     lossUp = Lbp + 20 + 25*log10(dist/Rbp);
       
   373   }
       
   374   else
       
   375   {
       
   376     lossLow = Lbp + 40*log10(dist/Rbp);
       
   377     lossUp = Lbp + 20 + 40*log10(dist/Rbp);
       
   378   }
       
   379   
       
   380   double loss = (lossUp + lossLow) / 2;
       
   381   
       
   382   return (loss);
       
   383 }
       
   384 
       
   385 
       
   386 double
       
   387 BuildingsPropagationLossModel::ItuR1411NlosOverRooftop (Ptr<BuildingsMobilityModel> a, Ptr<BuildingsMobilityModel> b) const
       
   388 {
       
   389   NS_LOG_INFO (this);
       
   390   double Lori = 0.0;
       
   391   double fmhz = m_frequency/1e6;
       
   392   if ((m_streetsOrientation>=0)&&(m_streetsOrientation<35))
       
   393     {
       
   394       Lori = -10.0 + 0.354*m_streetsOrientation;
       
   395     }
       
   396   else if ((m_streetsOrientation>=35)&&(m_streetsOrientation<55))
       
   397     {
       
   398       Lori = 2.5 + 0.075*(m_streetsOrientation - 35);
       
   399     }
       
   400   else if ((m_streetsOrientation>=55)&&(m_streetsOrientation<90))
       
   401     {
       
   402       Lori = 2.5 + 0.075*(m_streetsOrientation - 55);
       
   403     }
       
   404   else
       
   405     {
       
   406       NS_LOG_ERROR (this << " Street Orientation must be in [0,90]");
       
   407     }
       
   408   double distance = a->GetDistanceFrom (b);
       
   409   double hb = (a->GetPosition ().z>b->GetPosition ().z ? a->GetPosition ().z : b->GetPosition ().z);
       
   410   double hm = (a->GetPosition ().z< b->GetPosition ().z ? a->GetPosition ().z : b->GetPosition ().z);
       
   411   NS_ASSERT_MSG (hm > 0 && hb > 0, "nodes' height must be greater then 0");
       
   412   double Dhb = hb - m_rooftopHeight;
       
   413   double ds = (m_lambda * distance * distance) / (Dhb * Dhb);
       
   414   double Lmsd = 0.0;
       
   415   double pi = 3.141592653589793;
       
   416 //   NS_LOG_INFO (this << " build " << m_buildingsExtend << " ds " << ds << " roof " << m_rooftopHeight << " hb " << hb << " lambda " << m_lambda);
       
   417   if (ds < m_buildingsExtend)
       
   418     {
       
   419       double Lbsh = 0.0;
       
   420       double ka = 0.0;
       
   421       double kd = 0.0;
       
   422       double kf = 0.0;
       
   423       if (hb > m_rooftopHeight)
       
   424         {
       
   425           Lbsh = -18*log10(1+Dhb);
       
   426           ka = (fmhz > 2000 ? 71.4 : 54.0);
       
   427           kd = 18.0;
       
   428         }
       
   429       else 
       
   430         {
       
   431           Lbsh = 0;
       
   432           kd = 18.0 - 15*Dhb/a->GetPosition ().z;
       
   433           if (distance <500)
       
   434             {
       
   435               ka = 54.0 - 1.6*Dhb*distance/1000;
       
   436             }
       
   437             else
       
   438             {
       
   439               ka = 54.0 - 0.8*Dhb;
       
   440             }
       
   441         }
       
   442       if (fmhz>2000)
       
   443         {
       
   444           kf = -8;
       
   445         }
       
   446       else if ((m_environment==Urban)&&(m_citySize==Large))
       
   447         {
       
   448           kf = -4 + 0.7*(fmhz/925.0 -1);
       
   449         }
       
   450       else
       
   451         {
       
   452           kf = -4 + 1.5*(fmhz/925.0 -1);
       
   453         }
       
   454       
       
   455       Lmsd = Lbsh + ka + kd*log10(distance/1000.0) + kf*log10(fmhz) -9.0*log10(m_buildingSeparation); 
       
   456     }
       
   457   else
       
   458     {
       
   459       double theta = atan (Dhb/m_buildingSeparation);
       
   460       double rho = sqrt(Dhb*Dhb+m_buildingSeparation*m_buildingSeparation);
       
   461       double Qm = 0.0;
       
   462       if ((hb > m_rooftopHeight -1.0) && (hb < m_rooftopHeight + 1.0))
       
   463         {
       
   464           Qm = m_buildingSeparation / distance;
       
   465         }
       
   466       else if (hb > m_rooftopHeight)
       
   467         {
       
   468           Qm = 2.35*pow(Dhb/distance*sqrt(m_buildingSeparation/m_lambda), 0.9);
       
   469         }
       
   470       else
       
   471         {
       
   472           Qm = m_buildingSeparation/(2*pi*distance)*sqrt(m_lambda/rho)*(1/theta-(1/(2*pi+theta)));
       
   473         }
       
   474       Lmsd = -10*log10(Qm*Qm);
       
   475     }
       
   476   double Lbf = 32.4 + 20*log10(distance/1000) + 20*log10(fmhz);
       
   477   double Dhm = m_rooftopHeight - hm;
       
   478   double Lrts = -8.2 -10*log10 (m_streetsWidth) + 10*log10 (fmhz) + 20*log10 (Dhm) + Lori;
       
   479 //   NS_LOG_INFO (this << " Lbf " << Lbf << " Lrts " << Lrts << " Dhm" << Dhm << " Lmsd "  << Lmsd);
       
   480   double loss = 0.0;
       
   481   if (Lrts + Lmsd > 0)
       
   482     {
       
   483       loss = Lbf + Lrts + Lmsd;
       
   484     }
       
   485   else
       
   486     {
       
   487       loss = Lbf;
       
   488     }
       
   489   return (loss);
       
   490 }
       
   491 
       
   492 // double
       
   493 // BuildingsPropagationLossModel::ItuR1411NlosStreetCanyons (Ptr<BuildingsMobilityModel> a, Ptr<BuildingsMobilityModel> b) const
       
   494 // {
       
   495 //   NS_LOG_INFO (this);
       
   496 //   // reflection pathloss
       
   497 //   double x1 = a->GetStreetCrossingDistence ();
       
   498 //   double x2 = b->GetStreetCrossingDistence ();
       
   499 //   double f_alpha = 0.0;
       
   500 //   if (m_cornerAngle<= 0.33)
       
   501 //   {
       
   502 //     f_alpha = -41.0 + 110*m_cornerAngle;
       
   503 //   }
       
   504 //   else if (m_cornerAngle<= 0.42)
       
   505 //   {
       
   506 //     f_alpha = -13.94 + 28*m_cornerAngle;
       
   507 //   }
       
   508 //   else if (m_cornerAngle<= 0.71)
       
   509 //   {
       
   510 //     f_alpha = -5.33 + 7.51*m_cornerAngle;
       
   511 //   }
       
   512 //   double pi = 3.141592653589793;
       
   513 //   double Lr = -20*log10 (x1+x2) + (x1*x2*f_alpha/(m_streetsWidth*m_streetsWidth)) - 20*log10 (4*pi/m_lambda);
       
   514 //   
       
   515 //   // diffraction pathloss
       
   516 //   double Da = -1*(40/(2*pi))*(atan (x2/m_streetsWidth) + atan (x1/m_streetsWidth) - (pi/2));
       
   517 //   double Ld = -10*log10 (x2*x1*(x1+x2)) + 2*Da + 0.1*(90 - m_cornerAngle*(180/pi)) - 20*log10 (4*pi/m_lambda);
       
   518 //   
       
   519 //   double loss = -10*log10 (pow (10, Lr/10) + pow (10, Ld/10));
       
   520 //   return (loss);
       
   521 // }
       
   522 
       
   523 
       
   524 double
       
   525 BuildingsPropagationLossModel::ItuR1238 (Ptr<BuildingsMobilityModel> a, Ptr<BuildingsMobilityModel> b) const
       
   526 {
       
   527   double N = 0.0;
       
   528   int n = abs (a->GetFloorNumber () - b->GetFloorNumber ());
       
   529 //   NS_LOG_INFO (this << " A floor " << (uint16_t)a->GetFloorNumber () << " B floor " << (uint16_t)b->GetFloorNumber () << " n " << n);
       
   530   double Lf = 0.0;
       
   531   Ptr<Building> aBuilding = a->GetBuilding ();
       
   532   if (aBuilding->GetBuildingType () == Building::Residential)
       
   533   {
       
   534     N = 28;
       
   535     Lf = 4 * n;
       
   536 //     NS_LOG_INFO (this << " Residential ");
       
   537   }
       
   538   else if (aBuilding->GetBuildingType () == Building::Office)
       
   539   {
       
   540     N = 30;
       
   541     Lf = 15 + (4 * (n-1));
       
   542 //     NS_LOG_INFO (this << " Office ");
       
   543   }
       
   544   else if (aBuilding->GetBuildingType () == Building::Commercial)
       
   545   {
       
   546     N = 22;
       
   547     Lf = 6 + (3 * (n-1));
       
   548 //     NS_LOG_INFO (this << " Commercial ");
       
   549   }
       
   550   else
       
   551   {
       
   552     NS_LOG_ERROR (this << " Unkwnon Wall Type");
       
   553   }
       
   554   
       
   555   double loss = 20*log10(m_frequency/1e6/*MHz*/) + N*log10(a->GetDistanceFrom (b)) + Lf - 28.0;
       
   556   
       
   557   return (loss);
       
   558 }
       
   559 
       
   560 
       
   561 double
       
   562 BuildingsPropagationLossModel::BEWPL (Ptr<BuildingsMobilityModel> a) const
       
   563 {
       
   564   double loss = 0.0;
       
   565   Ptr<Building> aBuilding = a->GetBuilding ();
       
   566   if (aBuilding->GetExtWallsType () == Building::Wood)
       
   567     {
       
   568       loss = 4;
       
   569     }
       
   570   else if (aBuilding->GetExtWallsType () == Building::ConcreteWithWindows)
       
   571     {
       
   572       loss = 7;
       
   573     }
       
   574   else if (aBuilding->GetExtWallsType () == Building::ConcreteWithoutWindows)
       
   575     {
       
   576       loss = 15; // 10 ~ 20 dB
       
   577     }
       
   578   else if (aBuilding->GetExtWallsType () == Building::StoneBlocks)
       
   579     {
       
   580       loss = 12;
       
   581     }
       
   582   
       
   583     
       
   584   return (loss);
       
   585 }
       
   586 
       
   587 
       
   588 double
       
   589 BuildingsPropagationLossModel::HeightGain (Ptr<BuildingsMobilityModel> node) const
       
   590 {
       
   591   double loss = 0.0;
       
   592   
       
   593   int nfloors  = node->GetFloorNumber ();
       
   594   loss = -2*(nfloors);
       
   595   return (loss);
       
   596 }
       
   597 
       
   598 
       
   599 
       
   600 
       
   601 double
       
   602 BuildingsPropagationLossModel::GetLoss (Ptr<MobilityModel> a, Ptr<MobilityModel> b) const
       
   603 {
       
   604   
       
   605   double distance = a->GetDistanceFrom (b);
       
   606   if (distance <= m_minDistance)
       
   607     {
       
   608       return 0.0;
       
   609     }
       
   610   
       
   611   // get the BuildingsMobilityModel pointers
       
   612   Ptr<BuildingsMobilityModel> a1 = DynamicCast<BuildingsMobilityModel> (a);
       
   613   Ptr<BuildingsMobilityModel> b1 = DynamicCast<BuildingsMobilityModel> (b);
       
   614   
       
   615   double loss = 0.0;
       
   616   
       
   617   if (a1->IsOutdoor ())
       
   618     {
       
   619       if (b1->IsOutdoor ())
       
   620         {
       
   621           if (distance > 1000)
       
   622             {
       
   623               NS_LOG_INFO (this << a1->GetPosition ().z<<b1->GetPosition ().z<< m_rooftopHeight);
       
   624               if ((a1->GetPosition ().z < m_rooftopHeight)
       
   625                 && (b1->GetPosition ().z < m_rooftopHeight))
       
   626                 {
       
   627                   // ITU limit in distance (i.e., < 2000 for small cells)
       
   628                   if (distance < m_itu1411DistanceThreshold)
       
   629                     {  
       
   630                       // short range communication
       
   631                       loss = ItuR1411 (a1, b1);
       
   632                       NS_LOG_INFO (this << " 0-0 (>1000): down rooftop -> ITUR1411 : " << loss);
       
   633                     }
       
   634                     else
       
   635                     {
       
   636                       // out of bound
       
   637                       loss = std::numeric_limits<double>::infinity ();
       
   638                       NS_LOG_INFO (this << " 0-0 (>2000): down rooftop -> ITUR1411 : " << loss);
       
   639                     }
       
   640                 }
       
   641               else
       
   642                 {
       
   643                   // Over the rooftop tranmission -> Okumura Hata
       
   644                   loss = OkumuraHata (a1, b1);
       
   645                   NS_LOG_INFO (this << " O-O (>1000): Over the rooftop -> OH : " << loss);
       
   646                 }
       
   647             }
       
   648           else
       
   649             {
       
   650               // short range outdoor communication
       
   651               loss = ItuR1411 (a1, b1);
       
   652               NS_LOG_INFO (this << " 0-0 (<1000) Street canyon -> ITUR1411 : " << loss);
       
   653             }
       
   654         }
       
   655       else
       
   656         {
       
   657           // b indoor
       
   658           if (distance > 1000)
       
   659             {
       
   660               if ((a1->GetPosition ().z < m_rooftopHeight)
       
   661                 && (b1->GetPosition ().z < m_rooftopHeight))
       
   662                 {
       
   663                   
       
   664                   // ITU limit in distance (i.e., < 2000 for small cells)
       
   665                   if (distance < m_itu1411DistanceThreshold)
       
   666                     {  
       
   667                       // short range communication
       
   668                       loss = ItuR1411 (a1, b1) + BEWPL(b1) + HeightGain (a1);
       
   669                       NS_LOG_INFO (this << " 0-I (>1000): down rooftop -> ITUR1411 : " << loss);
       
   670                     }
       
   671                   else
       
   672                     {
       
   673                       // out of bound
       
   674                       loss = std::numeric_limits<double>::infinity ();
       
   675                       NS_LOG_INFO (this << " 0-I (>2000): down rooftop -> ITUR1411 : " << loss);
       
   676                     }
       
   677                 }
       
   678               else
       
   679                 {
       
   680                   // Over the rooftop tranmission -> Okumura Hata
       
   681                   loss = OkumuraHata (a1, b1) + BEWPL(b1);
       
   682                   NS_LOG_INFO (this << " O-I (>1000): Over the rooftop -> OH : " << loss);
       
   683                 }
       
   684             }
       
   685           else
       
   686             {
       
   687               loss = ItuR1411 (a1, b1) + BEWPL(b1) + HeightGain (b1);
       
   688               NS_LOG_INFO (this << " 0-I (<1000) ITUR1411 + BEL : " << loss);
       
   689             }
       
   690         } // end b1->isIndoor ()
       
   691     }
       
   692   else
       
   693     {
       
   694       // a is indoor
       
   695       if (b1->IsIndoor ())
       
   696         {
       
   697           if (a1->GetBuilding () == b1->GetBuilding ())
       
   698             {
       
   699                 // nodes are in same building -> indoor communication ITU-R P.1238
       
   700                 loss = ItuR1238 (a1, b1);
       
   701                 NS_LOG_INFO (this << " I-I (same building) ITUR1238 : " << loss);
       
   702                 
       
   703             }
       
   704           else
       
   705             {
       
   706               // nodes are in different buildings
       
   707               loss = ItuR1411 (a1, b1) + BEWPL(a1) + BEWPL(b1);
       
   708               NS_LOG_INFO (this << " I-I (different) ITUR1238 + 2*BEL : " << loss);
       
   709             }
       
   710         }
       
   711       else
       
   712         {
       
   713           // b is outdoor
       
   714           if (distance > 1000)
       
   715             {
       
   716               if ((a1->GetPosition ().z < m_rooftopHeight)
       
   717                 && (b1->GetPosition ().z < m_rooftopHeight))
       
   718                 {
       
   719                   
       
   720                   // ITU limit in distance (i.e., < 2000 for small cells)
       
   721                   if (distance < m_itu1411DistanceThreshold)
       
   722                     {  
       
   723                       // short range communication
       
   724                       loss = ItuR1411 (a1, b1) + BEWPL(a1) + HeightGain (a1);
       
   725                       NS_LOG_INFO (this << " I-O (>1000): down rooftop -> ITUR1411 : " << loss);
       
   726                     }
       
   727                   else
       
   728                     {
       
   729                       // out of bound
       
   730                       loss = std::numeric_limits<double>::infinity ();
       
   731                       NS_LOG_INFO (this << " I-O (>2000): down rooftop -> ITUR1411 : " << loss);
       
   732                     }
       
   733                 }
       
   734               else
       
   735                 {
       
   736                   // above rooftop -> OH
       
   737                   loss = OkumuraHata (a1, b1) + BEWPL(a1) + HeightGain (a1);
       
   738                   NS_LOG_INFO (this << " =I-O (>1000) over rooftop OH + BEL + HG: " << loss);
       
   739                 }
       
   740             }
       
   741           else
       
   742             {
       
   743               loss = ItuR1411 (a1, b1) + BEWPL(a1)  + HeightGain (a1);
       
   744               NS_LOG_INFO (this << " I-O (<1000)  ITUR1411 + BEL + HG: " << loss);
       
   745             }
       
   746         } // end b1->IsIndoor ()
       
   747     } // end a1->IsOutdoor ()
       
   748 
       
   749   // Evaluate the shadowing
       
   750   PairsList::iterator i = m_shadowingPairs.end ();
       
   751   while (i != m_shadowingPairs.begin ()) 
       
   752     {
       
   753       i--;
       
   754       PairsSet *ps = *i;
       
   755       if (ps->sender == a) 
       
   756         {
       
   757           m_shadowingPairs.erase (i);
       
   758           m_shadowingPairs.push_back (ps);
       
   759           for (DestinationList::iterator r = ps->receivers.begin (); r != ps->receivers.end (); r++) 
       
   760             {
       
   761               ShadowingLoss *pc = *r;
       
   762               if (pc->GetReceiver () == b) 
       
   763                 {
       
   764                   ps->receivers.erase (r);
       
   765                   ps->receivers.push_back (pc);
       
   766                   return loss + pc->GetLoss ();
       
   767                 }
       
   768             }
       
   769             double sigma = EvaluateSigma (a1, b1);
       
   770             ShadowingLoss *pc = new ShadowingLoss (0.0, sigma);
       
   771           ps->receivers.push_back (pc);
       
   772           return loss + pc->GetLoss ();
       
   773         }
       
   774     }
       
   775   PairsSet *ps = new PairsSet;
       
   776   ps->sender = a;
       
   777   double sigma = EvaluateSigma (a1, b1);
       
   778   ShadowingLoss *pc = new ShadowingLoss (0.0, sigma);
       
   779   ps->receivers.push_back (pc);
       
   780   m_shadowingPairs.push_back (ps);
       
   781   return loss + pc->GetLoss ();
       
   782   
       
   783   
       
   784   
       
   785 //   if (m_shadowingValue==0)
       
   786 //     {
       
   787 //       m_shadowingValue = new ShadowingLoss (m_shadowingMean, m_shadowingSigma);
       
   788 //     }
       
   789 //   
       
   790 //   return (loss + m_shadowingValue->GetLoss ());
       
   791 
       
   792 }
       
   793 
       
   794 double
       
   795 BuildingsPropagationLossModel::EvaluateSigma (Ptr<BuildingsMobilityModel> a, Ptr<BuildingsMobilityModel> b)
       
   796 const
       
   797 {
       
   798   if (a->IsOutdoor ())
       
   799   {
       
   800     if (b->IsOutdoor ())
       
   801     {
       
   802       return (m_shadowingSigmaOutdoor);
       
   803     }
       
   804     else
       
   805     {
       
   806       double sigma = sqrt((m_shadowingSigmaOutdoor*m_shadowingSigmaOutdoor) + (m_shadowingSigmaExtWalls*m_shadowingSigmaExtWalls));
       
   807       return (sigma);
       
   808     }
       
   809   }
       
   810   else
       
   811     if (b->IsIndoor ())
       
   812     {
       
   813       return (m_shadowingSigmaIndoor);
       
   814     }
       
   815     else
       
   816     {
       
   817       double sigma = sqrt((m_shadowingSigmaOutdoor*m_shadowingSigmaOutdoor) + (m_shadowingSigmaExtWalls*m_shadowingSigmaExtWalls));
       
   818       return (sigma);
       
   819     }
       
   820 }
       
   821 
       
   822 
       
   823 double
       
   824 BuildingsPropagationLossModel::DoCalcRxPower (double txPowerDbm, Ptr<MobilityModel> a, Ptr<MobilityModel> b) const
       
   825 {
       
   826   return txPowerDbm - GetLoss (a, b);
       
   827 }
       
   828 
       
   829 
       
   830 } // namespace ns3