A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
radio-environment-map-helper.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2012 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: Nicola Baldo <nbaldo@cttc.es>
19  */
20 
21 
23 
24 #include <ns3/abort.h>
25 #include <ns3/log.h>
26 #include <ns3/double.h>
27 #include <ns3/integer.h>
28 #include <ns3/uinteger.h>
29 #include <ns3/string.h>
30 #include <ns3/boolean.h>
31 #include <ns3/spectrum-channel.h>
32 #include <ns3/config.h>
33 #include <ns3/rem-spectrum-phy.h>
34 #include <ns3/mobility-building-info.h>
35 #include <ns3/constant-position-mobility-model.h>
36 #include <ns3/simulator.h>
37 #include <ns3/node.h>
38 #include <ns3/buildings-helper.h>
39 #include <ns3/lte-spectrum-value-helper.h>
40 
41 #include <fstream>
42 #include <limits>
43 
44 NS_LOG_COMPONENT_DEFINE ("RadioEnvironmentMapHelper");
45 
46 namespace ns3 {
47 
48 
49 
50 NS_OBJECT_ENSURE_REGISTERED (RadioEnvironmentMapHelper);
51 
53 {
54 }
55 
56 
58 {
59 }
60 
61 
62 
63 void
65 {
66  NS_LOG_FUNCTION (this);
67 }
68 
69 TypeId
71 {
72  NS_LOG_FUNCTION ("RadioEnvironmentMapHelper::GetTypeId");
73  static TypeId tid = TypeId ("ns3::RadioEnvironmentMapHelper")
74  .SetParent<Object> ()
75  .AddConstructor<RadioEnvironmentMapHelper> ()
76  .AddAttribute ("ChannelPath", "The path to the channel for which the Radio Environment Map is to be generated",
77  StringValue ("/ChannelList/0"),
78  MakeStringAccessor (&RadioEnvironmentMapHelper::m_channelPath),
79  MakeStringChecker ())
80  .AddAttribute ("OutputFile", "the filename to which the Radio Environment Map is saved",
81  StringValue ("rem.out"),
82  MakeStringAccessor (&RadioEnvironmentMapHelper::m_outputFile),
83  MakeStringChecker ())
84  .AddAttribute ("XMin", "The min x coordinate of the map.",
85  DoubleValue (0.0),
86  MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_xMin),
87  MakeDoubleChecker<double> ())
88  .AddAttribute ("YMin", "The min y coordinate of the map.",
89  DoubleValue (0.0),
90  MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_yMin),
91  MakeDoubleChecker<double> ())
92  .AddAttribute ("XMax", "The max x coordinate of the map.",
93  DoubleValue (1.0),
94  MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_xMax),
95  MakeDoubleChecker<double> ())
96  .AddAttribute ("YMax", "The max y coordinate of the map.",
97  DoubleValue (1.0),
98  MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_yMax),
99  MakeDoubleChecker<double> ())
100  .AddAttribute ("XRes", "The resolution (number of points) of the map along the x axis.",
101  UintegerValue (100),
102  MakeUintegerAccessor (&RadioEnvironmentMapHelper::m_xRes),
103  MakeUintegerChecker<uint32_t> (2,std::numeric_limits<uint16_t>::max ()))
104  .AddAttribute ("YRes", "The resolution (number of points) of the map along the y axis.",
105  UintegerValue (100),
106  MakeUintegerAccessor (&RadioEnvironmentMapHelper::m_yRes),
107  MakeUintegerChecker<uint16_t> (2,std::numeric_limits<uint16_t>::max ()))
108  .AddAttribute ("Z", "The value of the z coordinate for which the map is to be generated",
109  DoubleValue (0.0),
110  MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_z),
111  MakeDoubleChecker<double> ())
112  .AddAttribute ("StopWhenDone", "If true, Simulator::Stop () will be called as soon as the REM has been generated",
113  BooleanValue (true),
114  MakeBooleanAccessor (&RadioEnvironmentMapHelper::m_stopWhenDone),
115  MakeBooleanChecker ())
116  .AddAttribute ("NoisePower",
117  "the power of the measuring instrument noise, in Watts. Default to a kT of -174 dBm with a noise figure of 9 dB and a bandwidth of 25 LTE Resource Blocks",
118  DoubleValue (1.4230e-13),
119  MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_noisePower),
120  MakeDoubleChecker<double> ())
121  .AddAttribute ("MaxPointsPerIteration", "Maximum number of REM points to be calculated per iteration. Every point consumes approximately 5KB of memory.",
122  UintegerValue (20000),
124  MakeUintegerChecker<uint32_t> (1,std::numeric_limits<uint32_t>::max ()))
125  .AddAttribute ("Earfcn",
126  "E-UTRA Absolute Radio Frequency Channel Number (EARFCN) "
127  "as per 3GPP 36.101 Section 5.7.3. ",
128  UintegerValue (100),
129  MakeUintegerAccessor (&RadioEnvironmentMapHelper::m_earfcn),
130  MakeUintegerChecker<uint16_t> ())
131  .AddAttribute ("Bandwidth",
132  "Transmission Bandwidth Configuration (in number of RBs) over which the SINR will be calculated",
133  UintegerValue (25),
134  MakeUintegerAccessor (&RadioEnvironmentMapHelper::SetBandwidth,
136  MakeUintegerChecker<uint16_t> ())
137  .AddAttribute ("UseDataChannel",
138  "If true, REM will be generated for PDSCH and for PDCCH otherwise ",
139  BooleanValue (false),
140  MakeBooleanAccessor (&RadioEnvironmentMapHelper::m_useDataChannel),
141  MakeBooleanChecker ())
142  .AddAttribute ("RbId",
143  "Resource block Id, for which REM will be generated,"
144  "default value is -1, what means REM will be averaged from all RBs",
145  IntegerValue (-1),
146  MakeIntegerAccessor (&RadioEnvironmentMapHelper::m_rbId),
147  MakeIntegerChecker<int32_t> ())
148  ;
149  return tid;
150 }
151 
152 
153 uint8_t
155 {
156  return m_bandwidth;
157 }
158 
159 void
161 {
162  switch (bw)
163  {
164  case 6:
165  case 15:
166  case 25:
167  case 50:
168  case 75:
169  case 100:
170  m_bandwidth = bw;
171  break;
172 
173  default:
174  NS_FATAL_ERROR ("invalid bandwidth value " << (uint16_t) bw);
175  break;
176  }
177 }
178 
179 
180 
181 void
183 {
184  NS_LOG_FUNCTION (this);
185  if (!m_rem.empty ())
186  {
187  NS_FATAL_ERROR ("only one REM supported per instance of RadioEnvironmentMapHelper");
188  }
190  if (match.GetN () != 1)
191  {
192  NS_FATAL_ERROR ("Lookup " << m_channelPath << " should have exactly one match");
193  }
194  m_channel = match.Get (0)->GetObject<SpectrumChannel> ();
195  NS_ABORT_MSG_IF (m_channel == 0, "object at " << m_channelPath << "is not of type SpectrumChannel");
196 
197  m_outFile.open (m_outputFile.c_str ());
198  if (!m_outFile.is_open ())
199  {
200  NS_FATAL_ERROR ("Can't open file " << (m_outputFile));
201  return;
202  }
203 
204  double startDelay = 0.0026;
205 
206  if (m_useDataChannel)
207  {
208  //need time to start transmission of data channel
209  startDelay = 0.5001;
210  }
211 
212  Simulator::Schedule (Seconds (startDelay),
214  this);
215 }
216 
217 
218 void
220 {
221  NS_LOG_FUNCTION (this);
222  m_xStep = (m_xMax - m_xMin)/(m_xRes-1);
223  m_yStep = (m_yMax - m_yMin)/(m_yRes-1);
224 
225  if ((double)m_xRes * (double) m_yRes < (double) m_maxPointsPerIteration)
226  {
228  }
229 
230  for (uint32_t i = 0; i < m_maxPointsPerIteration; ++i)
231  {
232  RemPoint p;
233  p.phy = CreateObject<RemSpectrumPhy> ();
234  p.bmm = CreateObject<ConstantPositionMobilityModel> ();
235  Ptr<MobilityBuildingInfo> buildingInfo = CreateObject<MobilityBuildingInfo> ();
236  p.bmm->AggregateObject (buildingInfo); // operation usually done by BuildingsHelper::Install
238  p.phy->SetMobility (p.bmm);
239  p.phy->SetUseDataChannel (m_useDataChannel);
240  p.phy->SetRbId (m_rbId);
241  m_channel->AddRx (p.phy);
242  m_rem.push_back (p);
243  }
244 
245  double remIterationStartTime = 0.0001;
246  double xMinNext = m_xMin;
247  double yMinNext = m_yMin;
248  uint32_t numPointsCurrentIteration = 0;
249  bool justScheduled = false;
250  for (double x = m_xMin; x < m_xMax + 0.5*m_xStep; x += m_xStep)
251  {
252  for (double y = m_yMin; y < m_yMax + 0.5*m_yStep ; y += m_yStep)
253  {
254  if (justScheduled)
255  {
256  xMinNext = x;
257  yMinNext = y;
258  justScheduled = false;
259  }
260 
261  ++numPointsCurrentIteration;
262  if ((numPointsCurrentIteration == m_maxPointsPerIteration)
263  || ((x > m_xMax - 0.5*m_xStep) && (y > m_yMax - 0.5*m_yStep)) )
264  {
265  Simulator::Schedule (Seconds (remIterationStartTime),
267  this, xMinNext, x, yMinNext, y);
268  remIterationStartTime += 0.001;
269  justScheduled = true;
270  numPointsCurrentIteration = 0;
271  }
272  }
273  }
274 
275  Simulator::Schedule (Seconds (remIterationStartTime),
277  this);
278 }
279 
280 
281 void
282 RadioEnvironmentMapHelper::RunOneIteration (double xMin, double xMax, double yMin, double yMax)
283 {
284  NS_LOG_FUNCTION (this << xMin << xMax << yMin << yMax);
285  std::list<RemPoint>::iterator remIt = m_rem.begin ();
286  double x;
287  double y;
288  for (x = xMin; x < xMax + 0.5*m_xStep; x += m_xStep)
289  {
290  for (y = (x == xMin) ? yMin : m_yMin;
291  y < ((x == xMax) ? yMax : m_yMax) + 0.5*m_yStep;
292  y += m_yStep)
293  {
294  NS_ASSERT (remIt != m_rem.end ());
295  remIt->bmm->SetPosition (Vector (x, y, m_z));
296  BuildingsHelper::MakeConsistent (remIt->bmm);
297  ++remIt;
298  }
299  }
300 
301  if (remIt != m_rem.end ())
302  {
303  NS_ASSERT ((x > m_xMax - 0.5*m_xStep) && (y > m_yMax - 0.5*m_yStep));
304  NS_LOG_LOGIC ("deactivating RemSpectrumPhys that are unneeded in the last iteration");
305  while (remIt != m_rem.end ())
306  {
307  remIt->phy->Deactivate ();
308  ++remIt;
309  }
310  }
311 
313 }
314 
315 void
317 {
318  NS_LOG_FUNCTION (this);
319 
320  for (std::list<RemPoint>::iterator it = m_rem.begin ();
321  it != m_rem.end ();
322  ++it)
323  {
324  if (!(it->phy->IsActive ()))
325  {
326  // should occur only upon last iteration when some RemPoint
327  // at the end of the list can be unused
328  break;
329  }
330  Vector pos = it->bmm->GetPosition ();
331  NS_LOG_LOGIC ("output: " << pos.x << "\t"
332  << pos.y << "\t"
333  << pos.z << "\t"
334  << it->phy->GetSinr (m_noisePower));
335  m_outFile << pos.x << "\t"
336  << pos.y << "\t"
337  << pos.z << "\t"
338  << it->phy->GetSinr (m_noisePower)
339  << std::endl;
340  it->phy->Reset ();
341  }
342 }
343 
344 void
346 {
347  NS_LOG_FUNCTION (this);
348  m_outFile.close ();
349  if (m_stopWhenDone)
350  {
351  Simulator::Stop ();
352  }
353 }
354 
355 
356 } // namespace ns3
double x
x coordinate of vector
Definition: vector.h:49
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:60
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Hold a bool native type.
Definition: boolean.h:38
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
hold variables of type string
Definition: string.h:18
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
Hold a signed integer type.
Definition: integer.h:45
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:95
static Ptr< SpectrumModel > GetSpectrumModel(uint16_t earfcn, uint8_t bandwidth)
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:825
a 3d vector
Definition: vector.h:31
static void MakeConsistent(Ptr< MobilityModel > bmm)
Make the given mobility model consistent, by determining whether its position falls inside any of the...
Config::MatchContainer LookupMatches(std::string path)
Definition: config.cc:749
void RunOneIteration(double xMin, double xMax, double yMin, double yMax)
Hold an unsigned integer type.
Definition: uinteger.h:46
void AggregateObject(Ptr< Object > other)
Definition: object.cc:242
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:233
uint32_t GetN(void) const
Definition: config.cc:63
void Install()
Deploy the RemSpectrumPhy objects that generate the map according to the specified settings...
Ptr< Object > Get(uint32_t i) const
Definition: config.cc:69
double y
y coordinate of vector
Definition: vector.h:53
hold a set of objects which match a specific search string.
Definition: config.h:127
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if cond is true.
Definition: abort.h:101
static void Stop(void)
If an event invokes this method, it will be the last event scheduled by the Simulator::run method bef...
Definition: simulator.cc:165
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:845
Defines the interface for spectrum-aware channel implementations.
a base class which provides memory management and object aggregation
Definition: object.h:64
Hold a floating point type.
Definition: double.h:41
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Ptr< T > GetObject(void) const
Definition: object.h:362
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
double z
z coordinate of vector
Definition: vector.h:57