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