Merge Gauss Markov Mobility Model

This commit is contained in:
Dan Broyles
2010-03-03 10:58:27 -05:00
parent 14b0e0ae39
commit 8a0331ab36
10 changed files with 719 additions and 0 deletions

View File

@@ -48,3 +48,4 @@ Guillaume Vu-Brugier (gvubrugier@gmail.com)
Tom Wambold (tom5760@gmail.com)
Florian Westphal (fw@strlen.de)
Josh Pelkey (jpelkey@gatech.edu)
Dan Broyles (muxman@sbcglobal.net)

169
src/mobility/box.cc Normal file
View File

@@ -0,0 +1,169 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2009 Dan Broyles
*
* 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: Dan Broyles <dbroyl01@ku.edu>
*/
#include "box.h"
#include "ns3/vector.h"
#include "ns3/assert.h"
#include "ns3/fatal-error.h"
#include <cmath>
#include <algorithm>
#include <sstream>
namespace ns3 {
Box::Box (double _xMin, double _xMax,
double _yMin, double _yMax,
double _zMin, double _zMax)
: xMin (_xMin),
xMax (_xMax),
yMin (_yMin),
yMax (_yMax),
zMin (_zMin),
zMax (_zMax)
{}
Box::Box ()
: xMin (0.0),
xMax (0.0),
yMin (0.0),
yMax (0.0),
zMin (0.0),
zMax (0.0)
{}
bool
Box::IsInside (const Vector &position) const
{
return
position.x <= this->xMax && position.x >= this->xMin &&
position.y <= this->yMax && position.y >= this->yMin &&
position.z <= this->zMax && position.z >= this->zMin;
}
Box::Side
Box::GetClosestSide (const Vector &position) const
{
double xMinDist = std::abs (position.x - this->xMin);
double xMaxDist = std::abs (this->xMax - position.x);
double yMinDist = std::abs (position.y - this->yMin);
double yMaxDist = std::abs (this->yMax - position.y);
double zMinDist = std::abs (position.z - this->zMin);
double zMaxDist = std::abs (this->zMax - position.z);
double minX = std::min (xMinDist, xMaxDist);
double minY = std::min (yMinDist, yMaxDist);
double minZ = std::min (zMinDist, zMaxDist);
if (minX < minY && minX < minZ)
{
if (xMinDist < xMaxDist)
{
return LEFT;
}
else
{
return RIGHT;
}
}
else if (minY < minZ)
{
if (yMinDist < yMaxDist)
{
return BOTTOM;
}
else
{
return TOP;
}
}
else
{
if (zMinDist < zMaxDist)
{
return DOWN;
}
else
{
return UP;
}
}
}
Vector
Box::CalculateIntersection (const Vector &current, const Vector &speed) const
{
NS_ASSERT (IsInside (current));
double xMaxY = current.y + (this->xMax - current.x) / speed.x * speed.y;
double xMinY = current.y + (this->xMin - current.x) / speed.x * speed.y;
double yMaxX = current.x + (this->yMax - current.y) / speed.y * speed.x;
double yMinX = current.x + (this->yMin - current.y) / speed.y * speed.x;
bool xMaxYOk = (xMaxY <= this->yMax && xMaxY >= this->yMin);
bool xMinYOk = (xMinY <= this->yMax && xMinY >= this->yMin);
bool yMaxXOk = (yMaxX <= this->xMax && yMaxX >= this->xMin);
bool yMinXOk = (yMinX <= this->xMax && yMinX >= this->xMin);
if (xMaxYOk && speed.x >= 0)
{
return Vector (this->xMax, xMaxY, 0.0);
}
else if (xMinYOk && speed.x <= 0)
{
return Vector (this->xMin, xMinY, 0.0);
}
else if (yMaxXOk && speed.y >= 0)
{
return Vector (yMaxX, this->yMax, 0.0);
}
else if (yMinXOk && speed.y <= 0)
{
return Vector (yMinX, this->yMin, 0.0);
}
else
{
NS_ASSERT (false);
// quiet compiler
return Vector (0.0, 0.0, 0.0);
}
}
ATTRIBUTE_HELPER_CPP (Box);
std::ostream &
operator << (std::ostream &os, const Box &box)
{
os << box.xMin << "|" << box.xMax << "|" << box.yMin << "|" << box.yMax << "|" << box.zMin << "|" << box.zMax;
return os;
}
std::istream &
operator >> (std::istream &is, Box &box)
{
char c1, c2, c3, c4, c5;
is >> box.xMin >> c1 >> box.xMax >> c2 >> box.yMin >> c3 >> box.yMax >> c4 >> box.zMin >> c5 >> box.zMax;
if (c1 != '|' ||
c2 != '|' ||
c3 != '|' ||
c4 != '|' ||
c5 != '|')
{
is.setstate (std::ios_base::failbit);
}
return is;
}
} // namespace ns3

