diff --git a/examples/wifi-adhoc.cc b/examples/wifi-adhoc.cc index bdcd43470..dcfd026ce 100644 --- a/examples/wifi-adhoc.cc +++ b/examples/wifi-adhoc.cc @@ -249,7 +249,7 @@ int main (int argc, char *argv[]) gnuplot = Gnuplot ("rate-control.png"); - Config::SetDefault ("WifiPhy::Standard", String ("holland")); + Config::SetDefault ("ns3::WifiPhy::Standard", String ("holland")); NS_LOG_DEBUG ("arf"); diff --git a/samples/main-propagation-loss.cc b/samples/main-propagation-loss.cc index 0972153b0..7f998a8ad 100644 --- a/samples/main-propagation-loss.cc +++ b/samples/main-propagation-loss.cc @@ -41,7 +41,7 @@ PrintOne (double minTxpower, double maxTxpower, double stepTxpower, double min, std::cout << x << " "; for (double txpower = minTxpower; txpower < maxTxpower; txpower += stepTxpower) { - double rxPowerDbm = model->GetRxPower (txpower, a, b); + double rxPowerDbm = txpower + model->GetLoss (a, b); std::cout << rxPowerDbm << " "; } std::cout << std::endl; diff --git a/src/devices/wifi/composite-propagation-loss-model.cc b/src/devices/wifi/composite-propagation-loss-model.cc new file mode 100644 index 000000000..380bdcd96 --- /dev/null +++ b/src/devices/wifi/composite-propagation-loss-model.cc @@ -0,0 +1,79 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2005,2006,2007 INRIA + * + * 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: Federico Maguolo + */ + +#include "ns3/simulator.h" +#include "ns3/uinteger.h" +#include "ns3/double.h" +#include "ns3/random-variable.h" +#include "ns3/default-value.h" +#include "ns3/mobility-model.h" +#include "composite-propagation-loss-model.h" +#include + +namespace ns3 { + + + +NS_OBJECT_ENSURE_REGISTERED (CompositePropagationLossModel); + +TypeId +CompositePropagationLossModel::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::CompositePropagationLossModel") + .SetParent () + .AddConstructor () + ; + return tid; +} + +CompositePropagationLossModel::CompositePropagationLossModel () +{ + AddDefaults (); +} + +CompositePropagationLossModel::~CompositePropagationLossModel () +{} + +void +CompositePropagationLossModel::AddDefaults () +{} + +void +CompositePropagationLossModel::AddPropagationLossModel (Ptr pl) +{ + m_propagationModels.push_back (pl); +} + +double +CompositePropagationLossModel::GetLoss (Ptr a, + Ptr b) const +{ + double rxc = 0.0; + for(PropagationModelList::const_iterator i = m_propagationModels.begin (); + i != m_propagationModels.end (); + i++) { + rxc += (*i)->GetLoss (a, b); + } + + return rxc; +} + +} // namespace ns3 + diff --git a/src/devices/wifi/composite-propagation-loss-model.h b/src/devices/wifi/composite-propagation-loss-model.h new file mode 100644 index 000000000..497ea93e3 --- /dev/null +++ b/src/devices/wifi/composite-propagation-loss-model.h @@ -0,0 +1,63 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2005,2006,2007 INRIA + * + * 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: Federico Maguolo + */ +#ifndef PROPAGATION_COMP_MODEL_H +#define PROPAGATION_COMP_MODEL_H + +#include "ns3/nstime.h" +#include "propagation-loss-model.h" + +namespace ns3 { + +/** + * \brief a Composite propagation loss model + * + * This model is use to compute the receivng power + * using more than one propagation loss model (e.g. distance loss + * and jakes). + * + * The received power is computed considering the cascade of the models + */ +class CompositePropagationLossModel : public PropagationLossModel { +public: + static TypeId GetTypeId (void); + CompositePropagationLossModel (); + virtual ~CompositePropagationLossModel (); + + virtual double GetLoss (Ptr a, + Ptr b) const; + /** + * \param pl the propagation loss model to add + * + * Insert a propagation loss model to the composite. + */ + void AddPropagationLossModel (Ptr pl); +protected: + virtual void AddDefaults (void); +private: + typedef std::vector > PropagationModelList; + PropagationModelList m_propagationModels; +}; + + +} // namespace ns3 + +#endif /* PROPAGATION_COMP_MODEL_H */ + + diff --git a/src/devices/wifi/jakes-propagation-loss-model.cc b/src/devices/wifi/jakes-propagation-loss-model.cc new file mode 100644 index 000000000..a8ebac24e --- /dev/null +++ b/src/devices/wifi/jakes-propagation-loss-model.cc @@ -0,0 +1,235 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2005,2006,2007 INRIA + * + * 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: Federico Maguolo + */ + +#include "ns3/simulator.h" +#include "ns3/uinteger.h" +#include "ns3/double.h" +#include "ns3/random-variable.h" +#include "ns3/default-value.h" +#include "ns3/mobility-model.h" +#include "ns3/log.h" +#include "jakes-propagation-loss-model.h" +#include + +NS_LOG_COMPONENT_DEFINE ("Jakes"); + +namespace ns3 { + + + +class JakesPropagationLossModel::PathCoefficients { +public: + PathCoefficients (Ptr jakes, + Ptr receiver, + uint8_t nRays, + uint8_t nOscillators); + ~PathCoefficients (); + double GetLoss (void); + Ptr GetReceiver (void); +private: + void DoConstruct (void); + Ptr m_receiver; + uint8_t m_nOscillators; + uint8_t m_nRays; + double **m_phases; + Time m_lastUpdate; + Ptr m_jakes; +}; + + +JakesPropagationLossModel::PathCoefficients::PathCoefficients (Ptr jakes, + Ptr receiver, + uint8_t nRays, + uint8_t nOscillators) + : m_receiver (receiver), + m_nOscillators (nOscillators), + m_nRays (nRays), + m_jakes(jakes) +{ + DoConstruct (); +} + +JakesPropagationLossModel::PathCoefficients::~PathCoefficients () +{ + for (uint8_t i = 0; i < m_nRays; i++) { + delete [] m_phases[i]; + } + delete [] m_phases; +} + +void +JakesPropagationLossModel::PathCoefficients::DoConstruct () +{ + m_phases = new double*[m_nRays]; + for (uint8_t i = 0; i < m_nRays; i++) { + m_phases[i] = new double[m_nOscillators + 1]; + for (uint8_t j = 0; j <= m_nOscillators; j++) { + m_phases[i][j] = 2.0 * JakesPropagationLossModel::PI * m_jakes->m_variable.GetValue (); + } + } + m_lastUpdate = Simulator::Now (); +} + +Ptr +JakesPropagationLossModel::PathCoefficients::GetReceiver () +{ + return m_receiver; +} + +double +JakesPropagationLossModel::PathCoefficients::GetLoss (void) +{ + uint16_t N = 4 * m_nOscillators + 2; + Time interval = Simulator::Now () - m_lastUpdate; + ComplexNumber coef= {0.0, 0.0}; + ComplexNumber fading; + double norm = 0.0; + for (uint8_t i = 0; i < m_nRays; i++) { + fading.real = 0.0; + fading.imag = 0.0; + for (uint8_t j = 0; j <= m_nOscillators; j++) { + m_phases[i][j] += 2.0 * JakesPropagationLossModel::PI * cos (2.0 * JakesPropagationLossModel::PI * j / N) * m_jakes->m_fd * interval.GetSeconds (); + m_phases[i][j] -= 2.0 * JakesPropagationLossModel::PI * floor (m_phases[i][j] / 2.0 / JakesPropagationLossModel::PI); + fading.real += m_jakes->m_amp[j].real * cos (m_phases[i][j]); + fading.imag += m_jakes->m_amp[j].imag * cos (m_phases[i][j]); + norm += sqrt(pow (m_jakes->m_amp[j].real, 2) + pow(m_jakes->m_amp[j].imag, 2)); + } + coef.real += fading.real; + coef.imag += fading.imag; + } + m_lastUpdate = Simulator::Now (); + double k = sqrt (pow (coef.real, 2) + pow (coef.imag, 2)) / norm; + NS_LOG_DEBUG ("Jakes coef "<< k << " (" << 10 * log10 (k) << "dB)"); + return 10 * log10 (k); +} + +NS_OBJECT_ENSURE_REGISTERED (JakesPropagationLossModel); + +const double JakesPropagationLossModel::PI = 3.1415; + +TypeId +JakesPropagationLossModel::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::JakesPropagationLossModel") + .SetParent () + .AddConstructor () + .AddAttribute ("NumberOfRaysPerPath", + "The number of rays to use by default for compute the fading coeficent for a given path (default is 1)", + Uinteger (1), + MakeUintegerAccessor (&JakesPropagationLossModel::m_nRays), + MakeUintegerChecker ()) + .AddAttribute ("NumberOfOscillatorsPerRay", + "The number of oscillators to use by default for compute the coeficent for a given ray of a given path (default is 4)", + Uinteger (4), + MakeUintegerAccessor (&JakesPropagationLossModel::m_nOscillators), + MakeUintegerChecker ()) + .AddAttribute ("DopplerFreq", + "The doppler frequency in Hz (f_d = v / lambda = v * f / c, the defualt is 0)", + Double(0.0), + MakeDoubleAccessor (&JakesPropagationLossModel::m_fd), + MakeDoubleChecker ()) + .AddAttribute ("Distribution", + "The distribution to choose the initial phases.", + ConstantVariable (1.0), + MakeRandomVariableAccessor (&JakesPropagationLossModel::m_variable), + MakeRandomVariableChecker ()) + ; + return tid; +} + +JakesPropagationLossModel::JakesPropagationLossModel () +{ + DoConstruct (); +} + +JakesPropagationLossModel::~JakesPropagationLossModel () +{ + delete [] m_amp; + for (PathsList::iterator i = m_paths.end (); i != m_paths.begin (); i--) { + PathsSet *ps = *i; + for (DestinationList::iterator r = ps->receivers.begin (); r != ps->receivers.end (); r++) { + PathCoefficients *pc = *r; + delete pc; + } + delete ps; + } +} + +void +JakesPropagationLossModel::DoConstruct () +{ + uint16_t N = 4 * m_nOscillators + 2; + m_amp = new ComplexNumber[m_nOscillators + 1]; + m_amp[0].real = 2.0 * sqrt(2.0 / N) * cos (PI / 4.0); + m_amp[0].imag = 2.0 * sqrt(2.0 / N) * sin (PI / 4.0); + for (uint8_t i = 1; i <= m_nOscillators; i++) { + double beta = PI * (double)i / m_nOscillators; + m_amp[i].real = 4.0 * cos (beta) / sqrt(N); + m_amp[i].imag = 4.0 * sin (beta) / sqrt(N); + } +} + +void +JakesPropagationLossModel::SetNRays (uint8_t nRays) +{ + m_nRays = nRays; +} + +void +JakesPropagationLossModel::SetNOscillators (uint8_t nOscillators) +{ + m_nOscillators = nOscillators; +} + +double +JakesPropagationLossModel::GetLoss (Ptr a, + Ptr b) const +{ + PathsList::iterator i = m_paths.end (); + while (i != m_paths.begin ()) { + i--; + PathsSet *ps = *i; + if (PeekPointer (ps->sender) == PeekPointer(a)) { + m_paths.erase (i); + m_paths.push_back (ps); + for (DestinationList::iterator r = ps->receivers.begin (); r != ps->receivers.end (); r++) { + PathCoefficients *pc = *r; + if (PeekPointer (pc->GetReceiver ()) == PeekPointer (b)) { + ps->receivers.erase (r); + ps->receivers.push_back (pc); + return pc->GetLoss (); + } + } + PathCoefficients *pc = new PathCoefficients (this, b, m_nRays, m_nOscillators); + ps->receivers.push_back (pc); + return pc->GetLoss (); + } + } + PathsSet *ps = new PathsSet; + ps->sender = a; + PathCoefficients *pc = new PathCoefficients (this, b, m_nRays, m_nOscillators); + ps->receivers.push_back (pc); + m_paths.push_back (ps); + return pc->GetLoss (); +} + + +} // namespace ns3 + diff --git a/src/devices/wifi/jakes-propagation-loss-model.h b/src/devices/wifi/jakes-propagation-loss-model.h new file mode 100644 index 000000000..17ae36e63 --- /dev/null +++ b/src/devices/wifi/jakes-propagation-loss-model.h @@ -0,0 +1,131 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2005,2006,2007 INRIA + * + * 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: Federico Maguolo + */ +#ifndef PROPAGATION_JAKES_MODEL_H +#define PROPAGATION_JAKES_MODEL_H + +#include "ns3/nstime.h" +#include "propagation-loss-model.h" + +namespace ns3 { + + +/** + * \brief a Jakes propagation loss model + * + * The Jakes propagation loss model implemented here is + * described in [1]. + * + * + * We call path the set of rays that depart from a given + * transmitter and arrive to a given receiver. For each ray + * The complex coefficient is compute as follow: + * \f[ u(t)=u_c(t) + j u_s(t)\f] + * \f[ u_c(t) = \frac{2}{\sqrt{N}}\sum_{n=0}^{M}a_n\cos(\omega_n t+\phi_n)\f] + * \f[ u_s(t) = \frac{2}{\sqrt{N}}\sum_{n=0}^{M}b_n\cos(\omega_n t+\phi_n)\f] + * where + * \f[ a_n=\left \{ \begin{array}{ll} + * \sqrt{2}\cos\beta_0 & n=0 \\ + * 2\cos\beta_n & n=1,2,\ldots,M + * \end{array} + * \right .\f] + * \f[ b_n=\left \{ \begin{array}{ll} + * \sqrt{2}\sin\beta_0 & n=0 \\ + * 2\sin\beta_n & n=1,2,\ldots,M + * \end{array} + * \right .\f] + * \f[ \beta_n=\left \{ \begin{array}{ll} + * \frac{\pi}{4} & n=0 \\ + * \frac{\pi n}{M} & n=1,2,\ldots,M + * \end{array} + * \right .\f] + * \f[ \omega_n=\left \{ \begin{array}{ll} + * 2\pi f_d & n=0 \\ + * 2\pi f_d \cos\frac{2\pi n}{N} & n=1,2,\ldots,M + * \end{array} + * \right .\f] + * + * The parameter \f$f_d\f$ is the doppler frequency and \f$N=4M+2\f$ where + * \f$M\f$ is the number of oscillators per ray. + * + * The attenuation coefficent of the path is the magnitude of the sum of + * all the ray coefficients. This attenuation coefficient could be greater than + * \f$1\f$, hence it is divide by \f$ \frac{2N_r}{\sqrt{N}} \sum_{n+0}^{M}\sqrt{a_n^2 +b_n^2}\f$ + * where \f$N_r\f$ is the number of rays. + * + * The initail phases \f$\phi_i\f$ are random and they are choosen according + * to a given distribution. + * + * [1] Y. R. Zheng and C. Xiao, "Simulation Models With Correct + * Statistical Properties for Rayleigh Fading Channel", IEEE + * Trans. on Communications, Vol. 51, pp 920-928, June 2003 + */ +class JakesPropagationLossModel : public PropagationLossModel +{ +public: + static TypeId GetTypeId (void); + JakesPropagationLossModel (); + virtual ~JakesPropagationLossModel (); + + virtual double GetLoss (Ptr a, + Ptr b) const; + /** + * \param nRays Number of rays per path + * + * Set the number of rays for each path + */ + void SetNRays (uint8_t nRays); + /** + * \param nOscillators Number of oscillators + * + * Set the number of oscillators to use to compute the ray coefficient + */ + void SetNOscillators (uint8_t nOscillators); +protected: + class PathCoefficients; + struct ComplexNumber { + double real; + double imag; + }; + friend class PathCoefficents; + + static const double PI; + ComplexNumber* m_amp; + RandomVariable m_variable; + double m_fd; +private: + typedef std::vector DestinationList; + struct PathsSet { + Ptr sender; + DestinationList receivers; + }; + typedef std::vector PathsList; + + void DoConstruct (void); + + mutable PathsList m_paths; + uint8_t m_nRays; + uint8_t m_nOscillators; +}; + +} // namespace ns3 + +#endif /* PROPAGATION_JAKES_MODEL_H */ + + diff --git a/src/devices/wifi/propagation-loss-model.cc b/src/devices/wifi/propagation-loss-model.cc index 7327795b7..e522f0517 100644 --- a/src/devices/wifi/propagation-loss-model.cc +++ b/src/devices/wifi/propagation-loss-model.cc @@ -54,13 +54,12 @@ RandomPropagationLossModel::~RandomPropagationLossModel () {} double -RandomPropagationLossModel::GetRxPower (double txPowerDbm, - Ptr a, - Ptr b) const +RandomPropagationLossModel::GetLoss (Ptr a, + Ptr b) const { - double rxPower = txPowerDbm - m_variable.GetValue (); - NS_LOG_DEBUG ("tx power="< a, - Ptr b) const +FriisPropagationLossModel::GetLoss (Ptr a, + Ptr b) const { /* * Friis free space equation: * where Pt, Gr, Gr and P are in Watt units * L is in meter units. * - * Gt * Gr * (lambda^2) - * P = Pt --------------------- - * (4 * pi * d)^2 * L + * P Gt * Gr * (lambda^2) + * --- = --------------------- + * Pt (4 * pi * d)^2 * L * * Gt: tx gain (unit-less) * Gr: rx gain (unit-less) @@ -167,14 +165,13 @@ FriisPropagationLossModel::GetRxPower (double txPowerDbm, double distance = a->GetDistanceFrom (b); if (distance <= m_minDistance) { - return txPowerDbm; + return 0.0; } double numerator = m_lambda * m_lambda; double denominator = 16 * PI * PI * distance * distance * m_systemLoss; double pr = 10 * log10 (numerator / denominator); - double rxPowerDbm = txPowerDbm + pr; - NS_LOG_DEBUG ("distance="< a, - Ptr b) const +LogDistancePropagationLossModel::GetLoss (Ptr a, + Ptr b) const { double distance = a->GetDistanceFrom (b); if (distance <= m_referenceDistance) { - return txPowerDbm; + return 0.0; } /** * The formula is: @@ -257,13 +253,12 @@ LogDistancePropagationLossModel::GetRxPower (double txPowerDbm, static Ptr reference = CreateObject ("Position", Vector (m_referenceDistance, 0.0, 0.0)); - double rx0 = m_reference->GetRxPower (txPowerDbm, zero, reference); + double ref = m_reference->GetLoss (zero, reference); double pathLossDb = 10 * m_exponent * log10 (distance / m_referenceDistance); - double rxPowerDbm = rx0 - pathLossDb; - NS_LOG_DEBUG ("distance="< a, - Ptr b) const = 0; + virtual double GetLoss (Ptr a, + Ptr b) const = 0; }; /** @@ -59,9 +57,8 @@ public: RandomPropagationLossModel (); virtual ~RandomPropagationLossModel (); - virtual double GetRxPower (double txPowerDbm, - Ptr a, - Ptr b) const; + virtual double GetLoss (Ptr a, + Ptr b) const; private: RandomVariable m_variable; }; @@ -143,9 +140,8 @@ public: */ double GetSystemLoss (void) const; - virtual double GetRxPower (double txPowerDbm, - Ptr a, - Ptr b) const; + virtual double GetLoss (Ptr a, + Ptr b) const; private: double DbmToW (double dbm) const; double DbmFromW (double w) const; @@ -197,9 +193,8 @@ public: void SetReferenceDistance (double referenceDistance); - virtual double GetRxPower (double txPowerDbm, - Ptr a, - Ptr b) const; + virtual double GetLoss (Ptr a, + Ptr b) const; private: static Ptr CreateDefaultReference (void); diff --git a/src/devices/wifi/wifi-channel.cc b/src/devices/wifi/wifi-channel.cc index aa8301c97..1cc9d9076 100644 --- a/src/devices/wifi/wifi-channel.cc +++ b/src/devices/wifi/wifi-channel.cc @@ -93,7 +93,7 @@ WifiChannel::Send (Ptr sender, Ptr packet, double txPower { Ptr receiverMobility = i->first->GetNode ()->GetObject (); Time delay = m_delay->GetDelay (senderMobility, receiverMobility); - double rxPowerDbm = m_loss->GetRxPower (txPowerDbm, senderMobility, receiverMobility); + double rxPowerDbm = txPowerDbm + m_loss->GetLoss (senderMobility, receiverMobility); NS_LOG_DEBUG ("propagation: txPower="<