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 #ifndef POSITION_ALLOCATOR_H
21 #define POSITION_ALLOCATOR_H
22 
23 #include "ns3/object.h"
24 #include "ns3/random-variable-stream.h"
25 #include "ns3/vector.h"
26 
27 namespace ns3 {
28 
29 /**
30  * \ingroup mobility
31  * \brief Allocate a set of positions. The allocation strategy is implemented in subclasses.
32  *
33  * This is a pure abstract base class.
34  */
35 class PositionAllocator : public Object
36 {
37 public:
38   /**
39    * Register this type with the TypeId system.
40    * \return the object TypeId
41    */
42   static TypeId GetTypeId (void);
43   PositionAllocator ();
44   virtual ~PositionAllocator ();
45   /**
46    * \return the next chosen position.
47    *
48    * This method _must_ be implement in subclasses.
49    */
50   virtual Vector GetNext (void) const = 0;
51   /**
52    * Assign a fixed random variable stream number to the random variables
53    * used by this model. Return the number of streams (possibly zero) that
54    * have been assigned.
55    *
56    * This method _must_ be implement in subclasses.
57    *
58    * \param stream first stream index to use
59    * \return the number of stream indices assigned by this model
60    */
61   virtual int64_t AssignStreams (int64_t stream) = 0;
62 };
63 
64 /**
65  * \ingroup mobility
66  * \brief Allocate positions from a deterministic list specified by the user.
67  *
68  * The first call to ListPositionAllocator::GetNext  will return the
69  * first element of the list, the second call, the second element, and so on.
70  */
71 class ListPositionAllocator : public PositionAllocator
72 {
73 public:
74   /**
75    * Register this type with the TypeId system.
76    * \return the object TypeId
77    */
78   static TypeId GetTypeId (void);
79   ListPositionAllocator ();
80 
81   /**
82    * \brief Add a position to the list of positions
83    * \param v the position to append at the end of the list of positions to return from GetNext.
84    */
85   void Add (Vector v);
86 
87   /**
88    * \brief Add the positions listed in a file.
89    * The file should be a simple text file, with one position per line,
90    * either X and Y, or X, Y and Z, in meters.  The delimiter can
91    * be any character, such as ',' or '\\t'; the default is a comma ','.
92    *
93    * The file is read using CsvReader, which explains how comments
94    * and whitespace are handled.
95    *
96    * \param [in] filePath The path to the input file.
97    * \param [in] defaultZ The default Z value to use when reading files
98    *             with only X and Y positions.
99    * \param [in] delimiter The delimiter character; see CsvReader.
100    */
101   void Add (const std::string filePath,
102             double defaultZ = 0,
103             char delimiter = ',');
104 
105   /**
106    * Return the number of positions stored.  Note that this will not change
107    * based on calling GetNext(), as the number of positions is not altered
108    * by calling GetNext ().
109    *
110    * \return the number of positions stored
111    */
112   uint32_t GetSize (void) const;
113   virtual Vector GetNext (void) const;
114   virtual int64_t AssignStreams (int64_t stream);
115 
116 private:
117   std::vector<Vector> m_positions;  //!< vector of positions
118   mutable std::vector<Vector>::const_iterator m_current; //!< vector iterator
119 };
120 
121 /**
122  * \ingroup mobility
123  * \brief Allocate positions on a rectangular 2d grid.
124  */
125 class GridPositionAllocator : public PositionAllocator
126 {
127 public:
128   /**
129    * Register this type with the TypeId system.
130    * \return the object TypeId
131    */
132   static TypeId GetTypeId (void);
133 
134   /**
135    * Determine whether positions are allocated row first or column first.
136    */
137   enum LayoutType
138   {
139     /**
140      * In row-first mode, positions are allocated on the first row until
141      * N positions have been allocated. Then, the second row located a yMin + yDelta
142      * is used to allocate positions.
143      */
144     ROW_FIRST,
145     /**
146      * In column-first mode, positions are allocated on the first column until
147      * N positions have been allocated. Then, the second column located a xMin + xDelta
148      * is used to allocate positions.
149      */
150     COLUMN_FIRST
151   };
152 
153   GridPositionAllocator ();
154 
155   /**
156    * \param xMin the x coordinate where layout will start.
157    */
158   void SetMinX (double xMin);
159   /**
160    * \param yMin the y coordinate where layout will start
161    */
162   void SetMinY (double yMin);
163   /**
164    * \param z   the Z coordinate of all the positions allocated
165    */
166   void SetZ (double z);
167   /**
168    * \param deltaX the x interval between two x-consecutive positions.
169    */
170   void SetDeltaX (double deltaX);
171   /**
172    * \param deltaY the y interval between two y-consecutive positions.
173    */
174   void SetDeltaY (double deltaY);
175   /**
176    * \param n the number of positions allocated on each row (or each column)
177    *        before switching to the next column (or row).
178    */
179   void SetN (uint32_t n);
180   /**
181    * \param layoutType the type of layout to use (row first or column first).
182    */
183   void SetLayoutType (enum LayoutType layoutType);
184 
185   /**
186    * \return the x coordinate of the first allocated position.
187    */
188   double GetMinX (void) const;
189   /**
190    * \return the y coordinate of the first allocated position.
191    */
192   double GetMinY (void) const;
193   /**
194    * \return the x interval between two consecutive x-positions.
195    */
196   double GetDeltaX (void) const;
197   /**
198    * \return the y interval between two consecutive y-positions.
199    */
200   double GetDeltaY (void) const;
201   /**
202    * \return the number of positions to allocate on each row or each column.
203    */
204   uint32_t GetN (void) const;
205   /**
206    * \return the currently-selected layout type.
207    */
208   enum LayoutType GetLayoutType (void) const;
209 
210 
211   virtual Vector GetNext (void) const;
212   virtual int64_t AssignStreams (int64_t stream);
213 
214 private:
215   mutable uint32_t m_current; //!< currently position
216   enum LayoutType m_layoutType;  //!< currently selected layout type
217   double m_xMin; //!< minimum boundary on x positions
218   double m_yMin; //!< minimum boundary on y positions
219   double m_z; //!< z coordinate of all the positions generated
220   uint32_t m_n;  //!< number of positions to allocate on each row or column
221   double m_deltaX; //!< x interval between two consecutive x positions
222   double m_deltaY; //!< y interval between two consecutive y positions
223 };
224 
225 /**
226  * \ingroup mobility
227  * \brief Allocate random positions within a rectangle according to a pair of random variables.
228  */
229 class RandomRectanglePositionAllocator : public PositionAllocator
230 {
231 public:
232   /**
233    * Register this type with the TypeId system.
234    * \return the object TypeId
235    */
236   static TypeId GetTypeId (void);
237   RandomRectanglePositionAllocator ();
238   virtual ~RandomRectanglePositionAllocator ();
239 
240   /**
241    * \brief Set the random variable stream object that generates x-positions
242    * \param x pointer to a RandomVariableStream object
243    */
244   void SetX (Ptr<RandomVariableStream> x);
245   /**
246    * \brief Set the random variable stream object that generates y-positions
247    * \param y pointer to a RandomVariableStream object
248    */
249   void SetY (Ptr<RandomVariableStream> y);
250   /**
251    * \param z   the Z coordinate of all the positions allocated
252    */
253   void SetZ (double z);
254 
255   virtual Vector GetNext (void) const;
256   virtual int64_t AssignStreams (int64_t stream);
257 
258 private:
259   Ptr<RandomVariableStream> m_x; //!< pointer to x's random variable stream
260   Ptr<RandomVariableStream> m_y; //!< pointer to y's random variable stream
261   double m_z; //!< z coordinate of all the positions generated
262 };
263 
264 /**
265  * \ingroup mobility
266  * \brief Allocate random positions within a 3D box according to a set of three random variables.
267  */
268 class RandomBoxPositionAllocator : public PositionAllocator
269 {
270 public:
271   /**
272    * Register this type with the TypeId system.
273    * \return the object TypeId
274    */
275   static TypeId GetTypeId (void);
276   RandomBoxPositionAllocator ();
277   virtual ~RandomBoxPositionAllocator ();
278 
279   /**
280    * \brief Set the random variable stream object that generates x-positions
281    * \param x pointer to a RandomVariableStream object
282    */
283   void SetX (Ptr<RandomVariableStream> x);
284   /**
285    * \brief Set the random variable stream object that generates y-positions
286    * \param y pointer to a RandomVariableStream object
287    */
288   void SetY (Ptr<RandomVariableStream> y);
289   /**
290    * \brief Set the random variable stream object that generates z-positions
291    * \param z pointer to a RandomVariableStream object
292    */
293   void SetZ (Ptr<RandomVariableStream> z);
294 
295   virtual Vector GetNext (void) const;
296   virtual int64_t AssignStreams (int64_t stream);
297 
298 private:
299   Ptr<RandomVariableStream> m_x; //!< pointer to x's random variable stream
300   Ptr<RandomVariableStream> m_y; //!< pointer to y's random variable stream
301   Ptr<RandomVariableStream> m_z; //!< pointer to z's random variable stream
302 };
303 
304 /**
305  * \ingroup mobility
306  * \brief Allocate random positions within a disc according to
307  * a given distribution for the polar coordinates of each node
308  * with respect to the provided center of the disc.
309  *
310  * \note With the default uniform distribution over \f$2 \pi\f$ in \c theta and a
311  * uniform distribution for \c rho this position allocator will *not*
312  * uniformly populate the disc.  The radial distribution will be proportional
313  * to \f$\frac{1}{r^2}\f$.
314  *
315  * To get a uniform distribution over a circle use the UniformDiscPositionAllocator.
316  */
317 class RandomDiscPositionAllocator : public PositionAllocator
318 {
319 public:
320   /**
321    * Register this type with the TypeId system.
322    * \return the object TypeId
323    */
324   static TypeId GetTypeId (void);
325   RandomDiscPositionAllocator ();
326   virtual ~RandomDiscPositionAllocator ();
327 
328   /**
329    * \brief Set the random variable that generates position angle, in radians.
330    * \param theta Random variable that represents the angle in radians of a position in a random disc.
331    */
332   void SetTheta (Ptr<RandomVariableStream> theta);
333   /**
334    * \brief Set the random variable that generates position radius, in meters
335    * \param rho Random variable that represents the radius of a position, in meters, in a random disc.
336    */
337   void SetRho (Ptr<RandomVariableStream> rho);
338   /**
339    * \param x  the X coordinate of the center of the disc
340    */
341   void SetX (double x);
342   /**
343    * \param y   the Y coordinate of the center of the disc
344    */
345   void SetY (double y);
346   /**
347    * \param z   the Z coordinate of all the positions allocated
348    */
349   void SetZ (double z);
350 
351   virtual Vector GetNext (void) const;
352   virtual int64_t AssignStreams (int64_t stream);
353 
354 private:
355   Ptr<RandomVariableStream> m_theta; //!< pointer to theta's random variable stream
356   Ptr<RandomVariableStream> m_rho; //!< pointer to rho's random variable stream
357   double m_x; //!< x coordinate of center of disc
358   double m_y; //!< y coordinate of center of disc
359   double m_z;  //!< z coordinate of the disc
360 };
361 
362 
363 /**
364  * \ingroup mobility
365  * \brief Allocate the positions uniformly (with constant density) randomly within a disc.
366  *
367  * UniformDiscPositionAllocator allocates the positions randomly within a disc \f$ D \f$ lying on the
368  * plane \f$ z\f$ and having center at coordinates \f$ (x,y,z) \f$
369  * and radius \f$ \rho \f$. The random positions are chosen such that,
370  * for any subset \f$ S \subset D \f$, the expected value of the
371  * fraction of points which fall into \f$ S \subset D \f$ corresponds
372  * to \f$ \frac{|S|}{|D|} \f$, i.e., to the ratio of the area of the
373  * subset to the area of the whole disc.
374  *
375  * \note using UniformDiscPositionAllocator is not equivalent to using
376  * a RandomDiscPositionAllocator with a uniformly-distributed radius,
377  * since doing that would results in a point distribution which is
378  * more dense towards the center of the disc.
379  */
380 class UniformDiscPositionAllocator : public PositionAllocator
381 {
382 public:
383   /**
384    * Register this type with the TypeId system.
385    * \return the object TypeId
386    */
387   static TypeId GetTypeId (void);
388   UniformDiscPositionAllocator ();
389   virtual ~UniformDiscPositionAllocator ();
390 
391   /**
392    * \param rho the value of the radius of the disc
393    */
394   void SetRho (double rho);
395 
396   /**
397    * \param x  the X coordinate of the center of the disc
398    */
399   void SetX (double x);
400 
401   /**
402    * \param y   the Y coordinate of the center of the disc
403    */
404   void SetY (double y);
405 
406   /**
407    * \param z   the Z coordinate of all the positions allocated
408    */
409   void SetZ (double z);
410 
411   virtual Vector GetNext (void) const;
412   virtual int64_t AssignStreams (int64_t stream);
413 
414 private:
415   Ptr<UniformRandomVariable> m_rv;  //!< pointer to uniform random variable
416   double m_rho; //!< value of the radius of the disc
417   double m_x;  //!< x coordinate of center of disc
418   double m_y;  //!< y coordinate of center of disc
419   double m_z;  //!< z coordinate of the disc
420 };
421 
422 } // namespace ns3
423 
424 #endif /* RANDOM_POSITION_H */
425