merge ns-3-antenna with ns-3-lena-dev

This commit is contained in:
Nicola Baldo
2012-03-19 17:43:38 +01:00
7 changed files with 429 additions and 2 deletions

View File

@@ -88,6 +88,23 @@ practice alter the effective beamwidth of the resulting radiation
pattern.
ParabolicAntennaModel
+++++++++++++++++++++
This model is based on the parabolic approximation of the main lobe radiation pattern. It is often used in the context of cellular system to model the radiation pattern of a cell sector, see for instance [R4-092042]_ and [Calcev]_. The antenna gain in dB is determined as:
.. math::
g_{dB}(\phi, \theta) = -\min \left( 12 \left(\frac{\phi - \phi_{0}}{\phi_{3dB}} \right)^2, A_{max} \right)
where :math:`\phi_{0}` is the azimuthal orientation of the antenna
(i.e., its direction of maximum gain), :math:`\phi_{3dB}` is its 3 dB
beamwidth, and :math:`A_{max}` is the maximum attenuation in dB of the
antenna.
References
++++++++++
@@ -96,3 +113,13 @@ References
.. [Chunjian] Li Chunjian, "Efficient Antenna Patterns for
Three-Sector WCDMA Systems", Master of Science Thesis, Chalmers
University of Technology, Göteborg, Sweden, 2003
.. [Calcev] George Calcev and Matt Dillon, "Antenna Tilt Control in
CDMA Networks", in Proc. of the 2nd Annual International Wireless
Internet Conference (WICON), 2006
.. [R4-092042] 3GPP TSG RAN WG4 (Radio) Meeting #51, R4-092042, Simulation
assumptions and parameters for FDD HeNB RF requirements.

View File

@@ -54,6 +54,20 @@ values.
ParabolicAntennaModel
------------------
The unit test suite ``parabolic-antenna-model`` checks that the
``ParabolicAntennaModel`` class works properly. Several test cases are
provided that check for the antenna gain value calculated at different
directions and for different values of the orientation, the maximum attenuation
and the beamwidth. The reference gain is calculated by hand. Each
test case passes if the reference gain in dB is equal to the value returned
by ``ParabolicAntennaModel`` within a tolerance of 0.001, which accounts
for the approximation done for the calculation of the reference
values.

View File

@@ -31,7 +31,7 @@ namespace ns3 {
*
* \brief Cosine Antenna Model
*
* This class implements the cosine model as described in [1]
* This class implements the cosine model as described in:
*
* Li Chunjian, "Efficient Antenna Patterns for Three-Sector WCDMA Systems"
*
@@ -60,7 +60,7 @@ public:
private:
/**
* this is the variable "n" in [1]
* this is the variable "n" in the paper by Chunjian
*
*/
double m_exponent;

View File

@@ -0,0 +1,117 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2012 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/log.h>
#include <ns3/double.h>
#include <math.h>
#include "antenna-model.h"
#include "parabolic-antenna-model.h"
NS_LOG_COMPONENT_DEFINE ("ParabolicAntennaModel");
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (ParabolicAntennaModel);
TypeId
ParabolicAntennaModel::GetTypeId ()
{
static TypeId tid = TypeId ("ns3::ParabolicAntennaModel")
.SetParent<AntennaModel> ()
.AddConstructor<ParabolicAntennaModel> ()
.AddAttribute ("Beamwidth",
"The 3dB beamwidth (degrees)",
DoubleValue (60),
MakeDoubleAccessor (&ParabolicAntennaModel::SetBeamwidth,
&ParabolicAntennaModel::GetBeamwidth),
MakeDoubleChecker<double> (0, 180))
.AddAttribute ("Orientation",
"The angle (degrees) that expresses the orientation of the antenna on the x-y plane relative to the x axis",
DoubleValue (0.0),
MakeDoubleAccessor (&ParabolicAntennaModel::SetOrientation,
&ParabolicAntennaModel::GetOrientation),
MakeDoubleChecker<double> (-360, 360))
.AddAttribute ("MaxAttenuation",
"The maximum attenuation (dB) of the antenna radiation pattern.",
DoubleValue (20.0),
MakeDoubleAccessor (&ParabolicAntennaModel::m_maxAttenuation),
MakeDoubleChecker<double> ())
;
return tid;
}
void
ParabolicAntennaModel::SetBeamwidth (double beamwidthDegrees)
{
NS_LOG_FUNCTION (this << beamwidthDegrees);
m_beamwidthRadians = DegreesToRadians (beamwidthDegrees);
}
double
ParabolicAntennaModel::GetBeamwidth () const
{
return RadiansToDegrees (m_beamwidthRadians);
}
void
ParabolicAntennaModel::SetOrientation (double orientationDegrees)
{
NS_LOG_FUNCTION (this << orientationDegrees);
m_orientationRadians = DegreesToRadians (orientationDegrees);
}
double
ParabolicAntennaModel::GetOrientation () const
{
return RadiansToDegrees (m_orientationRadians);
}
double
ParabolicAntennaModel::GetGainDb (Angles a)
{
NS_LOG_FUNCTION (this << a);
// azimuth angle w.r.t. the reference system of the antenna
double phi = a.phi - m_orientationRadians;
// make sure phi is in (-pi, pi]
while (phi <= -M_PI)
{
phi += M_PI+M_PI;
}
while (phi > M_PI)
{
phi -= M_PI+M_PI;
}
NS_LOG_LOGIC ("phi = " << phi );
double gainDb = -std::min (12 * pow (phi / m_beamwidthRadians, 2), m_maxAttenuation);
NS_LOG_LOGIC ("gain = " << gainDb);
return gainDb;
}
}

