memory-efficient RadioEnvironmentMapHelper
authorNicola Baldo <nbaldo@cttc.es>
Tue, 20 Mar 2012 18:02:56 +0100
changeset 8688 b6abf3b8d4f5
parent 8687 055e7849df8b
child 8689 04363f082bec
memory-efficient RadioEnvironmentMapHelper
src/lte/helper/radio-environment-map-helper.cc
src/lte/helper/radio-environment-map-helper.h
src/lte/model/rem-spectrum-phy.cc
src/lte/model/rem-spectrum-phy.h
--- a/src/lte/helper/radio-environment-map-helper.cc	Mon Mar 19 17:43:38 2012 +0100
+++ b/src/lte/helper/radio-environment-map-helper.cc	Tue Mar 20 18:02:56 2012 +0100
@@ -101,7 +101,7 @@
     .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 @@
                    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 @@
   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 ();
--- a/src/lte/helper/radio-environment-map-helper.h	Mon Mar 19 17:43:38 2012 +0100
+++ b/src/lte/helper/radio-environment-map-helper.h	Tue Mar 20 18:02:56 2012 +0100
@@ -24,7 +24,7 @@
 
 
 #include <ns3/object.h>
-
+#include <fstream>
 
 
 namespace ns3 {
@@ -44,19 +44,24 @@
 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 @@
   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 @@
   Ptr<SpectrumChannel> m_channel;
 
   double m_noisePower;
+
+  std::ofstream m_outFile;
+
 };
 
 
--- a/src/lte/model/rem-spectrum-phy.cc	Mon Mar 19 17:43:38 2012 +0100
+++ b/src/lte/model/rem-spectrum-phy.cc	Tue Mar 20 18:02:56 2012 +0100
@@ -145,5 +145,18 @@
   m_active = false;
 }
 
+bool
+RemSpectrumPhy::IsActive ()
+{
+  return m_active;
+}
+
+void
+RemSpectrumPhy::Reset ()
+{
+  m_referenceSignalPower = 0;
+  m_sumPower = 0;
+}
+
 
 } // namespace ns3
--- a/src/lte/model/rem-spectrum-phy.h	Mon Mar 19 17:43:38 2012 +0100
+++ b/src/lte/model/rem-spectrum-phy.h	Tue Mar 20 18:02:56 2012 +0100
@@ -77,11 +77,22 @@
   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;