--- a/RELEASE_NOTES Tue Jul 05 18:40:17 2011 +0200
+++ b/RELEASE_NOTES Tue Jul 05 19:03:55 2011 +0200
@@ -21,6 +21,14 @@
New user-visible features
-------------------------
+- SpectrumChannel models now support the usage of single-frequency
+ propagation loss models based on the PropagationLossModel
+ class. These model can be used in conjunction with
+ the frequency-dependent propagation loss model based on the
+ SpectrumPropagationLossModel class already supported by
+ SpectrumChannel.
+
+
Bugs fixed
----------
- bug 1033 - Mesh airtime-metric fixed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/spectrum/examples/adhoc-aloha-ideal-phy-matrix-propagation-loss-model.cc Tue Jul 05 19:03:55 2011 +0200
@@ -0,0 +1,151 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 CTTC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+
+
+#include <iostream>
+
+#include <ns3/core-module.h>
+#include <ns3/network-module.h>
+#include <ns3/spectrum-model-ism2400MHz-res1MHz.h>
+#include <ns3/spectrum-model-300kHz-300GHz-log.h>
+#include <ns3/wifi-spectrum-value-helper.h>
+#include <ns3/single-model-spectrum-channel.h>
+#include <ns3/waveform-generator.h>
+#include <ns3/spectrum-analyzer.h>
+#include <ns3/log.h>
+#include <string>
+#include <iomanip>
+#include <ns3/friis-spectrum-propagation-loss.h>
+#include <ns3/propagation-delay-model.h>
+#include <ns3/mobility-module.h>
+#include <ns3/spectrum-helper.h>
+#include <ns3/applications-module.h>
+#include <ns3/adhoc-aloha-noack-ideal-phy-helper.h>
+
+NS_LOG_COMPONENT_DEFINE ("TestAdhocOfdmAloha");
+
+using namespace ns3;
+
+static bool g_verbose = false;
+static uint64_t g_rxBytes;
+
+void
+PhyRxEndOkTrace (std::string context, Ptr<const Packet> p)
+{
+ if (g_verbose)
+ {
+ std::cout << context << " PHY RX END OK p:" << p << std::endl;
+ }
+ g_rxBytes += p->GetSize ();
+}
+
+
+int main (int argc, char** argv)
+{
+ CommandLine cmd;
+ double lossDb;
+ double txPowerW = 0.1;
+ uint64_t phyRate = 500000;
+ uint32_t pktSize = 1000;
+ cmd.AddValue ("verbose", "Print trace information if true", g_verbose);
+ cmd.AddValue ("lossDb", "link loss in dB", lossDb);
+ cmd.AddValue ("txPowerW", "txPower in Watts", txPowerW);
+ cmd.AddValue ("phyRate", "PHY rate in bps", phyRate);
+ cmd.AddValue ("pktSize", "packet size in bytes", pktSize);
+ cmd.Parse (argc, argv);
+
+ NodeContainer c;
+ c.Create (2);
+
+ MobilityHelper mobility;
+ Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
+ positionAlloc->Add (Vector (0.0, 0.0, 0.0));
+ positionAlloc->Add (Vector (5.0, 0.0, 0.0));
+ mobility.SetPositionAllocator (positionAlloc);
+ mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+
+
+ mobility.Install (c);
+
+
+ SpectrumChannelHelper channelHelper;
+ channelHelper.SetChannel ("ns3::MultiModelSpectrumChannel");
+ channelHelper.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
+ Ptr<MatrixPropagationLossModel> propLoss = CreateObject<MatrixPropagationLossModel> ();
+ propLoss->SetLoss (c.Get (0)->GetObject<MobilityModel> (), c.Get (1)->GetObject<MobilityModel> (), lossDb, true);
+ channelHelper.AddPropagationLoss (propLoss);
+ Ptr<SpectrumChannel> channel = channelHelper.Create ();
+
+
+ WifiSpectrumValue5MhzFactory sf;
+
+ uint32_t channelNumber = 1;
+ Ptr<SpectrumValue> txPsd = sf.CreateTxPowerSpectralDensity (txPowerW, channelNumber);
+
+ // for the noise, we use the Power Spectral Density of thermal noise
+ // at room temperature. The value of the PSD will be constant over the band of interest.
+ const double k = 1.381e-23; //Boltzmann's constant
+ const double T = 290; // temperature in Kelvin
+ double noisePsdValue = k * T; // watts per hertz
+ Ptr<SpectrumValue> noisePsd = sf.CreateConstant (noisePsdValue);
+
+ AdhocAlohaNoackIdealPhyHelper deviceHelper;
+ deviceHelper.SetChannel (channel);
+ deviceHelper.SetTxPowerSpectralDensity (txPsd);
+ deviceHelper.SetNoisePowerSpectralDensity (noisePsd);
+ deviceHelper.SetPhyAttribute ("Rate", DataRateValue (DataRate (phyRate)));
+ NetDeviceContainer devices = deviceHelper.Install (c);
+
+ PacketSocketHelper packetSocket;
+ packetSocket.Install (c);
+
+ PacketSocketAddress socket;
+ socket.SetSingleDevice (devices.Get (0)->GetIfIndex ());
+ socket.SetPhysicalAddress (devices.Get (1)->GetAddress ());
+ socket.SetProtocol (1);
+
+ OnOffHelper onoff ("ns3::PacketSocketFactory", Address (socket));
+ onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (250)));
+ onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+ onoff.SetAttribute ("DataRate", DataRateValue (DataRate (2*phyRate)));
+ onoff.SetAttribute ("PacketSize", UintegerValue (pktSize));
+
+ ApplicationContainer apps = onoff.Install (c.Get (0));
+ apps.Start (Seconds (0.0));
+ apps.Stop (Seconds (10.0));
+
+ Config::Connect ("/NodeList/*/DeviceList/*/Phy/RxEndOk", MakeCallback (&PhyRxEndOkTrace));
+
+ g_rxBytes = 0;
+ Simulator::Stop (Seconds (10.0001));
+ Simulator::Run ();
+ double throughputBps = (g_rxBytes * 8.0) / 10.0;
+
+ std::cerr << "throughput: " << std::setw (20) << std::fixed << throughputBps << " bps" << std::endl;
+ std::cerr << "phy rate : " << std::setw (20) << std::fixed << phyRate*1.0 << " bps" << std::endl;
+ double rxPowerW = txPowerW / (pow (10.0, lossDb/10.0));
+ double capacity = 20e6*log2 (1.0 + (rxPowerW/20.0e6)/noisePsdValue);
+ std::cerr << "shannon capacity: " << std::setw (20) << std::fixed << capacity << " bps" << std::endl;
+
+
+ Simulator::Destroy ();
+ return 0;
+}
--- a/src/spectrum/examples/wscript Tue Jul 05 18:40:17 2011 +0200
+++ b/src/spectrum/examples/wscript Tue Jul 05 19:03:55 2011 +0200
@@ -5,6 +5,10 @@
['spectrum', 'mobility'])
obj.source = 'adhoc-aloha-ideal-phy.cc'
+ obj = bld.create_ns3_program('adhoc-aloha-ideal-phy-matrix-propagation-loss-model',
+ ['spectrum', 'mobility'])
+ obj.source = 'adhoc-aloha-ideal-phy-matrix-propagation-loss-model.cc'
+
obj = bld.create_ns3_program('adhoc-aloha-ideal-phy-with-microwave-oven',
['spectrum', 'mobility'])
obj.source = 'adhoc-aloha-ideal-phy-with-microwave-oven.cc'
--- a/src/spectrum/helper/spectrum-helper.cc Tue Jul 05 18:40:17 2011 +0200
+++ b/src/spectrum/helper/spectrum-helper.cc Tue Jul 05 19:03:55 2011 +0200
@@ -21,8 +21,6 @@
#include <ns3/simulator.h>
#include <ns3/config.h>
#include <ns3/names.h>
-#include <ns3/spectrum-propagation-loss-model.h>
-#include <ns3/propagation-delay-model.h>
#include <ns3/spectrum-channel.h>
#include <ns3/spectrum-phy.h>
#include <ns3/single-model-spectrum-channel.h>
@@ -66,6 +64,38 @@
m_channel.Set (n7, v7);
}
+void
+SpectrumChannelHelper::AddPropagationLoss (std::string type,
+ std::string n0, const AttributeValue &v0,
+ std::string n1, const AttributeValue &v1,
+ std::string n2, const AttributeValue &v2,
+ std::string n3, const AttributeValue &v3,
+ std::string n4, const AttributeValue &v4,
+ std::string n5, const AttributeValue &v5,
+ std::string n6, const AttributeValue &v6,
+ std::string n7, const AttributeValue &v7)
+{
+ ObjectFactory factory;
+ factory.SetTypeId (type);
+ factory.Set (n0, v0);
+ factory.Set (n1, v1);
+ factory.Set (n2, v2);
+ factory.Set (n3, v3);
+ factory.Set (n4, v4);
+ factory.Set (n5, v5);
+ factory.Set (n6, v6);
+ factory.Set (n7, v7);
+ Ptr<PropagationLossModel> m = factory.Create<PropagationLossModel> ();
+ AddPropagationLoss (m);
+}
+
+
+void
+SpectrumChannelHelper::AddPropagationLoss (Ptr<PropagationLossModel> m)
+{
+ m->SetNext (m_propagationLossModel);
+ m_propagationLossModel = m;
+}
void
SpectrumChannelHelper::AddSpectrumPropagationLoss (std::string type,
@@ -88,7 +118,15 @@
factory.Set (n5, v5);
factory.Set (n6, v6);
factory.Set (n7, v7);
- m_spectrumPropagationLoss.push_back (factory);
+ Ptr<SpectrumPropagationLossModel> m = factory.Create<SpectrumPropagationLossModel> ();
+ AddSpectrumPropagationLoss (m);
+}
+
+void
+SpectrumChannelHelper::AddSpectrumPropagationLoss (Ptr<SpectrumPropagationLossModel> m)
+{
+ m->SetNext (m_spectrumPropagationLossModel);
+ m_spectrumPropagationLossModel = m;
}
void
@@ -119,30 +157,14 @@
SpectrumChannelHelper::Create (void) const
{
Ptr<SpectrumChannel> channel = (m_channel.Create ())->GetObject<SpectrumChannel> ();
- Ptr<SpectrumPropagationLossModel> prev = 0;
- for (std::vector<ObjectFactory>::const_iterator i = m_spectrumPropagationLoss.begin (); i != m_spectrumPropagationLoss.end (); ++i)
- {
- Ptr<SpectrumPropagationLossModel> cur = (*i).Create<SpectrumPropagationLossModel> ();
- if (prev == 0)
- {
- channel->AddSpectrumPropagationLossModel (cur);
- }
- else
- {
- prev->SetNext (cur);
- }
- prev = cur;
- }
+ channel->AddSpectrumPropagationLossModel (m_spectrumPropagationLossModel);
+ channel->AddPropagationLossModel (m_propagationLossModel);
Ptr<PropagationDelayModel> delay = m_propagationDelay.Create<PropagationDelayModel> ();
channel->SetPropagationDelayModel (delay);
return channel;
}
-
-
-
-
void
SpectrumPhyHelper::SetPhy (std::string type,
std::string n0, const AttributeValue &v0,
--- a/src/spectrum/helper/spectrum-helper.h Tue Jul 05 18:40:17 2011 +0200
+++ b/src/spectrum/helper/spectrum-helper.h Tue Jul 05 19:03:55 2011 +0200
@@ -26,6 +26,8 @@
#include <ns3/object-factory.h>
#include <ns3/node-container.h>
#include <ns3/net-device-container.h>
+#include <ns3/propagation-loss-model.h>
+#include <ns3/spectrum-propagation-loss-model.h>
namespace ns3 {
@@ -72,6 +74,44 @@
std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
+ /**
+ * \param name the name of the model to set
+ * \param n0 the name of the attribute to set
+ * \param v0 the value of the attribute to set
+ * \param n1 the name of the attribute to set
+ * \param v1 the value of the attribute to set
+ * \param n2 the name of the attribute to set
+ * \param v2 the value of the attribute to set
+ * \param n3 the name of the attribute to set
+ * \param v3 the value of the attribute to set
+ * \param n4 the name of the attribute to set
+ * \param v4 the value of the attribute to set
+ * \param n5 the name of the attribute to set
+ * \param v5 the value of the attribute to set
+ * \param n6 the name of the attribute to set
+ * \param v6 the value of the attribute to set
+ * \param n7 the name of the attribute to set
+ * \param v7 the value of the attribute to set
+ *
+ * Add a new single-frequency propagation loss model to this channel helper.
+ */
+ void AddPropagationLoss (std::string name,
+ std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+ std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+ std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+ std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+ std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+ std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+ std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+ std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
+
+
+ /**
+ * Add a new single-frequency propagation loss model instance to this channel helper.
+ *
+ * \param m a pointer to the instance of the propagation loss model
+ */
+ void AddPropagationLoss (Ptr<PropagationLossModel> m);
/**
* \param name the name of the model to set
@@ -92,7 +132,7 @@
* \param n7 the name of the attribute to set
* \param v7 the value of the attribute to set
*
- * Add a new spectrum propagation loss to this channel helper.
+ * Add a new frequency-dependent propagation loss model to this channel helper.
*/
void AddSpectrumPropagationLoss (std::string name,
std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
@@ -103,6 +143,14 @@
std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
+
+ /**
+ * Add a new frequency-dependent propagation loss model instance to this channel helper.
+ *
+ * \param m a pointer to the instance of the propagation loss model
+ */
+ void AddSpectrumPropagationLoss (Ptr<SpectrumPropagationLossModel> m);
+
/**
* \param name the name of the model to set
* \param n0 the name of the attribute to set
@@ -142,7 +190,8 @@
Ptr<SpectrumChannel> Create (void) const;
private:
- std::vector<ObjectFactory> m_spectrumPropagationLoss;
+ Ptr<SpectrumPropagationLossModel> m_spectrumPropagationLossModel;
+ Ptr<PropagationLossModel> m_propagationLossModel;
ObjectFactory m_propagationDelay;
ObjectFactory m_channel;
};
--- a/src/spectrum/model/multi-model-spectrum-channel.cc Tue Jul 05 18:40:17 2011 +0200
+++ b/src/spectrum/model/multi-model-spectrum-channel.cc Tue Jul 05 19:03:55 2011 +0200
@@ -25,9 +25,13 @@
#include <ns3/packet-burst.h>
#include <ns3/net-device.h>
#include <ns3/node.h>
+#include <ns3/double.h>
#include <ns3/mobility-model.h>
#include <ns3/spectrum-phy.h>
#include <ns3/spectrum-converter.h>
+#include <ns3/spectrum-propagation-loss-model.h>
+#include <ns3/propagation-loss-model.h>
+#include <ns3/propagation-delay-model.h>
#include <iostream>
#include <utility>
#include "multi-model-spectrum-channel.h"
@@ -72,8 +76,6 @@
MultiModelSpectrumChannel::MultiModelSpectrumChannel ()
- : m_PropagationDelay (0),
- m_PropagationLoss (0)
{
NS_LOG_FUNCTION (this);
}
@@ -82,8 +84,9 @@
MultiModelSpectrumChannel::DoDispose ()
{
NS_LOG_FUNCTION (this);
- m_PropagationLoss = 0;
- m_PropagationDelay = 0;
+ m_propagationDelay = 0;
+ m_propagationLoss = 0;
+ m_spectrumPropagationLoss = 0;
m_txSpectrumModelInfoMap.clear ();
m_rxSpectrumModelInfoMap.clear ();
m_phyVector.clear ();
@@ -96,6 +99,18 @@
static TypeId tid = TypeId ("ns3::MultiModelSpectrumChannel")
.SetParent<SpectrumChannel> ()
.AddConstructor<MultiModelSpectrumChannel> ()
+ .AddAttribute ("MaxLossDb",
+ "If a single-frequency PropagationLossModel is used, this value "
+ "represents the maximum loss in dB for which transmissions will be "
+ "passed to the receiving PHY. Signals for which the PropagationLossModel "
+ "returns a loss bigger than this value will not be propagated to the receiver. "
+ "This parameter is to be used to reduce "
+ "the computational load by not propagating signals that are far beyond "
+ "the interference range. Note that the default value corresponds to "
+ "considering all signals for reception. Tune this value with care. ",
+ DoubleValue (1.0e9),
+ MakeDoubleAccessor (&MultiModelSpectrumChannel::m_maxLossDb),
+ MakeDoubleChecker<double> ())
;
return tid;
}
@@ -241,44 +256,43 @@
convertedTxPowerSpectrum = rxConverterIterator->second.Convert (originalTxPowerSpectrum);
}
- std::list<Ptr<SpectrumPhy> >::const_iterator rxPhyIterator = rxInfoIterator->second.m_rxPhyList.begin ();
- while (rxPhyIterator != rxInfoIterator->second.m_rxPhyList.end ())
+ for (std::list<Ptr<SpectrumPhy> >::const_iterator rxPhyIterator = rxInfoIterator->second.m_rxPhyList.begin ();
+ rxPhyIterator != rxInfoIterator->second.m_rxPhyList.end ();
+ ++rxPhyIterator)
{
NS_ASSERT_MSG ((*rxPhyIterator)->GetRxSpectrumModel ()->GetUid () == rxSpectrumModelUid,
"MultiModelSpectrumChannel only supports devices that use a single RxSpectrumModel that does not change for the whole simulation");
if ((*rxPhyIterator) != txPhy)
{
- Ptr <SpectrumValue> rxPowerSpectrum;
- Time delay;
+ Ptr <SpectrumValue> rxPowerSpectrum = convertedTxPowerSpectrum->Copy ();
+ Time delay = MicroSeconds (0);
+
Ptr<MobilityModel> receiverMobility = (*rxPhyIterator)->GetMobility ()->GetObject<MobilityModel> ();
if (txMobility && receiverMobility)
{
- if (m_PropagationLoss)
+ if (m_propagationLoss)
{
- rxPowerSpectrum = m_PropagationLoss->CalcRxPowerSpectralDensity (convertedTxPowerSpectrum, txMobility, receiverMobility);
- }
- else
- {
- // rxPowerSpectrum = Copy<SpectrumValue> (convertedTxPowerSpectrum);
- rxPowerSpectrum = convertedTxPowerSpectrum->Copy ();
+ double gainDb = m_propagationLoss->CalcRxPower (0, txMobility, receiverMobility);
+ if ( (-gainDb) > m_maxLossDb)
+ {
+ // beyond range
+ continue;
+ }
+ double gainLinear = pow (10.0, gainDb/10.0);
+ *rxPowerSpectrum = (*rxPowerSpectrum) * gainLinear;
}
- if (m_PropagationDelay)
- {
- delay = m_PropagationDelay->GetDelay (txMobility, receiverMobility);
- }
- else
+ if (m_spectrumPropagationLoss)
{
- delay = MicroSeconds (0);
+ rxPowerSpectrum = m_spectrumPropagationLoss->CalcRxPowerSpectralDensity (rxPowerSpectrum, txMobility, receiverMobility);
}
- }
- else
- {
- // rxPowerSpectrum = Copy<SpectrumValue> (convertedTxPowerSpectrum);
- rxPowerSpectrum = convertedTxPowerSpectrum->Copy ();
- delay = MicroSeconds (0);
+
+ if (m_propagationDelay)
+ {
+ delay = m_propagationDelay->GetDelay (txMobility, receiverMobility);
+ }
}
Ptr<PacketBurst> pktBurstCopy = p->Copy ();
@@ -297,7 +311,6 @@
pktBurstCopy, rxPowerSpectrum, st, duration, *rxPhyIterator);
}
}
- ++rxPhyIterator;
}
}
@@ -330,24 +343,32 @@
void
+MultiModelSpectrumChannel::AddPropagationLossModel (Ptr<PropagationLossModel> loss)
+{
+ NS_LOG_FUNCTION (this << loss);
+ NS_ASSERT (m_propagationLoss == 0);
+ m_propagationLoss = loss;
+}
+
+void
MultiModelSpectrumChannel::AddSpectrumPropagationLossModel (Ptr<SpectrumPropagationLossModel> loss)
{
- NS_ASSERT (m_PropagationLoss == 0);
- m_PropagationLoss = loss;
+ NS_ASSERT (m_propagationLoss == 0);
+ m_spectrumPropagationLoss = loss;
}
void
MultiModelSpectrumChannel::SetPropagationDelayModel (Ptr<PropagationDelayModel> delay)
{
- NS_ASSERT (m_PropagationDelay == 0);
- m_PropagationDelay = delay;
+ NS_ASSERT (m_propagationDelay == 0);
+ m_propagationDelay = delay;
}
Ptr<SpectrumPropagationLossModel>
MultiModelSpectrumChannel::GetSpectrumPropagationLossModel (void)
{
NS_LOG_FUNCTION (this);
- return m_PropagationLoss;
+ return m_spectrumPropagationLoss;
}
--- a/src/spectrum/model/multi-model-spectrum-channel.h Tue Jul 05 18:40:17 2011 +0200
+++ b/src/spectrum/model/multi-model-spectrum-channel.h Tue Jul 05 19:03:55 2011 +0200
@@ -88,6 +88,7 @@
static TypeId GetTypeId (void);
// inherited from SpectrumChannel
+ virtual void AddPropagationLossModel (Ptr<PropagationLossModel> loss);
virtual void AddSpectrumPropagationLossModel (Ptr<SpectrumPropagationLossModel> loss);
virtual void SetPropagationDelayModel (Ptr<PropagationDelayModel> delay);
virtual void AddRx (Ptr<SpectrumPhy> phy);
@@ -147,15 +148,19 @@
* propagation delay model to be used with this channel
*
*/
- Ptr<PropagationDelayModel> m_PropagationDelay;
-
+ Ptr<PropagationDelayModel> m_propagationDelay;
/**
- * propagation loss model to be used with this channel
+ * single-frequency propagation loss model to be used with this channel
+ *
+ */
+ Ptr<PropagationLossModel> m_propagationLoss;
+
+ /**
+ * frequency-dependent propagation loss model to be used with this channel
*
*/
- Ptr<SpectrumPropagationLossModel> m_PropagationLoss;
-
+ Ptr<SpectrumPropagationLossModel> m_spectrumPropagationLoss;
/**
@@ -180,6 +185,9 @@
*
*/
std::vector<Ptr<SpectrumPhy> > m_phyVector;
+
+
+ double m_maxLossDb;
};
--- a/src/spectrum/model/single-model-spectrum-channel.cc Tue Jul 05 18:40:17 2011 +0200
+++ b/src/spectrum/model/single-model-spectrum-channel.cc Tue Jul 05 19:03:55 2011 +0200
@@ -25,8 +25,14 @@
#include <ns3/packet-burst.h>
#include <ns3/net-device.h>
#include <ns3/node.h>
+#include <ns3/double.h>
#include <ns3/mobility-model.h>
#include <ns3/spectrum-phy.h>
+#include <ns3/spectrum-propagation-loss-model.h>
+#include <ns3/propagation-loss-model.h>
+#include <ns3/propagation-delay-model.h>
+
+
#include "single-model-spectrum-channel.h"
@@ -39,9 +45,6 @@
NS_OBJECT_ENSURE_REGISTERED (SingleModelSpectrumChannel);
SingleModelSpectrumChannel::SingleModelSpectrumChannel ()
- : m_spectrumModel (0),
- m_PropagationDelay (0),
- m_PropagationLoss (0)
{
NS_LOG_FUNCTION (this);
}
@@ -52,8 +55,9 @@
NS_LOG_FUNCTION (this);
m_phyList.clear ();
m_spectrumModel = 0;
- m_PropagationDelay = 0;
- m_PropagationLoss = 0;
+ m_propagationDelay = 0;
+ m_propagationLoss = 0;
+ m_spectrumPropagationLoss = 0;
SpectrumChannel::DoDispose ();
}
@@ -64,6 +68,18 @@
static TypeId tid = TypeId ("ns3::SingleModelSpectrumChannel")
.SetParent<SpectrumChannel> ()
.AddConstructor<SingleModelSpectrumChannel> ()
+ .AddAttribute ("MaxLossDb",
+ "If a single-frequency PropagationLossModel is used, this value "
+ "represents the maximum loss in dB for which transmissions will be "
+ "passed to the receiving PHY. Signals for which the PropagationLossModel "
+ "returns a loss bigger than this value will not be propagated to the receiver. "
+ "This parameter is to be used to reduce "
+ "the computational load by not propagating signals that are far beyond "
+ "the interference range. Note that the default value corresponds to "
+ "considering all signals for reception. Tune this value with care. ",
+ DoubleValue (1.0e9),
+ MakeDoubleAccessor (&SingleModelSpectrumChannel::m_maxLossDb),
+ MakeDoubleChecker<double> ())
;
return tid;
}
@@ -98,46 +114,44 @@
}
- PhyList::const_iterator rxPhyIterator = m_phyList.begin ();
+
Ptr<MobilityModel> senderMobility = txPhy->GetMobility ()->GetObject<MobilityModel> ();
- NS_ASSERT (rxPhyIterator != m_phyList.end ());
-
- while (rxPhyIterator != m_phyList.end ())
+ for (PhyList::const_iterator rxPhyIterator = m_phyList.begin ();
+ rxPhyIterator != m_phyList.end ();
+ ++rxPhyIterator)
{
if ((*rxPhyIterator) != txPhy)
{
- Ptr <SpectrumValue> rxPsd;
- Time delay;
+ Ptr <SpectrumValue> rxPsd = Copy<SpectrumValue> (txPsd);
+ Time delay = MicroSeconds (0);
+
Ptr<MobilityModel> receiverMobility = (*rxPhyIterator)->GetMobility ()->GetObject<MobilityModel> ();
if (senderMobility && receiverMobility)
{
-
-
- if (m_PropagationLoss)
+ if (m_propagationLoss)
{
- rxPsd = m_PropagationLoss->CalcRxPowerSpectralDensity (txPsd, senderMobility, receiverMobility);
- }
- else
- {
- rxPsd = txPsd;
+ double gainDb = m_propagationLoss->CalcRxPower (0, senderMobility, receiverMobility);
+ if ( (-gainDb) > m_maxLossDb)
+ {
+ // beyond range
+ continue;
+ }
+ double gainLinear = pow (10.0, gainDb/10.0);
+ *rxPsd = (*rxPsd) * gainLinear;
}
- if (m_PropagationDelay)
- {
- delay = m_PropagationDelay->GetDelay (senderMobility, receiverMobility);
- }
- else
+ if (m_spectrumPropagationLoss)
{
- delay = MicroSeconds (0);
+ rxPsd = m_spectrumPropagationLoss->CalcRxPowerSpectralDensity (rxPsd, senderMobility, receiverMobility);
}
- }
- else
- {
- rxPsd = txPsd;
- delay = MicroSeconds (0);
+
+ if (m_propagationDelay)
+ {
+ delay = m_propagationDelay->GetDelay (senderMobility, receiverMobility);
+ }
}
Ptr<PacketBurst> pktBurstCopy = p->Copy ();
@@ -156,7 +170,6 @@
pktBurstCopy, rxPsd, st, duration, *rxPhyIterator);
}
}
- ++rxPhyIterator;
}
}
@@ -186,21 +199,29 @@
}
+void
+SingleModelSpectrumChannel::AddPropagationLossModel (Ptr<PropagationLossModel> loss)
+{
+ NS_LOG_FUNCTION (this << loss);
+ NS_ASSERT (m_propagationLoss == 0);
+ m_propagationLoss = loss;
+}
+
void
SingleModelSpectrumChannel::AddSpectrumPropagationLossModel (Ptr<SpectrumPropagationLossModel> loss)
{
NS_LOG_FUNCTION (this << loss);
- NS_ASSERT (m_PropagationLoss == 0);
- m_PropagationLoss = loss;
+ NS_ASSERT (m_propagationLoss == 0);
+ m_spectrumPropagationLoss = loss;
}
void
SingleModelSpectrumChannel::SetPropagationDelayModel (Ptr<PropagationDelayModel> delay)
{
NS_LOG_FUNCTION (this << delay);
- NS_ASSERT (m_PropagationDelay == 0);
- m_PropagationDelay = delay;
+ NS_ASSERT (m_propagationDelay == 0);
+ m_propagationDelay = delay;
}
@@ -208,7 +229,7 @@
SingleModelSpectrumChannel::GetSpectrumPropagationLossModel (void)
{
NS_LOG_FUNCTION (this);
- return m_PropagationLoss;
+ return m_spectrumPropagationLoss;
}
--- a/src/spectrum/model/single-model-spectrum-channel.h Tue Jul 05 18:40:17 2011 +0200
+++ b/src/spectrum/model/single-model-spectrum-channel.h Tue Jul 05 19:03:55 2011 +0200
@@ -1,4 +1,4 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+//* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2009 CTTC
*
@@ -23,8 +23,6 @@
#include <ns3/spectrum-channel.h>
-#include <ns3/spectrum-propagation-loss-model.h>
-#include <ns3/propagation-delay-model.h>
namespace ns3 {
@@ -47,6 +45,7 @@
// inherited from SpectrumChannel
+ virtual void AddPropagationLossModel (Ptr<PropagationLossModel> loss);
virtual void AddSpectrumPropagationLossModel (Ptr<SpectrumPropagationLossModel> loss);
virtual void SetPropagationDelayModel (Ptr<PropagationDelayModel> delay);
virtual void AddRx (Ptr<SpectrumPhy> phy);
@@ -97,15 +96,23 @@
* propagation delay model to be used with this channel
*
*/
- Ptr<PropagationDelayModel> m_PropagationDelay;
+ Ptr<PropagationDelayModel> m_propagationDelay;
/**
- * propagation loss model to be used with this channel
+ * single-frequency propagation loss model to be used with this channel
+ *
+ */
+ Ptr<PropagationLossModel> m_propagationLoss;
+
+ /**
+ * frequency-dependent propagation loss model to be used with this channel
*
*/
- Ptr<SpectrumPropagationLossModel> m_PropagationLoss;
+ Ptr<SpectrumPropagationLossModel> m_spectrumPropagationLoss;
+
+ double m_maxLossDb;
};
--- a/src/spectrum/model/spectrum-channel.h Tue Jul 05 18:40:17 2011 +0200
+++ b/src/spectrum/model/spectrum-channel.h Tue Jul 05 19:03:55 2011 +0200
@@ -34,6 +34,7 @@
class SpectrumValue;
class SpectrumPhy;
class SpectrumPropagationLossModel;
+class PropagationLossModel;
class PropagationDelayModel;
/**
@@ -50,8 +51,16 @@
/**
- * set the propagation loss model to be used
- * \param loss Ptr to the propagation loss model to be used.
+ * set the single-frequency propagation loss model to be used
+ * \warning only models that do not depend on the TX power should be used.
+ *
+ * \param loss a pointer to the propagation loss model to be used.
+ */
+ virtual void AddPropagationLossModel (Ptr<PropagationLossModel> loss) = 0;
+
+ /**
+ * set the frequency-dependent propagation loss model to be used
+ * \param loss a pointer to the propagation loss model to be used.
*/
virtual void AddSpectrumPropagationLossModel (Ptr<SpectrumPropagationLossModel> loss) = 0;
--- a/src/spectrum/test/examples-to-run.py Tue Jul 05 18:40:17 2011 +0200
+++ b/src/spectrum/test/examples-to-run.py Tue Jul 05 19:03:55 2011 +0200
@@ -10,6 +10,7 @@
cpp_examples = [
("adhoc-aloha-ideal-phy", "True", "True"),
("adhoc-aloha-ideal-phy-with-microwave-oven", "True", "True"),
+ ("adhoc-aloha-ideal-phy-matrix-propagation-loss-model", "True", "True"),
]
# A list of Python examples to run in order to ensure that they remain
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/spectrum/test/spectrum-ideal-phy-test.cc Tue Jul 05 19:03:55 2011 +0200
@@ -0,0 +1,245 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 CTTC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include <ns3/object.h>
+#include <ns3/spectrum-interference.h>
+#include <ns3/spectrum-error-model.h>
+#include <ns3/log.h>
+#include <ns3/test.h>
+#include <ns3/simulator.h>
+#include <ns3/packet.h>
+#include <ns3/ptr.h>
+#include <iostream>
+
+#include <ns3/spectrum-model-ism2400MHz-res1MHz.h>
+#include <ns3/spectrum-model-300kHz-300GHz-log.h>
+#include <ns3/wifi-spectrum-value-helper.h>
+#include <ns3/single-model-spectrum-channel.h>
+#include <ns3/waveform-generator.h>
+#include <ns3/spectrum-analyzer.h>
+#include <ns3/log.h>
+#include <string>
+#include <iomanip>
+#include <ns3/friis-spectrum-propagation-loss.h>
+#include <ns3/propagation-delay-model.h>
+#include <ns3/spectrum-helper.h>
+#include <ns3/adhoc-aloha-noack-ideal-phy-helper.h>
+#include <ns3/mobility-helper.h>
+#include <ns3/data-rate.h>
+#include <ns3/uinteger.h>
+#include <ns3/packet-socket-helper.h>
+#include <ns3/packet-socket-address.h>
+#include <ns3/on-off-helper.h>
+#include <ns3/config.h>
+
+NS_LOG_COMPONENT_DEFINE ("SpectrumIdealPhyTest");
+
+namespace ns3 {
+
+
+static uint64_t g_rxBytes;
+static double g_bandwidth = 20e6; // Hz
+
+void
+PhyRxEndOkTrace (std::string context, Ptr<const Packet> p)
+{
+ g_rxBytes += p->GetSize ();
+}
+
+
+class SpectrumIdealPhyTestCase : public TestCase
+{
+public:
+ SpectrumIdealPhyTestCase (double snrLinear,
+ uint64_t phyRate,
+ bool rateIsAchievable,
+ std::string channelType);
+ virtual ~SpectrumIdealPhyTestCase ();
+
+private:
+ virtual void DoRun (void);
+
+ double m_snrLinear;
+ uint64_t m_phyRate;
+ bool m_rateIsAchievable;
+ std::string m_channelType;
+};
+
+
+
+
+SpectrumIdealPhyTestCase::SpectrumIdealPhyTestCase (double snrLinear,
+ uint64_t phyRate,
+ bool rateIsAchievable,
+ std::string channelType)
+ : TestCase (""),
+ m_snrLinear (snrLinear),
+ m_phyRate (phyRate),
+ m_rateIsAchievable (rateIsAchievable),
+ m_channelType (channelType)
+{
+ std::ostringstream oss;
+ oss << channelType
+ << " snr = " << snrLinear << " (linear), "
+ << " phyRate = " << phyRate << " bps";
+ SetName (oss.str ());
+}
+
+SpectrumIdealPhyTestCase::~SpectrumIdealPhyTestCase ()
+{
+}
+
+
+void
+SpectrumIdealPhyTestCase::DoRun (void)
+{
+ NS_LOG_FUNCTION (m_snrLinear << m_phyRate);
+ double txPowerW = 0.1;
+ // for the noise, we use the Power Spectral Density of thermal noise
+ // at room temperature. The value of the PSD will be constant over the band of interest.
+ const double k = 1.381e-23; //Boltzmann's constant
+ const double T = 290; // temperature in Kelvin
+ double noisePsdValue = k * T; // W/Hz
+ double lossLinear = (txPowerW) / (m_snrLinear * noisePsdValue * g_bandwidth);
+ double lossDb = 10 * log10 (lossLinear);
+ uint64_t phyRate = m_phyRate; // bps
+ uint32_t pktSize = 50; // bytes
+
+ uint32_t numPkts = 200; //desired number of packets in the
+ //test. Directly related with the accuracy
+ //of the measurement.
+
+ double testDuration = (numPkts * pktSize * 8.0) / phyRate;
+ NS_LOG_INFO ("test duration = " << std::fixed << testDuration);
+
+ NodeContainer c;
+ c.Create (2);
+
+ MobilityHelper mobility;
+ Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
+ positionAlloc->Add (Vector (0.0, 0.0, 0.0));
+ positionAlloc->Add (Vector (5.0, 0.0, 0.0));
+ mobility.SetPositionAllocator (positionAlloc);
+ mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+
+
+ mobility.Install (c);
+
+
+ SpectrumChannelHelper channelHelper;
+ channelHelper.SetChannel (m_channelType);
+ channelHelper.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
+ Ptr<MatrixPropagationLossModel> propLoss = CreateObject<MatrixPropagationLossModel> ();
+ propLoss->SetLoss (c.Get(0)->GetObject<MobilityModel> (), c.Get(1)->GetObject<MobilityModel> (), lossDb, true);
+ channelHelper.AddPropagationLoss (propLoss);
+ Ptr<SpectrumChannel> channel = channelHelper.Create ();
+
+
+ WifiSpectrumValue5MhzFactory sf;
+
+ uint32_t channelNumber = 1;
+ Ptr<SpectrumValue> txPsd = sf.CreateTxPowerSpectralDensity (txPowerW, channelNumber);
+
+ Ptr<SpectrumValue> noisePsd = sf.CreateConstant (noisePsdValue);
+
+ AdhocAlohaNoackIdealPhyHelper deviceHelper;
+ deviceHelper.SetChannel (channel);
+ deviceHelper.SetTxPowerSpectralDensity (txPsd);
+ deviceHelper.SetNoisePowerSpectralDensity (noisePsd);
+ deviceHelper.SetPhyAttribute ("Rate", DataRateValue (DataRate (phyRate)));
+ NetDeviceContainer devices = deviceHelper.Install (c);
+
+ PacketSocketHelper packetSocket;
+ packetSocket.Install (c);
+
+ PacketSocketAddress socket;
+ socket.SetSingleDevice (devices.Get (0)->GetIfIndex ());
+ socket.SetPhysicalAddress (devices.Get (1)->GetAddress ());
+ socket.SetProtocol (1);
+
+ OnOffHelper onoff ("ns3::PacketSocketFactory", Address (socket));
+ onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (250)));
+ onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+ onoff.SetAttribute ("DataRate", DataRateValue (DataRate (1.2*phyRate)));
+ onoff.SetAttribute ("PacketSize", UintegerValue (pktSize));
+
+ ApplicationContainer apps = onoff.Install (c.Get (0));
+ apps.Start (Seconds (0.0));
+ apps.Stop (Seconds (testDuration));
+
+ Config::Connect ("/NodeList/*/DeviceList/*/Phy/RxEndOk", MakeCallback (&PhyRxEndOkTrace));
+
+ g_rxBytes = 0;
+ Simulator::Stop (Seconds (testDuration+0.000000001));
+ Simulator::Run ();
+ double throughputBps = (g_rxBytes * 8.0) / testDuration;
+
+ if (m_rateIsAchievable)
+ {
+ NS_TEST_ASSERT_MSG_EQ_TOL (throughputBps, m_phyRate, m_phyRate*0.01, "throughput does not match PHY rate");
+ }
+ else
+ {
+ NS_TEST_ASSERT_MSG_EQ (throughputBps, 0.0, "PHY rate is not achievable but throughput is non-zero");
+ }
+
+ Simulator::Destroy ();
+}
+
+
+
+
+class SpectrumIdealPhyTestSuite : public TestSuite
+{
+public:
+ SpectrumIdealPhyTestSuite ();
+};
+
+SpectrumIdealPhyTestSuite::SpectrumIdealPhyTestSuite ()
+ : TestSuite ("spectrum-ideal-phy", SYSTEM)
+{
+
+ NS_LOG_INFO ("creating SpectrumIdealPhyTestSuite");
+
+ for (double snr = 0.01; snr <= 10 ; snr *= 2)
+ {
+ double achievableRate = g_bandwidth*log2(1+snr);
+ AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*0.1, true, "ns3::SingleModelSpectrumChannel"));
+ AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*0.5, true, "ns3::SingleModelSpectrumChannel"));
+ AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*0.95, true, "ns3::SingleModelSpectrumChannel"));
+ AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*1.05, false, "ns3::SingleModelSpectrumChannel"));
+ AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*2, false, "ns3::SingleModelSpectrumChannel"));
+ AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*4, false, "ns3::SingleModelSpectrumChannel"));
+ }
+ for (double snr = 0.01; snr <= 10 ; snr *= 10)
+ {
+ double achievableRate = g_bandwidth*log2(1+snr);
+ AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*0.1, true, "ns3::MultiModelSpectrumChannel"));
+ AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*0.5, true, "ns3::MultiModelSpectrumChannel"));
+ AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*0.95, true, "ns3::MultiModelSpectrumChannel"));
+ AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*1.05, false, "ns3::MultiModelSpectrumChannel"));
+ AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*2, false, "ns3::MultiModelSpectrumChannel"));
+ AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*4, false, "ns3::MultiModelSpectrumChannel"));
+ }
+}
+
+static SpectrumIdealPhyTestSuite g_spectrumIdealPhyTestSuite;
+
+} // namespace ns3
--- a/src/spectrum/wscript Tue Jul 05 18:40:17 2011 +0200
+++ b/src/spectrum/wscript Tue Jul 05 19:03:55 2011 +0200
@@ -36,6 +36,7 @@
module_test.source = [
'test/spectrum-interference-test.cc',
'test/spectrum-value-test.cc',
+ 'test/spectrum-ideal-phy-test.cc',
]
headers = bld.new_task_gen('ns3header')