PropagationLossModel::GetLoss -> CalcRxPower. Add ThreeLogDistancePropagationLossModel.
/* -*- 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Contributions: Timo Bingmann <timo.bingmann@student.kit.edu>
*/
#include "propagation-loss-model.h"
#include "ns3/log.h"
#include "ns3/mobility-model.h"
#include "ns3/static-mobility-model.h"
#include "ns3/boolean.h"
#include "ns3/double.h"
#include <math.h>
NS_LOG_COMPONENT_DEFINE ("PropagationLossModel");
namespace ns3 {
// ------------------------------------------------------------------------- //
NS_OBJECT_ENSURE_REGISTERED (PropagationLossModel);
TypeId
PropagationLossModel::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::PropagationLossModel")
.SetParent<Object> ()
;
return tid;
}
PropagationLossModel::PropagationLossModel ()
: m_next (0)
{}
PropagationLossModel::~PropagationLossModel ()
{}
void
PropagationLossModel::SetNext (Ptr<PropagationLossModel> next)
{
m_next = next;
}
double
PropagationLossModel::CalcRxPower (double txPowerDbm,
Ptr<MobilityModel> a,
Ptr<MobilityModel> b) const
{
double self = DoCalcRxPower (txPowerDbm, a, b);
if (m_next != 0)
{
self = m_next->CalcRxPower (self, a, b);
}
return self;
}
// ------------------------------------------------------------------------- //
NS_OBJECT_ENSURE_REGISTERED (RandomPropagationLossModel);
TypeId
RandomPropagationLossModel::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::RandomPropagationLossModel")
.SetParent<PropagationLossModel> ()
.AddConstructor<RandomPropagationLossModel> ()
.AddAttribute ("Variable", "The random variable used to pick a loss everytime CalcRxPower is invoked.",
RandomVariableValue (ConstantVariable (1.0)),
MakeRandomVariableAccessor (&RandomPropagationLossModel::m_variable),
MakeRandomVariableChecker ())
;
return tid;
}
RandomPropagationLossModel::RandomPropagationLossModel ()
: PropagationLossModel ()
{}
RandomPropagationLossModel::~RandomPropagationLossModel ()
{}
double
RandomPropagationLossModel::DoCalcRxPower (double txPowerDbm,
Ptr<MobilityModel> a,
Ptr<MobilityModel> b) const
{
double rxc = -m_variable.GetValue ();
NS_LOG_DEBUG ("attenuation coefficent="<<rxc<<"Db");
return txPowerDbm + rxc;
}
// ------------------------------------------------------------------------- //
NS_OBJECT_ENSURE_REGISTERED (FriisPropagationLossModel);
const double FriisPropagationLossModel::PI = 3.1415;
TypeId
FriisPropagationLossModel::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::FriisPropagationLossModel")
.SetParent<PropagationLossModel> ()
.AddConstructor<FriisPropagationLossModel> ()
.AddAttribute ("Lambda",
"The wavelength (default is 5.15 GHz at 300 000 km/s).",
DoubleValue (300000000.0 / 5.150e9),
MakeDoubleAccessor (&FriisPropagationLossModel::m_lambda),
MakeDoubleChecker<double> ())
.AddAttribute ("SystemLoss", "The system loss",
DoubleValue (1.0),
MakeDoubleAccessor (&FriisPropagationLossModel::m_systemLoss),
MakeDoubleChecker<double> ())
.AddAttribute ("MinDistance",
"The distance under which the propagation model refuses to give results (m)",
DoubleValue (0.5),
MakeDoubleAccessor (&FriisPropagationLossModel::SetMinDistance,
&FriisPropagationLossModel::GetMinDistance),
MakeDoubleChecker<double> ())
;
return tid;
}
FriisPropagationLossModel::FriisPropagationLossModel ()
{}
void
FriisPropagationLossModel::SetSystemLoss (double systemLoss)
{
m_systemLoss = systemLoss;
}
double
FriisPropagationLossModel::GetSystemLoss (void) const
{
return m_systemLoss;
}
void
FriisPropagationLossModel::SetMinDistance (double minDistance)
{
m_minDistance = minDistance;
}
double
FriisPropagationLossModel::GetMinDistance (void) const
{
return m_minDistance;
}
void
FriisPropagationLossModel::SetLambda (double frequency, double speed)
{
m_lambda = speed / frequency;
}
void
FriisPropagationLossModel::SetLambda (double lambda)
{
m_lambda = lambda;
}
double
FriisPropagationLossModel::GetLambda (void) const
{
return m_lambda;
}
double
FriisPropagationLossModel::DbmToW (double dbm) const
{
double mw = pow(10.0,dbm/10.0);
return mw / 1000.0;
}
double
FriisPropagationLossModel::DbmFromW (double w) const
{
double dbm = log10 (w * 1000.0) * 10.0;
return dbm;
}
double
FriisPropagationLossModel::DoCalcRxPower (double txPowerDbm,
Ptr<MobilityModel> a,
Ptr<MobilityModel> b) const
{
/*
* Friis free space equation:
* where Pt, Gr, Gr and P are in Watt units
* L is in meter units.
*
* P Gt * Gr * (lambda^2)
* --- = ---------------------
* Pt (4 * pi * d)^2 * L
*
* Gt: tx gain (unit-less)
* Gr: rx gain (unit-less)
* Pt: tx power (W)
* d: distance (m)
* L: system loss
* lambda: wavelength (m)
*
* Here, we ignore tx and rx gain and the input and output values
* are in dB or dBm:
*
* lambda^2
* rx = tx + 10 log10 (-------------------)
* (4 * pi * d)^2 * L
*
* rx: rx power (dB)
* tx: tx power (dB)
* d: distance (m)
* L: system loss (unit-less)
* lambda: wavelength (m)
*/
double distance = a->GetDistanceFrom (b);
if (distance <= m_minDistance)
{
return txPowerDbm;
}
double numerator = m_lambda * m_lambda;
double denominator = 16 * PI * PI * distance * distance * m_systemLoss;
double pr = 10 * log10 (numerator / denominator);
NS_LOG_DEBUG ("distance="<<distance<<"m, attenuation coefficient="<<pr<<"dB");
return txPowerDbm + pr;
}
// ------------------------------------------------------------------------- //
NS_OBJECT_ENSURE_REGISTERED (LogDistancePropagationLossModel);
TypeId
LogDistancePropagationLossModel::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::LogDistancePropagationLossModel")
.SetParent<PropagationLossModel> ()
.AddConstructor<LogDistancePropagationLossModel> ()
.AddAttribute ("Exponent",
"The exponent of the Path Loss propagation model",
DoubleValue (3.0),
MakeDoubleAccessor (&LogDistancePropagationLossModel::m_exponent),
MakeDoubleChecker<double> ())
.AddAttribute ("ReferenceDistance",
"The distance at which the reference loss is calculated (m)",
DoubleValue (1.0),
MakeDoubleAccessor (&LogDistancePropagationLossModel::m_referenceDistance),
MakeDoubleChecker<double> ())
.AddAttribute ("ReferenceLoss",
"The reference loss at reference distance (dB). (Default is Friis at 1m with 5.15 GHz)",
DoubleValue (46.6777),
MakeDoubleAccessor (&LogDistancePropagationLossModel::m_referenceLoss),
MakeDoubleChecker<double> ())
;
return tid;
}
LogDistancePropagationLossModel::LogDistancePropagationLossModel ()
{}
void
LogDistancePropagationLossModel::SetPathLossExponent (double n)
{
m_exponent = n;
}
void
LogDistancePropagationLossModel::SetReference (double referenceDistance, double referenceLoss)
{
m_referenceDistance = referenceDistance;
m_referenceLoss = referenceLoss;
}
double
LogDistancePropagationLossModel::GetPathLossExponent (void) const
{
return m_exponent;
}
double
LogDistancePropagationLossModel::DoCalcRxPower (double txPowerDbm,
Ptr<MobilityModel> a,
Ptr<MobilityModel> b) const
{
double distance = a->GetDistanceFrom (b);
if (distance <= m_referenceDistance)
{
return txPowerDbm;
}
/**
* The formula is:
* rx = 10 * log (Pr0(tx)) - n * 10 * log (d/d0)
*
* Pr0: rx power at reference distance d0 (W)
* d0: reference distance: 1.0 (m)
* d: distance (m)
* tx: tx power (dB)
* rx: dB
*
* Which, in our case is:
*
* rx = rx0(tx) - 10 * n * log (d/d0)
*/
double pathLossDb = 10 * m_exponent * log10 (distance / m_referenceDistance);
double rxc = -m_referenceLoss - pathLossDb;
NS_LOG_DEBUG ("distance="<<distance<<"m, reference-attenuation="<<-m_referenceLoss<<"dB, "<<
"attenuation coefficient="<<rxc<<"db");
return txPowerDbm + rxc;
}
// ------------------------------------------------------------------------- //
NS_OBJECT_ENSURE_REGISTERED (ThreeLogDistancePropagationLossModel);
TypeId
ThreeLogDistancePropagationLossModel::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::ThreeLogDistancePropagationLossModel")
.SetParent<PropagationLossModel> ()
.AddConstructor<ThreeLogDistancePropagationLossModel> ()
.AddAttribute ("Distance0",
"Beginning of the first (near) distance field",
DoubleValue (1.0),
MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_distance0),
MakeDoubleChecker<double> ())
.AddAttribute ("Distance1",
"Beginning of the second (middle) distance field.",
DoubleValue (200.0),
MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_distance1),
MakeDoubleChecker<double> ())
.AddAttribute ("Distance2",
"Beginning of the third (far) distance field.",
DoubleValue (500.0),
MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_distance2),
MakeDoubleChecker<double> ())
.AddAttribute ("Exponent0",
"The exponent for the first field.",
DoubleValue (1.9),
MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_exponent0),
MakeDoubleChecker<double> ())
.AddAttribute ("Exponent1",
"The exponent for the second field.",
DoubleValue (3.8),
MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_exponent1),
MakeDoubleChecker<double> ())
.AddAttribute ("Exponent2",
"The exponent for the third field.",
DoubleValue (3.8),
MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_exponent2),
MakeDoubleChecker<double> ())
.AddAttribute ("ReferenceLoss",
"The reference loss at distance d0 (dB). (Default is Friis at 1m with 5.15 GHz)",
DoubleValue (46.6777),
MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_referenceLoss),
MakeDoubleChecker<double> ())
;
return tid;
}
ThreeLogDistancePropagationLossModel::ThreeLogDistancePropagationLossModel ()
{
}
double
ThreeLogDistancePropagationLossModel::DoCalcRxPower (double txPowerDbm,
Ptr<MobilityModel> a,
Ptr<MobilityModel> b) const
{
double distance = a->GetDistanceFrom (b);
NS_ASSERT(distance >= 0);
// See doxygen comments for the formula and explanation
double pathLossDb;
if (distance < m_distance0)
{
pathLossDb = 0;
}
else if (distance < m_distance1)
{
pathLossDb = m_referenceLoss
+ 10 * m_exponent0 * log10(distance / m_distance0);
}
else if (distance < m_distance2)
{
pathLossDb = m_referenceLoss
+ 10 * m_exponent0 * log10(m_distance1 / m_distance0)
+ 10 * m_exponent1 * log10(distance / m_distance1);
}
else
{
pathLossDb = m_referenceLoss
+ 10 * m_exponent0 * log10(m_distance1 / m_distance0)
+ 10 * m_exponent1 * log10(m_distance2 / m_distance1)
+ 10 * m_exponent2 * log10(distance / m_distance2);
}
NS_LOG_DEBUG ("ThreeLogDistance distance=" << distance << "m, " <<
"attenuation=" << pathLossDb << "dB");
return txPowerDbm - pathLossDb;
}
} // namespace ns3