1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * Copyright (c) 2007 INRIA
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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19 */
20 #include "position-allocator.h"
21 #include "ns3/double.h"
22 #include "ns3/string.h"
23 #include "ns3/pointer.h"
24 #include "ns3/uinteger.h"
25 #include "ns3/enum.h"
26 #include "ns3/log.h"
27 #include "ns3/csv-reader.h"
28
29 #include <cmath>
30
31 namespace ns3 {
32
33 NS_LOG_COMPONENT_DEFINE ("PositionAllocator");
34
35 NS_OBJECT_ENSURE_REGISTERED (PositionAllocator);
36
37 TypeId
GetTypeId(void)38 PositionAllocator::GetTypeId (void)
39 {
40 static TypeId tid = TypeId ("ns3::PositionAllocator")
41 .SetParent<Object> ()
42 .SetGroupName ("Mobility");
43 return tid;
44 }
45
PositionAllocator()46 PositionAllocator::PositionAllocator ()
47 {}
48
~PositionAllocator()49 PositionAllocator::~PositionAllocator ()
50 {}
51
52
53 NS_OBJECT_ENSURE_REGISTERED (ListPositionAllocator);
54
55 TypeId
GetTypeId(void)56 ListPositionAllocator::GetTypeId (void)
57 {
58 static TypeId tid = TypeId ("ns3::ListPositionAllocator")
59 .SetParent<PositionAllocator> ()
60 .SetGroupName ("Mobility")
61 .AddConstructor<ListPositionAllocator> ()
62 ;
63 return tid;
64 }
65
ListPositionAllocator()66 ListPositionAllocator::ListPositionAllocator ()
67 {}
68
69 void
Add(Vector v)70 ListPositionAllocator::Add (Vector v)
71 {
72 m_positions.push_back (v);
73 m_current = m_positions.begin ();
74 }
75
76 void
Add(const std::string filePath,double defaultZ,char delimiter)77 ListPositionAllocator::Add (const std::string filePath,
78 double defaultZ /* = 0 */,
79 char delimiter /* = ',' */)
80 {
81 NS_LOG_FUNCTION (this << filePath << std::string ("'") + delimiter + "'");
82
83 CsvReader csv (filePath, delimiter);
84 while (csv.FetchNextRow ())
85 {
86 if (csv.ColumnCount () == 1)
87 {
88 // comment line
89 continue;
90 }
91
92 double x, y, z;
93 bool ok = csv.GetValue (0, x);
94 NS_LOG_INFO ("read x: " << x << (ok ? " ok" : " FAIL"));
95 NS_ASSERT_MSG (ok, "failed reading x");
96 ok = csv.GetValue (1, y);
97 NS_LOG_INFO ("read y = " << y << (ok ? " ok" : " FAIL"));
98 NS_ASSERT_MSG (ok, "failed reading y");
99 if (csv.ColumnCount () > 2)
100 {
101 ok = csv.GetValue (2, z);
102 NS_LOG_INFO ("read z = " << z << (ok ? " ok" : " FAIL"));
103 NS_ASSERT_MSG (ok, "failed reading z");
104 }
105 else
106 {
107 z = defaultZ;
108 NS_LOG_LOGIC ("using default Z " << defaultZ);
109 }
110
111 Vector pos (x, y, z);
112 Add (pos);
113
114 } // while FetchNextRow
115 NS_LOG_INFO ("read " << csv.RowNumber () << " rows");
116 }
117
118 Vector
GetNext(void) const119 ListPositionAllocator::GetNext (void) const
120 {
121 Vector v = *m_current;
122 m_current++;
123 if (m_current == m_positions.end ())
124 {
125 m_current = m_positions.begin ();
126 }
127 return v;
128 }
129
130 int64_t
AssignStreams(int64_t stream)131 ListPositionAllocator::AssignStreams (int64_t stream)
132 {
133 return 0;
134 }
135
136 uint32_t
GetSize(void) const137 ListPositionAllocator::GetSize (void) const
138 {
139 return m_positions.size ();
140 }
141
142
143 NS_OBJECT_ENSURE_REGISTERED (GridPositionAllocator);
144
145 TypeId
GetTypeId(void)146 GridPositionAllocator::GetTypeId (void)
147 {
148 static TypeId tid = TypeId ("ns3::GridPositionAllocator")
149 .SetParent<PositionAllocator> ()
150 .SetGroupName ("Mobility")
151 .AddConstructor<GridPositionAllocator> ()
152 .AddAttribute ("GridWidth", "The number of objects laid out on a line.",
153 UintegerValue (10),
154 MakeUintegerAccessor (&GridPositionAllocator::m_n),
155 MakeUintegerChecker<uint32_t> ())
156 .AddAttribute ("MinX", "The x coordinate where the grid starts.",
157 DoubleValue (1.0),
158 MakeDoubleAccessor (&GridPositionAllocator::m_xMin),
159 MakeDoubleChecker<double> ())
160 .AddAttribute ("MinY", "The y coordinate where the grid starts.",
161 DoubleValue (0.0),
162 MakeDoubleAccessor (&GridPositionAllocator::m_yMin),
163 MakeDoubleChecker<double> ())
164 .AddAttribute ("Z",
165 "The z coordinate of all the positions allocated.",
166 DoubleValue (0.0),
167 MakeDoubleAccessor (&GridPositionAllocator::m_z),
168 MakeDoubleChecker<double> ())
169 .AddAttribute ("DeltaX", "The x space between objects.",
170 DoubleValue (1.0),
171 MakeDoubleAccessor (&GridPositionAllocator::m_deltaX),
172 MakeDoubleChecker<double> ())
173 .AddAttribute ("DeltaY", "The y space between objects.",
174 DoubleValue (1.0),
175 MakeDoubleAccessor (&GridPositionAllocator::m_deltaY),
176 MakeDoubleChecker<double> ())
177 .AddAttribute ("LayoutType", "The type of layout.",
178 EnumValue (ROW_FIRST),
179 MakeEnumAccessor (&GridPositionAllocator::m_layoutType),
180 MakeEnumChecker (ROW_FIRST, "RowFirst",
181 COLUMN_FIRST, "ColumnFirst"))
182 ;
183 return tid;
184 }
185
GridPositionAllocator()186 GridPositionAllocator::GridPositionAllocator ()
187 : m_current (0)
188 {}
189
190 void
SetMinX(double xMin)191 GridPositionAllocator::SetMinX (double xMin)
192 {
193 m_xMin = xMin;
194 }
195
196 void
SetMinY(double yMin)197 GridPositionAllocator::SetMinY (double yMin)
198 {
199 m_yMin = yMin;
200 }
201
202 void
SetZ(double z)203 GridPositionAllocator::SetZ (double z)
204 {
205 m_z = z;
206 }
207
208 void
SetDeltaX(double deltaX)209 GridPositionAllocator::SetDeltaX (double deltaX)
210 {
211 m_deltaX = deltaX;
212 }
213
214 void
SetDeltaY(double deltaY)215 GridPositionAllocator::SetDeltaY (double deltaY)
216 {
217 m_deltaY = deltaY;
218 }
219
220 void
SetN(uint32_t n)221 GridPositionAllocator::SetN (uint32_t n)
222 {
223 m_n = n;
224 }
225
226 void
SetLayoutType(enum LayoutType layoutType)227 GridPositionAllocator::SetLayoutType (enum LayoutType layoutType)
228 {
229 m_layoutType = layoutType;
230 }
231
232 double
GetMinX(void) const233 GridPositionAllocator::GetMinX (void) const
234 {
235 return m_xMin;
236 }
237
238 double
GetMinY(void) const239 GridPositionAllocator::GetMinY (void) const
240 {
241 return m_yMin;
242 }
243
244 double
GetDeltaX(void) const245 GridPositionAllocator::GetDeltaX (void) const
246 {
247 return m_deltaX;
248 }
249
250 double
GetDeltaY(void) const251 GridPositionAllocator::GetDeltaY (void) const
252 {
253 return m_deltaY;
254 }
255
256 uint32_t
GetN(void) const257 GridPositionAllocator::GetN (void) const
258 {
259 return m_n;
260 }
261
262 enum GridPositionAllocator::LayoutType
GetLayoutType(void) const263 GridPositionAllocator::GetLayoutType (void) const
264 {
265 return m_layoutType;
266 }
267
268 Vector
GetNext(void) const269 GridPositionAllocator::GetNext (void) const
270 {
271 double x = 0.0, y = 0.0;
272 switch (m_layoutType)
273 {
274 case ROW_FIRST:
275 x = m_xMin + m_deltaX * (m_current % m_n);
276 y = m_yMin + m_deltaY * (m_current / m_n);
277 break;
278 case COLUMN_FIRST:
279 x = m_xMin + m_deltaX * (m_current / m_n);
280 y = m_yMin + m_deltaY * (m_current % m_n);
281 break;
282 }
283 m_current++;
284 return Vector (x, y, m_z);
285 }
286
287 int64_t
AssignStreams(int64_t stream)288 GridPositionAllocator::AssignStreams (int64_t stream)
289 {
290 return 0;
291 }
292
293
294 NS_OBJECT_ENSURE_REGISTERED (RandomRectanglePositionAllocator);
295
296 TypeId
GetTypeId(void)297 RandomRectanglePositionAllocator::GetTypeId (void)
298 {
299 static TypeId tid = TypeId ("ns3::RandomRectanglePositionAllocator")
300 .SetParent<PositionAllocator> ()
301 .SetGroupName ("Mobility")
302 .AddConstructor<RandomRectanglePositionAllocator> ()
303 .AddAttribute ("X",
304 "A random variable which represents the x coordinate of a position in a random rectangle.",
305 StringValue ("ns3::UniformRandomVariable[Min=0.0|Max=1.0]"),
306 MakePointerAccessor (&RandomRectanglePositionAllocator::m_x),
307 MakePointerChecker<RandomVariableStream> ())
308 .AddAttribute ("Y",
309 "A random variable which represents the y coordinate of a position in a random rectangle.",
310 StringValue ("ns3::UniformRandomVariable[Min=0.0|Max=1.0]"),
311 MakePointerAccessor (&RandomRectanglePositionAllocator::m_y),
312 MakePointerChecker<RandomVariableStream> ())
313 .AddAttribute ("Z",
314 "The z coordinate of all the positions allocated.",
315 DoubleValue (0.0),
316 MakeDoubleAccessor (&RandomRectanglePositionAllocator::m_z),
317 MakeDoubleChecker<double> ())
318 ;
319 return tid;
320 }
321
RandomRectanglePositionAllocator()322 RandomRectanglePositionAllocator::RandomRectanglePositionAllocator ()
323 {}
324
~RandomRectanglePositionAllocator()325 RandomRectanglePositionAllocator::~RandomRectanglePositionAllocator ()
326 {}
327
328 void
SetX(Ptr<RandomVariableStream> x)329 RandomRectanglePositionAllocator::SetX (Ptr<RandomVariableStream> x)
330 {
331 m_x = x;
332 }
333
334 void
SetY(Ptr<RandomVariableStream> y)335 RandomRectanglePositionAllocator::SetY (Ptr<RandomVariableStream> y)
336 {
337 m_y = y;
338 }
339
340 void
SetZ(double z)341 RandomRectanglePositionAllocator::SetZ (double z)
342 {
343 m_z = z;
344 }
345
346 Vector
GetNext(void) const347 RandomRectanglePositionAllocator::GetNext (void) const
348 {
349 double x = m_x->GetValue ();
350 double y = m_y->GetValue ();
351 return Vector (x, y, m_z);
352 }
353
354 int64_t
AssignStreams(int64_t stream)355 RandomRectanglePositionAllocator::AssignStreams (int64_t stream)
356 {
357 m_x->SetStream (stream);
358 m_y->SetStream (stream + 1);
359 return 2;
360 }
361
362
363 NS_OBJECT_ENSURE_REGISTERED (RandomBoxPositionAllocator);
364
365 TypeId
GetTypeId(void)366 RandomBoxPositionAllocator::GetTypeId (void)
367 {
368 static TypeId tid = TypeId ("ns3::RandomBoxPositionAllocator")
369 .SetParent<PositionAllocator> ()
370 .SetGroupName ("Mobility")
371 .AddConstructor<RandomBoxPositionAllocator> ()
372 .AddAttribute ("X",
373 "A random variable which represents the x coordinate of a position in a random box.",
374 StringValue ("ns3::UniformRandomVariable[Min=0.0|Max=1.0]"),
375 MakePointerAccessor (&RandomBoxPositionAllocator::m_x),
376 MakePointerChecker<RandomVariableStream> ())
377 .AddAttribute ("Y",
378 "A random variable which represents the y coordinate of a position in a random box.",
379 StringValue ("ns3::UniformRandomVariable[Min=0.0|Max=1.0]"),
380 MakePointerAccessor (&RandomBoxPositionAllocator::m_y),
381 MakePointerChecker<RandomVariableStream> ())
382 .AddAttribute ("Z",
383 "A random variable which represents the z coordinate of a position in a random box.",
384 StringValue ("ns3::UniformRandomVariable[Min=0.0|Max=1.0]"),
385 MakePointerAccessor (&RandomBoxPositionAllocator::m_z),
386 MakePointerChecker<RandomVariableStream> ())
387 ;
388 return tid;
389 }
390
RandomBoxPositionAllocator()391 RandomBoxPositionAllocator::RandomBoxPositionAllocator ()
392 {}
393
~RandomBoxPositionAllocator()394 RandomBoxPositionAllocator::~RandomBoxPositionAllocator ()
395 {}
396
397 void
SetX(Ptr<RandomVariableStream> x)398 RandomBoxPositionAllocator::SetX (Ptr<RandomVariableStream> x)
399 {
400 m_x = x;
401 }
402
403 void
SetY(Ptr<RandomVariableStream> y)404 RandomBoxPositionAllocator::SetY (Ptr<RandomVariableStream> y)
405 {
406 m_y = y;
407 }
408
409 void
SetZ(Ptr<RandomVariableStream> z)410 RandomBoxPositionAllocator::SetZ (Ptr<RandomVariableStream> z)
411 {
412 m_z = z;
413 }
414
415 Vector
GetNext(void) const416 RandomBoxPositionAllocator::GetNext (void) const
417 {
418 double x = m_x->GetValue ();
419 double y = m_y->GetValue ();
420 double z = m_z->GetValue ();
421 return Vector (x, y, z);
422 }
423
424 int64_t
AssignStreams(int64_t stream)425 RandomBoxPositionAllocator::AssignStreams (int64_t stream)
426 {
427 m_x->SetStream (stream);
428 m_y->SetStream (stream + 1);
429 m_z->SetStream (stream + 2);
430 return 3;
431 }
432
433
434 NS_OBJECT_ENSURE_REGISTERED (RandomDiscPositionAllocator);
435
436 TypeId
GetTypeId(void)437 RandomDiscPositionAllocator::GetTypeId (void)
438 {
439 static TypeId tid = TypeId ("ns3::RandomDiscPositionAllocator")
440 .SetParent<PositionAllocator> ()
441 .SetGroupName ("Mobility")
442 .AddConstructor<RandomDiscPositionAllocator> ()
443 .AddAttribute ("Theta",
444 "A random variable which represents the angle (gradients) of a position in a random disc.",
445 StringValue ("ns3::UniformRandomVariable[Min=0.0|Max=6.2830]"),
446 MakePointerAccessor (&RandomDiscPositionAllocator::m_theta),
447 MakePointerChecker<RandomVariableStream> ())
448 .AddAttribute ("Rho",
449 "A random variable which represents the radius of a position in a random disc.",
450 StringValue ("ns3::UniformRandomVariable[Min=0.0|Max=200.0]"),
451 MakePointerAccessor (&RandomDiscPositionAllocator::m_rho),
452 MakePointerChecker<RandomVariableStream> ())
453 .AddAttribute ("X",
454 "The x coordinate of the center of the random position disc.",
455 DoubleValue (0.0),
456 MakeDoubleAccessor (&RandomDiscPositionAllocator::m_x),
457 MakeDoubleChecker<double> ())
458 .AddAttribute ("Y",
459 "The y coordinate of the center of the random position disc.",
460 DoubleValue (0.0),
461 MakeDoubleAccessor (&RandomDiscPositionAllocator::m_y),
462 MakeDoubleChecker<double> ())
463 .AddAttribute ("Z",
464 "The z coordinate of all the positions in the disc.",
465 DoubleValue (0.0),
466 MakeDoubleAccessor (&RandomDiscPositionAllocator::m_z),
467 MakeDoubleChecker<double> ())
468 ;
469 return tid;
470 }
471
RandomDiscPositionAllocator()472 RandomDiscPositionAllocator::RandomDiscPositionAllocator ()
473 {}
474
~RandomDiscPositionAllocator()475 RandomDiscPositionAllocator::~RandomDiscPositionAllocator ()
476 {}
477
478 void
SetTheta(Ptr<RandomVariableStream> theta)479 RandomDiscPositionAllocator::SetTheta (Ptr<RandomVariableStream> theta)
480 {
481 m_theta = theta;
482 }
483
484 void
SetRho(Ptr<RandomVariableStream> rho)485 RandomDiscPositionAllocator::SetRho (Ptr<RandomVariableStream> rho)
486 {
487 m_rho = rho;
488 }
489
490 void
SetX(double x)491 RandomDiscPositionAllocator::SetX (double x)
492 {
493 m_x = x;
494 }
495
496 void
SetY(double y)497 RandomDiscPositionAllocator::SetY (double y)
498 {
499 m_y = y;
500 }
501
502 void
SetZ(double z)503 RandomDiscPositionAllocator::SetZ (double z)
504 {
505 m_z = z;
506 }
507
508 Vector
GetNext(void) const509 RandomDiscPositionAllocator::GetNext (void) const
510 {
511 double theta = m_theta->GetValue ();
512 double rho = m_rho->GetValue ();
513 double x = m_x + std::cos (theta) * rho;
514 double y = m_y + std::sin (theta) * rho;
515 NS_LOG_DEBUG ("Disc position x=" << x << ", y=" << y);
516 return Vector (x, y, m_z);
517 }
518
519 int64_t
AssignStreams(int64_t stream)520 RandomDiscPositionAllocator::AssignStreams (int64_t stream)
521 {
522 m_theta->SetStream (stream);
523 m_rho->SetStream (stream + 1);
524 return 2;
525 }
526
527
528 NS_OBJECT_ENSURE_REGISTERED (UniformDiscPositionAllocator);
529
530 TypeId
GetTypeId(void)531 UniformDiscPositionAllocator::GetTypeId (void)
532 {
533 static TypeId tid = TypeId ("ns3::UniformDiscPositionAllocator")
534 .SetParent<PositionAllocator> ()
535 .SetGroupName ("Mobility")
536 .AddConstructor<UniformDiscPositionAllocator> ()
537 .AddAttribute ("rho",
538 "The radius of the disc",
539 DoubleValue (0.0),
540 MakeDoubleAccessor (&UniformDiscPositionAllocator::m_rho),
541 MakeDoubleChecker<double> ())
542 .AddAttribute ("X",
543 "The x coordinate of the center of the disc.",
544 DoubleValue (0.0),
545 MakeDoubleAccessor (&UniformDiscPositionAllocator::m_x),
546 MakeDoubleChecker<double> ())
547 .AddAttribute ("Y",
548 "The y coordinate of the center of the disc.",
549 DoubleValue (0.0),
550 MakeDoubleAccessor (&UniformDiscPositionAllocator::m_y),
551 MakeDoubleChecker<double> ())
552 .AddAttribute ("Z",
553 "The z coordinate of all the positions in the disc.",
554 DoubleValue (0.0),
555 MakeDoubleAccessor (&UniformDiscPositionAllocator::m_z),
556 MakeDoubleChecker<double> ())
557 ;
558 return tid;
559 }
560
UniformDiscPositionAllocator()561 UniformDiscPositionAllocator::UniformDiscPositionAllocator ()
562 {
563 m_rv = CreateObject<UniformRandomVariable> ();
564 }
565
~UniformDiscPositionAllocator()566 UniformDiscPositionAllocator::~UniformDiscPositionAllocator ()
567 {}
568
569 void
SetRho(double rho)570 UniformDiscPositionAllocator::SetRho (double rho)
571 {
572 m_rho = rho;
573 }
574
575 void
SetX(double x)576 UniformDiscPositionAllocator::SetX (double x)
577 {
578 m_x = x;
579 }
580
581 void
SetY(double y)582 UniformDiscPositionAllocator::SetY (double y)
583 {
584 m_y = y;
585 }
586
587 void
SetZ(double z)588 UniformDiscPositionAllocator::SetZ (double z)
589 {
590 m_z = z;
591 }
592
593 Vector
GetNext(void) const594 UniformDiscPositionAllocator::GetNext (void) const
595 {
596 double x,y;
597 do
598 {
599 x = m_rv->GetValue (-m_rho, m_rho);
600 y = m_rv->GetValue (-m_rho, m_rho);
601 }
602 while (std::sqrt (x * x + y * y) > m_rho);
603
604 x += m_x;
605 y += m_y;
606 NS_LOG_DEBUG ("Disc position x=" << x << ", y=" << y);
607 return Vector (x, y, m_z);
608 }
609
610 int64_t
AssignStreams(int64_t stream)611 UniformDiscPositionAllocator::AssignStreams (int64_t stream)
612 {
613 m_rv->SetStream (stream);
614 return 1;
615 }
616
617
618 } // namespace ns3
619