View File

@@ -0,0 +1,76 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2012 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>
*/
#ifndef PARABOLIC_ANTENNA_MODEL_H
#define PARABOLIC_ANTENNA_MODEL_H
#include <ns3/object.h>
#include <ns3/antenna-model.h>
namespace ns3 {
/**
*
* \brief Antenna model based on a parabolic approximation of the main lobe radiation pattern.
*
* This class implements the parabolic model as described in some 3GPP document, e.g., R4-092042
*
* A similar model appears in
*
* George Calcev and Matt Dillon, "Antenna Tilt Control in CDMA Networks"
* in Proc. of the 2nd Annual International Wireless Internet Conference (WICON), 2006
*
* though the latter addresses also the elevation plane, which the present model doesn't.
*
*
*/
class ParabolicAntennaModel : public AntennaModel
{
public:
// inherited from Object
static TypeId GetTypeId ();
// inherited from AntennaModel
virtual double GetGainDb (Angles a);
// attribute getters/setters
void SetBeamwidth (double beamwidthDegrees);
double GetBeamwidth () const;
void SetOrientation (double orientationDegrees);
double GetOrientation () const;
private:
double m_beamwidthRadians;
double m_orientationRadians;
double m_maxAttenuation;
};
} // namespace ns3
#endif // PARABOLIC_ANTENNA_MODEL_H

View File