113
src/mobility/box.h Normal file
View File

@@ -0,0 +1,113 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2009 Dan Broyles
*
* 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: Dan Broyles <dbroyl01@ku.edu>
*/
#ifndef BOX_H
#define BOX_H
#include "ns3/attribute.h"
#include "ns3/attribute-helper.h"
#include "ns3/vector.h"
namespace ns3 {
/**
* \brief a 3d box
*/
class Box
{
public:
enum Side {
RIGHT,
LEFT,
TOP,
BOTTOM,
UP,
DOWN
};
/**
* \param _xMin x coordinates of left boundary.
* \param _xMax x coordinates of right boundary.
* \param _yMin y coordinates of bottom boundary.
* \param _yMax y coordinates of top boundary.
* \param _zMin z coordinates of down boundary.
* \param _zMax z coordinates of up boundary.
*
* Create a box.
*/
Box (double _xMin, double _xMax,
double _yMin, double _yMax,
double _zMin, double _zMax);
/**
* Create a zero-sized box located at coordinates (0.0,0.0,0.0)
*/
Box ();
/**
* \param position the position to test.
* \returns true if the input position is located within the box,
* false otherwise.
*
* This method compares the x, y, and z coordinates of the input position.
*/
bool IsInside (const Vector &position) const;
/**
* \param position the position to test.
* \returns the side of the cube the input position is closest to.
*
* This method compares the x, y, and z coordinates of the input position.
*/
Side GetClosestSide (const Vector &position) const;
/**
* \param current the current position
* \param speed the current speed
* \returns the intersection point between the rectangle and the current+speed vector.
*
* This method assumes that the current position is located _inside_
* the cube and checks for this with an assert.
* This method compares only the x and y coordinates of the input position
* and speed. It ignores the z coordinate.
*/
Vector CalculateIntersection (const Vector &current, const Vector &speed) const;
/* The x coordinate of the left bound of the box */
double xMin;
/* The x coordinate of the right bound of the box */
double xMax;
/* The y coordinate of the bottom bound of the box */
double yMin;
/* The y coordinate of the top bound of the box */
double yMax;
/* The z coordinate of the down bound of the box */
double zMin;
/* The z coordinate of the up bound of the box */
double zMax;
};
std::ostream &operator << (std::ostream &os, const Box &box);
std::istream &operator >> (std::istream &is, Box &box);
/**
* \class ns3::BoxValue
* \brief hold objects of type ns3::Box
*/
ATTRIBUTE_HELPER_HEADER (Box);
} // namespace ns3
#endif /* BOX_H */

View File

