A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
itu-r-1411-nlos-over-rooftop-propagation-loss-model.cc
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2011, 2012 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  * Nicola Baldo <nbaldo@cttc.es>
20  *
21  */
22 #include "ns3/log.h"
23 #include "ns3/double.h"
24 #include "ns3/enum.h"
25 #include "ns3/mobility-model.h"
26 #include <cmath>
27 
28 #include "itu-r-1411-nlos-over-rooftop-propagation-loss-model.h"
29 
30 NS_LOG_COMPONENT_DEFINE ("ItuR1411NlosOverRooftopPropagationLossModel");
31 
32 namespace ns3 {
33 
34 NS_OBJECT_ENSURE_REGISTERED (ItuR1411NlosOverRooftopPropagationLossModel);
35 
36 
37 TypeId
38 ItuR1411NlosOverRooftopPropagationLossModel::GetTypeId (void)
39 {
40  static TypeId tid = TypeId ("ns3::ItuR1411NlosOverRooftopPropagationLossModel")
41 
42  .SetParent<PropagationLossModel> ()
43 
44  .AddAttribute ("Frequency",
45  "The Frequency (default is 2.106 GHz).",
46  DoubleValue (2160e6),
48  MakeDoubleChecker<double> ())
49 
50 
51  .AddAttribute ("Environment",
52  "Environment Scenario",
53  EnumValue (UrbanEnvironment),
54  MakeEnumAccessor (&ItuR1411NlosOverRooftopPropagationLossModel::m_environment),
55  MakeEnumChecker (UrbanEnvironment, "Urban",
56  SubUrbanEnvironment, "SubUrban",
57  OpenAreasEnvironment, "OpenAreas"))
58 
59  .AddAttribute ("CitySize",
60  "Dimension of the city",
61  EnumValue (LargeCity),
62  MakeEnumAccessor (&ItuR1411NlosOverRooftopPropagationLossModel::m_citySize),
63  MakeEnumChecker (SmallCity, "Small",
64  MediumCity, "Medium",
65  LargeCity, "Large"))
66 
67  .AddAttribute ("RooftopLevel",
68  "The height of the rooftop level in meters",
69  DoubleValue (20.0),
71  MakeDoubleChecker<double> (0.0, 90.0))
72 
73  .AddAttribute ("StreetsOrientation",
74  "The orientation of streets in degrees [0,90] with respect to the direction of propagation",
75  DoubleValue (45.0),
77  MakeDoubleChecker<double> (0.0, 90.0))
78 
79  .AddAttribute ("StreetsWidth",
80  "The width of streets",
81  DoubleValue (20.0),
83  MakeDoubleChecker<double> (0.0, 1000.0))
84 
85  .AddAttribute ("BuildingsExtend",
86  "The distance over which the buildings extend",
87  DoubleValue (80.0),
89  MakeDoubleChecker<double> ())
90 
91  .AddAttribute ("BuildingSeparation",
92  "The separation between buildings",
93  DoubleValue (50.0),
95  MakeDoubleChecker<double> ());
96 
97  return tid;
98 }
99 
100 
101 double
103 {
104  NS_LOG_FUNCTION (this << a << b);
105  double Lori = 0.0;
106  double fmhz = m_frequency / 1e6;
107 
109  " Street Orientation must be in [0,90]");
110  if (m_streetsOrientation < 35)
111  {
112  Lori = -10.0 + 0.354 * m_streetsOrientation;
113  }
114  else if ((m_streetsOrientation >= 35)&&(m_streetsOrientation < 55))
115  {
116  Lori = 2.5 + 0.075 * (m_streetsOrientation - 35);
117  }
118  else // m_streetsOrientation >= 55
119  {
120  Lori = 2.5 + 0.075 * (m_streetsOrientation - 55);
121  }
122 
123  double distance = a->GetDistanceFrom (b);
124  double hb = (a->GetPosition ().z > b->GetPosition ().z ? a->GetPosition ().z : b->GetPosition ().z);
125  double hm = (a->GetPosition ().z < b->GetPosition ().z ? a->GetPosition ().z : b->GetPosition ().z);
126  NS_ASSERT_MSG (hm > 0 && hb > 0, "nodes' height must be greater then 0");
127  double Dhb = hb - m_rooftopHeight;
128  double ds = (m_lambda * distance * distance) / (Dhb * Dhb);
129  double Lmsd = 0.0;
130  NS_LOG_LOGIC (this << " build " << m_buildingsExtend << " ds " << ds << " roof " << m_rooftopHeight << " hb " << hb << " lambda " << m_lambda);
131  if (ds < m_buildingsExtend)
132  {
133  double Lbsh = 0.0;
134  double ka = 0.0;
135  double kd = 0.0;
136  double kf = 0.0;
137  if (hb > m_rooftopHeight)
138  {
139  Lbsh = -18 * std::log10 (1 + Dhb);
140  ka = (fmhz > 2000 ? 71.4 : 54.0);
141  kd = 18.0;
142  }
143  else
144  {
145  Lbsh = 0;
146  kd = 18.0 - 15 * Dhb / a->GetPosition ().z;
147  if (distance < 500)
148  {
149  ka = 54.0 - 1.6 * Dhb * distance / 1000;
150  }
151  else
152  {
153  ka = 54.0 - 0.8 * Dhb;
154  }
155  }
156  if (fmhz > 2000)
157  {
158  kf = -8;
159  }
160  else if ((m_environment == UrbanEnvironment)&&(m_citySize == LargeCity))
161  {
162  kf = -4 + 0.7 * (fmhz / 925.0 - 1);
163  }
164  else
165  {
166  kf = -4 + 1.5 * (fmhz / 925.0 - 1);
167  }
168 
169  Lmsd = Lbsh + ka + kd * std::log10 (distance / 1000.0) + kf * std::log10 (fmhz) - 9.0 * std::log10 (m_buildingSeparation);
170  }
171  else
172  {
173  double theta = std::atan (Dhb / m_buildingSeparation);
174  double rho = std::sqrt (Dhb * Dhb + m_buildingSeparation * m_buildingSeparation);
175  double Qm = 0.0;
176  if ((hb > m_rooftopHeight - 1.0) && (hb < m_rooftopHeight + 1.0))
177  {
178  Qm = m_buildingSeparation / distance;
179  }
180  else if (hb > m_rooftopHeight)
181  {
182  Qm = 2.35 * pow (Dhb / distance * std::sqrt (m_buildingSeparation / m_lambda), 0.9);
183  }
184  else
185  {
186  Qm = m_buildingSeparation / (2 * M_PI * distance) * std::sqrt (m_lambda / rho) * (1 / theta - (1 / (2 * M_PI + theta)));
187  }
188  Lmsd = -10 * std::log10 (Qm * Qm);
189  }
190  double Lbf = 32.4 + 20 * std::log10 (distance / 1000) + 20 * std::log10 (fmhz);
191  double Dhm = m_rooftopHeight - hm;
192  double Lrts = -8.2 - 10 * std::log10 (m_streetsWidth) + 10 * std::log10 (fmhz) + 20 * std::log10 (Dhm) + Lori;
193  NS_LOG_LOGIC (this << " Lbf " << Lbf << " Lrts " << Lrts << " Dhm" << Dhm << " Lmsd " << Lmsd);
194  double loss = 0.0;
195  if (Lrts + Lmsd > 0)
196  {
197  loss = Lbf + Lrts + Lmsd;
198  }
199  else
200  {
201  loss = Lbf;
202  }
203  return loss;
204 }
205 
206 
207 void
209 {
210  m_frequency = freq;
211  m_lambda = 299792458.0 / freq;
212 }
213 
214 
215 double
216 ItuR1411NlosOverRooftopPropagationLossModel::DoCalcRxPower (double txPowerDbm,
218  Ptr<MobilityModel> b) const
219 {
220  return (txPowerDbm - GetLoss (a, b));
221 }
222 
223 int64_t
225 {
226  return 0;
227 }
228 
229 
230 } // namespace ns3
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
double GetLoss(Ptr< MobilityModel > a, Ptr< MobilityModel > b) const
double GetDistanceFrom(Ptr< const MobilityModel > position) const
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
Vector GetPosition(void) const
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
double z
Definition: vector.h:57