memory-efficient RadioEnvironmentMapHelper
This commit is contained in:
@@ -101,7 +101,7 @@ RadioEnvironmentMapHelper::GetTypeId (void)
|
||||
.AddAttribute ("YRes", "The resolution (number of points) of the map along the y axis.",
|
||||
UintegerValue (100),
|
||||
MakeUintegerAccessor (&RadioEnvironmentMapHelper::m_yRes),
|
||||
MakeUintegerChecker<uint32_t> (2,std::numeric_limits<uint16_t>::max ()))
|
||||
MakeUintegerChecker<uint16_t> (2,std::numeric_limits<uint16_t>::max ()))
|
||||
.AddAttribute ("Z", "The value of the z coordinate for which the map is to be generated",
|
||||
DoubleValue (0.0),
|
||||
MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_z),
|
||||
@@ -115,6 +115,10 @@ RadioEnvironmentMapHelper::GetTypeId (void)
|
||||
DoubleValue (1.4230e-10),
|
||||
MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_noisePower),
|
||||
MakeDoubleChecker<double> ())
|
||||
.AddAttribute ("MaxPointsPerIteration", "Maximum number of REM points to be calculated per iteration. Every point consumes approximately 5KB of memory.",
|
||||
UintegerValue (20000),
|
||||
MakeUintegerAccessor (&RadioEnvironmentMapHelper::m_maxPointsPerIteration),
|
||||
MakeUintegerChecker<uint32_t> (1,std::numeric_limits<uint32_t>::max ()))
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
@@ -138,66 +142,144 @@ RadioEnvironmentMapHelper::Install ()
|
||||
m_channel = match.Get (0)->GetObject<SpectrumChannel> ();
|
||||
NS_ABORT_MSG_IF (m_channel == 0, "object at " << m_channelPath << "is not of type SpectrumChannel");
|
||||
|
||||
double xStep = (m_xMax - m_xMin)/(m_xRes-1);
|
||||
double yStep = (m_yMax - m_yMin)/(m_yRes-1);
|
||||
|
||||
|
||||
for (double x = m_xMin; x < m_xMax + 0.5*xStep; x += xStep)
|
||||
{
|
||||
for (double y = m_yMin; y < m_yMax + 0.5*yStep ; y += yStep)
|
||||
{
|
||||
RemPoint p;
|
||||
p.phy = CreateObject<RemSpectrumPhy> ();
|
||||
p.bmm = CreateObject<BuildingsMobilityModel> ();
|
||||
p.phy->SetMobility (p.bmm);
|
||||
p.bmm->SetPosition (Vector (x, y, m_z));
|
||||
BuildingsHelper::MakeConsistent (p.bmm);
|
||||
m_rem.push_back (p);
|
||||
}
|
||||
}
|
||||
Simulator::Schedule (Seconds (0.0055), &RadioEnvironmentMapHelper::Connect, this);
|
||||
Simulator::Schedule (Seconds (0.0065), &RadioEnvironmentMapHelper::PrintAndDeactivate, this);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
RadioEnvironmentMapHelper::Connect ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
for (std::list<RemPoint>::iterator it = m_rem.begin ();
|
||||
it != m_rem.end ();
|
||||
++it)
|
||||
{
|
||||
NS_LOG_LOGIC ("adding phy " << it->phy);
|
||||
m_channel->AddRx (it->phy);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RadioEnvironmentMapHelper::PrintAndDeactivate ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
std::ofstream outFile;
|
||||
outFile.open (m_outputFile.c_str ());
|
||||
if (!outFile.is_open ())
|
||||
m_outFile.open (m_outputFile.c_str ());
|
||||
if (!m_outFile.is_open ())
|
||||
{
|
||||
NS_FATAL_ERROR ("Can't open file " << (m_outputFile));
|
||||
return;
|
||||
}
|
||||
|
||||
Simulator::Schedule (Seconds (0.0016),
|
||||
&RadioEnvironmentMapHelper::DelayedInstall,
|
||||
this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RadioEnvironmentMapHelper::DelayedInstall ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_xStep = (m_xMax - m_xMin)/(m_xRes-1);
|
||||
m_yStep = (m_yMax - m_yMin)/(m_yRes-1);
|
||||
|
||||
if ((double)m_xRes * (double) m_yRes < (double) m_maxPointsPerIteration)
|
||||
{
|
||||
m_maxPointsPerIteration = m_xRes * m_yRes;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < m_maxPointsPerIteration; ++i)
|
||||
{
|
||||
RemPoint p;
|
||||
p.phy = CreateObject<RemSpectrumPhy> ();
|
||||
p.bmm = CreateObject<BuildingsMobilityModel> ();
|
||||
p.phy->SetMobility (p.bmm);
|
||||
m_channel->AddRx (p.phy);
|
||||
m_rem.push_back (p);
|
||||
}
|
||||
|
||||
double remIterationStartTime = 0.0001;
|
||||
double xMinNext = m_xMin;
|
||||
double yMinNext = m_yMin;
|
||||
uint32_t numPointsCurrentIteration = 0;
|
||||
bool justScheduled = false;
|
||||
for (double x = m_xMin; x < m_xMax + 0.5*m_xStep; x += m_xStep)
|
||||
{
|
||||
for (double y = m_yMin; y < m_yMax + 0.5*m_yStep ; y += m_yStep)
|
||||
{
|
||||
if (justScheduled)
|
||||
{
|
||||
xMinNext = x;
|
||||
yMinNext = y;
|
||||
justScheduled = false;
|
||||
}
|
||||
|
||||
++numPointsCurrentIteration;
|
||||
if ((numPointsCurrentIteration == m_maxPointsPerIteration)
|
||||
|| ((x > m_xMax - 0.5*m_xStep) && (y > m_yMax - 0.5*m_yStep)) )
|
||||
{
|
||||
Simulator::Schedule (Seconds (remIterationStartTime),
|
||||
&RadioEnvironmentMapHelper::RunOneIteration,
|
||||
this, xMinNext, x, yMinNext, y);
|
||||
remIterationStartTime += 0.001;
|
||||
justScheduled = true;
|
||||
numPointsCurrentIteration = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
Simulator::Schedule (Seconds (remIterationStartTime),
|
||||
&RadioEnvironmentMapHelper::Finalize,
|
||||
this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RadioEnvironmentMapHelper::RunOneIteration (double xMin, double xMax, double yMin, double yMax)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << xMin << xMax << yMin << yMax);
|
||||
std::list<RemPoint>::iterator remIt = m_rem.begin ();
|
||||
double x;
|
||||
double y;
|
||||
for (x = xMin; x < xMax + 0.5*m_xStep; x += m_xStep)
|
||||
{
|
||||
for (y = (x == xMin) ? yMin : m_yMin;
|
||||
y < ((x == xMax) ? yMax : m_yMax) + 0.5*m_yStep;
|
||||
y += m_yStep)
|
||||
{
|
||||
NS_ASSERT (remIt != m_rem.end ());
|
||||
remIt->bmm->SetPosition (Vector (x, y, m_z));
|
||||
BuildingsHelper::MakeConsistent (remIt->bmm);
|
||||
++remIt;
|
||||
}
|
||||
}
|
||||
|
||||
if (remIt != m_rem.end ())
|
||||
{
|
||||
NS_ASSERT ((x > m_xMax - 0.5*m_xStep) && (y > m_yMax - 0.5*m_yStep));
|
||||
NS_LOG_LOGIC ("deactivating RemSpectrumPhys that are unneeded in the last iteration");
|
||||
while (remIt != m_rem.end ())
|
||||
{
|
||||
remIt->phy->Deactivate ();
|
||||
++remIt;
|
||||
}
|
||||
}
|
||||
|
||||
Simulator::Schedule (Seconds (0.0005), &RadioEnvironmentMapHelper::PrintAndReset, this);
|
||||
}
|
||||
|
||||
void
|
||||
RadioEnvironmentMapHelper::PrintAndReset ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
for (std::list<RemPoint>::iterator it = m_rem.begin ();
|
||||
it != m_rem.end ();
|
||||
++it)
|
||||
{
|
||||
if (!(it->phy->IsActive ()))
|
||||
{
|
||||
// should occur only upon last iteration when some RemPoint
|
||||
// at the end of the list can be unused
|
||||
break;
|
||||
}
|
||||
Vector pos = it->bmm->GetPosition ();
|
||||
outFile << pos.x << "\t"
|
||||
<< pos.y << "\t"
|
||||
<< pos.z << "\t"
|
||||
<< it->phy->GetSinr (m_noisePower)
|
||||
<< std::endl;
|
||||
it->phy->Deactivate ();
|
||||
NS_LOG_LOGIC ("output: " << pos.x << "\t"
|
||||
<< pos.y << "\t"
|
||||
<< pos.z << "\t"
|
||||
<< it->phy->GetSinr (m_noisePower));
|
||||
m_outFile << pos.x << "\t"
|
||||
<< pos.y << "\t"
|
||||
<< pos.z << "\t"
|
||||
<< it->phy->GetSinr (m_noisePower)
|
||||
<< std::endl;
|
||||
it->phy->Reset ();
|
||||
}
|
||||
outFile.close ();
|
||||
}
|
||||
|
||||
void
|
||||
RadioEnvironmentMapHelper::Finalize ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_outFile.close ();
|
||||
if (m_stopWhenDone)
|
||||
{
|
||||
Simulator::Stop ();
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
|
||||
#include <ns3/object.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
|
||||
namespace ns3 {
|
||||
@@ -44,19 +44,24 @@ class RadioEnvironmentMapHelper : public Object
|
||||
public:
|
||||
|
||||
RadioEnvironmentMapHelper ();
|
||||
|
||||
virtual ~RadioEnvironmentMapHelper ();
|
||||
|
||||
// inherited from Object
|
||||
virtual void DoDispose (void);
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
/**
|
||||
* Deploy the RemSpectrumPhy objects that generate the map according to the specified settings.
|
||||
*
|
||||
*/
|
||||
void Install ();
|
||||
|
||||
private:
|
||||
|
||||
void Connect ();
|
||||
void PrintAndDeactivate ();
|
||||
void DelayedInstall ();
|
||||
void RunOneIteration (double xMin, double xMax, double yMin, double yMax);
|
||||
void PrintAndReset ();
|
||||
void Finalize ();
|
||||
|
||||
|
||||
struct RemPoint
|
||||
@@ -70,10 +75,14 @@ private:
|
||||
double m_xMin;
|
||||
double m_xMax;
|
||||
uint16_t m_xRes;
|
||||
double m_xStep;
|
||||
|
||||
double m_yMin;
|
||||
double m_yMax;
|
||||
uint16_t m_yRes;
|
||||
double m_yStep;
|
||||
|
||||
uint32_t m_maxPointsPerIteration;
|
||||
|
||||
double m_z;
|
||||
|
||||
@@ -85,6 +94,9 @@ private:
|
||||
Ptr<SpectrumChannel> m_channel;
|
||||
|
||||
double m_noisePower;
|
||||
|
||||
std::ofstream m_outFile;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -145,5 +145,18 @@ RemSpectrumPhy::Deactivate ()
|
||||
m_active = false;
|
||||
}
|
||||
|
||||
bool
|
||||
RemSpectrumPhy::IsActive ()
|
||||
{
|
||||
return m_active;
|
||||
}
|
||||
|
||||
void
|
||||
RemSpectrumPhy::Reset ()
|
||||
{
|
||||
m_referenceSignalPower = 0;
|
||||
m_sumPower = 0;
|
||||
}
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -77,11 +77,22 @@ public:
|
||||
double GetSinr (double noisePower);
|
||||
|
||||
/**
|
||||
* make StartRx a no-op from now on
|
||||
* make StartRx a no-op from now on, and mark instance as inactive
|
||||
*
|
||||
*/
|
||||
void Deactivate ();
|
||||
|
||||
/**
|
||||
*
|
||||
* \return true if active
|
||||
*/
|
||||
bool IsActive ();
|
||||
|
||||
/**
|
||||
* Reset the SINR calculator
|
||||
*
|
||||
*/
|
||||
void Reset ();
|
||||
|
||||
private:
|
||||
Ptr<MobilityModel> m_mobility;
|
||||
|
||||
Reference in New Issue
Block a user