@@ -19,6 +19,7 @@
*/
#include "ns3/simulator.h"
#include "ns3/rectangle.h"
#include "ns3/box.h"
#include "constant-velocity-helper.h"
namespace ns3 {
@@ -89,6 +90,18 @@ ConstantVelocityHelper::UpdateWithBounds (const Rectangle &bounds) const
m_position.y = std::max (bounds.yMin, m_position.y);
}
void
ConstantVelocityHelper::UpdateWithBounds (const Box &bounds) const
{
Update ();
m_position.x = std::min (bounds.xMax, m_position.x);
m_position.x = std::max (bounds.xMin, m_position.x);
m_position.y = std::min (bounds.yMax, m_position.y);
m_position.y = std::max (bounds.yMin, m_position.y);
m_position.z = std::min (bounds.zMax, m_position.z);
m_position.z = std::max (bounds.zMin, m_position.z);
}
void
ConstantVelocityHelper::Pause (void)
{

View File

@@ -22,6 +22,7 @@
#include "ns3/nstime.h"
#include "ns3/vector.h"
#include "ns3/box.h"
namespace ns3 {
@@ -43,6 +44,7 @@ class ConstantVelocityHelper
void Unpause (void);
void UpdateWithBounds (const Rectangle &rectangle) const;
void UpdateWithBounds (const Box &bounds) const;
void Update (void) const;
private:
mutable Time m_lastUpdate;

View File

@@ -0,0 +1,222 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2009 Dan Broyles
*
* 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: Dan Broyles <dbroyl01@ku.edu>
*/
#include <cmath>
#include "ns3/simulator.h"
#include "ns3/random-variable.h"
#include "ns3/double.h"
#include "ns3/pointer.h"
#include "gauss-markov-mobility-model.h"
#include "position-allocator.h"
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (GaussMarkovMobilityModel);
TypeId
GaussMarkovMobilityModel::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::GaussMarkovMobilityModel")
.SetParent<MobilityModel> ()
.SetGroupName ("Mobility")
.AddConstructor<GaussMarkovMobilityModel> ()
.AddAttribute ("Bounds",
"Bounds of the area to cruise.",
BoxValue (Box (-100.0, 100.0, -100.0, 100.0, 0.0, 100.0)),
MakeBoxAccessor (&GaussMarkovMobilityModel::m_bounds),
MakeBoxChecker ())
.AddAttribute ("TimeStep",
"Change current direction and speed after moving for this time.",
TimeValue (Seconds (1.0)),
MakeTimeAccessor (&GaussMarkovMobilityModel::m_timeStep),
MakeTimeChecker ())
.AddAttribute ("Alpha",
"A constant representing the tunable parameter in the Gauss-Markov model.",
DoubleValue (1.0),
MakeDoubleAccessor (&GaussMarkovMobilityModel::m_alpha),
MakeDoubleChecker<double> ())
.AddAttribute ("MeanVelocity",
"A random variable used to assign the average velocity.",
RandomVariableValue (UniformVariable (0.0, 1.0)),
MakeRandomVariableAccessor (&GaussMarkovMobilityModel::m_rndMeanVelocity),
MakeRandomVariableChecker ())
.AddAttribute ("MeanDirection",
"A random variable used to assign the average direction.",
RandomVariableValue (UniformVariable (0.0, 6.283185307)),
MakeRandomVariableAccessor (&GaussMarkovMobilityModel::m_rndMeanDirection),
MakeRandomVariableChecker ())
.AddAttribute ("MeanPitch",
"A random variable used to assign the average pitch.",
RandomVariableValue (ConstantVariable (0.0)),
MakeRandomVariableAccessor (&GaussMarkovMobilityModel::m_rndMeanPitch),
MakeRandomVariableChecker ())
.AddAttribute ("NormalVelocity",
"A gaussian random variable used to calculate the next velocity value.",
RandomVariableValue (NormalVariable (0.0, 1.0, 10.0)), // Defaults to zero mean, and std dev = 1, and bound to +-10 of the mean
MakeRandomVariableAccessor (&GaussMarkovMobilityModel::m_normalVelocity),
MakeRandomVariableChecker ())
.AddAttribute ("NormalDirection",
"A gaussian random variable used to calculate the next direction value.",
RandomVariableValue (NormalVariable (0.0, 1.0, 10.0)),
MakeRandomVariableAccessor (&GaussMarkovMobilityModel::m_normalDirection),
MakeRandomVariableChecker ())
.AddAttribute ("NormalPitch",
"A gaussian random variable used to calculate the next pitch value.",
RandomVariableValue (NormalVariable (0.0, 1.0, 10.0)),
MakeRandomVariableAccessor (&GaussMarkovMobilityModel::m_normalPitch),
MakeRandomVariableChecker ());
return tid;
}
GaussMarkovMobilityModel::GaussMarkovMobilityModel ()
{
m_meanVelocity = 0.0;
m_meanDirection = 0.0;
m_meanPitch = 0.0;
m_event = Simulator::ScheduleNow (&GaussMarkovMobilityModel::Start, this);
m_helper.Unpause ();
}
void
GaussMarkovMobilityModel::Start (void)
{
if (m_meanVelocity == 0.0)
{
//Initialize the mean velocity, direction, and pitch variables
m_meanVelocity = m_rndMeanVelocity.GetValue ();
m_meanDirection = m_rndMeanDirection.GetValue ();
m_meanPitch = m_rndMeanPitch.GetValue ();
double cosD = std::cos (m_meanDirection);
double cosP = std::cos (m_meanPitch);
double sinD = std::sin (m_meanDirection);
double sinP = std::sin (m_meanPitch);
//Initialize the starting velocity, direction, and pitch to be identical to the mean ones
m_Velocity = m_meanVelocity;
m_Direction = m_meanDirection;
m_Pitch = m_meanPitch;
//Set the velocity vector to give to the constant velocity helper
m_helper.SetVelocity (Vector (m_Velocity*cosD*cosP, m_Velocity*sinD*cosP, m_Velocity*sinP));
}
m_helper.Update ();
//Get the next values from the gaussian distributions for velocity, direction, and pitch
double rv = m_normalVelocity.GetValue ();
double rd = m_normalDirection.GetValue ();
double rp = m_normalPitch.GetValue ();
//Calculate the NEW velocity, direction, and pitch values using the Gauss-Markov formula:
//newVal = alpha*oldVal + (1-alpha)*meanVal + sqrt(1-alpha^2)*rv
//where rv is a random number from a normal (gaussian) distribution
double one_minus_alpha = 1 - m_alpha;
double sqrt_alpha = std::sqrt (1 - m_alpha*m_alpha);
m_Velocity = m_alpha * m_Velocity + one_minus_alpha * m_meanVelocity + sqrt_alpha * rv;
m_Direction = m_alpha * m_Direction + one_minus_alpha * m_meanDirection + sqrt_alpha * rd;
m_Pitch = m_alpha * m_Pitch + one_minus_alpha * m_meanPitch + sqrt_alpha * rp;
//Calculate the linear velocity vector to give to the constant velocity helper
double cosDir = std::cos (m_Direction);
double cosPit = std::cos (m_Pitch);
double sinDir = std::sin (m_Direction);
double sinPit = std::sin (m_Pitch);
double vx = m_Velocity * cosDir * cosPit;
double vy = m_Velocity * sinDir * cosPit;
double vz = m_Velocity * sinPit;
m_helper.SetVelocity (Vector (vx, vy, vz));
m_helper.Unpause ();
DoWalk (m_timeStep);
}
void
GaussMarkovMobilityModel::DoWalk (Time delayLeft)
{
m_helper.UpdateWithBounds (m_bounds);
Vector position = m_helper.GetCurrentPosition ();
Vector speed = m_helper.GetVelocity ();
Vector nextPosition = position;
nextPosition.x += speed.x * delayLeft.GetSeconds ();
nextPosition.y += speed.y * delayLeft.GetSeconds ();
nextPosition.z += speed.z * delayLeft.GetSeconds ();
if (delayLeft.GetSeconds () < 0.0) delayLeft = Seconds (1.0);
// Make sure that the position by the next time step is still within the boundary.
// If out of bounds, then alter the velocity vector and average direction to keep the position in bounds
if (m_bounds.IsInside (nextPosition))
{
m_event = Simulator::Schedule (delayLeft, &GaussMarkovMobilityModel::Start, this);
}
else
{
if (nextPosition.x > m_bounds.xMax || nextPosition.x < m_bounds.xMin)
{
speed.x = - speed.x;
m_meanDirection = 3.14159265 - m_meanDirection;
}
if (nextPosition.y > m_bounds.yMax || nextPosition.y < m_bounds.yMin)
{
speed.y = - speed.y;
m_meanDirection = - m_meanDirection;
}
if (nextPosition.z > m_bounds.zMax || nextPosition.z < m_bounds.zMin)
{
speed.z = - speed.z;
m_meanPitch = - m_meanPitch;
}
m_Direction = m_meanDirection;
m_Pitch = m_meanPitch;
m_helper.SetVelocity (speed);
m_helper.Unpause ();
m_event = Simulator::Schedule (delayLeft, &GaussMarkovMobilityModel::Start, this);
}
NotifyCourseChange ();
}
void
GaussMarkovMobilityModel::DoDispose (void)
{
// chain up
MobilityModel::DoDispose ();
}
Vector
GaussMarkovMobilityModel::DoGetPosition (void) const
{
m_helper.Update ();
return m_helper.GetCurrentPosition ();
}
void
GaussMarkovMobilityModel::DoSetPosition (const Vector &position)
{
m_helper.SetPosition (position);
Simulator::Remove (m_event);
m_event = Simulator::ScheduleNow (&GaussMarkovMobilityModel::Start, this);
}
Vector
GaussMarkovMobilityModel::DoGetVelocity (void) const
{
return m_helper.GetVelocity ();
}
} // namespace ns3

