A Discrete-Event Network Simulator
API
building-position-allocator.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (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  * Michele Polese <michele.polese@gmail.com> for the OutdoorPositionAllocator class
19  */
21 
22 #include "buildings-helper.h"
23 
24 #include "ns3/boolean.h"
25 #include "ns3/box.h"
26 #include "ns3/building-list.h"
27 #include "ns3/building.h"
28 #include "ns3/double.h"
29 #include "ns3/enum.h"
30 #include "ns3/log.h"
31 #include "ns3/mobility-model.h"
32 #include "ns3/pointer.h"
33 #include "ns3/random-variable-stream.h"
34 #include "ns3/string.h"
35 #include "ns3/uinteger.h"
36 #include <ns3/mobility-building-info.h>
37 
38 #include <cmath>
39 
40 namespace ns3
41 {
42 
43 NS_LOG_COMPONENT_DEFINE("BuildingPositionAllocator");
44 
45 NS_OBJECT_ENSURE_REGISTERED(RandomBuildingPositionAllocator);
46 
48 {
49  m_rand = CreateObject<UniformRandomVariable>();
50 }
51 
52 TypeId
54 {
55  static TypeId tid =
56  TypeId("ns3::RandomBuildingPositionAllocator")
58  .SetGroupName("Buildings")
59  .AddConstructor<RandomBuildingPositionAllocator>()
60  .AddAttribute("WithReplacement",
61  "If true, the building will be randomly selected with replacement. "
62  "If false, no replacement will occur, until the list of buildings "
63  "to select becomes empty, at which point it will be filled again "
64  "with the list of all buildings.",
65  BooleanValue(false),
68  return tid;
69 }
70 
71 Vector
73 {
74  NS_ASSERT_MSG(BuildingList::GetNBuildings() > 0, "no building found");
75  Ptr<Building> b;
77  {
78  uint32_t n = m_rand->GetInteger(0, BuildingList::GetNBuildings() - 1);
80  }
81  else
82  {
84  {
85  for (auto bit = BuildingList::Begin(); bit != BuildingList::End(); ++bit)
86  {
87  m_buildingListWithoutReplacement.push_back(*bit);
88  }
89  }
90  uint32_t n = m_rand->GetInteger(0, m_buildingListWithoutReplacement.size() - 1);
93  }
94 
95  Ptr<RandomBoxPositionAllocator> pa = CreateObject<RandomBoxPositionAllocator>();
96  BoxValue bv;
97  b->GetAttribute("Boundaries", bv);
98  double x = m_rand->GetValue(bv.Get().xMin, bv.Get().xMax);
99  double y = m_rand->GetValue(bv.Get().yMin, bv.Get().yMax);
100  double z = m_rand->GetValue(bv.Get().zMin, bv.Get().zMax);
101  return Vector(x, y, z);
102 }
103 
104 int64_t
106 {
107  m_rand->SetStream(stream);
108  return 1;
109 }
110 
112 
114 {
115 }
116 
117 TypeId
119 {
120  static TypeId tid =
121  TypeId("ns3::OutdoorPositionAllocator")
123  .SetGroupName("Buildings")
124  .AddConstructor<OutdoorPositionAllocator>()
125  .AddAttribute("X",
126  "A random variable which represents the x coordinate of a position in a "
127  "random box.",
128  StringValue("ns3::UniformRandomVariable[Min=0.0|Max=1.0]"),
130  MakePointerChecker<RandomVariableStream>())
131  .AddAttribute("Y",
132  "A random variable which represents the y coordinate of a position in a "
133  "random box.",
134  StringValue("ns3::UniformRandomVariable[Min=0.0|Max=1.0]"),
136  MakePointerChecker<RandomVariableStream>())
137  .AddAttribute("Z",
138  "A random variable which represents the z coordinate of a position in a "
139  "random box.",
140  StringValue("ns3::UniformRandomVariable[Min=0.0|Max=1.0]"),
142  MakePointerChecker<RandomVariableStream>())
143  .AddAttribute("MaxAttempts",
144  "Maximum number of attempts for the rejection sampling before giving up.",
145  UintegerValue(1000),
147  MakeUintegerChecker<uint32_t>());
148 
149  return tid;
150 }
151 
152 void
154 {
155  m_x = x;
156 }
157 
158 void
160 {
161  m_y = y;
162 }
163 
164 void
166 {
167  m_z = z;
168 }
169 
170 Vector
172 {
173  NS_ABORT_MSG_IF(BuildingList::GetNBuildings() == 0, "no building found");
174 
175  bool outdoor = false;
176  uint32_t attempts = 0;
177  Vector position = Vector(0, 0, 0);
178 
179  while (!outdoor && attempts < m_maxAttempts)
180  {
181  // get a random position
182  double x = m_x->GetValue();
183  double y = m_y->GetValue();
184  double z = m_z->GetValue();
185 
186  position = Vector(x, y, z);
187 
188  NS_LOG_INFO("Position " << position);
189 
190  bool inside = false;
191  for (auto bit = BuildingList::Begin(); bit != BuildingList::End(); ++bit)
192  {
193  if ((*bit)->IsInside(position))
194  {
195  NS_LOG_INFO("Position "
196  << position << " is inside the building with boundaries "
197  << (*bit)->GetBoundaries().xMin << " " << (*bit)->GetBoundaries().xMax
198  << " " << (*bit)->GetBoundaries().yMin << " "
199  << (*bit)->GetBoundaries().yMax << " " << (*bit)->GetBoundaries().zMin
200  << " " << (*bit)->GetBoundaries().zMax);
201  inside = true;
202  break;
203  }
204  }
205 
206  if (inside)
207  {
208  NS_LOG_INFO("Inside a building, attempt " << attempts << " out of " << m_maxAttempts);
209  attempts++;
210  }
211  else
212  {
213  NS_LOG_INFO("Outdoor position found " << position);
214  outdoor = true;
215  }
216  }
217 
218  NS_ABORT_MSG_IF(attempts >= m_maxAttempts, "Too many attempts, give up");
219  NS_ABORT_MSG_IF(!outdoor, "Still indoor, give up");
220  return position;
221 }
222 
223 int64_t
225 {
226  m_x->SetStream(stream);
227  m_y->SetStream(stream + 1);
228  m_z->SetStream(stream + 2);
229  return 3;
230 }
231 
233 
235 {
236  m_rand = CreateObject<UniformRandomVariable>();
237 }
238 
239 TypeId
241 {
242  static TypeId tid = TypeId("ns3::RandomRoomPositionAllocator")
244  .SetGroupName("Buildings")
245  .AddConstructor<RandomRoomPositionAllocator>();
246  return tid;
247 }
248 
249 Vector
251 {
252  NS_LOG_FUNCTION(this);
253  NS_ASSERT_MSG(BuildingList::GetNBuildings() > 0, "no building found");
254 
255  if (m_roomListWithoutReplacement.empty())
256  {
257  for (auto bit = BuildingList::Begin(); bit != BuildingList::End(); ++bit)
258  {
259  NS_LOG_LOGIC("building " << (*bit)->GetId());
260  for (uint32_t rx = 1; rx <= (*bit)->GetNRoomsX(); ++rx)
261  {
262  for (uint32_t ry = 1; ry <= (*bit)->GetNRoomsY(); ++ry)
263  {
264  for (uint32_t f = 1; f <= (*bit)->GetNFloors(); ++f)
265  {
266  RoomInfo i;
267  i.roomx = rx;
268  i.roomy = ry;
269  i.floor = f;
270  i.b = *bit;
271  NS_LOG_LOGIC("adding room (" << rx << ", " << ry << ", " << f << ")");
272  m_roomListWithoutReplacement.push_back(i);
273  }
274  }
275  }
276  }
277  }
278  uint32_t n = m_rand->GetInteger(0, m_roomListWithoutReplacement.size() - 1);
281  NS_LOG_LOGIC("considering building " << r.b->GetId() << " room (" << r.roomx << ", " << r.roomy
282  << ", " << r.floor << ")");
283 
284  Ptr<RandomBoxPositionAllocator> pa = CreateObject<RandomBoxPositionAllocator>();
285  BoxValue bv;
286  r.b->GetAttribute("Boundaries", bv);
287  Box box = bv.Get();
288  double rdx = (box.xMax - box.xMin) / r.b->GetNRoomsX();
289  double rdy = (box.yMax - box.yMin) / r.b->GetNRoomsY();
290  double rdz = (box.zMax - box.zMin) / r.b->GetNFloors();
291  double x1 = box.xMin + rdx * (r.roomx - 1);
292  double x2 = box.xMin + rdx * r.roomx;
293  double y1 = box.yMin + rdy * (r.roomy - 1);
294  double y2 = box.yMin + rdy * r.roomy;
295  double z1 = box.zMin + rdz * (r.floor - 1);
296  double z2 = box.zMin + rdz * r.floor;
297  NS_LOG_LOGIC("randomly allocating position in "
298  << " (" << x1 << "," << x2 << ") "
299  << "x (" << y1 << "," << y2 << ") "
300  << "x (" << z1 << "," << z2 << ") ");
301 
302  double x = m_rand->GetValue(x1, x2);
303  double y = m_rand->GetValue(y1, y2);
304  double z = m_rand->GetValue(z1, z2);
305 
306  return Vector(x, y, z);
307 }
308 
309 int64_t
311 {
312  m_rand->SetStream(stream);
313  return 1;
314 }
315 
317 
319 {
320  NS_FATAL_ERROR(" Constructor \"SameRoomPositionAllocator ()\" should not be used");
321 }
322 
324  : m_nodes(c)
325 {
326  m_rand = CreateObject<UniformRandomVariable>();
327  m_nodeIt = m_nodes.Begin();
328  // this is needed to make sure the building models associated with c have been initialized
329  for (auto it = m_nodes.Begin(); it != m_nodes.End(); ++it)
330  {
332  NS_ASSERT_MSG(mm, "no mobility model aggregated to this node");
334  NS_ASSERT_MSG(bmm,
335  "MobilityBuildingInfo has not been aggregated to this node mobility model");
336  bmm->MakeConsistent(mm);
337  }
338 }
339 
340 TypeId
342 {
343  static TypeId tid = TypeId("ns3::SameRoomPositionAllocator")
345  .SetGroupName("Buildings")
346  .AddConstructor<SameRoomPositionAllocator>();
347  return tid;
348 }
349 
350 Vector
352 {
353  NS_LOG_FUNCTION(this);
354  if (m_nodeIt == m_nodes.End())
355  {
356  m_nodeIt = m_nodes.Begin();
357  }
358 
359  NS_ASSERT_MSG(m_nodeIt != m_nodes.End(), "no node in container");
360 
361  NS_LOG_LOGIC("considering node " << (*m_nodeIt)->GetId());
362  Ptr<MobilityModel> mm = (*m_nodeIt)->GetObject<MobilityModel>();
363  NS_ASSERT_MSG(mm, "no mobility model aggregated to this node");
365  NS_ASSERT_MSG(bmm, "MobilityBuildingInfo has not been aggregated to this node mobility model");
366 
367  ++m_nodeIt;
368  uint32_t roomx = bmm->GetRoomNumberX();
369  uint32_t roomy = bmm->GetRoomNumberY();
370  uint32_t floor = bmm->GetFloorNumber();
371  NS_LOG_LOGIC("considering building " << bmm->GetBuilding()->GetId() << " room (" << roomx
372  << ", " << roomy << ", " << floor << ")");
373 
374  Ptr<Building> b = bmm->GetBuilding();
375  Ptr<RandomBoxPositionAllocator> pa = CreateObject<RandomBoxPositionAllocator>();
376  BoxValue bv;
377  b->GetAttribute("Boundaries", bv);
378  Box box = bv.Get();
379  double rdx = (box.xMax - box.xMin) / b->GetNRoomsX();
380  double rdy = (box.yMax - box.yMin) / b->GetNRoomsY();
381  double rdz = (box.zMax - box.zMin) / b->GetNFloors();
382  double x1 = box.xMin + rdx * (roomx - 1);
383  double x2 = box.xMin + rdx * roomx;
384  double y1 = box.yMin + rdy * (roomy - 1);
385  double y2 = box.yMin + rdy * roomy;
386  double z1 = box.zMin + rdz * (floor - 1);
387  double z2 = box.zMin + rdz * floor;
388  NS_LOG_LOGIC("randomly allocating position in "
389  << " (" << x1 << "," << x2 << ") "
390  << "x (" << y1 << "," << y2 << ") "
391  << "x (" << z1 << "," << z2 << ") ");
392 
393  double x = m_rand->GetValue(x1, x2);
394  double y = m_rand->GetValue(y1, y2);
395  double z = m_rand->GetValue(z1, z2);
396 
397  return Vector(x, y, z);
398 }
399 
400 int64_t
402 {
403  m_rand->SetStream(stream);
404  return 1;
405 }
406 
408 
410  uint32_t y,
411  uint32_t z,
412  Ptr<Building> pbtr)
413 {
414  m_rand = CreateObject<UniformRandomVariable>();
415  roomx = x;
416  roomy = y;
417  floor = z;
418  bptr = pbtr;
419 }
420 
421 TypeId
423 {
424  static TypeId tid = TypeId("ns3::FixedRoomPositionAllocator")
426  .SetGroupName("Buildings")
427  .AddConstructor<SameRoomPositionAllocator>();
428  return tid;
429 }
430 
431 Vector
433 {
434  NS_LOG_LOGIC("considering building " << bptr->GetId() << " room (" << roomx << ", " << roomy
435  << ", " << floor << ")");
436 
437  Ptr<RandomBoxPositionAllocator> pa = CreateObject<RandomBoxPositionAllocator>();
438 
439  Box box = bptr->GetBoundaries();
440  double rdx = (box.xMax - box.xMin) / bptr->GetNRoomsX();
441  double rdy = (box.yMax - box.yMin) / bptr->GetNRoomsY();
442  double rdz = (box.zMax - box.zMin) / bptr->GetNFloors();
443  double x1 = box.xMin + rdx * (roomx - 1);
444  double x2 = box.xMin + rdx * roomx;
445  double y1 = box.yMin + rdy * (roomy - 1);
446  double y2 = box.yMin + rdy * roomy;
447  double z1 = box.zMin + rdz * (floor - 1);
448  double z2 = box.zMin + rdz * floor;
449  NS_LOG_LOGIC("randomly allocating position in "
450  << " (" << x1 << "," << x2 << ") "
451  << "x (" << y1 << "," << y2 << ") "
452  << "x (" << z1 << "," << z2 << ") ");
453 
454  double x = m_rand->GetValue(x1, x2);
455  double y = m_rand->GetValue(y1, y2);
456  double z = m_rand->GetValue(z1, z2);
457  return Vector(x, y, z);
458 }
459 
460 int64_t
462 {
463  m_rand->SetStream(stream);
464  return 1;
465 }
466 
467 } // namespace ns3
double f(double x, void *params)
Definition: 80211b.c:70
a 3d box
Definition: box.h:35
double yMax
The y coordinate of the top bound of the box.
Definition: box.h:116
double xMin
The x coordinate of the left bound of the box.
Definition: box.h:110
double yMin
The y coordinate of the bottom bound of the box.
Definition: box.h:114
double xMax
The x coordinate of the right bound of the box.
Definition: box.h:112
double zMin
The z coordinate of the down bound of the box.
Definition: box.h:118
double zMax
The z coordinate of the up bound of the box.
Definition: box.h:120
static Ptr< Building > GetBuilding(uint32_t n)
static uint32_t GetNBuildings()
static Iterator End()
static Iterator Begin()
Generate a random position uniformly distributed in the volume of a chosen room inside a chosen build...
uint32_t floor
Index of the room on the z-axis (i.e., floor number)
uint32_t roomx
Index of the room on the x-axis.
uint32_t roomy
Index of the room on the y-axis.
Ptr< UniformRandomVariable > m_rand
Provides uniform random variables.
Ptr< Building > bptr
Pointer to the chosen building.
int64_t AssignStreams(int64_t) override
Assign a fixed random variable stream number to the random variables used by this model.
static TypeId GetTypeId()
Get the type ID.
FixedRoomPositionAllocator(uint32_t x, uint32_t y, uint32_t z, Ptr< Building > b)
mobility buildings information (to be used by mobility models)
Keep track of the current position and velocity of an object.
keep track of a set of node pointers.
Iterator End() const
Get an iterator which indicates past-the-last Node in the container.
Iterator Begin() const
Get an iterator which refers to the first Node in the container.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
void SetY(Ptr< RandomVariableStream > y)
Set the random variable stream object that generates y-positions.
uint32_t m_maxAttempts
maximum number of attempts before giving up
static TypeId GetTypeId()
Get the type ID.
void SetX(Ptr< RandomVariableStream > x)
Set the random variable stream object that generates x-positions.
Ptr< RandomVariableStream > m_x
pointer to x's random variable stream
Ptr< RandomVariableStream > m_z
pointer to z's random variable stream
Ptr< RandomVariableStream > m_y
pointer to y's random variable stream
void SetZ(Ptr< RandomVariableStream > z)
Set the random variable stream object that generates z-positions.
int64_t AssignStreams(int64_t stream) override
Assign a fixed random variable stream number to the random variables used by this model.
Allocate a set of positions.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Allocate each position by randomly choosing a building from the list of all buildings,...
std::vector< Ptr< Building > > m_buildingListWithoutReplacement
List of building without replacement.
int64_t AssignStreams(int64_t stream) override
Assign a fixed random variable stream number to the random variables used by this model.
bool m_withReplacement
If true, the building will be randomly selected with replacement.
Ptr< UniformRandomVariable > m_rand
Provides uniform random variables.
Allocate each position by randomly choosing a room from the list of all buildings,...
int64_t AssignStreams(int64_t stream) override
Assign a fixed random variable stream number to the random variables used by this model.
std::vector< RoomInfo > m_roomListWithoutReplacement
Container of rooms.
static TypeId GetTypeId()
Get the type ID.
Ptr< UniformRandomVariable > m_rand
Provides uniform random variables.
virtual double GetValue()=0
Get the next random value drawn from the distribution.
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
Walks a given NodeContainer sequentially, and for each node allocate a new position randomly in the s...
NodeContainer m_nodes
Nodes container.
Ptr< UniformRandomVariable > m_rand
Provides uniform random variables.
int64_t AssignStreams(int64_t) override
Assign a fixed random variable stream number to the random variables used by this model.
NodeContainer::Iterator m_nodeIt
Nodes iterator.
static TypeId GetTypeId()
Get the type ID.
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
double GetValue(double min, double max)
Get the next random value drawn from the distribution.
uint32_t GetInteger(uint32_t min, uint32_t max)
Get the next random value drawn from the distribution.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
#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_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
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 > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46