mobility: Enable ListPositionAllocator to read positions from a csv file

Merges !443
This commit is contained in:
Peter D. Barnes, Jr
2020-10-15 16:06:00 -07:00
committed by Tom Henderson
parent ed5a19f227
commit 34b23fac26
2 changed files with 157 additions and 59 deletions

View File

@@ -24,6 +24,8 @@
#include "ns3/uinteger.h"
#include "ns3/enum.h"
#include "ns3/log.h"
#include "ns3/csv-reader.h"
#include <cmath>
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<PositionAllocator> ()
.SetGroupName ("Mobility")
.AddConstructor<ListPositionAllocator> ()
;
;
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<RandomVariableStream> x)
{
m_x = x;
}
void
RandomRectanglePositionAllocator::SetY (Ptr<RandomVariableStream> 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<RandomVariableStream> ());
MakePointerChecker<RandomVariableStream> ())
;
return tid;
}
RandomBoxPositionAllocator::RandomBoxPositionAllocator ()
{
}
{}
RandomBoxPositionAllocator::~RandomBoxPositionAllocator ()
{
}
{}
void
RandomBoxPositionAllocator::SetX (Ptr<RandomVariableStream> x)
{
m_x = x;
}
void
RandomBoxPositionAllocator::SetY (Ptr<RandomVariableStream> y)
{
m_y = y;
}
void
RandomBoxPositionAllocator::SetZ (Ptr<RandomVariableStream> 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<double> ())
;
;
return tid;
}
RandomDiscPositionAllocator::RandomDiscPositionAllocator ()
{
}
{}
RandomDiscPositionAllocator::~RandomDiscPositionAllocator ()
{
}
{}
void
RandomDiscPositionAllocator::SetTheta (Ptr<RandomVariableStream> theta)
{
m_theta = theta;
}
void
RandomDiscPositionAllocator::SetRho (Ptr<RandomVariableStream> 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<double> ())
;
;
return tid;
}
@@ -494,30 +562,34 @@ UniformDiscPositionAllocator::UniformDiscPositionAllocator ()
{
m_rv = CreateObject<UniformRandomVariable> ();
}
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

View File

@@ -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<Vector> m_positions; //!< vector of positions
mutable std::vector<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<RandomVariableStream> 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<RandomVariableStream> m_x; //!< pointer to x's random variable stream
Ptr<RandomVariableStream> 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<RandomVariableStream> m_x; //!< pointer to x's random variable stream
Ptr<RandomVariableStream> 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<RandomVariableStream> 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<RandomVariableStream> m_theta; //!< pointer to theta's random variable stream
Ptr<RandomVariableStream> 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<UniformRandomVariable> m_rv; //!< pointer to uniform random variable
Ptr<UniformRandomVariable> 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