@@ -0,0 +1,190 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011,12 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/log.h>
#include <ns3/test.h>
#include <ns3/double.h>
#include <ns3/parabolic-antenna-model.h>
#include <ns3/simulator.h>
#include <math.h>
#include <string>
#include <iostream>
#include <sstream>
NS_LOG_COMPONENT_DEFINE ("TestParabolicAntennaModel");
namespace ns3 {
enum ParabolicAntennaModelGainTestCondition {
EQUAL = 0,
LESSTHAN = 1
};
class ParabolicAntennaModelTestCase : public TestCase
{
public:
static std::string BuildNameString (Angles a, double b, double o, double g);
ParabolicAntennaModelTestCase (Angles a, double b, double o, double g, double expectedGainDb, ParabolicAntennaModelGainTestCondition cond);
private:
virtual void DoRun (void);
Angles m_a;
double m_b;
double m_o;
double m_g;
double m_expectedGain;
ParabolicAntennaModelGainTestCondition m_cond;
};
std::string ParabolicAntennaModelTestCase::BuildNameString (Angles a, double b, double o, double g)
{
std::ostringstream oss;
oss << "theta=" << a.theta << " , phi=" << a.phi
<< ", beamdwidth=" << b << "deg"
<< ", orientation=" << o
<< ", maxAttenuation=" << g << " dB";
return oss.str ();
}
ParabolicAntennaModelTestCase::ParabolicAntennaModelTestCase (Angles a, double b, double o, double g, double expectedGainDb, ParabolicAntennaModelGainTestCondition cond)
: TestCase (BuildNameString (a, b, o, g)),
m_a (a),
m_b (b),
m_o (o),
m_g (g),
m_expectedGain (expectedGainDb),
m_cond (cond)
{
}
void
ParabolicAntennaModelTestCase::DoRun ()
{
NS_LOG_FUNCTION (this << BuildNameString (m_a, m_b, m_o, m_g));
Ptr<ParabolicAntennaModel> a = CreateObject<ParabolicAntennaModel> ();
a->SetAttribute ("Beamwidth", DoubleValue (m_b));
a->SetAttribute ("Orientation", DoubleValue (m_o));
a->SetAttribute ("MaxAttenuation", DoubleValue (m_g));
double actualGain = a->GetGainDb (m_a);
switch (m_cond)
{
case EQUAL:
NS_TEST_EXPECT_MSG_EQ_TOL (actualGain, m_expectedGain, 0.001, "wrong value of the radiation pattern");
break;
case LESSTHAN:
NS_TEST_EXPECT_MSG_LT (actualGain, m_expectedGain, "gain higher than expected");
break;
default:
break;
}
}
class ParabolicAntennaModelTestSuite : public TestSuite
{
public:
ParabolicAntennaModelTestSuite ();
};
ParabolicAntennaModelTestSuite::ParabolicAntennaModelTestSuite ()
: TestSuite ("parabolic-antenna-model", UNIT)
{
// with a 60 deg beamwidth, gain is -20dB at +-77.460 degrees from boresight
// phi, theta, beamwidth, orientation, maxAttn, expectedGain, condition
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (0), 0), 60, 0, 20, 0, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (30), 0), 60, 0, 20, -3, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-30), 0), 60, 0, 20, -3, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-90), 0), 60, 0, 20, -20, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (90), 0), 60, 0, 20, -20, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (100), 0), 60, 0, 20, -20, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (150), 0), 60, 0, 20, -20, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (180), 0), 60, 0, 20, -20, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-100), 0), 60, 0, 20, -20, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-150), 0), 60, 0, 20, -20, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-180), 0), 60, 0, 20, -20, EQUAL));
// with a 60 deg beamwidth, gain is -10dB at +-54.772 degrees from boresight
// test positive orientation
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (60), 0), 60, 60, 10, 0, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (90), 0), 60, 60, 10, -3, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (30), 0), 60, 60, 10, -3, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-30), 0), 60, 60, 10, -10, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (150), 0), 60, 60, 10, -10, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (160), 0), 60, 60, 10, -10, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (210), 0), 60, 60, 10, -10, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (240), 0), 60, 60, 10, -10, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-40), 0), 60, 60, 10, -10, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-90), 0), 60, 60, 10, -10, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-120), 0), 60, 60, 10, -10, EQUAL));
// test negative orientation and different beamwidths
// with a 80 deg beamwidth, gain is -20dB at +- 73.030 degrees from boresight
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-150), 0), 80, -150, 10, 0, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-110), 0), 80, -150, 10, -3, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-190), 0), 80, -150, 10, -3, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-70), 0), 80, -150, 10, -10, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (92), 0), 80, -150, 10, -10, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-30), 0), 80, -150, 10, -10, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (0), 0), 80, -150, 10, -10, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (60), 0), 80, -150, 10, -10, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (90), 0), 80, -150, 10, -10, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (30), 0), 80, -150, 10, -10, EQUAL));
// test elevation angle
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (0), 2), 60, 0, 20, 0, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (30), 2), 60, 0, 20, -3, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-30), 2), 60, 0, 20, -3, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-90), 2), 60, 0, 20, -20, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-180), 2), 60, 0, 20, -20, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (60), -3), 60, 60, 20, 0, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (90), -3), 60, 60, 20, -3, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (30), -3), 60, 60, 20, -3, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-120), -3), 60, 60, 20, -20, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-150), -3), 100, -150, 10, 0, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-100), -3), 100, -150, 10, -3, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-200), -3), 100, -150, 10, -3, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-30), -3), 100, -150, 10, -10, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (90), 9.5), 100, -150, 10, -10, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (0), 9.5), 60, 0, 20, 0, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (30), 9.5), 60, 0, 20, -3, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-30), 9.5), 60, 0, 20, -3, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (100), 9.5), 60, 0, 20, -20, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-150), 9.5), 100, -150, 30, 0, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-100), 9.5), 100, -150, 30, -3, EQUAL));
AddTestCase (new ParabolicAntennaModelTestCase (Angles (DegreesToRadians (-200), 9.5), 100, -150, 30, -3, EQUAL));
};
static ParabolicAntennaModelTestSuite staticParabolicAntennaModelTestSuiteInstance;
} // namespace ns3

View File

@@ -9,6 +9,7 @@ def build(bld):
'model/antenna-model.cc',
'model/isotropic-antenna-model.cc',
'model/cosine-antenna-model.cc',
'model/parabolic-antenna-model.cc',
]
module_test = bld.create_ns3_module_test_library('antenna')
@@ -17,6 +18,7 @@ def build(bld):
'test/test-degrees-radians.cc',
'test/test-isotropic-antenna.cc',
'test/test-cosine-antenna.cc',
'test/test-parabolic-antenna.cc',
]
headers = bld.new_task_gen(features=['ns3header'])
@@ -26,6 +28,7 @@ def build(bld):
'model/antenna-model.h',
'model/isotropic-antenna-model.h',
'model/cosine-antenna-model.h',
'model/parabolic-antenna-model.h',
]