View File

@@ -0,0 +1,113 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2009 Dan Broyles
*
* 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: Dan Broyles <dbroyl01@ku.edu>
* Thanks to the students and faculty in the ResiliNets initiative
* at Kansas University, https://wiki.ittc.ku.edu/resilinets/Main_Page
*/
#ifndef GAUSS_MARKOV_MOBILITY_MODEL_H
#define GAUSS_MARKOV_MOBILITY_MODEL_H
#include "constant-velocity-helper.h"
#include "mobility-model.h"
#include "position-allocator.h"
#include "ns3/ptr.h"
#include "ns3/object.h"
#include "ns3/nstime.h"
#include "ns3/event-id.h"
#include "ns3/box.h"
#include "ns3/random-variable.h"
namespace ns3 {
/**
* \brief description of gauss markov mobility model
*
* This is a 3D version of the Gauss-Markov mobility model described in [1].
* Unlike the other mobility models in ns-3, which are memoryless, the Gauss
* Markov model has both memory and variability. The tunable alpha parameter
* determines the how much memory and randomness you want to model.
* Each object starts with a specific velocity, direction (radians), and pitch
* angle (radians) equivalent to the mean velocity, direction, and pitch.
* At each timestep, a new velocity, direction, and pitch angle are generated
* based upon the previous value, the mean value, and a gaussian random variable.
* This version is suited for simple airplane flight, where direction, velocity,
* and pitch are the key variables.
* The motion field is limited by a 3D bounding box (called "box") which is a 3D
* version of the "rectangle" field that is used in 2-dimensional ns-3 mobility models.
*
* Here is an example of how to implement the model and set the initial node positions:
*
* MobilityHelper mobility;
*
* mobility.SetMobilityModel ("ns3::GaussMarkovMobilityModel",
* "Bounds", BoxValue (Box (0, 150000, 0, 150000, 0, 10000)),
* "TimeStep", TimeValue (Seconds (0.5)),
* "Alpha", DoubleValue (0.85),
* "MeanVelocity", RandomVariableValue (UniformVariable (800, 1200)),
* "MeanDirection", RandomVariableValue (UniformVariable (0, 6.283185307)),
* "MeanPitch", RandomVariableValue (UniformVariable (0.05, 0.05)),
* "NormalVelocity", RandomVariableValue (NormalVariable (0.0, 0.0, 0.0)),
* "NormalDirection", RandomVariableValue (NormalVariable (0.0, 0.2, 0.4)),
* "NormalPitch", RandomVariableValue (NormalVariable (0.0, 0.02, 0.04)));
*
* mobility.SetPositionAllocator ("ns3::RandomBoxPositionAllocator",
* "X", RandomVariableValue (UniformVariable (0, 150000)),
* "Y", RandomVariableValue (UniformVariable (0, 150000)),
* "Z", RandomVariableValue (UniformVariable (0, 10000)));
*
* mobility.Install (wifiStaNodes);
*
* [1] Tracy Camp, Jeff Boleng, Vanessa Davies, "A Survey of Mobility Models
* for Ad Hoc Network Research", Wireless Communications and Mobile Computing,
* Wiley, vol.2 iss.5, September 2002, pp.483-502
*/
class GaussMarkovMobilityModel : public MobilityModel
{
public:
static TypeId GetTypeId (void);
GaussMarkovMobilityModel ();
private:
void Start (void);
void DoWalk (Time timeLeft);
virtual void DoDispose (void);
virtual Vector DoGetPosition (void) const;
virtual void DoSetPosition (const Vector &position);
virtual Vector DoGetVelocity (void) const;
ConstantVelocityHelper m_helper;
Time m_timeStep;
double m_alpha;
double m_meanVelocity;
double m_meanDirection;
double m_meanPitch;
double m_Velocity;
double m_Direction;
double m_Pitch;
RandomVariable m_rndMeanVelocity;
RandomVariable m_normalVelocity;
RandomVariable m_rndMeanDirection;
RandomVariable m_normalDirection;
RandomVariable m_rndMeanPitch;
RandomVariable m_normalPitch;
EventId m_event;
Box m_bounds;
};
} // namespace ns3
#endif /* GAUSS_MARKOV_MOBILITY_MODEL_H */

