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