/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2007 INRIA * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation; * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Mathieu Lacage */ #ifndef POSITION_ALLOCATOR_H #define POSITION_ALLOCATOR_H #include "ns3/object.h" #include "ns3/random-variable-stream.h" #include "ns3/vector.h" namespace ns3 { /** * \ingroup mobility * \brief Allocate a set of positions. The allocation strategy is implemented in subclasses. * * This is a pure abstract base class. */ class PositionAllocator : public Object { public: /** * Register this type with the TypeId system. * \return the object TypeId */ static TypeId GetTypeId (void); PositionAllocator (); virtual ~PositionAllocator (); /** * \return the next chosen position. * * This method _must_ be implement in subclasses. */ virtual Vector GetNext (void) const = 0; /** * Assign a fixed random variable stream number to the random variables * used by this model. Return the number of streams (possibly zero) that * have been assigned. * * This method _must_ be implement in subclasses. * * \param stream first stream index to use * \return the number of stream indices assigned by this model */ virtual int64_t AssignStreams (int64_t stream) = 0; }; /** * \ingroup mobility * \brief Allocate positions from a deterministic list specified by the user. * * The first call to ListPositionAllocator::GetNext will return the * first element of the list, the second call, the second element, and so on. */ class ListPositionAllocator : public PositionAllocator { public: /** * Register this type with the TypeId system. * \return the object TypeId */ static TypeId GetTypeId (void); ListPositionAllocator (); /** * \brief Add a position to the list of positions * \param v the position to append at the end of the list of positions to return from GetNext. */ void Add (Vector v); /** * Return the number of positions stored. Note that this will not change * based on calling GetNext(), as the number of positions is not altered * by calling GetNext (). * * \return the number of positions stored */ uint32_t GetSize (void) const; virtual Vector GetNext (void) const; virtual int64_t AssignStreams (int64_t stream); private: std::vector m_positions; //!< vector of positions mutable std::vector::const_iterator m_current; //!< vector iterator }; /** * \ingroup mobility * \brief Allocate positions on a rectangular 2d grid. */ class GridPositionAllocator : public PositionAllocator { public: /** * Register this type with the TypeId system. * \return the object TypeId */ static TypeId GetTypeId (void); /** * Determine whether positions are allocated row first or column first. */ enum LayoutType { /** * In row-first mode, positions are allocated on the first row until * N positions have been allocated. Then, the second row located a yMin + yDelta * is used to allocate positions. */ ROW_FIRST, /** * In column-first mode, positions are allocated on the first column until * N positions have been allocated. Then, the second column located a xMin + xDelta * is used to allocate positions. */ COLUMN_FIRST }; GridPositionAllocator (); /** * \param xMin the x coordinate where layout will start. */ void SetMinX (double xMin); /** * \param yMin the y coordinate where layout will start */ void SetMinY (double yMin); /** * \param z the Z coordinate of all the positions allocated */ void SetZ (double z); /** * \param deltaX the x interval between two x-consecutive positions. */ void SetDeltaX (double deltaX); /** * \param deltaY the y interval between two y-consecutive positions. */ void SetDeltaY (double deltaY); /** * \param n the number of positions allocated on each row (or each column) * before switching to the next column (or row). */ void SetN (uint32_t n); /** * \param layoutType the type of layout to use (row first or column first). */ void SetLayoutType (enum LayoutType layoutType); /** * \return the x coordinate of the first allocated position. */ double GetMinX (void) const; /** * \return the y coordinate of the first allocated position. */ double GetMinY (void) const; /** * \return the x interval between two consecutive x-positions. */ double GetDeltaX (void) const; /** * \return the y interval between two consecutive y-positions. */ double GetDeltaY (void) const; /** * \return the number of positions to allocate on each row or each column. */ uint32_t GetN (void) const; /** * \return the currently-selected layout type. */ enum LayoutType GetLayoutType (void) const; virtual Vector GetNext (void) const; virtual int64_t AssignStreams (int64_t stream); private: mutable uint32_t m_current; //!< currently position enum LayoutType m_layoutType; //!< currently selected layout type double m_xMin; //!< minimum boundary on x positions double m_yMin; //!< minimum boundary on y positions double m_z; //!< z coordinate of all the positions generated uint32_t m_n; //!< number of positions to allocate on each row or column double m_deltaX; //!< x interval between two consecutive x positions double m_deltaY; //!< y interval between two consecutive y positions }; /** * \ingroup mobility * \brief Allocate random positions within a rectangle according to a pair of random variables. */ class RandomRectanglePositionAllocator : public PositionAllocator { public: /** * Register this type with the TypeId system. * \return the object TypeId */ static TypeId GetTypeId (void); RandomRectanglePositionAllocator (); virtual ~RandomRectanglePositionAllocator (); /** * \brief Set the random variable stream object that generates x-positions * \param x pointer to a RandomVariableStream object */ void SetX (Ptr x); /** * \brief Set the random variable stream object that generates y-positions * \param y pointer to a RandomVariableStream object */ void SetY (Ptr y); /** * \param z the Z coordinate of all the positions allocated */ void SetZ (double z); virtual Vector GetNext (void) const; virtual int64_t AssignStreams (int64_t stream); private: Ptr m_x; //!< pointer to x's random variable stream Ptr m_y; //!< pointer to y's random variable stream double m_z; //!< z coordinate of all the positions generated }; /** * \ingroup mobility * \brief Allocate random positions within a 3D box according to a set of three random variables. */ class RandomBoxPositionAllocator : public PositionAllocator { public: /** * Register this type with the TypeId system. * \return the object TypeId */ static TypeId GetTypeId (void); RandomBoxPositionAllocator (); virtual ~RandomBoxPositionAllocator (); /** * \brief Set the random variable stream object that generates x-positions * \param x pointer to a RandomVariableStream object */ void SetX (Ptr x); /** * \brief Set the random variable stream object that generates y-positions * \param y pointer to a RandomVariableStream object */ void SetY (Ptr y); /** * \brief Set the random variable stream object that generates z-positions * \param z pointer to a RandomVariableStream object */ void SetZ (Ptr z); virtual Vector GetNext (void) const; virtual int64_t AssignStreams (int64_t stream); private: Ptr m_x; //!< pointer to x's random variable stream Ptr m_y; //!< pointer to y's random variable stream Ptr m_z; //!< pointer to z's random variable stream }; /** * \ingroup mobility * \brief Allocate random positions within a disc according to a given distribution for the polar coordinates of each node with respect to the provided center of the disc */ class RandomDiscPositionAllocator : public PositionAllocator { public: /** * Register this type with the TypeId system. * \return the object TypeId */ static TypeId GetTypeId (void); RandomDiscPositionAllocator (); virtual ~RandomDiscPositionAllocator (); /** * \brief Set the random variable that generates position angle, in radians. * \param theta Random variable that represents the angle in radians of a position in a random disc. */ void SetTheta (Ptr theta); /** * \brief Set the random variable that generates position radius, in meters * \param rho Random variable that represents the radius of a position, in meters, in a random disc. */ void SetRho (Ptr rho); /** * \param x the X coordinate of the center of the disc */ void SetX (double x); /** * \param y the Y coordinate of the center of the disc */ void SetY (double y); /** * \param z the Z coordinate of all the positions allocated */ void SetZ (double z); virtual Vector GetNext (void) const; virtual int64_t AssignStreams (int64_t stream); private: Ptr m_theta; //!< pointer to theta's random variable stream Ptr m_rho; //!< pointer to rho's random variable stream double m_x; //!< x coordinate of center of disc double m_y; //!< y coordinate of center of disc double m_z; //!< z coordinate of the disc }; /** * \ingroup mobility * \brief Allocate the positions uniformely (with constant density) randomly within a disc. * * UniformDiscPositionAllocator allocates the positions randomly within a disc \f$ D \f$ lying on the * plane \f$ z\f$ and having center at coordinates \f$ (x,y,z) \f$ * and radius \f$ \rho \f$. The random positions are chosen such that, * for any subset \f$ S \subset D \f$, the expected value of the * fraction of points which fall into \f$ S \subset D \f$ corresponds * to \f$ \frac{|S|}{|D|} \f$, i.e., to the ratio of the area of the * subset to the area of the whole disc. * * \note using UniformDiscPositionAllocator is not equivalent to using * a RandomDiscPositionAllocator with a uniformly-distributed radius, * since doing that would results in a point distribution which is * more dense towards the center of the disc. */ class UniformDiscPositionAllocator : public PositionAllocator { public: /** * Register this type with the TypeId system. * \return the object TypeId */ static TypeId GetTypeId (void); UniformDiscPositionAllocator (); virtual ~UniformDiscPositionAllocator (); /** * \param rho the value of the radius of the disc */ void SetRho (double rho); /** * \param x the X coordinate of the center of the disc */ void SetX (double x); /** * \param y the Y coordinate of the center of the disc */ void SetY (double y); /** * \param z the Z coordinate of all the positions allocated */ void SetZ (double z); virtual Vector GetNext (void) const; virtual int64_t AssignStreams (int64_t stream); private: Ptr m_rv; //!< pointer to uniform random variable double m_rho; //!< value of the radius of the disc double m_x; //!< x coordinate of center of disc double m_y; //!< y coordinate of center of disc double m_z; //!< z coordinate of the disc }; } // namespace ns3 #endif /* RANDOM_POSITION_H */