A Discrete-Event Network Simulator
API
itu-r-1411-nlos-over-rooftop-propagation-loss-model.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011, 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Marco Miozzo <marco.miozzo@cttc.es>,
18  * Nicola Baldo <nbaldo@cttc.es>
19  *
20  */
22 
23 #include "ns3/double.h"
24 #include "ns3/enum.h"
25 #include "ns3/log.h"
26 #include "ns3/mobility-model.h"
27 
28 #include <cmath>
29 
30 namespace ns3
31 {
32 
33 NS_LOG_COMPONENT_DEFINE("ItuR1411NlosOverRooftopPropagationLossModel");
34 
35 NS_OBJECT_ENSURE_REGISTERED(ItuR1411NlosOverRooftopPropagationLossModel);
36 
37 TypeId
39 {
40  static TypeId tid =
41  TypeId("ns3::ItuR1411NlosOverRooftopPropagationLossModel")
43  .SetGroupName("Propagation")
45  .AddAttribute(
46  "Frequency",
47  "The Frequency (default is 2.106 GHz).",
48  DoubleValue(2160e6),
50  MakeDoubleChecker<double>())
51  .AddAttribute("Environment",
52  "Environment Scenario",
54  MakeEnumAccessor<EnvironmentType>(
57  "Urban",
59  "SubUrban",
61  "OpenAreas"))
62  .AddAttribute(
63  "CitySize",
64  "Dimension of the city",
66  MakeEnumAccessor<CitySize>(
68  MakeEnumChecker(SmallCity, "Small", MediumCity, "Medium", LargeCity, "Large"))
69  .AddAttribute(
70  "RooftopLevel",
71  "The height of the rooftop level in meters",
72  DoubleValue(20.0),
74  MakeDoubleChecker<double>(0.0, 90.0))
75  .AddAttribute("StreetsOrientation",
76  "The orientation of streets in degrees [0,90] with respect to the "
77  "direction of propagation",
78  DoubleValue(45.0),
81  MakeDoubleChecker<double>(0.0, 90.0))
82  .AddAttribute(
83  "StreetsWidth",
84  "The width of streets",
85  DoubleValue(20.0),
87  MakeDoubleChecker<double>(0.0, 1000.0))
88  .AddAttribute(
89  "BuildingsExtend",
90  "The distance over which the buildings extend",
91  DoubleValue(80.0),
93  MakeDoubleChecker<double>())
94  .AddAttribute("BuildingSeparation",
95  "The separation between buildings",
96  DoubleValue(50.0),
99  MakeDoubleChecker<double>());
100 
101  return tid;
102 }
103 
106 {
107 }
108 
110 {
111 }
112 
113 double
115  Ptr<MobilityModel> b) const
116 {
117  NS_LOG_FUNCTION(this << a << b);
118  double Lori = 0.0;
119  double fmhz = m_frequency / 1e6;
120 
122  " Street Orientation must be in [0,90]");
123  if (m_streetsOrientation < 35)
124  {
125  Lori = -10.0 + 0.354 * m_streetsOrientation;
126  }
127  else if ((m_streetsOrientation >= 35) && (m_streetsOrientation < 55))
128  {
129  Lori = 2.5 + 0.075 * (m_streetsOrientation - 35);
130  }
131  else // m_streetsOrientation >= 55
132  {
133  Lori = 2.5 + 0.075 * (m_streetsOrientation - 55);
134  }
135 
136  double distance = a->GetDistanceFrom(b);
137  double hb = (a->GetPosition().z > b->GetPosition().z ? a->GetPosition().z : b->GetPosition().z);
138  double hm = (a->GetPosition().z < b->GetPosition().z ? a->GetPosition().z : b->GetPosition().z);
139  NS_ASSERT_MSG(hm > 0 && hb > 0, "nodes' height must be greater then 0");
140  double Dhb = hb - m_rooftopHeight;
141  double ds = (m_lambda * distance * distance) / (Dhb * Dhb);
142  double Lmsd = 0.0;
143  NS_LOG_LOGIC(this << " build " << m_buildingsExtend << " ds " << ds << " roof "
144  << m_rooftopHeight << " hb " << hb << " lambda " << m_lambda);
145  if (ds < m_buildingsExtend)
146  {
147  double Lbsh = 0.0;
148  double ka = 0.0;
149  double kd = 0.0;
150  double kf = 0.0;
151  if (hb > m_rooftopHeight)
152  {
153  Lbsh = -18 * std::log10(1 + Dhb);
154  ka = (fmhz > 2000 ? 71.4 : 54.0);
155  kd = 18.0;
156  }
157  else
158  {
159  Lbsh = 0;
160  kd = 18.0 - 15 * Dhb / a->GetPosition().z;
161  if (distance < 500)
162  {
163  ka = 54.0 - 1.6 * Dhb * distance / 1000;
164  }
165  else
166  {
167  ka = 54.0 - 0.8 * Dhb;
168  }
169  }
170  if (fmhz > 2000)
171  {
172  kf = -8;
173  }
174  else if ((m_environment == UrbanEnvironment) && (m_citySize == LargeCity))
175  {
176  kf = -4 + 0.7 * (fmhz / 925.0 - 1);
177  }
178  else
179  {
180  kf = -4 + 1.5 * (fmhz / 925.0 - 1);
181  }
182 
183  Lmsd = Lbsh + ka + kd * std::log10(distance / 1000.0) + kf * std::log10(fmhz) -
184  9.0 * std::log10(m_buildingSeparation);
185  }
186  else
187  {
188  double theta = std::atan(Dhb / m_buildingSeparation);
189  double rho = std::sqrt(Dhb * Dhb + m_buildingSeparation * m_buildingSeparation);
190  double Qm = 0.0;
191  if ((hb > m_rooftopHeight - 1.0) && (hb < m_rooftopHeight + 1.0))
192  {
193  Qm = m_buildingSeparation / distance;
194  }
195  else if (hb > m_rooftopHeight)
196  {
197  Qm = 2.35 * pow(Dhb / distance * std::sqrt(m_buildingSeparation / m_lambda), 0.9);
198  }
199  else
200  {
201  Qm = m_buildingSeparation / (2 * M_PI * distance) * std::sqrt(m_lambda / rho) *
202  (1 / theta - (1 / (2 * M_PI + theta)));
203  }
204  Lmsd = -10 * std::log10(Qm * Qm);
205  }
206  double Lbf = 32.4 + 20 * std::log10(distance / 1000) + 20 * std::log10(fmhz);
207  double Dhm = m_rooftopHeight - hm;
208  double Lrts = -8.2 - 10 * std::log10(m_streetsWidth) + 10 * std::log10(fmhz) +
209  20 * std::log10(Dhm) + Lori;
210  NS_LOG_LOGIC(this << " Lbf " << Lbf << " Lrts " << Lrts << " Dhm" << Dhm << " Lmsd " << Lmsd);
211  double loss = 0.0;
212  if (Lrts + Lmsd > 0)
213  {
214  loss = Lbf + Lrts + Lmsd;
215  }
216  else
217  {
218  loss = Lbf;
219  }
220  return loss;
221 }
222 
223 void
225 {
226  m_frequency = freq;
227  m_lambda = 299792458.0 / freq;
228 }
229 
230 double
233  Ptr<MobilityModel> b) const
234 {
235  return (txPowerDbm - GetLoss(a, b));
236 }
237 
238 int64_t
240 {
241  return 0;
242 }
243 
244 } // namespace ns3
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
Hold variables of type enum.
Definition: enum.h:62
int64_t DoAssignStreams(int64_t stream) override
Assign a fixed random variable stream number to the random variables used by this model.
double DoCalcRxPower(double txPowerDbm, Ptr< MobilityModel > a, Ptr< MobilityModel > b) const override
PropagationLossModel.
double GetLoss(Ptr< MobilityModel > a, Ptr< MobilityModel > b) const
double GetDistanceFrom(Ptr< const MobilityModel > position) const
Vector GetPosition() const
Models the propagation loss through a transmission medium.
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.h:194
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43