# HG changeset patch # User Nicola Baldo # Date 1337614222 -7200 # Node ID 6b31c0c234ccadde8e449c2217aab58cd74af993 # Parent e939e081efd578b381ffefe471d7b7df7b6eab26# Parent 8f366d5eee06e265172dd42300aec6376af70af4 merge diff -r e939e081efd5 -r 6b31c0c234cc src/propagation/examples/jakes-propagation-model-example.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/propagation/examples/jakes-propagation-model-example.cc Mon May 21 17:30:22 2012 +0200 @@ -0,0 +1,98 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2012 Telum (www.telum.ru) + * + * 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: Kirill Andreev + */ +#include "ns3/core-module.h" +#include "ns3/mobility-module.h" +#include "ns3/jakes-propagation-loss-model.h" +#include +#include + +using namespace ns3; +/** + * \ingroup propagation + * \brief Constructs a JakesPropagationlossModel and print the loss value as a function of time into std::cout. + * Distribution and correlation statistics is compared woth a theoretical ones using R package (http://www.r-project.org/). + * Scripts are presented within comments. + */ +class JakesPropagationExample +{ +public: + JakesPropagationExample (); + ~JakesPropagationExample (); +private: + Ptr m_loss; + Ptr m_firstMobility; + Ptr m_secondMobility; + Time m_step; + EventId m_nextEvent; + void Next (); + +}; + +JakesPropagationExample::JakesPropagationExample () : + m_step (Seconds (0.0002)) //1/5000 part of the second +{ + m_loss = CreateObject (); + m_firstMobility = CreateObject (); + m_secondMobility = CreateObject (); + m_firstMobility->SetPosition (Vector (0, 0, 0)); + m_secondMobility->SetPosition (Vector (10, 0, 0)); + m_nextEvent = Simulator::Schedule (m_step, &JakesPropagationExample::Next, this); +} + +JakesPropagationExample::~JakesPropagationExample () +{ +} + +void JakesPropagationExample::Next () +{ + m_nextEvent = Simulator::Schedule (m_step, &JakesPropagationExample::Next, this); + std::cout << Simulator::Now ().GetMilliSeconds () << " " << m_loss->CalcRxPower (0, m_firstMobility, m_secondMobility) << std::endl; +} + +int main (int argc, char *argv[]) +{ + Config::SetDefault ("ns3::JakesProcess::NumberOfOscillators", UintegerValue (100)); + CommandLine cmd; + cmd.Parse (argc, argv); + JakesPropagationExample example; + Simulator::Stop (Seconds (1000)); + Simulator::Run (); + Simulator::Destroy (); + /* + * R script for plotting a distribution: + data<-read.table ("data") + rayleigh<-(rnorm(1e6)^2+rnorm(1e6)^2)/2 + qqplot(10*log10(rayleigh), data$V2, main="QQ-plot for improved Jakes model", xlab="Reference Rayleigh distribution [power, dB]", ylab="Sum-of-sinusoids distribution [power, dB]", xlim=c(-45, 10), ylim=c(-45, 10)) + lines (c(-50, 50), c(-50, 50)) + abline (v=-50:50*2, h=-50:50*2, col="light grey") + */ + + /* + * R script to plot autocorrelation function: + # Read amplitude distribution: + data<-10^(read.table ("data")$V2/20) + x<-1:2000/10 + acf (data, lag.max=200, main="Autocorrelation function of the improved Jakes model", xlab="Time x200 microseconds ", ylab="Autocorrelation") + # If we have a delta T = 1/5000 part of the second and doppler freq = 80 Hz + lines (x, besselJ(x*80*2*pi/5000, 0)^2) + abline (h=0:10/10, col="light grey") + */ + return 0; +} diff -r e939e081efd5 -r 6b31c0c234cc src/propagation/examples/main-propagation-loss.cc --- a/src/propagation/examples/main-propagation-loss.cc Mon May 21 17:01:36 2012 +0200 +++ b/src/propagation/examples/main-propagation-loss.cc Mon May 21 17:30:22 2012 +0200 @@ -249,7 +249,7 @@ Ptr jakes = CreateObject (); // doppler frequency shift for 5.15 GHz at 100 km/h - jakes->SetAttribute ("DopplerFreq", DoubleValue (477.9)); + Config::SetDefault ("ns3::JakesProcess::DopplerFrequencyHz", DoubleValue (477.9)); Gnuplot plot = TestDeterministicByTime (jakes, Seconds (0.001), Seconds (1.0)); plot.SetTitle ("ns3::JakesPropagationLossModel (with 477.9 Hz shift and 1 millisec resolution)"); @@ -260,7 +260,7 @@ Ptr jakes = CreateObject (); // doppler frequency shift for 5.15 GHz at 100 km/h - jakes->SetAttribute ("DopplerFreq", DoubleValue (477.9)); + Config::SetDefault ("ns3::JakesProcess::DopplerFrequencyHz", DoubleValue (477.9)); Gnuplot plot = TestDeterministicByTime (jakes, Seconds (0.0001), Seconds (0.1)); plot.SetTitle ("ns3::JakesPropagationLossModel (with 477.9 Hz shift and 0.1 millisec resolution)"); diff -r e939e081efd5 -r 6b31c0c234cc src/propagation/examples/wscript --- a/src/propagation/examples/wscript Mon May 21 17:01:36 2012 +0200 +++ b/src/propagation/examples/wscript Mon May 21 17:30:22 2012 +0200 @@ -8,4 +8,9 @@ ['core', 'mobility', 'config-store', 'tools', 'propagation']) obj.source = 'main-propagation-loss.cc' + obj = bld.create_ns3_program('jakes-propagation-model-example', + ['core', 'propagation']) + obj.source = 'jakes-propagation-model-example.cc' + + diff -r e939e081efd5 -r 6b31c0c234cc src/propagation/model/jakes-process.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/propagation/model/jakes-process.cc Mon May 21 17:30:22 2012 +0200 @@ -0,0 +1,134 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2012 Telum (www.telum.ru) + * + * 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: Kirill Andreev , Alexander Sofronov + */ + +#include "jakes-process.h" +#include "ns3/random-variable.h" +#include "ns3/simulator.h" +#include "ns3/double.h" +#include "ns3/uinteger.h" + +namespace ns3 { +const double JakesProcess::PI = 3.14159265358979323846; + +/// Represents a single oscillator +JakesProcess::Oscillator::Oscillator (std::complex amplitude, double initialPhase, double omega) : + m_amplitude (amplitude), + m_phase (initialPhase), + m_omega (omega) +{} + +std::complex +JakesProcess::Oscillator::GetValueAt (Time at) const +{ + return (m_amplitude * cos (at.GetSeconds () * m_omega + m_phase)); +} + +NS_OBJECT_ENSURE_REGISTERED (JakesProcess); + +TypeId +JakesProcess::GetTypeId () +{ + static TypeId tid = TypeId ("ns3::JakesProcess") + .SetParent () + .AddConstructor () + .AddAttribute ("DopplerFrequencyHz", "Corresponding doppler frequency[Hz]", + DoubleValue (80), + MakeDoubleAccessor (&JakesProcess::SetDopplerFrequencyHz), + MakeDoubleChecker (0.0, 1e4)) + .AddAttribute ("NumberOfOscillators", "The number of oscillators", + UintegerValue (20), + MakeUintegerAccessor (&JakesProcess::SetNOscillators), + MakeUintegerChecker (4, 1000)) + ; + return tid; +} + +void +JakesProcess::SetNOscillators (unsigned int nOscillators) +{ + m_nOscillators = nOscillators; + if (m_omegaDopplerMax != 0) + { + ConstructOscillators (); + } +} + +void +JakesProcess::SetDopplerFrequencyHz (double dopplerFrequencyHz) +{ + m_omegaDopplerMax = 2 * dopplerFrequencyHz * PI; + if (m_nOscillators != 0) + { + ConstructOscillators (); + } +} + +void +JakesProcess::ConstructOscillators () +{ + // Initial phase is common for all oscillators: + double phi = UniformVariable (-PI, PI).GetValue (); + // Theta is common for all oscillatoer: + double theta = UniformVariable (-PI, PI).GetValue (); + for (unsigned int i = 0; i < m_nOscillators; i++) + { + unsigned int n = i + 1; + /// 1. Rotation speed + /// 1a. Initiate \f[ \alpha_n = \frac{2\pi n - \pi + \theta}{4M}, n=1,2, \ldots,M\f], n is oscillatorNumber, M is m_nOscillators + double alpha = (2.0 * PI * n - PI + theta) / (4.0 * m_nOscillators); + /// 1b. Initiate rotation speed: + double omega = m_omegaDopplerMax * cos (alpha); + /// 2. Initiate complex amplitude: + double psi = UniformVariable (-PI, PI).GetValue (); + std::complex amplitude = std::complex (cos (psi), sin (psi)) * 2.0 / sqrt (m_nOscillators); + /// 3. Construct oscillator: + m_oscillators.push_back (Oscillator (amplitude, phi, omega)); + } +} + +JakesProcess::JakesProcess () : + m_omegaDopplerMax (0), + m_nOscillators (0) +{} + +JakesProcess::~JakesProcess() +{ + m_oscillators.clear (); +} + +std::complex +JakesProcess::GetComplexGain () const +{ + std::complex sumAplitude = std::complex (0, 0); + for (unsigned int i = 0; i < m_oscillators.size (); i++) + { + sumAplitude += m_oscillators[i].GetValueAt (Now ()); + } + return sumAplitude; +} + +double +JakesProcess::GetChannelGainDb () const +{ + std::complex complexGain = GetComplexGain (); + return (10 * log10 ((pow (complexGain.real (), 2) + pow (complexGain.imag (), 2)) / 2)); +} + +} // namespace ns3 diff -r e939e081efd5 -r 6b31c0c234cc src/propagation/model/jakes-process.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/propagation/model/jakes-process.h Mon May 21 17:30:22 2012 +0200 @@ -0,0 +1,92 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2012 Telum (www.telum.ru) + * + * 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: Kirill Andreev , Alexander Sofronov + */ +#ifndef DOPPLER_PROCESS_H +#define DOPPLER_PROCESS_H + +#include "ns3/object.h" +#include "ns3/nstime.h" +#include + +namespace ns3 +{ +/** + * \ingroup fading + * + * \brief Implementation for a single path Stationary Jakes propagation loss model. + * + * The Jakes propagation loss model implemented here is + * described in [1]. + * + * We consider one transmitter - receiver pair and calculate + * the complex coefficients for this case as follow: + * \f[ X(t)=X_c(t) + j X_s(t)\f] + * \f[ X_c(t) = \frac{2}{\sqrt{M}}\sum_{n=1}^{M}\cos(\psi_n)\cos(\omega_d t\cos(\alpha_n)+\phi_n)\f] + * \f[ X_s(t) = \frac{2}{\sqrt{M}}\sum_{n=1}^{M}\sin(\psi_n)\cos(\omega_d t\cos(\alpha_n)+\phi_n)\f] + * with + * \f[ \alpha_n = \frac{2\pi n - \pi + \theta}{4M}, n=1,2, \ldots,M\f] + * where + *\f$\theta\f$, \f$\phi\f$, and \f$\psi_n\f$ are statically independent and uniformly distributed over \f$[-\pi, \pi)\f$ for all \f$n\f$. + * + * + * [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 JakesProcess : public Object +{ +public: + static TypeId GetTypeId (void); + JakesProcess (); + virtual ~JakesProcess(); + std::complex GetComplexGain () const; + /// Get Channel gain [dB] + double GetChannelGainDb () const; +private: + /// Represents a single oscillator + struct Oscillator + { + /// Initiate oscillator with complex amplitude, initial phase and rotation speed + Oscillator (std::complex amplitude, double initialPhase, double omega); + // Get the complex amplitude at moment \param t + std::complex GetValueAt (Time t) const; + /// Complex number \f[Re=\cos(\psi_n), Im = i\sin(\psi_n)] + std::complex m_amplitude; + /// Phase \f[\phi_n] of the oscillator + double m_phase; + /// Rotation speed of the oscillator \f[\omega_d \cos(\alpha_n)] + double m_omega; + }; + /// PI Constant + static const double PI; +private: + void SetNOscillators (unsigned int nOscillators); + void SetDopplerFrequencyHz (double dopplerFrequencyHz); + void ConstructOscillators (); +private: + /// Vector of oscillators: + std::vector m_oscillators; + ///\name Attributes: + ///\{ + double m_omegaDopplerMax; + unsigned int m_nOscillators; + ///\} +}; +} // namespace ns3 +#endif // DOPPLER_PROCESS_H diff -r e939e081efd5 -r 6b31c0c234cc src/propagation/model/jakes-propagation-loss-model.cc --- a/src/propagation/model/jakes-propagation-loss-model.cc Mon May 21 17:01:36 2012 +0200 +++ b/src/propagation/model/jakes-propagation-loss-model.cc Mon May 21 17:30:22 2012 +0200 @@ -1,9 +1,9 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2005,2006,2007 INRIA + * Copyright (c) 2012 Telum (www.telum.ru) * * 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 + * 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, @@ -15,246 +15,37 @@ * 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 + * Author: Kirill Andreev */ -#include "ns3/simulator.h" -#include "ns3/uinteger.h" -#include "ns3/double.h" -#include "ns3/random-variable.h" -#include "ns3/mobility-model.h" -#include "ns3/log.h" #include "jakes-propagation-loss-model.h" -#include -NS_LOG_COMPONENT_DEFINE ("Jakes"); - -namespace ns3 { - +namespace ns3 +{ NS_OBJECT_ENSURE_REGISTERED (JakesPropagationLossModel); -class JakesPropagationLossModel::PathCoefficients -{ -public: - PathCoefficients (Ptr jakes, - Ptr receiver, - uint8_t nRays, - uint8_t nOscillators); - ~PathCoefficients (); - double GetLoss (Ptr jakes); - Ptr GetReceiver (void); -private: - void DoConstruct (Ptr jakes); - Ptr m_receiver; - uint8_t m_nOscillators; - uint8_t m_nRays; - double **m_phases; - Time m_lastUpdate; -}; - - -JakesPropagationLossModel::PathCoefficients::PathCoefficients (Ptr jakes, - Ptr receiver, - uint8_t nRays, - uint8_t nOscillators) - : m_receiver (receiver), - m_nOscillators (nOscillators), - m_nRays (nRays) -{ - DoConstruct (jakes); -} - -JakesPropagationLossModel::PathCoefficients::~PathCoefficients () -{ - for (uint8_t i = 0; i < m_nRays; i++) - { - delete [] m_phases[i]; - } - delete [] m_phases; -} +JakesPropagationLossModel::JakesPropagationLossModel() +{} -void -JakesPropagationLossModel::PathCoefficients::DoConstruct (Ptr jakes) -{ - 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 * jakes->m_variable.GetValue (); - } - } - m_lastUpdate = Simulator::Now (); -} - -Ptr -JakesPropagationLossModel::PathCoefficients::GetReceiver () -{ - return m_receiver; -} - -double -JakesPropagationLossModel::PathCoefficients::GetLoss (Ptr jakes) -{ - 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) * jakes->m_fd * interval.GetSeconds (); - m_phases[i][j] -= 2.0 * JakesPropagationLossModel::PI * - floor (m_phases[i][j] / 2.0 / JakesPropagationLossModel::PI); - fading.real += jakes->m_amp[j].real * cos (m_phases[i][j]); - fading.imag += jakes->m_amp[j].imag * cos (m_phases[i][j]); - norm += sqrt (pow (jakes->m_amp[j].real, 2) + pow (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); -} - -const double JakesPropagationLossModel::PI = 3.14159265358979323846; +JakesPropagationLossModel::~JakesPropagationLossModel() +{} TypeId -JakesPropagationLossModel::GetTypeId (void) +JakesPropagationLossModel::GetTypeId () { 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)", - UintegerValue (1), - MakeUintegerAccessor (&JakesPropagationLossModel::SetNRays, - &JakesPropagationLossModel::GetNRays), - 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)", - UintegerValue (4), - MakeUintegerAccessor (&JakesPropagationLossModel::SetNOscillators, - &JakesPropagationLossModel::GetNOscillators), - MakeUintegerChecker ()) - .AddAttribute ("DopplerFreq", - "The doppler frequency in Hz (f_d = v / lambda = v * f / c), the default is 0)", - DoubleValue (0.0), - MakeDoubleAccessor (&JakesPropagationLossModel::m_fd), - MakeDoubleChecker ()) - .AddAttribute ("Distribution", - "The distribution to choose the initial phases.", - RandomVariableValue (ConstantVariable (1.0)), - MakeRandomVariableAccessor (&JakesPropagationLossModel::m_variable), - MakeRandomVariableChecker ()) ; return tid; } -JakesPropagationLossModel::JakesPropagationLossModel () - : m_amp (0), - m_nRays (0), - m_nOscillators (0) -{ -} - -JakesPropagationLossModel::~JakesPropagationLossModel () -{ - delete [] m_amp; - for (PathsList::reverse_iterator i = m_paths.rbegin (); i != m_paths.rend (); i++) - { - PathsSet *ps = *i; - for (DestinationList::iterator r = ps->receivers.begin (); r != ps->receivers.end (); r++) - { - PathCoefficients *pc = *r; - delete pc; - } - ps->sender = 0; - ps->receivers.clear (); - delete ps; - } - m_paths.clear (); -} - -void -JakesPropagationLossModel::SetNRays (uint8_t nRays) -{ - m_nRays = nRays; -} - -void -JakesPropagationLossModel::SetNOscillators (uint8_t nOscillators) -{ - m_nOscillators = nOscillators; - delete [] m_amp; - 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); - } -} - -uint8_t -JakesPropagationLossModel::GetNRays (void) const -{ - return m_nRays; -} -uint8_t -JakesPropagationLossModel::GetNOscillators (void) const -{ - return m_nOscillators; -} - - -double +double JakesPropagationLossModel::DoCalcRxPower (double txPowerDbm, Ptr a, Ptr b) const { - PathsList::iterator i = m_paths.end (); - while (i != m_paths.begin ()) - { - i--; - PathsSet *ps = *i; - if (ps->sender == 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 (pc->GetReceiver () == b) - { - ps->receivers.erase (r); - ps->receivers.push_back (pc); - return txPowerDbm + pc->GetLoss (this); - } - } - PathCoefficients *pc = new PathCoefficients (this, b, m_nRays, m_nOscillators); - ps->receivers.push_back (pc); - return txPowerDbm + pc->GetLoss (this); - } - } - 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 txPowerDbm + pc->GetLoss (this); + return txPowerDbm + m_propagationCache.GetPathData (a, b, 0 /**Spectrum model uid is not used in PropagationLossModel*/)->GetChannelGainDb (); } } // namespace ns3 diff -r e939e081efd5 -r 6b31c0c234cc src/propagation/model/jakes-propagation-loss-model.h --- a/src/propagation/model/jakes-propagation-loss-model.h Mon May 21 17:01:36 2012 +0200 +++ b/src/propagation/model/jakes-propagation-loss-model.h Mon May 21 17:30:22 2012 +0200 @@ -1,9 +1,9 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2005,2006,2007 INRIA + * Copyright (c) 2012 Telum (www.telum.ru) * * 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 + * 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, @@ -15,125 +15,41 @@ * 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 + * Author: Kirill Andreev */ -#ifndef PROPAGATION_JAKES_MODEL_H -#define PROPAGATION_JAKES_MODEL_H +#ifndef JAKES_STATIONARY_LOSS_MODEL_H +#define JAKES_STATIONARY_LOSS_MODEL_H -#include "ns3/nstime.h" -#include "propagation-loss-model.h" +#include "ns3/propagation-loss-model.h" +#include "ns3/propagation-cache.h" +#include "ns3/jakes-process.h" -namespace ns3 { - - +namespace ns3 +{ /** * \ingroup propagation * - * \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 + * \brief a jakes narrowband propagation model. + * Symmetrical cache for JakesProcess */ + class JakesPropagationLossModel : public PropagationLossModel { public: - static TypeId GetTypeId (void); + static TypeId GetTypeId (); JakesPropagationLossModel (); virtual ~JakesPropagationLossModel (); - /** - * \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); - - uint8_t GetNRays (void) const; - uint8_t GetNOscillators (void) const; +private: + double DoCalcRxPower (double txPowerDbm, + Ptr a, + Ptr b) const; private: - JakesPropagationLossModel (const JakesPropagationLossModel &o); - JakesPropagationLossModel & operator = (const JakesPropagationLossModel &o); - void DoConstruct (void); - virtual double DoCalcRxPower (double txPowerDbm, - Ptr a, - Ptr b) const; - - class PathCoefficients; - struct ComplexNumber { - double real; - double imag; - }; - friend class PathCoefficents; - typedef std::vector DestinationList; - struct PathsSet { - Ptr sender; - DestinationList receivers; - }; - typedef std::vector PathsList; - - - static const double PI; - ComplexNumber* m_amp; - RandomVariable m_variable; - double m_fd; - mutable PathsList m_paths; - uint8_t m_nRays; - uint8_t m_nOscillators; + mutable PropagationCache m_propagationCache; }; } // namespace ns3 -#endif /* PROPAGATION_JAKES_MODEL_H */ +#endif /* JAKES_STATIONARY_LOSS_MODEL_H */ - diff -r e939e081efd5 -r 6b31c0c234cc src/propagation/model/propagation-cache.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/propagation/model/propagation-cache.h Mon May 21 17:30:22 2012 +0200 @@ -0,0 +1,86 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2012 Telum (www.telum.ru) + * + * 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: Kirill Andreev + */ +#ifndef PROPAGATION_CACHE_H_ +#define PROPAGATION_CACHE_H_ + +#include "ns3/mobility-model.h" +#include + +namespace ns3 +{ +/** + * \ingroup propagation + * \brief Constructs a cache of objects, where each obect is responsible for a single propagation path loss calculations. + * Propagation path a-->b and b-->a is the same thing. Propagation path is identified by + * a couple of MobilityModels and a spectrum model UID + */ +template +class PropagationCache +{ +public: + PropagationCache () {}; + ~PropagationCache () {}; + Ptr GetPathData (Ptr a, Ptr b, uint32_t modelUid) + { + PropagationPathIdentifier key = PropagationPathIdentifier (a, b, modelUid); + typename PathCache::iterator it = m_pathCache.find (key); + if (it == m_pathCache.end ()) + { + Ptr newPath = CreateObject (); + m_pathCache.insert (std::make_pair (key, newPath)); + return newPath; + } + return it->second; + }; +private: + /// Each path is identified by + struct PropagationPathIdentifier + { + PropagationPathIdentifier (Ptr a, Ptr b, uint32_t modelUid) : + m_srcMobility (a), m_dstMobility (b), m_spectrumModelUid (modelUid) + {}; + Ptr m_srcMobility; + Ptr m_dstMobility; + uint32_t m_spectrumModelUid; + bool operator < (const PropagationPathIdentifier & other) const + { + if (m_spectrumModelUid != other.m_spectrumModelUid) + { + return m_spectrumModelUid < other.m_spectrumModelUid; + } + /// Links are supposed to be symmetrical! + if (std::min (m_dstMobility, m_srcMobility) != std::min (other.m_dstMobility, other.m_srcMobility)) + { + return std::min (m_dstMobility, m_srcMobility) < std::min (other.m_dstMobility, other.m_srcMobility); + } + if (std::max (m_dstMobility, m_srcMobility) != std::max (other.m_dstMobility, other.m_srcMobility)) + { + return std::max (m_dstMobility, m_srcMobility) < std::max (other.m_dstMobility, other.m_srcMobility); + } + return false; + } + }; + typedef std::map > PathCache; +private: + PathCache m_pathCache; +}; +} // namespace ns3 + +#endif // PROPAGATION_CACHE_H_ diff -r e939e081efd5 -r 6b31c0c234cc src/propagation/wscript --- a/src/propagation/wscript Mon May 21 17:01:36 2012 +0200 +++ b/src/propagation/wscript Mon May 21 17:30:22 2012 +0200 @@ -7,6 +7,7 @@ 'model/propagation-delay-model.cc', 'model/propagation-loss-model.cc', 'model/jakes-propagation-loss-model.cc', + 'model/jakes-process.cc', 'model/cost231-propagation-loss-model.cc', 'model/okumura-hata-propagation-loss-model.cc', 'model/itu-r-1411-los-propagation-loss-model.cc', @@ -29,6 +30,8 @@ 'model/propagation-delay-model.h', 'model/propagation-loss-model.h', 'model/jakes-propagation-loss-model.h', + 'model/jakes-process.h', + 'model/propagation-cache.h', 'model/cost231-propagation-loss-model.h', 'model/propagation-environment.h', 'model/okumura-hata-propagation-loss-model.h',