Composite and Jakes propagation loss models.

This commit is contained in:
src/devices/wifi/Federico Maguolo
2008-03-21 04:51:36 +01:00
parent 73ea5d6192
commit c9785a0ef0
5 changed files with 512 additions and 0 deletions

View File

@@ -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 <maguolof@dei.unipd.it>
*/
#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 <math.h>
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (CompositePropagationLossModel);
TypeId
CompositePropagationLossModel::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::CompositePropagationLossModel")
.SetParent<PropagationLossModel> ()
.AddConstructor<CompositePropagationLossModel> ()
;
return tid;
}
CompositePropagationLossModel::CompositePropagationLossModel ()
{
AddDefaults ();
}
CompositePropagationLossModel::~CompositePropagationLossModel ()
{}
void
CompositePropagationLossModel::AddDefaults ()
{}
void
CompositePropagationLossModel::AddPropagationLossModel (Ptr<PropagationLossModel> pl)
{
m_propagationModels.push_back (pl);
}
double
CompositePropagationLossModel::GetLoss (Ptr<MobilityModel> a,
Ptr<MobilityModel> 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

View File

@@ -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 <maguolof@dei.unipd.it>
*/
#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<MobilityModel> a,
Ptr<MobilityModel> b) const;
/**
* \param pl the propagation loss model to add
*
* Insert a propagation loss model to the composite.
*/
void AddPropagationLossModel (Ptr<PropagationLossModel> pl);
protected:
virtual void AddDefaults (void);
private:
typedef std::vector<Ptr<PropagationLossModel> > PropagationModelList;
PropagationModelList m_propagationModels;
};
} // namespace ns3
#endif /* PROPAGATION_COMP_MODEL_H */

View File

@@ -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 <maguolof@dei.unipd.it>
*/
#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 <math.h>
NS_LOG_COMPONENT_DEFINE ("Jakes");
namespace ns3 {
class JakesPropagationLossModel::PathCoefficients {
public:
PathCoefficients (Ptr<const JakesPropagationLossModel> jakes,
Ptr<MobilityModel> receiver,
uint8_t nRays,
uint8_t nOscillators);
~PathCoefficients ();
double GetLoss (void);
Ptr<MobilityModel> GetReceiver (void);
private:
void DoConstruct (void);
Ptr<MobilityModel> m_receiver;
uint8_t m_nOscillators;
uint8_t m_nRays;
double **m_phases;
Time m_lastUpdate;
Ptr<const JakesPropagationLossModel> m_jakes;
};
JakesPropagationLossModel::PathCoefficients::PathCoefficients (Ptr<const JakesPropagationLossModel> jakes,
Ptr<MobilityModel> 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<MobilityModel>
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<PropagationLossModel> ()
.AddConstructor<JakesPropagationLossModel> ()
.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<uint8_t> ())
.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<uint8_t> ())
.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<double> ())
.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<MobilityModel> a,
Ptr<MobilityModel> 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

View File

@@ -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 <maguolof@dei.unipd.it>
*/
#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<MobilityModel> a,
Ptr<MobilityModel> 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<PathCoefficients *> DestinationList;
struct PathsSet {
Ptr<MobilityModel> sender;
DestinationList receivers;
};
typedef std::vector<PathsSet *> PathsList;
void DoConstruct (void);
mutable PathsList m_paths;
uint8_t m_nRays;
uint8_t m_nOscillators;
};
} // namespace ns3
#endif /* PROPAGATION_JAKES_MODEL_H */

View File

@@ -5,6 +5,8 @@ def build(bld):
obj.source = [
'propagation-delay-model.cc',
'propagation-loss-model.cc',
'composite-propagation-loss-model.cc',
'jakes-propagation-loss-model.cc',
'wifi-channel.cc',
'wifi-mode.cc',
'ssid.cc',
@@ -43,6 +45,8 @@ def build(bld):
headers.source = [
'propagation-delay-model.h',
'propagation-loss-model.h',
'composite-propagation-loss-model.h',
'jakes-propagation-loss-model.h',
'wifi-net-device.h',
'wifi-channel.h',
'wifi-mode.h',