A Discrete-Event Network Simulator
API
channel-condition-model.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2019 SIGNET Lab, Department of Information Engineering,
4  * University of Padova
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */
19 
21 #include "ns3/log.h"
22 #include "ns3/double.h"
23 #include "ns3/mobility-model.h"
24 #include <cmath>
25 #include "ns3/node.h"
26 #include "ns3/simulator.h"
27 
28 namespace ns3 {
29 
30 NS_LOG_COMPONENT_DEFINE ("ChannelConditionModel");
31 
32 NS_OBJECT_ENSURE_REGISTERED (ChannelCondition);
33 
34 TypeId
36 {
37  static TypeId tid = TypeId ("ns3::ChannelCondition")
38  .SetParent<Object> ()
39  .SetGroupName ("Propagation")
40  ;
41  return tid;
42 }
43 
45 {
46 }
47 
49 {
50 }
51 
54 {
55  return m_losCondition;
56 }
57 
58 void
60 {
61  m_losCondition = cond;
62 }
63 
64 // ------------------------------------------------------------------------- //
65 
67 
68 TypeId
70 {
71  static TypeId tid = TypeId ("ns3::ChannelConditionModel")
72  .SetParent<Object> ()
73  .SetGroupName ("Propagation")
74  ;
75  return tid;
76 }
77 
79 {
80 }
81 
83 {
84 }
85 
86 // ------------------------------------------------------------------------- //
87 
89 
90 TypeId
92 {
93  static TypeId tid = TypeId ("ns3::AlwaysLosChannelConditionModel")
94  .SetParent<Object> ()
95  .SetGroupName ("Propagation")
96  .AddConstructor<AlwaysLosChannelConditionModel> ()
97  ;
98  return tid;
99 }
100 
102 {
103 }
104 
106 {
107 }
108 
111  Ptr<const MobilityModel> b) const
112 {
113  NS_UNUSED (a);
114  NS_UNUSED (b);
115 
116  Ptr<ChannelCondition> c = CreateObject<ChannelCondition> ();
117  c->SetLosCondition (ChannelCondition::LOS);
118 
119  return c;
120 }
121 
122 int64_t
124 {
125  return 0;
126 }
127 
128 // ------------------------------------------------------------------------- //
129 
131 
132 TypeId
134 {
135  static TypeId tid = TypeId ("ns3::NeverLosChannelConditionModel")
136  .SetParent<Object> ()
137  .SetGroupName ("Propagation")
138  .AddConstructor<NeverLosChannelConditionModel> ()
139  ;
140  return tid;
141 }
142 
144 {
145 }
146 
148 {
149 }
150 
153  Ptr<const MobilityModel> b) const
154 {
155  NS_UNUSED (a);
156  NS_UNUSED (b);
157 
158  Ptr<ChannelCondition> c = CreateObject<ChannelCondition> ();
159  c->SetLosCondition (ChannelCondition::NLOS);
160 
161  return c;
162 }
163 
164 int64_t
166 {
167  return 0;
168 }
169 
170 // ------------------------------------------------------------------------- //
171 
173 
174 TypeId
176 {
177  static TypeId tid = TypeId ("ns3::ThreeGppChannelConditionModel")
179  .SetGroupName ("Propagation")
180  .AddAttribute ("UpdatePeriod", "Specifies the time period after which the channel condition is recomputed. If set to 0, the channel condition is never updated.",
181  TimeValue (MilliSeconds (0)),
183  MakeTimeChecker ())
184  ;
185  return tid;
186 }
187 
190 {
191  m_uniformVar = CreateObject<UniformRandomVariable> ();
192  m_uniformVar->SetAttribute ("Min", DoubleValue (0));
193  m_uniformVar->SetAttribute ("Max", DoubleValue (1));
194 }
195 
197 {
198 }
199 
202  Ptr<const MobilityModel> b) const
203 {
205 
206  // get the key for this channel
207  uint32_t key = GetKey (a, b);
208 
209  bool notFound = false; // indicates if the channel condition is not present in the map
210  bool update = false; // indicates if the channel condition has to be updated
211 
212  // look for the channel condition in m_channelConditionMap
213  auto mapItem = m_channelConditionMap.find (key);
214  if (mapItem != m_channelConditionMap.end ())
215  {
216  NS_LOG_DEBUG ("found the channel condition in the map");
217  cond = mapItem->second.m_condition;
218 
219  // check if it has to be updated
220  if (!m_updatePeriod.IsZero () && Simulator::Now () - mapItem->second.m_generatedTime > m_updatePeriod)
221  {
222  NS_LOG_DEBUG ("it has to be updated");
223  update = true;
224  }
225  }
226  else
227  {
228  NS_LOG_DEBUG ("channel condition not found");
229  notFound = true;
230  }
231 
232  // if the channel condition was not found or if it has to be updated
233  // generate a new channel condition
234  if (notFound || update)
235  {
236  // compute the LOS probability (see 3GPP TR 38.901, Sec. 7.4.2)
237  double pLos = ComputePlos (a, b);
238 
239  // draw a random value
240  double pRef = m_uniformVar->GetValue ();
241 
242  // get the channel condition
243  cond = CreateObject<ChannelCondition> ();
244  if (pRef <= pLos)
245  {
246  // LOS
247  cond->SetLosCondition (ChannelCondition::LosConditionValue::LOS);
248  }
249  else
250  {
251  // NLOS
252  cond->SetLosCondition (ChannelCondition::LosConditionValue::NLOS);
253  }
254 
255  {
256  // store the channel condition in m_channelConditionMap, used as cache.
257  // For this reason you see a const_cast.
258  Item mapItem;
259  mapItem.m_condition = cond;
260  mapItem.m_generatedTime = Simulator::Now ();
261  const_cast<ThreeGppChannelConditionModel*> (this)->m_channelConditionMap [key] = mapItem;
262  }
263  }
264 
265  return cond;
266 }
267 
268 int64_t
270 {
271  m_uniformVar->SetStream (stream);
272  return 1;
273 }
274 
275 double
276 ThreeGppChannelConditionModel::Calculate2dDistance (const Vector &a, const Vector &b)
277 {
278  double x = a.x - b.x;
279  double y = a.y - b.y;
280  double distance2D = sqrt (x * x + y * y);
281 
282  return distance2D;
283 }
284 
285 uint32_t
287 {
288  // use the nodes ids to obtain a unique key for the channel between a and b
289  // sort the nodes ids so that the key is reciprocal
290  uint32_t x1 = std::min (a->GetObject<Node> ()->GetId (), b->GetObject<Node> ()->GetId ());
291  uint32_t x2 = std::max (a->GetObject<Node> ()->GetId (), b->GetObject<Node> ()->GetId ());
292 
293  // use the cantor function to obtain the key
294  uint32_t key = (((x1 + x2) * (x1 + x2 + 1)) / 2) + x2;
295 
296  return key;
297 }
298 
299 // ------------------------------------------------------------------------- //
300 
302 
303 TypeId
305 {
306  static TypeId tid = TypeId ("ns3::ThreeGppRmaChannelConditionModel")
308  .SetGroupName ("Propagation")
309  .AddConstructor<ThreeGppRmaChannelConditionModel> ()
310  ;
311  return tid;
312 }
313 
316 {
317 }
318 
320 {
321 }
322 
323 double
325  Ptr<const MobilityModel> b) const
326 {
327  // compute the 2D distance between a and b
328  double distance2D = Calculate2dDistance (a->GetPosition (), b->GetPosition ());
329 
330  // NOTE: no indication is given about the heights of the BS and the UT used
331  // to derive the LOS probability
332 
333  // compute the LOS probability (see 3GPP TR 38.901, Sec. 7.4.2)
334  double pLos = 0.0;
335  if (distance2D <= 10.0)
336  {
337  pLos = 1.0;
338  }
339  else
340  {
341  pLos = exp (-(distance2D - 10.0) / 1000.0);
342  }
343 
344  return pLos;
345 }
346 
347 // ------------------------------------------------------------------------- //
348 
350 
351 TypeId
353 {
354  static TypeId tid = TypeId ("ns3::ThreeGppUmaChannelConditionModel")
356  .SetGroupName ("Propagation")
357  .AddConstructor<ThreeGppUmaChannelConditionModel> ()
358  ;
359  return tid;
360 }
361 
364 {
365 }
366 
368 {
369 }
370 
371 double
373  Ptr<const MobilityModel> b) const
374 {
375  // compute the 2D distance between a and b
376  double distance2D = Calculate2dDistance (a->GetPosition (), b->GetPosition ());
377 
378  // retrieve h_UT, it should be smaller than 23 m
379  double h_UT = std::min (a->GetPosition ().z, b->GetPosition ().z);
380  if (h_UT > 23.0)
381  {
382  NS_LOG_WARN ("The height of the UT should be smaller than 23 m (see TR 38.901, Table 7.4.2-1)");
383  }
384 
385  // retrieve h_BS, it should be equal to 25 m
386  double h_BS = std::max (a->GetPosition ().z, b->GetPosition ().z);
387  if (h_BS != 25.0)
388  {
389  NS_LOG_WARN ("The LOS probability was derived assuming BS antenna heights of 25 m (see TR 38.901, Table 7.4.2-1)");
390  }
391 
392  // compute the LOS probability (see 3GPP TR 38.901, Sec. 7.4.2)
393  double pLos = 0.0;
394  if (distance2D <= 18.0)
395  {
396  pLos = 1.0;
397  }
398  else
399  {
400  // compute C'(h_UT)
401  double c = 0.0;
402  if (h_UT <= 13.0)
403  {
404  c = 0;
405  }
406  else
407  {
408  c = pow ((h_UT - 13.0) / 10.0, 1.5);
409  }
410 
411  pLos = (18.0 / distance2D + exp (-distance2D / 63.0) * (1.0 - 18.0 / distance2D)) * (1.0 + c * 5.0 / 4.0 * pow (distance2D / 100.0, 3.0) * exp (-distance2D / 150.0));
412  }
413 
414  return pLos;
415 }
416 
417 // ------------------------------------------------------------------------- //
418 
420 
421 TypeId
423 {
424  static TypeId tid = TypeId ("ns3::ThreeGppUmiStreetCanyonChannelConditionModel")
426  .SetGroupName ("Propagation")
428  ;
429  return tid;
430 }
431 
434 {
435 }
436 
438 {
439 }
440 
441 double
443  Ptr<const MobilityModel> b) const
444 {
445  // compute the 2D distance between a and b
446  double distance2D = Calculate2dDistance (a->GetPosition (), b->GetPosition ());
447 
448  // NOTE: no idication is given about the UT height used to derive the
449  // LOS probability
450 
451  // h_BS should be equal to 10 m. We check if at least one of the two
452  // nodes has height equal to 10 m
453  if (a->GetPosition ().z != 10.0 && b->GetPosition ().z != 10.0)
454  {
455  NS_LOG_WARN ("The LOS probability was derived assuming BS antenna heights of 10 m (see TR 38.901, Table 7.4.2-1)");
456  }
457 
458  // compute the LOS probability (see 3GPP TR 38.901, Sec. 7.4.2)
459  double pLos = 0.0;
460  if (distance2D <= 18.0)
461  {
462  pLos = 1.0;
463  }
464  else
465  {
466  pLos = 18.0 / distance2D + exp (-distance2D / 36.0) * (1.0 - 18.0 / distance2D);
467  }
468 
469  return pLos;
470 }
471 
472 // ------------------------------------------------------------------------- //
473 
475 
476 TypeId
478 {
479  static TypeId tid = TypeId ("ns3::ThreeGppIndoorMixedOfficeChannelConditionModel")
481  .SetGroupName ("Propagation")
483  ;
484  return tid;
485 }
486 
489 {
490 }
491 
493 {
494 }
495 
496 double
498  Ptr<const MobilityModel> b) const
499 {
500  // compute the 2D distance between a and b
501  double distance2D = Calculate2dDistance (a->GetPosition (), b->GetPosition ());
502 
503  // NOTE: no idication is given about the UT height used to derive the
504  // LOS probability
505 
506  // retrieve h_BS, it should be equal to 3 m
507  double h_BS = std::max (a->GetPosition ().z, b->GetPosition ().z);
508  if (h_BS != 3.0)
509  {
510  NS_LOG_WARN ("The LOS probability was derived assuming BS antenna heights of 3 m (see TR 38.901, Table 7.4.2-1)");
511  }
512 
513  // compute the LOS probability (see 3GPP TR 38.901, Sec. 7.4.2)
514  double pLos = 0.0;
515  if (distance2D <= 1.2)
516  {
517  pLos = 1.0;
518  }
519  else if (distance2D > 1.2 && distance2D < 6.5)
520  {
521  pLos = exp (-(distance2D - 1.2) / 4.7);
522  }
523  else
524  {
525  pLos = exp (-(distance2D - 6.5) / 32.6) * 0.32;
526  }
527 
528  return pLos;
529 }
530 
531 // ------------------------------------------------------------------------- //
532 
534 
535 TypeId
537 {
538  static TypeId tid = TypeId ("ns3::ThreeGppIndoorOpenOfficeChannelConditionModel")
540  .SetGroupName ("Propagation")
542  ;
543  return tid;
544 }
545 
548 {
549 }
550 
552 {
553 }
554 
555 double
557  Ptr<const MobilityModel> b) const
558 {
559  // compute the 2D distance between a and b
560  double distance2D = Calculate2dDistance (a->GetPosition (), b->GetPosition ());
561 
562  // NOTE: no idication is given about the UT height used to derive the
563  // LOS probability
564 
565  // retrieve h_BS, it should be equal to 3 m
566  double h_BS = std::max (a->GetPosition ().z, b->GetPosition ().z);
567  if (h_BS != 3.0)
568  {
569  NS_LOG_WARN ("The LOS probability was derived assuming BS antenna heights of 3 m (see TR 38.901, Table 7.4.2-1)");
570  }
571 
572  // compute the LOS probability (see 3GPP TR 38.901, Sec. 7.4.2)
573  double pLos = 0.0;
574  if (distance2D <= 5.0)
575  {
576  pLos = 1.0;
577  }
578  else if (distance2D > 5.0 && distance2D <= 49.0)
579  {
580  pLos = exp (-(distance2D - 5.0) / 70.8);
581  }
582  else
583  {
584  pLos = exp (-(distance2D - 49.0) / 211.7) * 0.54;
585  }
586 
587  return pLos;
588 }
589 
590 } // end namespace ns3
virtual double ComputePlos(Ptr< const MobilityModel > a, Ptr< const MobilityModel > b) const =0
Compute the LOS probability as specified in Table 7.4.2-1 of 3GPP TR 38.901.
virtual int64_t AssignStreams(int64_t stream) override
If this model uses objects of type RandomVariableStream, set the stream numbers to the integers start...
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
Models the channel condition.
uint32_t GetId(void) const
Definition: node.cc:107
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
virtual ~ThreeGppIndoorOpenOfficeChannelConditionModel() override
Destructor for the ThreeGppIndoorOpenOfficeChannelConditionModel class.
LosConditionValue m_losCondition
contains the information about the LOS/NLOS state of the channel
#define min(a, b)
Definition: 80211b.c:42
virtual double ComputePlos(Ptr< const MobilityModel > a, Ptr< const MobilityModel > b) const override
Compute the LOS probability as specified in Table 7.4.2-1 of 3GPP TR 38.901 for the UMi-Street Canyon...
Struct to store the channel condition in the m_channelConditionMap.
ThreeGppChannelConditionModel()
Constructor for the ThreeGppRmaChannelConditionModel class.
static TypeId GetTypeId(void)
Get the type ID.
virtual Ptr< ChannelCondition > GetChannelCondition(Ptr< const MobilityModel > a, Ptr< const MobilityModel > b) const override
Computes the condition of the channel between a and b, that will be always non-LoS.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
static double Calculate2dDistance(const Vector &a, const Vector &b)
Computes the 2D distance between two 3D vectors.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1078
std::unordered_map< uint32_t, Item > m_channelConditionMap
map to store the channel conditions
virtual ~ChannelConditionModel()
Destructor for the ChannelConditionModel class.
#define NS_UNUSED(x)
Mark a local variable as unused.
Definition: unused.h:36
ThreeGppUmiStreetCanyonChannelConditionModel()
Constructor for the ThreeGppUmiStreetCanyonChannelConditionModel class.
LosConditionValue GetLosCondition() const
Get the LosConditionValue contaning the information about the LOS/NLOS state of the channel...
Ptr< UniformRandomVariable > m_uniformVar
uniform random variable
ThreeGppIndoorOpenOfficeChannelConditionModel()
Constructor for the ThreeGppIndoorOpenOfficeChannelConditionModel class.
static uint32_t GetKey(Ptr< const MobilityModel > a, Ptr< const MobilityModel > b)
Returns a unique and reciprocal key for the channel between a and b.
virtual ~ThreeGppIndoorMixedOfficeChannelConditionModel() override
Destructor for the ThreeGppIndoorMixedOfficeChannelConditionModel class.
ThreeGppUmaChannelConditionModel()
Constructor for the ThreeGppUmaChannelConditionModel class.
static TypeId GetTypeId(void)
Get the type ID.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:449
virtual int64_t AssignStreams(int64_t stream) override
If this model uses objects of type RandomVariableStream, set the stream numbers to the integers start...
virtual ~AlwaysLosChannelConditionModel()
Destructor for the ChannelConditionModel class.
#define max(a, b)
Definition: 80211b.c:43
bool IsZero(void) const
Definition: nstime.h:294
virtual ~ThreeGppUmiStreetCanyonChannelConditionModel() override
Destructor for the ThreeGppUmiStreetCanyonChannelConditionModel class.
AttributeValue implementation for Time.
Definition: nstime.h:1132
Ptr< ChannelCondition > m_condition
the channel condition
static TypeId GetTypeId(void)
Get the type ID.
ThreeGppIndoorMixedOfficeChannelConditionModel()
Constructor for the ThreeGppIndoorMixedOfficeChannelConditionModel class.
Base class for the 3GPP channel condition models.
Computes the channel condition for the RMa scenario.
Computes the channel condition for the UMa scenario.
virtual double ComputePlos(Ptr< const MobilityModel > a, Ptr< const MobilityModel > b) const override
Compute the LOS probability as specified in Table 7.4.2-1 of 3GPP TR 38.901 for the RMa scenario...
virtual ~ThreeGppRmaChannelConditionModel() override
Destructor for the ThreeGppRmaChannelConditionModel class.
virtual Ptr< ChannelCondition > GetChannelCondition(Ptr< const MobilityModel > a, Ptr< const MobilityModel > b) const override
Computes the condition of the channel between a and b, that will be always LoS.
Computes the channel condition for the Indoor Mixed Office scenario.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
virtual double ComputePlos(Ptr< const MobilityModel > a, Ptr< const MobilityModel > b) const override
Compute the LOS probability as specified in Table 7.4.2-1 of 3GPP TR 38.901 for the Indoor Mixed Offi...
virtual double ComputePlos(Ptr< const MobilityModel > a, Ptr< const MobilityModel > b) const override
Compute the LOS probability as specified in Table 7.4.2-1 of 3GPP TR 38.901 for the Indoor Open Offic...
Computes the channel condition for the Indoor Open Office scenario.
virtual Ptr< ChannelCondition > GetChannelCondition(Ptr< const MobilityModel > a, Ptr< const MobilityModel > b) const override
Retrieve the condition of the channel between a and b.
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
static TypeId GetTypeId(void)
Get the type ID.
virtual ~ChannelCondition()
Destructor for the ChannelCondition class.
static TypeId GetTypeId(void)
Get the type ID.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:1133
static TypeId GetTypeId(void)
Get the type ID.
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:193
ChannelConditionModel()
Constructor for the ChannelConditionModel class.
Time m_updatePeriod
the update period for the channel condition
ThreeGppRmaChannelConditionModel()
Constructor for the ThreeGppRmaChannelConditionModel class.
virtual ~NeverLosChannelConditionModel()
Destructor for the ChannelConditionModel class.
void SetLosCondition(LosConditionValue losCondition)
Set the LosConditionValue with the information about the LOS/NLOS state of the channel.
NeverLosChannelConditionModel()
Constructor for the ChannelConditionModel class.
Models a never in-LoS condition model.
virtual ~ThreeGppChannelConditionModel() override
Destructor for the ThreeGppRmaChannelConditionModel class.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
virtual ~ThreeGppUmaChannelConditionModel() override
Destructor for the ThreeGppUmaChannelConditionModel class.
static TypeId GetTypeId(void)
Get the type ID.
Time m_generatedTime
the time when the condition was generated
A network Node.
Definition: node.h:56
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
Models an always in-LoS condition model.
A base class which provides memory management and object aggregation.
Definition: object.h:87
LosConditionValue
Possible values for Line-of-Sight condition.
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
ChannelCondition()
Constructor for the ChannelCondition class.
Computes the channel condition for the UMi-Street canyon scenario.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:187
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
virtual int64_t AssignStreams(int64_t stream) override
If this model uses objects of type RandomVariableStream, set the stream numbers to the integers start...
AlwaysLosChannelConditionModel()
Constructor for the ChannelConditionModel class.
virtual double ComputePlos(Ptr< const MobilityModel > a, Ptr< const MobilityModel > b) const override
Compute the LOS probability as specified in Table 7.4.2-1 of 3GPP TR 38.901 for the UMa scenario...