View File

@@ -245,6 +245,66 @@ RandomRectanglePositionAllocator::GetNext (void) const
return Vector (x, y, 0.0);
}
NS_OBJECT_ENSURE_REGISTERED (RandomBoxPositionAllocator);
TypeId
RandomBoxPositionAllocator::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::RandomBoxPositionAllocator")
.SetParent<PositionAllocator> ()
.SetGroupName ("Mobility")
.AddConstructor<RandomBoxPositionAllocator> ()
.AddAttribute ("X",
"A random variable which represents the x coordinate of a position in a random box.",
RandomVariableValue (UniformVariable (0.0, 1.0)),
MakeRandomVariableAccessor (&RandomBoxPositionAllocator::m_x),
MakeRandomVariableChecker ())
.AddAttribute ("Y",
"A random variable which represents the y coordinate of a position in a random box.",
RandomVariableValue (UniformVariable (0.0, 1.0)),
MakeRandomVariableAccessor (&RandomBoxPositionAllocator::m_y),
MakeRandomVariableChecker ())
.AddAttribute ("Z",
"A random variable which represents the z coordinate of a position in a random box.",
RandomVariableValue (UniformVariable (0.0, 1.0)),
MakeRandomVariableAccessor (&RandomBoxPositionAllocator::m_z),
MakeRandomVariableChecker ());
return tid;
}
RandomBoxPositionAllocator::RandomBoxPositionAllocator ()
{}
RandomBoxPositionAllocator::~RandomBoxPositionAllocator ()
{}
void
RandomBoxPositionAllocator::SetX (RandomVariable x)
{
m_x = x;
}
void
RandomBoxPositionAllocator::SetY (RandomVariable y)
{
m_y = y;
}
void
RandomBoxPositionAllocator::SetZ (RandomVariable z)
{
m_z = z;
}
Vector
RandomBoxPositionAllocator::GetNext (void) const
{
double x = m_x.GetValue ();
double y = m_y.GetValue ();
double z = m_z.GetValue ();
return Vector (x, y, z);
}
NS_OBJECT_ENSURE_REGISTERED (RandomDiscPositionAllocator);
TypeId

