A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
radio-environment-map-helper.cc
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 
22 #include "radio-environment-map-helper.h"
23 
24 #include <ns3/abort.h>
25 #include <ns3/log.h>
26 #include <ns3/double.h>
27 #include <ns3/uinteger.h>
28 #include <ns3/string.h>
29 #include <ns3/boolean.h>
30 #include <ns3/spectrum-channel.h>
31 #include <ns3/config.h>
32 #include <ns3/rem-spectrum-phy.h>
33 #include <ns3/buildings-mobility-model.h>
34 #include <ns3/simulator.h>
35 #include <ns3/node.h>
36 #include <ns3/buildings-helper.h>
37 #include <ns3/lte-spectrum-value-helper.h>
38 
39 #include <fstream>
40 #include <limits>
41 
42 NS_LOG_COMPONENT_DEFINE ("RadioEnvironmentMapHelper");
43 
44 namespace ns3 {
45 
46 
47 
48 NS_OBJECT_ENSURE_REGISTERED (RadioEnvironmentMapHelper);
49 
50 RadioEnvironmentMapHelper::RadioEnvironmentMapHelper ()
51 {
52 }
53 
54 
55 RadioEnvironmentMapHelper::~RadioEnvironmentMapHelper ()
56 {
57 }
58 
59 
60 
61 void
63 {
64  NS_LOG_FUNCTION (this);
65 }
66 
67 TypeId
68 RadioEnvironmentMapHelper::GetTypeId (void)
69 {
70  NS_LOG_FUNCTION ("RadioEnvironmentMapHelper::GetTypeId");
71  static TypeId tid = TypeId ("ns3::RadioEnvironmentMapHelper")
72  .SetParent<Object> ()
73  .AddConstructor<RadioEnvironmentMapHelper> ()
74  .AddAttribute ("ChannelPath", "The path to the channel for which the Radio Environment Map is to be generated",
75  StringValue ("/ChannelList/0"),
76  MakeStringAccessor (&RadioEnvironmentMapHelper::m_channelPath),
77  MakeStringChecker ())
78  .AddAttribute ("OutputFile", "the filename to which the Radio Environment Map is saved",
79  StringValue ("rem.out"),
80  MakeStringAccessor (&RadioEnvironmentMapHelper::m_outputFile),
81  MakeStringChecker ())
82  .AddAttribute ("XMin", "The min x coordinate of the map.",
83  DoubleValue (0.0),
84  MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_xMin),
85  MakeDoubleChecker<double> ())
86  .AddAttribute ("YMin", "The min y coordinate of the map.",
87  DoubleValue (0.0),
88  MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_yMin),
89  MakeDoubleChecker<double> ())
90  .AddAttribute ("XMax", "The max x coordinate of the map.",
91  DoubleValue (1.0),
92  MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_xMax),
93  MakeDoubleChecker<double> ())
94  .AddAttribute ("YMax", "The max y coordinate of the map.",
95  DoubleValue (1.0),
96  MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_yMax),
97  MakeDoubleChecker<double> ())
98  .AddAttribute ("XRes", "The resolution (number of points) of the map along the x axis.",
99  UintegerValue (100),
100  MakeUintegerAccessor (&RadioEnvironmentMapHelper::m_xRes),
101  MakeUintegerChecker<uint32_t> (2,std::numeric_limits<uint16_t>::max ()))
102  .AddAttribute ("YRes", "The resolution (number of points) of the map along the y axis.",
103  UintegerValue (100),
104  MakeUintegerAccessor (&RadioEnvironmentMapHelper::m_yRes),
105  MakeUintegerChecker<uint16_t> (2,std::numeric_limits<uint16_t>::max ()))
106  .AddAttribute ("Z", "The value of the z coordinate for which the map is to be generated",
107  DoubleValue (0.0),
108  MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_z),
109  MakeDoubleChecker<double> ())
110  .AddAttribute ("StopWhenDone", "If true, Simulator::Stop () will be called as soon as the REM has been generated",
111  BooleanValue (true),
112  MakeBooleanAccessor (&RadioEnvironmentMapHelper::m_stopWhenDone),
113  MakeBooleanChecker ())
114  .AddAttribute ("NoisePower",
115  "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",
116  DoubleValue (1.4230e-10),
117  MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_noisePower),
118  MakeDoubleChecker<double> ())
119  .AddAttribute ("MaxPointsPerIteration", "Maximum number of REM points to be calculated per iteration. Every point consumes approximately 5KB of memory.",
120  UintegerValue (20000),
121  MakeUintegerAccessor (&RadioEnvironmentMapHelper::m_maxPointsPerIteration),
122  MakeUintegerChecker<uint32_t> (1,std::numeric_limits<uint32_t>::max ()))
123  .AddAttribute ("Earfcn",
124  "E-UTRA Absolute Radio Frequency Channel Number (EARFCN) "
125  "as per 3GPP 36.101 Section 5.7.3. ",
126  UintegerValue (100),
127  MakeUintegerAccessor (&RadioEnvironmentMapHelper::m_earfcn),
128  MakeUintegerChecker<uint16_t> ())
129  .AddAttribute ("Bandwidth",
130  "Transmission Bandwidth Configuration (in number of RBs) over which the SINR will be calculated",
131  UintegerValue (25),
132  MakeUintegerAccessor (&RadioEnvironmentMapHelper::SetBandwidth,
134  MakeUintegerChecker<uint16_t> ())
135  ;
136  return tid;
137 }
138 
139 
140 uint8_t
142 {
143  return m_bandwidth;
144 }
145 
146 void
148 {
149  switch (bw)
150  {
151  case 6:
152  case 15:
153  case 25:
154  case 50:
155  case 75:
156  case 100:
157  m_bandwidth = bw;
158  break;
159 
160  default:
161  NS_FATAL_ERROR ("invalid bandwidth value " << (uint16_t) bw);
162  break;
163  }
164 }
165 
166 
167 
168 void
170 {
171  NS_LOG_FUNCTION (this);
172  if (!m_rem.empty ())
173  {
174  NS_FATAL_ERROR ("only one REM supported per instance of RadioEnvironmentMapHelper");
175  }
176  Config::MatchContainer match = Config::LookupMatches (m_channelPath);
177  if (match.GetN () != 1)
178  {
179  NS_FATAL_ERROR ("Lookup " << m_channelPath << " should have exactly one match");
180  }
181  m_channel = match.Get (0)->GetObject<SpectrumChannel> ();
182  NS_ABORT_MSG_IF (m_channel == 0, "object at " << m_channelPath << "is not of type SpectrumChannel");
183 
184  m_outFile.open (m_outputFile.c_str ());
185  if (!m_outFile.is_open ())
186  {
187  NS_FATAL_ERROR ("Can't open file " << (m_outputFile));
188  return;
189  }
190 
191  Simulator::Schedule (Seconds (0.0026),
192  &RadioEnvironmentMapHelper::DelayedInstall,
193  this);
194 }
195 
196 
197 void
198 RadioEnvironmentMapHelper::DelayedInstall ()
199 {
200  NS_LOG_FUNCTION (this);
201  m_xStep = (m_xMax - m_xMin)/(m_xRes-1);
202  m_yStep = (m_yMax - m_yMin)/(m_yRes-1);
203 
204  if ((double)m_xRes * (double) m_yRes < (double) m_maxPointsPerIteration)
205  {
206  m_maxPointsPerIteration = m_xRes * m_yRes;
207  }
208 
209  for (uint32_t i = 0; i < m_maxPointsPerIteration; ++i)
210  {
211  RemPoint p;
212  p.phy = CreateObject<RemSpectrumPhy> ();
213  p.bmm = CreateObject<BuildingsMobilityModel> ();
214  p.phy->SetRxSpectrumModel (LteSpectrumValueHelper::GetSpectrumModel (m_earfcn, m_bandwidth));
215  p.phy->SetMobility (p.bmm);
216  m_channel->AddRx (p.phy);
217  m_rem.push_back (p);
218  }
219 
220  double remIterationStartTime = 0.0001;
221  double xMinNext = m_xMin;
222  double yMinNext = m_yMin;
223  uint32_t numPointsCurrentIteration = 0;
224  bool justScheduled = false;
225  for (double x = m_xMin; x < m_xMax + 0.5*m_xStep; x += m_xStep)
226  {
227  for (double y = m_yMin; y < m_yMax + 0.5*m_yStep ; y += m_yStep)
228  {
229  if (justScheduled)
230  {
231  xMinNext = x;
232  yMinNext = y;
233  justScheduled = false;
234  }
235 
236  ++numPointsCurrentIteration;
237  if ((numPointsCurrentIteration == m_maxPointsPerIteration)
238  || ((x > m_xMax - 0.5*m_xStep) && (y > m_yMax - 0.5*m_yStep)) )
239  {
240  Simulator::Schedule (Seconds (remIterationStartTime),
241  &RadioEnvironmentMapHelper::RunOneIteration,
242  this, xMinNext, x, yMinNext, y);
243  remIterationStartTime += 0.001;
244  justScheduled = true;
245  numPointsCurrentIteration = 0;
246  }
247  }
248  }
249  Simulator::Schedule (Seconds (remIterationStartTime),
250  &RadioEnvironmentMapHelper::Finalize,
251  this);
252 }
253 
254 
255 void
256 RadioEnvironmentMapHelper::RunOneIteration (double xMin, double xMax, double yMin, double yMax)
257 {
258  NS_LOG_FUNCTION (this << xMin << xMax << yMin << yMax);
259  std::list<RemPoint>::iterator remIt = m_rem.begin ();
260  double x;
261  double y;
262  for (x = xMin; x < xMax + 0.5*m_xStep; x += m_xStep)
263  {
264  for (y = (x == xMin) ? yMin : m_yMin;
265  y < ((x == xMax) ? yMax : m_yMax) + 0.5*m_yStep;
266  y += m_yStep)
267  {
268  NS_ASSERT (remIt != m_rem.end ());
269  remIt->bmm->SetPosition (Vector (x, y, m_z));
270  BuildingsHelper::MakeConsistent (remIt->bmm);
271  ++remIt;
272  }
273  }
274 
275  if (remIt != m_rem.end ())
276  {
277  NS_ASSERT ((x > m_xMax - 0.5*m_xStep) && (y > m_yMax - 0.5*m_yStep));
278  NS_LOG_LOGIC ("deactivating RemSpectrumPhys that are unneeded in the last iteration");
279  while (remIt != m_rem.end ())
280  {
281  remIt->phy->Deactivate ();
282  ++remIt;
283  }
284  }
285 
286  Simulator::Schedule (Seconds (0.0005), &RadioEnvironmentMapHelper::PrintAndReset, this);
287 }
288 
289 void
290 RadioEnvironmentMapHelper::PrintAndReset ()
291 {
292  NS_LOG_FUNCTION (this);
293 
294  for (std::list<RemPoint>::iterator it = m_rem.begin ();
295  it != m_rem.end ();
296  ++it)
297  {
298  if (!(it->phy->IsActive ()))
299  {
300  // should occur only upon last iteration when some RemPoint
301  // at the end of the list can be unused
302  break;
303  }
304  Vector pos = it->bmm->GetPosition ();
305  NS_LOG_LOGIC ("output: " << pos.x << "\t"
306  << pos.y << "\t"
307  << pos.z << "\t"
308  << it->phy->GetSinr (m_noisePower));
309  m_outFile << pos.x << "\t"
310  << pos.y << "\t"
311  << pos.z << "\t"
312  << it->phy->GetSinr (m_noisePower)
313  << std::endl;
314  it->phy->Reset ();
315  }
316 }
317 
318 void
319 RadioEnvironmentMapHelper::Finalize ()
320 {
321  NS_LOG_FUNCTION (this);
322  m_outFile.close ();
323  if (m_stopWhenDone)
324  {
325  Simulator::Stop ();
326  }
327 }
328 
329 
330 } // namespace ns3
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
Hold a bool native type.
Definition: boolean.h:38
hold variables of type string
Definition: string.h:19
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
static Ptr< SpectrumModel > GetSpectrumModel(uint16_t earfcn, uint8_t bandwidth)
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
Config::MatchContainer LookupMatches(std::string path)
Definition: config.cc:739
Hold an unsigned integer type.
Definition: uinteger.h:46
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
uint32_t GetN(void) const
Definition: config.cc:63
Ptr< Object > Get(uint32_t i) const
Definition: config.cc:69
hold a set of objects which match a specific search string.
Definition: config.h:127
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
static void Stop(void)
Definition: simulator.cc:164
a base class which provides memory management and object aggregation
Definition: object.h:63
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if cond is true.
Definition: abort.h:98
Hold an floating point type.
Definition: double.h:41
Ptr< T > GetObject(void) const
Definition: object.h:332
a unique identifier for an interface.
Definition: type-id.h:44
TypeId SetParent(TypeId tid)
Definition: type-id.cc:471