diff --git a/src/mobility/model/position-allocator.cc b/src/mobility/model/position-allocator.cc index 3a82263ed..fa363ea87 100644 --- a/src/mobility/model/position-allocator.cc +++ b/src/mobility/model/position-allocator.cc @@ -24,6 +24,8 @@ #include "ns3/uinteger.h" #include "ns3/enum.h" #include "ns3/log.h" +#include "ns3/csv-reader.h" + #include namespace ns3 { @@ -32,7 +34,7 @@ NS_LOG_COMPONENT_DEFINE ("PositionAllocator"); NS_OBJECT_ENSURE_REGISTERED (PositionAllocator); -TypeId +TypeId PositionAllocator::GetTypeId (void) { static TypeId tid = TypeId ("ns3::PositionAllocator") @@ -42,12 +44,11 @@ PositionAllocator::GetTypeId (void) } PositionAllocator::PositionAllocator () -{ -} +{} PositionAllocator::~PositionAllocator () -{ -} +{} + NS_OBJECT_ENSURE_REGISTERED (ListPositionAllocator); @@ -58,18 +59,62 @@ ListPositionAllocator::GetTypeId (void) .SetParent () .SetGroupName ("Mobility") .AddConstructor () - ; + ; return tid; } + ListPositionAllocator::ListPositionAllocator () -{ -} +{} + void ListPositionAllocator::Add (Vector v) { m_positions.push_back (v); m_current = m_positions.begin (); } + +void +ListPositionAllocator::Add (const std::string filePath, + double defaultZ /* = 0 */, + char delimiter /* = ',' */) +{ + NS_LOG_FUNCTION (this << filePath << std::string ("'") + delimiter + "'"); + + CsvReader csv (filePath, delimiter); + while (csv.FetchNextRow ()) + { + if (csv.ColumnCount () == 1) + { + // comment line + continue; + } + + double x, y, z; + bool ok = csv.GetValue (0, x); + NS_LOG_INFO ("read x: " << x << (ok ? " ok" : " FAIL")); + NS_ASSERT_MSG (ok, "failed reading x"); + ok = csv.GetValue (1, y); + NS_LOG_INFO ("read y = " << y << (ok ? " ok" : " FAIL")); + NS_ASSERT_MSG (ok, "failed reading y"); + if (csv.ColumnCount () > 2) + { + ok = csv.GetValue (2, z); + NS_LOG_INFO ("read z = " << z << (ok ? " ok" : " FAIL")); + NS_ASSERT_MSG (ok, "failed reading z"); + } + else + { + z = defaultZ; + NS_LOG_LOGIC ("using default Z " << defaultZ); + } + + Vector pos (x, y, z); + Add (pos); + + } // while FetchNextRow + NS_LOG_INFO ("read " << csv.RowNumber () << " rows"); +} + Vector ListPositionAllocator::GetNext (void) const { @@ -81,6 +126,7 @@ ListPositionAllocator::GetNext (void) const } return v; } + int64_t ListPositionAllocator::AssignStreams (int64_t stream) { @@ -93,9 +139,10 @@ ListPositionAllocator::GetSize (void) const return m_positions.size (); } + NS_OBJECT_ENSURE_REGISTERED (GridPositionAllocator); -TypeId +TypeId GridPositionAllocator::GetTypeId (void) { static TypeId tid = TypeId ("ns3::GridPositionAllocator") @@ -132,44 +179,50 @@ GridPositionAllocator::GetTypeId (void) MakeEnumAccessor (&GridPositionAllocator::m_layoutType), MakeEnumChecker (ROW_FIRST, "RowFirst", COLUMN_FIRST, "ColumnFirst")) - ; + ; return tid; } + GridPositionAllocator::GridPositionAllocator () : m_current (0) -{ -} +{} void GridPositionAllocator::SetMinX (double xMin) { m_xMin = xMin; } + void GridPositionAllocator::SetMinY (double yMin) { m_yMin = yMin; } + void GridPositionAllocator::SetZ (double z) { m_z = z; } + void GridPositionAllocator::SetDeltaX (double deltaX) { m_deltaX = deltaX; } + void GridPositionAllocator::SetDeltaY (double deltaY) { m_deltaY = deltaY; } + void GridPositionAllocator::SetN (uint32_t n) { m_n = n; } + void GridPositionAllocator::SetLayoutType (enum LayoutType layoutType) { @@ -181,26 +234,31 @@ GridPositionAllocator::GetMinX (void) const { return m_xMin; } + double GridPositionAllocator::GetMinY (void) const { return m_yMin; } + double GridPositionAllocator::GetDeltaX (void) const { return m_deltaX; } + double GridPositionAllocator::GetDeltaY (void) const { return m_deltaY; } + uint32_t GridPositionAllocator::GetN (void) const { return m_n; } + enum GridPositionAllocator::LayoutType GridPositionAllocator::GetLayoutType (void) const { @@ -211,15 +269,16 @@ Vector GridPositionAllocator::GetNext (void) const { double x = 0.0, y = 0.0; - switch (m_layoutType) { - case ROW_FIRST: - x = m_xMin + m_deltaX * (m_current % m_n); - y = m_yMin + m_deltaY * (m_current / m_n); - break; - case COLUMN_FIRST: - x = m_xMin + m_deltaX * (m_current / m_n); - y = m_yMin + m_deltaY * (m_current % m_n); - break; + switch (m_layoutType) + { + case ROW_FIRST: + x = m_xMin + m_deltaX * (m_current % m_n); + y = m_yMin + m_deltaY * (m_current / m_n); + break; + case COLUMN_FIRST: + x = m_xMin + m_deltaX * (m_current / m_n); + y = m_yMin + m_deltaY * (m_current % m_n); + break; } m_current++; return Vector (x, y, m_z); @@ -231,6 +290,7 @@ GridPositionAllocator::AssignStreams (int64_t stream) return 0; } + NS_OBJECT_ENSURE_REGISTERED (RandomRectanglePositionAllocator); TypeId @@ -260,22 +320,23 @@ RandomRectanglePositionAllocator::GetTypeId (void) } RandomRectanglePositionAllocator::RandomRectanglePositionAllocator () -{ -} +{} + RandomRectanglePositionAllocator::~RandomRectanglePositionAllocator () -{ -} +{} void RandomRectanglePositionAllocator::SetX (Ptr x) { m_x = x; } + void RandomRectanglePositionAllocator::SetY (Ptr y) { m_y = y; } + void RandomRectanglePositionAllocator::SetZ (double z) { @@ -298,6 +359,7 @@ RandomRectanglePositionAllocator::AssignStreams (int64_t stream) return 2; } + NS_OBJECT_ENSURE_REGISTERED (RandomBoxPositionAllocator); TypeId @@ -321,27 +383,29 @@ RandomBoxPositionAllocator::GetTypeId (void) "A random variable which represents the z coordinate of a position in a random box.", StringValue ("ns3::UniformRandomVariable[Min=0.0|Max=1.0]"), MakePointerAccessor (&RandomBoxPositionAllocator::m_z), - MakePointerChecker ()); + MakePointerChecker ()) + ; return tid; } RandomBoxPositionAllocator::RandomBoxPositionAllocator () -{ -} +{} + RandomBoxPositionAllocator::~RandomBoxPositionAllocator () -{ -} +{} void RandomBoxPositionAllocator::SetX (Ptr x) { m_x = x; } + void RandomBoxPositionAllocator::SetY (Ptr y) { m_y = y; } + void RandomBoxPositionAllocator::SetZ (Ptr z) { @@ -366,6 +430,7 @@ RandomBoxPositionAllocator::AssignStreams (int64_t stream) return 3; } + NS_OBJECT_ENSURE_REGISTERED (RandomDiscPositionAllocator); TypeId @@ -400,42 +465,46 @@ RandomDiscPositionAllocator::GetTypeId (void) DoubleValue (0.0), MakeDoubleAccessor (&RandomDiscPositionAllocator::m_z), MakeDoubleChecker ()) - ; + ; return tid; } RandomDiscPositionAllocator::RandomDiscPositionAllocator () -{ -} +{} + RandomDiscPositionAllocator::~RandomDiscPositionAllocator () -{ -} +{} void RandomDiscPositionAllocator::SetTheta (Ptr theta) { m_theta = theta; } + void RandomDiscPositionAllocator::SetRho (Ptr rho) { m_rho = rho; } + void RandomDiscPositionAllocator::SetX (double x) { m_x = x; } + void RandomDiscPositionAllocator::SetY (double y) { m_y = y; } + void RandomDiscPositionAllocator::SetZ (double z) { m_z = z; } + Vector RandomDiscPositionAllocator::GetNext (void) const { @@ -456,7 +525,6 @@ RandomDiscPositionAllocator::AssignStreams (int64_t stream) } - NS_OBJECT_ENSURE_REGISTERED (UniformDiscPositionAllocator); TypeId @@ -486,7 +554,7 @@ UniformDiscPositionAllocator::GetTypeId (void) DoubleValue (0.0), MakeDoubleAccessor (&UniformDiscPositionAllocator::m_z), MakeDoubleChecker ()) - ; + ; return tid; } @@ -494,30 +562,34 @@ UniformDiscPositionAllocator::UniformDiscPositionAllocator () { m_rv = CreateObject (); } + UniformDiscPositionAllocator::~UniformDiscPositionAllocator () -{ -} +{} void UniformDiscPositionAllocator::SetRho (double rho) { m_rho = rho; } + void UniformDiscPositionAllocator::SetX (double x) { m_x = x; } + void UniformDiscPositionAllocator::SetY (double y) { m_y = y; } + void UniformDiscPositionAllocator::SetZ (double z) { m_z = z; } + Vector UniformDiscPositionAllocator::GetNext (void) const { @@ -527,7 +599,7 @@ UniformDiscPositionAllocator::GetNext (void) const x = m_rv->GetValue (-m_rho, m_rho); y = m_rv->GetValue (-m_rho, m_rho); } - while (std::sqrt (x*x + y*y) > m_rho); + while (std::sqrt (x * x + y * y) > m_rho); x += m_x; y += m_y; @@ -543,4 +615,4 @@ UniformDiscPositionAllocator::AssignStreams (int64_t stream) } -} // namespace ns3 +} // namespace ns3 diff --git a/src/mobility/model/position-allocator.h b/src/mobility/model/position-allocator.h index a1efc78a9..9b4c44548 100644 --- a/src/mobility/model/position-allocator.h +++ b/src/mobility/model/position-allocator.h @@ -83,6 +83,25 @@ public: * \param v the position to append at the end of the list of positions to return from GetNext. */ void Add (Vector v); + + /** + * \brief Add the positions listed in a file. + * The file should be a simple text file, with one position per line, + * either X and Y, or X, Y and Z, in meters. The delimiter can + * be any character, such as ',' or '\t'; the default is a comma ','. + * + * The file is read using CsvReader, which explains how comments + * and whitespace are handled. + * + * \param [in] filePath The path to the input file. + * \param [in] defaultZ The default Z value to use when reading files + * with only X and Y positions. + * \param [in] delimiter The delimiter character; see CsvReader. + */ + void Add (const std::string filePath, + double defaultZ = 0, + char delimiter = ','); + /** * Return the number of positions stored. Note that this will not change * based on calling GetNext(), as the number of positions is not altered @@ -93,6 +112,7 @@ public: 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 @@ -114,7 +134,8 @@ public: /** * Determine whether positions are allocated row first or column first. */ - enum LayoutType { + 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 @@ -140,7 +161,7 @@ public: */ void SetMinY (double yMin); /** - * \param z the Z coordinate of all the positions allocated + * \param z the Z coordinate of all the positions allocated */ void SetZ (double z); /** @@ -189,6 +210,7 @@ public: 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 @@ -225,13 +247,14 @@ public: * \param y pointer to a RandomVariableStream object */ void SetY (Ptr y); - /** - * \param z the Z coordinate of all the positions allocated + /** + * \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 @@ -271,6 +294,7 @@ public: 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 @@ -280,7 +304,7 @@ private: /** * \ingroup mobility * \brief Allocate random positions within a disc according to - * a given distribution for the polar coordinates of each node + * a given distribution for the polar coordinates of each node * with respect to the provided center of the disc. * * \note With the default uniform distribution over \f$2 \pi\f$ in \c theta and a @@ -311,21 +335,22 @@ public: * \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 + /** + * \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 + /** + * \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 @@ -345,7 +370,7 @@ private: * 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. + * subset to the area of the whole disc. * * \note using UniformDiscPositionAllocator is not equivalent to using * a RandomDiscPositionAllocator with a uniformly-distributed radius, @@ -363,30 +388,31 @@ public: 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 + /** + * \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 + /** + * \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 + 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