# HG changeset patch # Date 1412506398 -7200 # User Tommaso Pecorella # Parent d581ebd5cc0858b524acbf51e0cb457a77126b60 lr-wpan - MultiModelSpectrum diff --git a/src/lr-wpan/bindings/modulegen__gcc_ILP32.py b/src/lr-wpan/bindings/modulegen__gcc_ILP32.py --- a/src/lr-wpan/bindings/modulegen__gcc_ILP32.py +++ b/src/lr-wpan/bindings/modulegen__gcc_ILP32.py @@ -1702,10 +1702,10 @@ cls.add_method('CreateTxPowerSpectralDensity', 'ns3::Ptr< ns3::SpectrumValue >', [param('double', 'txPower'), param('uint32_t', 'channel')]) - ## lr-wpan-spectrum-value-helper.h (module 'lr-wpan'): static double ns3::LrWpanSpectrumValueHelper::TotalAvgPower(ns3::Ptr psd) [member function] + ## lr-wpan-spectrum-value-helper.h (module 'lr-wpan'): static double ns3::LrWpanSpectrumValueHelper::TotalAvgPower(ns3::Ptr psd, uint32_t channel) [member function] cls.add_method('TotalAvgPower', 'double', - [param('ns3::Ptr< ns3::SpectrumValue const >', 'psd')], + [param('ns3::Ptr< ns3::SpectrumValue const >', 'psd'), param('uint32_t', 'channel')], is_static=True) return @@ -2929,6 +2929,12 @@ def register_Ns3LrWpanHelper_methods(root_module, cls): ## lr-wpan-helper.h (module 'lr-wpan'): ns3::LrWpanHelper::LrWpanHelper() [constructor] cls.add_constructor([]) + ## lr-wpan-helper.h (module 'lr-wpan'): ns3::LrWpanHelper::LrWpanHelper(bool useMultiModelSpectrumChannel) [constructor] + cls.add_constructor([param('bool', 'useMultiModelSpectrumChannel')]) + ## lr-wpan-helper.h (module 'lr-wpan'): ns3::Ptr ns3::LrWpanHelper::GetChannel() [member function] + cls.add_method('GetChannel', + 'ns3::Ptr< ns3::SpectrumChannel >', + []) ## lr-wpan-helper.h (module 'lr-wpan'): void ns3::LrWpanHelper::AddMobility(ns3::Ptr phy, ns3::Ptr m) [member function] cls.add_method('AddMobility', 'void', diff --git a/src/lr-wpan/bindings/modulegen__gcc_LP64.py b/src/lr-wpan/bindings/modulegen__gcc_LP64.py --- a/src/lr-wpan/bindings/modulegen__gcc_LP64.py +++ b/src/lr-wpan/bindings/modulegen__gcc_LP64.py @@ -1702,10 +1702,10 @@ cls.add_method('CreateTxPowerSpectralDensity', 'ns3::Ptr< ns3::SpectrumValue >', [param('double', 'txPower'), param('uint32_t', 'channel')]) - ## lr-wpan-spectrum-value-helper.h (module 'lr-wpan'): static double ns3::LrWpanSpectrumValueHelper::TotalAvgPower(ns3::Ptr psd) [member function] + ## lr-wpan-spectrum-value-helper.h (module 'lr-wpan'): static double ns3::LrWpanSpectrumValueHelper::TotalAvgPower(ns3::Ptr psd, uint32_t channel) [member function] cls.add_method('TotalAvgPower', 'double', - [param('ns3::Ptr< ns3::SpectrumValue const >', 'psd')], + [param('ns3::Ptr< ns3::SpectrumValue const >', 'psd'), param('uint32_t', 'channel')], is_static=True) return @@ -2929,6 +2929,12 @@ def register_Ns3LrWpanHelper_methods(root_module, cls): ## lr-wpan-helper.h (module 'lr-wpan'): ns3::LrWpanHelper::LrWpanHelper() [constructor] cls.add_constructor([]) + ## lr-wpan-helper.h (module 'lr-wpan'): ns3::LrWpanHelper::LrWpanHelper(bool useMultiModelSpectrumChannel) [constructor] + cls.add_constructor([param('bool', 'useMultiModelSpectrumChannel')]) + ## lr-wpan-helper.h (module 'lr-wpan'): ns3::Ptr ns3::LrWpanHelper::GetChannel() [member function] + cls.add_method('GetChannel', + 'ns3::Ptr< ns3::SpectrumChannel >', + []) ## lr-wpan-helper.h (module 'lr-wpan'): void ns3::LrWpanHelper::AddMobility(ns3::Ptr phy, ns3::Ptr m) [member function] cls.add_method('AddMobility', 'void', diff --git a/src/lr-wpan/examples/lr-wpan-error-distance-plot.cc b/src/lr-wpan/examples/lr-wpan-error-distance-plot.cc --- a/src/lr-wpan/examples/lr-wpan-error-distance-plot.cc +++ b/src/lr-wpan/examples/lr-wpan-error-distance-plot.cc @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -95,7 +96,7 @@ Ptr dev1 = CreateObject (); dev0->SetAddress (Mac16Address ("00:01")); dev1->SetAddress (Mac16Address ("00:02")); - Ptr channel = CreateObject (); + Ptr channel = CreateObject (); Ptr model = CreateObject (); channel->AddPropagationLossModel (model); dev0->SetChannel (channel); diff --git a/src/lr-wpan/helper/lr-wpan-helper.cc b/src/lr-wpan/helper/lr-wpan-helper.cc --- a/src/lr-wpan/helper/lr-wpan-helper.cc +++ b/src/lr-wpan/helper/lr-wpan-helper.cc @@ -25,8 +25,10 @@ #include #include #include +#include #include #include +#include "ns3/names.h" namespace ns3 { @@ -63,8 +65,29 @@ LrWpanHelper::LrWpanHelper (void) { m_channel = CreateObject (); - Ptr model = CreateObject (); - m_channel->AddPropagationLossModel (model); + + Ptr lossModel = CreateObject (); + m_channel->AddPropagationLossModel (lossModel); + + Ptr delayModel = CreateObject (); + m_channel->SetPropagationDelayModel (delayModel); +} + +LrWpanHelper::LrWpanHelper (bool useMultiModelSpectrumChannel) +{ + if (useMultiModelSpectrumChannel) + { + m_channel = CreateObject (); + } + else + { + m_channel = CreateObject (); + } + Ptr lossModel = CreateObject (); + m_channel->AddPropagationLossModel (lossModel); + + Ptr delayModel = CreateObject (); + m_channel->SetPropagationDelayModel (delayModel); } LrWpanHelper::~LrWpanHelper (void) @@ -167,6 +190,27 @@ return devices; } + +Ptr +LrWpanHelper::GetChannel (void) +{ + return m_channel; +} + +void +LrWpanHelper::SetChannel (Ptr channel) +{ + m_channel = channel; +} + +void +LrWpanHelper::SetChannel (std::string channelName) +{ + Ptr channel = Names::Find (channelName); + m_channel = channel; +} + + int64_t LrWpanHelper::AssignStreams (NetDeviceContainer c, int64_t stream) { diff --git a/src/lr-wpan/helper/lr-wpan-helper.h b/src/lr-wpan/helper/lr-wpan-helper.h --- a/src/lr-wpan/helper/lr-wpan-helper.h +++ b/src/lr-wpan/helper/lr-wpan-helper.h @@ -29,7 +29,7 @@ namespace ns3 { -class SingleModelSpectrumChannel; +class SpectrumChannel; class MobilityModel; /** @@ -50,13 +50,39 @@ * \brief Create a LrWpan helper in an empty state. */ LrWpanHelper (void); + + /** + * \brief Create a LrWpan helper in an empty state with either a + * SingleModelSpectrumChannel or a MultiModelSpectrumChannel. + * \param useMultiModelSpectrumChannel use a MultiModelSpectrumChannel if true, a SingleModelSpectrumChannel otherwise + */ + LrWpanHelper (bool useMultiModelSpectrumChannel); + virtual ~LrWpanHelper (void); /** - * \brief Add mobility model to a physical device - * \param phy the physical device - * \param m the mobility model - */ + * \brief Get the channel associated to this helper + * \returns the channel + */ + Ptr GetChannel (void); + + /** + * \brief Set the channel associated to this helper + * \param channel the channel + */ + void SetChannel (Ptr channel); + + /** + * \brief Set the channel associated to this helper + * \param channelName the channel name + */ + void SetChannel (std::string channelName); + + /** + * \brief Add mobility model to a physical device + * \param phy the physical device + * \param m the mobility model + */ void AddMobility (Ptr phy, Ptr m); /** @@ -151,7 +177,7 @@ bool explicitFilename); private: - Ptr m_channel; //!< channel to be used for the devices + Ptr m_channel; //!< channel to be used for the devices }; diff --git a/src/lr-wpan/model/lr-wpan-phy.cc b/src/lr-wpan/model/lr-wpan-phy.cc --- a/src/lr-wpan/model/lr-wpan-phy.cc +++ b/src/lr-wpan/model/lr-wpan-phy.cc @@ -260,20 +260,38 @@ NS_LOG_FUNCTION (this << spectrumRxParams); LrWpanSpectrumValueHelper psdHelper; - - Ptr lrWpanRxParams = DynamicCast (spectrumRxParams); - NS_ASSERT (lrWpanRxParams != 0); - Ptr 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 lrWpanRxParams = DynamicCast (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 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 ()) { @@ -293,12 +311,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 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. @@ -343,7 +361,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; @@ -352,7 +370,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 @@ -376,7 +395,7 @@ Ptr 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. @@ -402,23 +421,33 @@ } void -LrWpanPhy::EndRx (Ptr params) +LrWpanPhy::EndRx (Ptr par) { NS_LOG_FUNCTION (this); - NS_ASSERT (params != 0); + //NS_ASSERT (params != 0); + + Ptr params = DynamicCast (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 (params == 0) + { + NS_LOG_LOGIC ("Node: " << m_device->GetAddress() << " Removing interferent: " << *(par->psd)); + return; + } + + // NS_LOG_UNCOND("Node: " << m_device->GetAddress() << " removing signal: " << *(params->psd)); // If this is the end of the currently received packet, check if reception was successfull. Ptr currentRxParams = m_currentRxPacket.first; @@ -1029,7 +1058,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; @@ -1063,7 +1092,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; diff --git a/src/lr-wpan/model/lr-wpan-phy.h b/src/lr-wpan/model/lr-wpan-phy.h --- a/src/lr-wpan/model/lr-wpan-phy.h +++ b/src/lr-wpan/model/lr-wpan-phy.h @@ -499,7 +499,7 @@ * * \param params signal parameters of the packet */ - void EndRx (Ptr params); + void EndRx (Ptr params); /** * Cancel an ongoing ED procedure. This is called when the transceiver is diff --git a/src/lr-wpan/model/lr-wpan-spectrum-value-helper.cc b/src/lr-wpan/model/lr-wpan-spectrum-value-helper.cc --- a/src/lr-wpan/model/lr-wpan-spectrum-value-helper.cc +++ b/src/lr-wpan/model/lr-wpan-spectrum-value-helper.cc @@ -54,7 +54,7 @@ g_LrWpanSpectrumModel = Create (bands); } -} g_LrWpanSpectrumModelInitializerInstance; //!< Global object used to initialize the LrWpan Spectrum Model +} g_LrWpanSpectrumModelInitializerInstance; LrWpanSpectrumValueHelper::LrWpanSpectrumValueHelper (void) { @@ -124,15 +124,22 @@ } double -LrWpanSpectrumValueHelper::TotalAvgPower (Ptr psd) +LrWpanSpectrumValueHelper::TotalAvgPower (Ptr 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); - totalAvgPower = Sum (*psd * 1.0e6); + // numerically integrate to get area under psd using 1 MHz resolution + + 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; } diff --git a/src/lr-wpan/model/lr-wpan-spectrum-value-helper.h b/src/lr-wpan/model/lr-wpan-spectrum-value-helper.h --- a/src/lr-wpan/model/lr-wpan-spectrum-value-helper.h +++ b/src/lr-wpan/model/lr-wpan-spectrum-value-helper.h @@ -53,11 +53,13 @@ Ptr 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 psd); + static double TotalAvgPower (Ptr psd, uint32_t channel); private: /** diff --git a/src/lr-wpan/test/lr-wpan-spectrum-value-helper-test.cc b/src/lr-wpan/test/lr-wpan-spectrum-value-helper-test.cc --- a/src/lr-wpan/test/lr-wpan-spectrum-value-helper-test.cc +++ b/src/lr-wpan/test/lr-wpan-spectrum-value-helper-test.cc @@ -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); } } }