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 
201 {
202  m_channelConditionMap.clear ();
203  m_updatePeriod = Seconds (0.0);
204 }
205 
208  Ptr<const MobilityModel> b) const
209 {
211 
212  // get the key for this channel
213  uint32_t key = GetKey (a, b);
214 
215  bool notFound = false; // indicates if the channel condition is not present in the map
216  bool update = false; // indicates if the channel condition has to be updated
217 
218  // look for the channel condition in m_channelConditionMap
219  auto mapItem = m_channelConditionMap.find (key);
220  if (mapItem != m_channelConditionMap.end ())
221  {
222  NS_LOG_DEBUG ("found the channel condition in the map");
223  cond = mapItem->second.m_condition;
224 
225  // check if it has to be updated
226  if (!m_updatePeriod.IsZero () && Simulator::Now () - mapItem->second.m_generatedTime > m_updatePeriod)
227  {
228  NS_LOG_DEBUG ("it has to be updated");
229  update = true;
230  }
231  }
232  else
233  {
234  NS_LOG_DEBUG ("channel condition not found");
235  notFound = true;
236  }
237 
238  // if the channel condition was not found or if it has to be updated
239  // generate a new channel condition
240  if (notFound || update)
241  {
242  // compute the LOS probability (see 3GPP TR 38.901, Sec. 7.4.2)
243  double pLos = ComputePlos (a, b);
244 
245  // draw a random value
246  double pRef = m_uniformVar->GetValue ();
247 
248  // get the channel condition
249  cond = CreateObject<ChannelCondition> ();
250  if (pRef <= pLos)
251  {
252  // LOS
253  cond->SetLosCondition (ChannelCondition::LosConditionValue::LOS);
254  }
255  else
256  {
257  // NLOS
258  cond->SetLosCondition (ChannelCondition::LosConditionValue::NLOS);
259  }
260 
261  {
262  // store the channel condition in m_channelConditionMap, used as cache.
263  // For this reason you see a const_cast.
264  Item mapItem;
265  mapItem.m_condition = cond;
266  mapItem.m_generatedTime = Simulator::Now ();
267  const_cast<ThreeGppChannelConditionModel*> (this)->m_channelConditionMap [key] = mapItem;
268  }
269  }
270 
271  return cond;
272 }
273 
274 int64_t
276 {
277  m_uniformVar->SetStream (stream);
278  return 1;
279 }
280 
281 double
282 ThreeGppChannelConditionModel::Calculate2dDistance (const Vector &a, const Vector &b)
283 {
284  double x = a.x - b.x;
285  double y = a.y - b.y;
286  double distance2D = sqrt (x * x + y * y);
287 
288  return distance2D;
289 }
290 
291 uint32_t
293 {
294  // use the nodes ids to obtain a unique key for the channel between a and b
295  // sort the nodes ids so that the key is reciprocal
296  uint32_t x1 = std::min (a->GetObject<Node> ()->GetId (), b->GetObject<Node> ()->GetId ());
297  uint32_t x2 = std::max (a->GetObject<Node> ()->GetId (), b->GetObject<Node> ()->GetId ());
298 
299  // use the cantor function to obtain the key
300  uint32_t key = (((x1 + x2) * (x1 + x2 + 1)) / 2) + x2;
301 
302  return key;
303 }
304 
305 // ------------------------------------------------------------------------- //
306 
308 
309 TypeId
311 {
312  static TypeId tid = TypeId ("ns3::ThreeGppRmaChannelConditionModel")
314  .SetGroupName ("Propagation")
315  .AddConstructor<ThreeGppRmaChannelConditionModel> ()
316  ;
317  return tid;
318 }
319 
322 {
323 }
324 
326 {
327 }
328 
329 double
331  Ptr<const MobilityModel> b) const
332 {
333  // compute the 2D distance between a and b
334  double distance2D = Calculate2dDistance (a->GetPosition (), b->GetPosition ());
335 
336  // NOTE: no indication is given about the heights of the BS and the UT used
337  // to derive the LOS probability
338 
339  // compute the LOS probability (see 3GPP TR 38.901, Sec. 7.4.2)
340  double pLos = 0.0;
341  if (distance2D <= 10.0)
342  {
343  pLos = 1.0;
344  }
345  else
346  {
347  pLos = exp (-(distance2D - 10.0) / 1000.0);
348  }
349 
350  return pLos;
351 }
352 
353 // ------------------------------------------------------------------------- //
354 
356 
357 TypeId
359 {
360  static TypeId tid = TypeId ("ns3::ThreeGppUmaChannelConditionModel")
362  .SetGroupName ("Propagation")
363  .AddConstructor<ThreeGppUmaChannelConditionModel> ()
364  ;
365  return tid;
366 }
367 
370 {
371 }
372 
374 {
375 }
376 
377 double
379  Ptr<const MobilityModel> b) const
380 {
381  // compute the 2D distance between a and b
382  double distance2D = Calculate2dDistance (a->GetPosition (), b->GetPosition ());
383 
384  // retrieve h_UT, it should be smaller than 23 m
385  double h_UT = std::min (a->GetPosition ().z, b->GetPosition ().z);
386  if (h_UT > 23.0)
387  {
388  NS_LOG_WARN ("The height of the UT should be smaller than 23 m (see TR 38.901, Table 7.4.2-1)");
389  }
390 
391  // retrieve h_BS, it should be equal to 25 m
392  double h_BS = std::max (a->GetPosition ().z, b->GetPosition ().z);
393  if (h_BS != 25.0)
394  {
395  NS_LOG_WARN ("The LOS probability was derived assuming BS antenna heights of 25 m (see TR 38.901, Table 7.4.2-1)");
396  }
397 
398  // compute the LOS probability (see 3GPP TR 38.901, Sec. 7.4.2)
399  double pLos = 0.0;
400  if (distance2D <= 18.0)
401  {
402  pLos = 1.0;
403  }
404  else
405  {
406  // compute C'(h_UT)
407  double c = 0.0;
408  if (h_UT <= 13.0)
409  {
410  c = 0;
411  }
412  else
413  {
414  c = pow ((h_UT - 13.0) / 10.0, 1.5);
415  }
416 
417  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));
418  }
419 
420  return pLos;
421 }
422 
423 // ------------------------------------------------------------------------- //
424 
426 
427 TypeId
429 {
430  static TypeId tid = TypeId ("ns3::ThreeGppUmiStreetCanyonChannelConditionModel")
432  .SetGroupName ("Propagation")
434  ;
435  return tid;
436 }
437 
440 {
441 }
442 
444 {
445 }
446 
447 double
449  Ptr<const MobilityModel> b) const
450 {
451  // compute the 2D distance between a and b
452  double distance2D = Calculate2dDistance (a->GetPosition (), b->GetPosition ());
453 
454  // NOTE: no idication is given about the UT height used to derive the
455  // LOS probability
456 
457  // h_BS should be equal to 10 m. We check if at least one of the two
458  // nodes has height equal to 10 m
459  if (a->GetPosition ().z != 10.0 && b->GetPosition ().z != 10.0)
460  {
461  NS_LOG_WARN ("The LOS probability was derived assuming BS antenna heights of 10 m (see TR 38.901, Table 7.4.2-1)");
462  }
463 
464  // compute the LOS probability (see 3GPP TR 38.901, Sec. 7.4.2)
465  double pLos = 0.0;
466  if (distance2D <= 18.0)
467  {
468  pLos = 1.0;
469  }
470  else
471  {
472  pLos = 18.0 / distance2D + exp (-distance2D / 36.0) * (1.0 - 18.0 / distance2D);
473  }
474 
475  return pLos;
476 }
477 
478 // ------------------------------------------------------------------------- //
479 
481 
482 TypeId
484 {
485  static TypeId tid = TypeId ("ns3::ThreeGppIndoorMixedOfficeChannelConditionModel")
487  .SetGroupName ("Propagation")
489  ;
490  return tid;
491 }
492 
495 {
496 }
497 
499 {
500 }
501 
502 double
504  Ptr<const MobilityModel> b) const
505 {
506  // compute the 2D distance between a and b
507  double distance2D = Calculate2dDistance (a->GetPosition (), b->GetPosition ());
508 
509  // NOTE: no idication is given about the UT height used to derive the
510  // LOS probability
511 
512  // retrieve h_BS, it should be equal to 3 m
513  double h_BS = std::max (a->GetPosition ().z, b->GetPosition ().z);
514  if (h_BS != 3.0)
515  {
516  NS_LOG_WARN ("The LOS probability was derived assuming BS antenna heights of 3 m (see TR 38.901, Table 7.4.2-1)");
517  }
518 
519  // compute the LOS probability (see 3GPP TR 38.901, Sec. 7.4.2)
520  double pLos = 0.0;
521  if (distance2D <= 1.2)
522  {
523  pLos = 1.0;
524  }
525  else if (distance2D > 1.2 && distance2D < 6.5)
526  {
527  pLos = exp (-(distance2D - 1.2) / 4.7);
528  }
529  else
530  {
531  pLos = exp (-(distance2D - 6.5) / 32.6) * 0.32;
532  }
533 
534  return pLos;
535 }
536 
537 // ------------------------------------------------------------------------- //
538 
540 
541 TypeId
543 {
544  static TypeId tid = TypeId ("ns3::ThreeGppIndoorOpenOfficeChannelConditionModel")
546  .SetGroupName ("Propagation")
548  ;
549  return tid;
550 }
551 
554 {
555 }
556 
558 {
559 }
560 
561 double
563  Ptr<const MobilityModel> b) const
564 {
565  // compute the 2D distance between a and b
566  double distance2D = Calculate2dDistance (a->GetPosition (), b->GetPosition ());
567 
568  // NOTE: no idication is given about the UT height used to derive the
569  // LOS probability
570 
571  // retrieve h_BS, it should be equal to 3 m
572  double h_BS = std::max (a->GetPosition ().z, b->GetPosition ().z);
573  if (h_BS != 3.0)
574  {
575  NS_LOG_WARN ("The LOS probability was derived assuming BS antenna heights of 3 m (see TR 38.901, Table 7.4.2-1)");
576  }
577 
578  // compute the LOS probability (see 3GPP TR 38.901, Sec. 7.4.2)
579  double pLos = 0.0;
580  if (distance2D <= 5.0)
581  {
582  pLos = 1.0;
583  }
584  else if (distance2D > 5.0 && distance2D <= 49.0)
585  {
586  pLos = exp (-(distance2D - 5.0) / 70.8);
587  }
588  else
589  {
590  pLos = exp (-(distance2D - 49.0) / 211.7) * 0.54;
591  }
592 
593  return pLos;
594 }
595 
596 } // 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:109
#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:1286
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.
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
Exactly equivalent to t == 0.
Definition: nstime.h:300
virtual ~ThreeGppUmiStreetCanyonChannelConditionModel() override
Destructor for the ThreeGppUmiStreetCanyonChannelConditionModel class.
AttributeValue implementation for Time.
Definition: nstime.h:1342
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.
virtual void DoDispose() override
Destructor implementation.
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:1343
static TypeId GetTypeId(void)
Get the type ID.
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
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
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1278
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:472
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:185
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...