A Discrete-Event Network Simulator
API
radio-environment-map-helper.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 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: Nicola Baldo <nbaldo@cttc.es>
18  */
19 
21 
22 #include <ns3/abort.h>
23 #include <ns3/boolean.h>
24 #include <ns3/buildings-helper.h>
25 #include <ns3/config.h>
26 #include <ns3/constant-position-mobility-model.h>
27 #include <ns3/double.h>
28 #include <ns3/integer.h>
29 #include <ns3/log.h>
30 #include <ns3/lte-spectrum-value-helper.h>
31 #include <ns3/mobility-building-info.h>
32 #include <ns3/node.h>
33 #include <ns3/pointer.h>
34 #include <ns3/rem-spectrum-phy.h>
35 #include <ns3/simulator.h>
36 #include <ns3/spectrum-channel.h>
37 #include <ns3/string.h>
38 #include <ns3/uinteger.h>
39 
40 #include <fstream>
41 #include <limits>
42 
43 namespace ns3
44 {
45 
46 NS_LOG_COMPONENT_DEFINE("RadioEnvironmentMapHelper");
47 
48 NS_OBJECT_ENSURE_REGISTERED(RadioEnvironmentMapHelper);
49 
51 {
52 }
53 
55 {
56 }
57 
58 void
60 {
61  NS_LOG_FUNCTION(this);
62 }
63 
64 TypeId
66 {
67  NS_LOG_FUNCTION("RadioEnvironmentMapHelper::GetTypeId");
68  static TypeId tid =
69  TypeId("ns3::RadioEnvironmentMapHelper")
70  .SetParent<Object>()
71  .SetGroupName("Lte")
72  .AddConstructor<RadioEnvironmentMapHelper>()
73  .AddAttribute(
74  "Channel",
75  "The DL spectrum channel for which the RadioEnvironment Map is to be generated. "
76  "Alternatively ChannelPath attribute can be used."
77  "Only one of the two (Channel or ChannelPath) should be set.",
78  PointerValue(nullptr),
80  MakePointerChecker<SpectrumChannel>())
81  .AddAttribute(
82  "ChannelPath",
83  "The path to the channel for which the Radio Environment Map is to be generated."
84  "This attribute is an alternative to Channel attribute and is only used if Channel "
85  "is not set (equal to nullptr). "
86  "Only one of the two (Channel or ChannelPath) should be set.",
87  StringValue("/ChannelList/0"),
90  .AddAttribute("OutputFile",
91  "the filename to which the Radio Environment Map is saved",
92  StringValue("rem.out"),
95  .AddAttribute("XMin",
96  "The min x coordinate of the map.",
97  DoubleValue(0.0),
99  MakeDoubleChecker<double>())
100  .AddAttribute("YMin",
101  "The min y coordinate of the map.",
102  DoubleValue(0.0),
104  MakeDoubleChecker<double>())
105  .AddAttribute("XMax",
106  "The max x coordinate of the map.",
107  DoubleValue(1.0),
109  MakeDoubleChecker<double>())
110  .AddAttribute("YMax",
111  "The max y coordinate of the map.",
112  DoubleValue(1.0),
114  MakeDoubleChecker<double>())
115  .AddAttribute("XRes",
116  "The resolution (number of points) of the map along the x axis.",
117  UintegerValue(100),
119  MakeUintegerChecker<uint32_t>(2, std::numeric_limits<uint16_t>::max()))
120  .AddAttribute("YRes",
121  "The resolution (number of points) of the map along the y axis.",
122  UintegerValue(100),
124  MakeUintegerChecker<uint16_t>(2, std::numeric_limits<uint16_t>::max()))
125  .AddAttribute("Z",
126  "The value of the z coordinate for which the map is to be generated",
127  DoubleValue(0.0),
129  MakeDoubleChecker<double>())
130  .AddAttribute(
131  "StopWhenDone",
132  "If true, Simulator::Stop () will be called as soon as the REM has been generated",
133  BooleanValue(true),
136  .AddAttribute(
137  "NoisePower",
138  "the power of the measuring instrument noise, in Watts. Default to a kT of -174 "
139  "dBm with a noise figure of 9 dB and a bandwidth of 25 LTE Resource Blocks",
140  DoubleValue(1.4230e-13),
142  MakeDoubleChecker<double>())
143  .AddAttribute("MaxPointsPerIteration",
144  "Maximum number of REM points to be calculated per iteration. Every "
145  "point consumes approximately 5KB of memory.",
146  UintegerValue(20000),
148  MakeUintegerChecker<uint32_t>(1, std::numeric_limits<uint32_t>::max()))
149  .AddAttribute("Earfcn",
150  "E-UTRA Absolute Radio Frequency Channel Number (EARFCN) "
151  "as per 3GPP 36.101 Section 5.7.3.",
152  UintegerValue(100),
154  MakeUintegerChecker<uint16_t>())
155  .AddAttribute("Bandwidth",
156  "Transmission Bandwidth Configuration (in number of RBs) over which the "
157  "SINR will be calculated",
158  UintegerValue(25),
161  MakeUintegerChecker<uint16_t>())
162  .AddAttribute("UseDataChannel",
163  "If true, REM will be generated for PDSCH and for PDCCH otherwise",
164  BooleanValue(false),
167  .AddAttribute("RbId",
168  "Resource block Id, for which REM will be generated, "
169  "default value is -1, what means REM will be averaged from all RBs",
170  IntegerValue(-1),
172  MakeIntegerChecker<int32_t>());
173  return tid;
174 }
175 
176 uint16_t
178 {
179  return m_bandwidth;
180 }
181 
182 void
184 {
185  switch (bw)
186  {
187  case 6:
188  case 15:
189  case 25:
190  case 50:
191  case 75:
192  case 100:
193  m_bandwidth = bw;
194  break;
195 
196  default:
197  NS_FATAL_ERROR("invalid bandwidth value " << bw);
198  break;
199  }
200 }
201 
202 void
204 {
205  NS_LOG_FUNCTION(this);
206  if (!m_rem.empty())
207  {
208  NS_FATAL_ERROR("only one REM supported per instance of RadioEnvironmentMapHelper");
209  }
210 
211  if (!m_channel) // if Channel attribute is not set, then use the ChannelPath attribute
212  {
214  if (match.GetN() != 1)
215  {
216  NS_FATAL_ERROR("Lookup " << m_channelPath << " should have exactly one match");
217  }
218  m_channel = match.Get(0)->GetObject<SpectrumChannel>();
220  "object at " << m_channelPath << " is not of type SpectrumChannel");
221  }
222 
223  m_outFile.open(m_outputFile.c_str());
224  if (!m_outFile.is_open())
225  {
226  NS_FATAL_ERROR("Can't open file " << (m_outputFile));
227  return;
228  }
229 
230  double startDelay = 0.0026;
231 
232  if (m_useDataChannel)
233  {
234  // need time to start transmission of data channel
235  startDelay = 0.5001;
236  }
237 
239 }
240 
241 void
243 {
244  NS_LOG_FUNCTION(this);
245  m_xStep = (m_xMax - m_xMin) / (m_xRes - 1);
246  m_yStep = (m_yMax - m_yMin) / (m_yRes - 1);
247 
248  if ((double)m_xRes * (double)m_yRes < (double)m_maxPointsPerIteration)
249  {
251  }
252 
253  for (uint32_t i = 0; i < m_maxPointsPerIteration; ++i)
254  {
255  RemPoint p;
256  p.phy = CreateObject<RemSpectrumPhy>();
257  p.bmm = CreateObject<ConstantPositionMobilityModel>();
258  Ptr<MobilityBuildingInfo> buildingInfo = CreateObject<MobilityBuildingInfo>();
259  p.bmm->AggregateObject(buildingInfo); // operation usually done by BuildingsHelper::Install
261  p.phy->SetMobility(p.bmm);
262  p.phy->SetUseDataChannel(m_useDataChannel);
263  p.phy->SetRbId(m_rbId);
264  m_channel->AddRx(p.phy);
265  m_rem.push_back(p);
266  }
267 
268  double remIterationStartTime = 0.0001;
269  double xMinNext = m_xMin;
270  double yMinNext = m_yMin;
271  uint32_t numPointsCurrentIteration = 0;
272  bool justScheduled = false;
273  for (double x = m_xMin; x < m_xMax + 0.5 * m_xStep; x += m_xStep)
274  {
275  for (double y = m_yMin; y < m_yMax + 0.5 * m_yStep; y += m_yStep)
276  {
277  if (justScheduled)
278  {
279  xMinNext = x;
280  yMinNext = y;
281  justScheduled = false;
282  }
283 
284  ++numPointsCurrentIteration;
285  if ((numPointsCurrentIteration == m_maxPointsPerIteration) ||
286  ((x > m_xMax - 0.5 * m_xStep) && (y > m_yMax - 0.5 * m_yStep)))
287  {
288  Simulator::Schedule(Seconds(remIterationStartTime),
290  this,
291  xMinNext,
292  x,
293  yMinNext,
294  y);
295  remIterationStartTime += 0.001;
296  justScheduled = true;
297  numPointsCurrentIteration = 0;
298  }
299  }
300  }
301 
302  Simulator::Schedule(Seconds(remIterationStartTime), &RadioEnvironmentMapHelper::Finalize, this);
303 }
304 
305 void
306 RadioEnvironmentMapHelper::RunOneIteration(double xMin, double xMax, double yMin, double yMax)
307 {
308  NS_LOG_FUNCTION(this << xMin << xMax << yMin << yMax);
309  auto remIt = m_rem.begin();
310  double x = 0.0;
311  double y = 0.0;
312  for (x = xMin; x < xMax + 0.5 * m_xStep; x += m_xStep)
313  {
314  for (y = (x == xMin) ? yMin : m_yMin; y < ((x == xMax) ? yMax : m_yMax) + 0.5 * m_yStep;
315  y += m_yStep)
316  {
317  NS_ASSERT(remIt != m_rem.end());
318  remIt->bmm->SetPosition(Vector(x, y, m_z));
319  Ptr<MobilityBuildingInfo> buildingInfo =
320  (remIt->bmm)->GetObject<MobilityBuildingInfo>();
321  buildingInfo->MakeConsistent(remIt->bmm);
322  ++remIt;
323  }
324  }
325 
326  if (remIt != m_rem.end())
327  {
328  NS_ASSERT((x > m_xMax - 0.5 * m_xStep) && (y > m_yMax - 0.5 * m_yStep));
329  NS_LOG_LOGIC("deactivating RemSpectrumPhys that are unneeded in the last iteration");
330  while (remIt != m_rem.end())
331  {
332  remIt->phy->Deactivate();
333  ++remIt;
334  }
335  }
336 
338 }
339 
340 void
342 {
343  NS_LOG_FUNCTION(this);
344 
345  for (auto it = m_rem.begin(); it != m_rem.end(); ++it)
346  {
347  if (!(it->phy->IsActive()))
348  {
349  // should occur only upon last iteration when some RemPoint
350  // at the end of the list can be unused
351  break;
352  }
353  Vector pos = it->bmm->GetPosition();
354  NS_LOG_LOGIC("output: " << pos.x << "\t" << pos.y << "\t" << pos.z << "\t"
355  << it->phy->GetSinr(m_noisePower));
356  m_outFile << pos.x << "\t" << pos.y << "\t" << pos.z << "\t"
357  << it->phy->GetSinr(m_noisePower) << std::endl;
358  it->phy->Reset();
359  }
360 }
361 
362 void
364 {
365  NS_LOG_FUNCTION(this);
366  m_outFile.close();
367  if (m_stopWhenDone)
368  {
369  Simulator::Stop();
370  }
371 }
372 
373 } // namespace ns3
#define max(a, b)
Definition: 80211b.c:42
hold a set of objects which match a specific search string.
Definition: config.h:195
Ptr< Object > Get(std::size_t i) const
Definition: config.cc:82
std::size_t GetN() const
Definition: config.cc:75
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
Hold a signed integer type.
Definition: integer.h:45
static Ptr< SpectrumModel > GetSpectrumModel(uint32_t earfcn, uint16_t bandwidth)
A base class which provides memory management and object aggregation.
Definition: object.h:89
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:259
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Generates a 2D map of the SINR from the strongest transmitter in the downlink of an LTE FDD system.
void Install()
Deploy the RemSpectrumPhy objects that generate the map according to the specified settings.
static TypeId GetTypeId()
Register this type.
std::list< RemPoint > m_rem
List of listeners in the environment.
Ptr< SpectrumChannel > m_channel
The Channel attribute, which is a direct pointer to the DL channel object for which will be created t...
std::ofstream m_outFile
Stream the output to a file.
bool m_useDataChannel
The UseDataChannel attribute.
std::string m_outputFile
The OutputFile attribute.
double m_noisePower
The NoisePower attribute.
void Finalize()
Called when the map generation procedure has been completed.
void DoDispose() override
Destructor implementation.
uint16_t m_earfcn
The Earfcn attribute.
uint32_t m_maxPointsPerIteration
The MaxPointsPerIteration attribute.
double m_xStep
Distance along X axis between adjacent listening points.
void DelayedInstall()
Scheduled by Install() to perform the actual generation of map.
std::string m_channelPath
The ChannelPath attribute.
void PrintAndReset()
Go through every listener, write the computed SINR, and then reset it.
uint16_t m_bandwidth
The Bandwidth attribute.
void RunOneIteration(double xMin, double xMax, double yMin, double yMax)
Mobilize all the listeners to a specified area.
double m_yStep
Distance along Y axis between adjacent listening points.
bool m_stopWhenDone
The StopWhenDone attribute.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
Defines the interface for spectrum-aware channel implementations.
Hold variables of type string.
Definition: string.h:56
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
Hold an unsigned integer type.
Definition: uinteger.h:45
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
MatchContainer LookupMatches(std::string path)
Definition: config.cc:998
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#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
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:227
Ptr< const AttributeAccessor > MakeIntegerAccessor(T1 a1)
Definition: integer.h:46
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
Ptr< const AttributeChecker > MakeStringChecker()
Definition: string.cc:30
Ptr< const AttributeAccessor > MakeStringAccessor(T1 a1)
Definition: string.h:57
A complete Radio Environment Map is composed of many of this structure.
Ptr< RemSpectrumPhy > phy
Simplified listener which compute SINR over the DL channel.
Ptr< MobilityModel > bmm
Position of the listener in the environment.