bug 1774: compute signal power around channel, not across whole band
authorTommaso Pecorella <tommaso.pecorella@unifi.it>
Sun, 01 Feb 2015 21:08:32 -0800
changeset 11205 29b708f01eb1
parent 11204 f8f2488b08ca
child 11206 70702e9427a9
bug 1774: compute signal power around channel, not across whole band
src/lr-wpan/model/lr-wpan-phy.cc
src/lr-wpan/model/lr-wpan-phy.h
src/lr-wpan/model/lr-wpan-spectrum-value-helper.cc
src/lr-wpan/model/lr-wpan-spectrum-value-helper.h
src/lr-wpan/test/lr-wpan-spectrum-value-helper-test.cc
--- a/src/lr-wpan/model/lr-wpan-phy.cc	Sun Feb 01 21:01:25 2015 -0800
+++ b/src/lr-wpan/model/lr-wpan-phy.cc	Sun Feb 01 21:08:32 2015 -0800
@@ -274,20 +274,38 @@
   NS_LOG_FUNCTION (this << spectrumRxParams);
   LrWpanSpectrumValueHelper psdHelper;
 
-
-  Ptr<LrWpanSpectrumSignalParameters> lrWpanRxParams = DynamicCast<LrWpanSpectrumSignalParameters> (spectrumRxParams);
-  NS_ASSERT (lrWpanRxParams != 0);
-  Ptr<Packet> p = (lrWpanRxParams->packetBurst->GetPackets ()).front ();
-  NS_ASSERT (p != 0);
-
   if (!m_edRequest.IsExpired ())
     {
       // Update the average receive power during ED.
       Time now = Simulator::Now ();
-      m_edPower.averagePower += LrWpanSpectrumValueHelper::TotalAvgPower (m_signal->GetSignalPsd ()) * (now - m_edPower.lastUpdate).GetTimeStep () / m_edPower.measurementLength.GetTimeStep ();
+      m_edPower.averagePower += LrWpanSpectrumValueHelper::TotalAvgPower (m_signal->GetSignalPsd (), m_phyPIBAttributes.phyCurrentChannel) * (now - m_edPower.lastUpdate).GetTimeStep () / m_edPower.measurementLength.GetTimeStep ();
       m_edPower.lastUpdate = now;
     }
 
