From 2f9a00005464c9283c977cf511ed62814c2cb7d4 Mon Sep 17 00:00:00 2001 From: Nicola Baldo Date: Tue, 20 Mar 2012 18:02:56 +0100 Subject: [PATCH] memory-efficient RadioEnvironmentMapHelper --- .../helper/radio-environment-map-helper.cc | 182 +++++++++++++----- src/lte/helper/radio-environment-map-helper.h | 20 +- src/lte/model/rem-spectrum-phy.cc | 13 ++ src/lte/model/rem-spectrum-phy.h | 13 +- 4 files changed, 173 insertions(+), 55 deletions(-) diff --git a/src/lte/helper/radio-environment-map-helper.cc b/src/lte/helper/radio-environment-map-helper.cc index a858f3fd6..01bb85318 100644 --- a/src/lte/helper/radio-environment-map-helper.cc +++ b/src/lte/helper/radio-environment-map-helper.cc @@ -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 (2,std::numeric_limits::max ())) + MakeUintegerChecker (2,std::numeric_limits::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 ()) + .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 (1,std::numeric_limits::max ())) ; return tid; } @@ -138,66 +142,144 @@ RadioEnvironmentMapHelper::Install () m_channel = match.Get (0)->GetObject (); 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 (); - p.bmm = CreateObject (); - 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::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 (); + p.bmm = CreateObject (); + 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::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::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 (); diff --git a/src/lte/helper/radio-environment-map-helper.h b/src/lte/helper/radio-environment-map-helper.h index 66e2f35e6..856aa91a1 100644 --- a/src/lte/helper/radio-environment-map-helper.h +++ b/src/lte/helper/radio-environment-map-helper.h @@ -24,7 +24,7 @@ #include - +#include 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 m_channel; double m_noisePower; + + std::ofstream m_outFile; + }; diff --git a/src/lte/model/rem-spectrum-phy.cc b/src/lte/model/rem-spectrum-phy.cc index 5944ef271..f21ae65fa 100644 --- a/src/lte/model/rem-spectrum-phy.cc +++ b/src/lte/model/rem-spectrum-phy.cc @@ -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 diff --git a/src/lte/model/rem-spectrum-phy.h b/src/lte/model/rem-spectrum-phy.h index a22ba7336..b0a23ac96 100644 --- a/src/lte/model/rem-spectrum-phy.h +++ b/src/lte/model/rem-spectrum-phy.h @@ -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 m_mobility;