View File

@@ -180,6 +180,28 @@ private:
RandomVariable m_y;
};
/**
* \brief allocate random positions within a 3D box
* according to a set of three random variables.
*/
class RandomBoxPositionAllocator : public PositionAllocator
{
public:
static TypeId GetTypeId (void);
RandomBoxPositionAllocator ();
virtual ~RandomBoxPositionAllocator ();
void SetX (RandomVariable x);
void SetY (RandomVariable y);
void SetZ (RandomVariable z);
virtual Vector GetNext (void) const;
private:
RandomVariable m_x;
RandomVariable m_y;
RandomVariable m_z;
};
/**
* \brief allocate random positions within a disc
* according to a given distribution for the polar coordinates of each

View File

@@ -7,9 +7,11 @@ def build(bld):
'mobility-model.cc',
'position-allocator.cc',
'rectangle.cc',
'box.cc',
'constant-position-mobility-model.cc',
'constant-velocity-helper.cc',
'constant-velocity-mobility-model.cc',
'gauss-markov-mobility-model.cc',
'random-waypoint-mobility-model.cc',
'steady-state-random-waypoint-mobility-model.cc',
'random-walk-2d-mobility-model.cc',
@@ -26,9 +28,11 @@ def build(bld):
'mobility-model.h',
'position-allocator.h',
'rectangle.h',
'box.h',
'constant-position-mobility-model.h',
'constant-velocity-helper.h',
'constant-velocity-mobility-model.h',
'gauss-markov-mobility-model.h',
'random-waypoint-mobility-model.h',
'steady-state-random-waypoint-mobility-model.h',
'random-walk-2d-mobility-model.h',