+  Ptr<LrWpanSpectrumSignalParameters> lrWpanRxParams = DynamicCast<LrWpanSpectrumSignalParameters> (spectrumRxParams);
+
+  if ( lrWpanRxParams == 0)
+    {
+      CheckInterference ();
+      m_signal->AddSignal (spectrumRxParams->psd);
+
+      // Update peak power if CCA is in progress.
+      if (!m_ccaRequest.IsExpired ())
+        {
+          double power = LrWpanSpectrumValueHelper::TotalAvgPower (m_signal->GetSignalPsd (), m_phyPIBAttributes.phyCurrentChannel);
+          if (m_ccaPeakPower < power)
+            {
+              m_ccaPeakPower = power;
+            }
+        }
+
+      Simulator::Schedule (spectrumRxParams->duration, &LrWpanPhy::EndRx, this, spectrumRxParams);
+      return;
+    }
+
+  Ptr<Packet> p = (lrWpanRxParams->packetBurst->GetPackets ()).front ();
+  NS_ASSERT (p != 0);
+
   // Prevent PHY from receiving another packet while switching the transceiver state.
   if (m_trxState == IEEE_802_15_4_PHY_RX_ON && !m_setTRXState.IsRunning ())
     {
@@ -307,12 +325,12 @@
 
       // Add any incoming packet to the current interference before checking the
       // SINR.
-      NS_LOG_DEBUG (this << " receiving packet with power: " << 10 * log10(LrWpanSpectrumValueHelper::TotalAvgPower (lrWpanRxParams->psd)) + 30 << "dBm");
+      NS_LOG_DEBUG (this << " receiving packet with power: " << 10 * log10(LrWpanSpectrumValueHelper::TotalAvgPower (lrWpanRxParams->psd, m_phyPIBAttributes.phyCurrentChannel)) + 30 << "dBm");
       m_signal->AddSignal (lrWpanRxParams->psd);
       Ptr<SpectrumValue> interferenceAndNoise = m_signal->GetSignalPsd ();
       *interferenceAndNoise -= *lrWpanRxParams->psd;
       *interferenceAndNoise += *m_noise;
-      double sinr = LrWpanSpectrumValueHelper::TotalAvgPower (lrWpanRxParams->psd) / LrWpanSpectrumValueHelper::TotalAvgPower (interferenceAndNoise);
+      double sinr = LrWpanSpectrumValueHelper::TotalAvgPower (lrWpanRxParams->psd, m_phyPIBAttributes.phyCurrentChannel) / LrWpanSpectrumValueHelper::TotalAvgPower (interferenceAndNoise, m_phyPIBAttributes.phyCurrentChannel);
 
       // Std. 802.15.4-2006, appendix E, Figure E.2
       // At SNR < -5 the BER is less than 10e-1.
@@ -357,7 +375,7 @@
   // Update peak power if CCA is in progress.
   if (!m_ccaRequest.IsExpired ())
     {
-      double power = LrWpanSpectrumValueHelper::TotalAvgPower (m_signal->GetSignalPsd ());
+      double power = LrWpanSpectrumValueHelper::TotalAvgPower (m_signal->GetSignalPsd (), m_phyPIBAttributes.phyCurrentChannel);
       if (m_ccaPeakPower < power)
         {
           m_ccaPeakPower = power;
@@ -366,7 +384,8 @@
 
   // Always call EndRx to update the interference.
   // \todo: Do we need to keep track of these events to unschedule them when disposing off the PHY?
-  Simulator::Schedule (lrWpanRxParams->duration, &LrWpanPhy::EndRx, this, lrWpanRxParams);
+
+  Simulator::Schedule (spectrumRxParams->duration, &LrWpanPhy::EndRx, this, spectrumRxParams);
 }
 
 void
@@ -390,7 +409,7 @@
           Ptr<SpectrumValue> interferenceAndNoise = m_signal->GetSignalPsd ();
           *interferenceAndNoise -= *currentRxParams->psd;
           *interferenceAndNoise += *m_noise;
-          double sinr = LrWpanSpectrumValueHelper::TotalAvgPower (currentRxParams->psd) / LrWpanSpectrumValueHelper::TotalAvgPower (interferenceAndNoise);
+          double sinr = LrWpanSpectrumValueHelper::TotalAvgPower (currentRxParams->psd, m_phyPIBAttributes.phyCurrentChannel) / LrWpanSpectrumValueHelper::TotalAvgPower (interferenceAndNoise, m_phyPIBAttributes.phyCurrentChannel);
           double per = 1.0 - m_errorModel->GetChunkSuccessRate (sinr, chunkSize);
 
           // The LQI is the total packet success rate scaled to 0-255.
@@ -416,25 +435,32 @@
 }
 
 void
-LrWpanPhy::EndRx (Ptr<LrWpanSpectrumSignalParameters> params)
+LrWpanPhy::EndRx (Ptr<SpectrumSignalParameters> par)
 {
   NS_LOG_FUNCTION (this);
-  NS_ASSERT (params != 0);
+
+  Ptr<LrWpanSpectrumSignalParameters> params = DynamicCast<LrWpanSpectrumSignalParameters> (par);
 
   if (!m_edRequest.IsExpired ())
     {
       // Update the average receive power during ED.
       Time now = Simulator::Now ();
-      m_edPower.averagePower += LrWpanSpectrumValueHelper::TotalAvgPower (m_signal->GetSignalPsd ()) * (now - m_edPower.lastUpdate).GetTimeStep () / m_edPower.measurementLength.GetTimeStep ();
+      m_edPower.averagePower += LrWpanSpectrumValueHelper::TotalAvgPower (m_signal->GetSignalPsd (), m_phyPIBAttributes.phyCurrentChannel) * (now - m_edPower.lastUpdate).GetTimeStep () / m_edPower.measurementLength.GetTimeStep ();
       m_edPower.lastUpdate = now;
     }
 
   CheckInterference ();
 
   // Update the interference.
-  m_signal->RemoveSignal (params->psd);
+  m_signal->RemoveSignal (par->psd);
 
-  // If this is the end of the currently received packet, check if reception was successfull.
+  if (params == 0)
+    {
+      NS_LOG_LOGIC ("Node: " << m_device->GetAddress() << " Removing interferent: " << *(par->psd));
+      return;
+    }
+
+  // If this is the end of the currently received packet, check if reception was successful.
   Ptr<LrWpanSpectrumSignalParameters> currentRxParams = m_currentRxPacket.first;
   if (currentRxParams == params)
     {
@@ -1043,7 +1069,7 @@
 {
   NS_LOG_FUNCTION (this);
 
-  m_edPower.averagePower += LrWpanSpectrumValueHelper::TotalAvgPower (m_signal->GetSignalPsd ()) * (Simulator::Now () - m_edPower.lastUpdate).GetTimeStep () / m_edPower.measurementLength.GetTimeStep ();
+  m_edPower.averagePower += LrWpanSpectrumValueHelper::TotalAvgPower (m_signal->GetSignalPsd (), m_phyPIBAttributes.phyCurrentChannel) * (Simulator::Now () - m_edPower.lastUpdate).GetTimeStep () / m_edPower.measurementLength.GetTimeStep ();
 
   uint8_t energyLevel;
 
@@ -1077,7 +1103,7 @@
   LrWpanPhyEnumeration sensedChannelState = IEEE_802_15_4_PHY_UNSPECIFIED;
 
   // Update peak power.
-  double power = LrWpanSpectrumValueHelper::TotalAvgPower (m_signal->GetSignalPsd ());
+  double power = LrWpanSpectrumValueHelper::TotalAvgPower (m_signal->GetSignalPsd (), m_phyPIBAttributes.phyCurrentChannel);
   if (m_ccaPeakPower < power)
     {
       m_ccaPeakPower = power;
--- a/src/lr-wpan/model/lr-wpan-phy.h	Sun Feb 01 21:01:25 2015 -0800
+++ b/src/lr-wpan/model/lr-wpan-phy.h	Sun Feb 01 21:08:32 2015 -0800
@@ -547,7 +547,7 @@
    *
    * \param params signal parameters of the packet
    */
-  void EndRx (Ptr<LrWpanSpectrumSignalParameters> params);
+  void EndRx (Ptr<SpectrumSignalParameters> params);
 
   /**
    * Cancel an ongoing ED procedure. This is called when the transceiver is
--- a/src/lr-wpan/model/lr-wpan-spectrum-value-helper.cc	Sun Feb 01 21:01:25 2015 -0800
+++ b/src/lr-wpan/model/lr-wpan-spectrum-value-helper.cc	Sun Feb 01 21:08:32 2015 -0800
@@ -54,7 +54,7 @@
     g_LrWpanSpectrumModel = Create<SpectrumModel> (bands);
   }
 
-} g_LrWpanSpectrumModelInitializerInstance;  //!< Global object used to initialize the LrWpan Spectrum Model
+} g_LrWpanSpectrumModelInitializerInstance; //!< Global object used to initialize the LrWpan Spectrum Model
 
 LrWpanSpectrumValueHelper::LrWpanSpectrumValueHelper (void)
 {
@@ -124,15 +124,22 @@
 }
 
 double
-LrWpanSpectrumValueHelper::TotalAvgPower (Ptr<const SpectrumValue> psd)
+LrWpanSpectrumValueHelper::TotalAvgPower (Ptr<const SpectrumValue> psd, uint32_t channel)
 {
   NS_LOG_FUNCTION (psd);
   double totalAvgPower = 0.0;
 
-  // numerically integrate to get area under psd using
-  // 1 MHz resolution from 2400 to 2483 MHz (center freq)
+  NS_ASSERT (psd->GetSpectrumModel () == g_LrWpanSpectrumModel);
+
+  // numerically integrate to get area under psd using 1 MHz resolution
 
-  totalAvgPower = Sum (*psd * 1.0e6);
+  totalAvgPower += (*psd)[2405 + 5 * (channel - 11) - 2400 - 2];
+  totalAvgPower += (*psd)[2405 + 5 * (channel - 11) - 2400 - 1];
+  totalAvgPower += (*psd)[2405 + 5 * (channel - 11) - 2400];
+  totalAvgPower += (*psd)[2405 + 5 * (channel - 11) - 2400 + 1];
+  totalAvgPower += (*psd)[2405 + 5 * (channel - 11) - 2400 + 2];
+  totalAvgPower *= 1.0e6;
+
   return totalAvgPower;
 }
 
--- a/src/lr-wpan/model/lr-wpan-spectrum-value-helper.h	Sun Feb 01 21:01:25 2015 -0800
+++ b/src/lr-wpan/model/lr-wpan-spectrum-value-helper.h	Sun Feb 01 21:08:32 2015 -0800
@@ -53,11 +53,13 @@
   Ptr<SpectrumValue> CreateNoisePowerSpectralDensity (uint32_t channel);
 
   /**
-   * \brief total average power of the signal is the integral of the PSD
+   * \brief total average power of the signal is the integral of the PSD using
+   * the limits of the given channel
    * \param psd spectral density
-   * \return total power (using composite trap. rule to numerally integrate
+   * \param channel the channel number per IEEE802.15.4
+   * \return total power (using composite trap. rule to numerally integrate)
    */
-  static double TotalAvgPower (Ptr<const SpectrumValue> psd);
+  static double TotalAvgPower (Ptr<const SpectrumValue> psd, uint32_t channel);
 
 private:
   /**
--- a/src/lr-wpan/test/lr-wpan-spectrum-value-helper-test.cc	Sun Feb 01 21:01:25 2015 -0800
+++ b/src/lr-wpan/test/lr-wpan-spectrum-value-helper-test.cc	Sun Feb 01 21:08:32 2015 -0800
@@ -59,7 +59,7 @@
           value = helper.CreateTxPowerSpectralDensity (pwrdBm, chan);
           pwrWatts = pow (10.0, pwrdBm / 10.0) / 1000;
           // Test that average power calculation is within +/- 25% of expected
-          NS_TEST_ASSERT_MSG_EQ_TOL (helper.TotalAvgPower (value), pwrWatts, pwrWatts / 4.0, "Not equal for channel " << chan << " pwrdBm " << pwrdBm);
+          NS_TEST_ASSERT_MSG_EQ_TOL (helper.TotalAvgPower (value, chan), pwrWatts, pwrWatts / 4.0, "Not equal for channel " << chan << " pwrdBm " << pwrdBm);
         }
     }
 }