This commit is contained in:
Marco Miozzo
2012-03-22 18:27:46 +01:00
32 changed files with 1382 additions and 368 deletions

View File

@@ -17,6 +17,10 @@ SOURCES = \
source/internet-models.rst \
source/network.rst \
source/emulation-overview.rst \
$(SRC)/antenna/doc/source/antenna.rst \
$(SRC)/antenna/doc/source/antenna-design.rst \
$(SRC)/antenna/doc/source/antenna-user.rst \
$(SRC)/antenna/doc/source/antenna-testing.rst \
$(SRC)/aodv/doc/aodv.rst \
$(SRC)/applications/doc/applications.rst \
$(SRC)/bridge/doc/bridge.rst \
@@ -68,6 +72,7 @@ SOURCES = \
SOURCEFIGS = \
figures/testbed.dia \
figures/emulated-channel.dia \
$(SRC)/antenna/doc/source/figures/antenna-coordinate-system.dia \
$(SRC)/network/doc/packet.dia \
$(SRC)/network/doc/node.dia \
$(SRC)/network/doc/buffer.dia \
@@ -91,6 +96,10 @@ SOURCEFIGS = \
$(SRC)/lte/doc/source/figures/epc-data-flow-ul.dia \
$(SRC)/lte/doc/source/figures/lte-arch-data-rrc-pdcp-rlc.dia \
$(SRC)/lte/doc/source/figures/lte-epc-e2e-data-protocol-stack.dia \
$(SRC)/lte/doc/source/figures/MCS_2_test.eps \
$(SRC)/lte/doc/source/figures/MCS_12_test.eps \
$(SRC)/lte/doc/source/figures/MCS_14_test.eps \
$(SRC)/lte/doc/source/figures/lena-dual-stripe.eps \
$(SRC)/lte/doc/source/figures/lte-mcs-index.eps \
$(SRC)/lte/doc/source/figures/lenaThrTestCase1.eps \
$(SRC)/lte/doc/source/figures/lenaThrTestCase2.eps \
@@ -106,16 +115,32 @@ SOURCEFIGS = \
$(SRC)/lte/doc/source/figures/lte-rlc-data-retx-dl.eps \
$(SRC)/lte/doc/source/figures/lte-rlc-data-txon-ul.eps \
$(SRC)/lte/doc/source/figures/lte-rlc-data-retx-ul.eps \
$(SRC)/lte/doc/source/figures/fading_pedestrian.png \
$(SRC)/lte/doc/source/figures/fading_vehicular.png \
$(SRC)/lte/doc/source/figures/fading_urban_3kmph.png \
$(SRC)/lte/doc/source/figures/fading_pedestrian.png \
$(SRC)/lte/doc/source/figures/fading_pedestrian.pdf \
$(SRC)/lte/doc/source/figures/fading_vehicular.pdf \
$(SRC)/lte/doc/source/figures/fading_urban_3kmph.pdf \
$(SRC)/lte/doc/source/figures/fading_pedestrian.pdf \
$(SRC)/lte/doc/source/figures/MCS_1_4.pdf \
$(SRC)/lte/doc/source/figures/MCS_1_4.png \
$(SRC)/lte/doc/source/figures/MCS_5_8.pdf \
$(SRC)/lte/doc/source/figures/MCS_5_8.png \
$(SRC)/lte/doc/source/figures/MCS_9_12.pdf \
$(SRC)/lte/doc/source/figures/MCS_9_12.png \
$(SRC)/lte/doc/source/figures/MCS_13_16.pdf \
$(SRC)/lte/doc/source/figures/MCS_13_16.png \
$(SRC)/lte/doc/source/figures/MCS_17_20.pdf \
$(SRC)/lte/doc/source/figures/MCS_17_20.png \
$(SRC)/lte/doc/source/figures/MCS_21_24.pdf \
$(SRC)/lte/doc/source/figures/MCS_21_24.png \
$(SRC)/lte/doc/source/figures/MCS_25_27.pdf \
$(SRC)/lte/doc/source/figures/MCS_25_27.png \
$(SRC)/lte/doc/source/figures/lte-phy-interference.png \
$(SRC)/lte/doc/source/figures/lte-phy-interference.pdf \
$(SRC)/lte/doc/source/figures/helpers.png \
$(SRC)/lte/doc/source/figures/helpers.pdf \
$(SRC)/lte/doc/source/figures/miesm_scheme.pdf \
$(SRC)/lte/doc/source/figures/miesm_scheme.png \
$(SRC)/uan/doc/auvmobility-classes.dia \
$(SRC)/stats/doc/Stat-framework-arch.png \
$(SRC)/stats/doc/Wifi-default.png \
@@ -131,6 +156,7 @@ IMAGES_EPS = \
$(FIGURES)/node.eps \
$(FIGURES)/buffer.eps \
$(FIGURES)/sockets-overview.eps \
$(FIGURES)/antenna-coordinate-system.eps \
$(FIGURES)/internet-node-send.eps \
$(FIGURES)/internet-node-recv.eps \
$(FIGURES)/routing.eps \
@@ -150,6 +176,10 @@ IMAGES_EPS = \
$(FIGURES)/epc-data-flow-ul.eps \
$(FIGURES)/lte-arch-data-rrc-pdcp-rlc.eps \
$(FIGURES)/lte-epc-e2e-data-protocol-stack.eps \
$(FIGURES)/MCS_2_test.eps \
$(FIGURES)/MCS_12_test.eps \
$(FIGURES)/MCS_14_test.eps \
$(FIGURES)/lena-dual-stripe.eps \
$(FIGURES)/lte-mcs-index.eps \
$(FIGURES)/lenaThrTestCase1.eps \
$(FIGURES)/lenaThrTestCase2.eps \

View File

@@ -18,6 +18,7 @@ This document is written in `reStructuredText <http://docutils.sourceforge.net/r
organization
animation
antenna
aodv
applications
bridge

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',
]

View File

@@ -190,7 +190,9 @@ GridBuildingAllocator::Create (uint32_t n) const
}
double bxmax = bxmin + m_lengthX;
double bymax = bymin + m_lengthY;
BoxValue boxValue (Box (bxmin, bxmax, bymin, bymax, 0, m_height));
Box box (bxmin, bxmax, bymin, bymax, 0, m_height);
NS_LOG_LOGIC ("new building : " << box);
BoxValue boxValue (box);
m_buildingFactory.Set ("Boundaries", boxValue);
Ptr<Building> b = m_buildingFactory.Create<Building> ();
//b->SetAttribute ("Boundaries", boxValue);

View File

@@ -18,6 +18,7 @@
* Author: Nicola Baldo <nbaldo@cttc.es>
*/
#include "building-position-allocator.h"
#include "ns3/buildings-mobility-model.h"
#include "ns3/random-variable.h"
#include "ns3/double.h"
#include "ns3/uinteger.h"
@@ -177,4 +178,77 @@ RandomRoomPositionAllocator::GetNext () const
NS_OBJECT_ENSURE_REGISTERED (SameRoomPositionAllocator);
SameRoomPositionAllocator::SameRoomPositionAllocator ()
{
NS_FATAL_ERROR (" Constructor \"SameRoomPositionAllocator ()\" should not be used");
}
SameRoomPositionAllocator::SameRoomPositionAllocator (NodeContainer c)
: m_nodes (c),
m_nodeIt (c.Begin ())
{
}
TypeId
SameRoomPositionAllocator::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::SameRoomPositionAllocator")
.SetParent<PositionAllocator> ()
.SetGroupName ("Mobility")
.AddConstructor<SameRoomPositionAllocator> ();
return tid;
}
Vector
SameRoomPositionAllocator::GetNext () const
{
NS_LOG_FUNCTION (this);
UniformVariable rand;
if (m_nodeIt == m_nodes.End ())
{
m_nodeIt = m_nodes.Begin ();
}
NS_ASSERT_MSG (m_nodeIt != m_nodes.End (), "no node in container");
Ptr<BuildingsMobilityModel> bmm = (*m_nodeIt)->GetObject<BuildingsMobilityModel> ();
uint32_t roomx = bmm->GetRoomNumberX ();
uint32_t roomy = bmm->GetRoomNumberY ();
uint32_t floor = bmm->GetFloorNumber ();
NS_LOG_LOGIC ("considering room (" << roomx << ", " << roomy << ", " << floor << ")");
Ptr<Building> b = bmm->GetBuilding ();
Ptr<RandomBoxPositionAllocator> pa = CreateObject<RandomBoxPositionAllocator> ();
UniformVariable v;
BoxValue bv;
b->GetAttribute ("Boundaries", bv);
Box box = bv.Get ();
double rdx = (box.xMax - box.xMin) / b->GetNRoomsX ();
double rdy = (box.yMax - box.yMin) / b->GetNRoomsY ();
double rdz = (box.zMax - box.zMin) / b->GetNFloors ();
double x1 = box.xMin + rdx * roomx;
double x2 = box.xMin + rdx * (roomx + 1);
double y1 = box.yMin + rdy * roomy;
double y2 = box.yMin + rdy * (roomy + 1);
double z1 = box.zMin + rdz * floor;
double z2 = box.zMin + rdz * (floor + 1);
NS_LOG_LOGIC ("randomly allocating position in "
<< " (" << x1 << "," << x2 << ") "
<< "x (" << y1 << "," << y2 << ") "
<< "x (" << z1 << "," << z2 << ") ");
double x = v.GetValue (x1, x2);
double y = v.GetValue (y1, y2);
double z = v.GetValue (z1, z2);
return Vector (x, y, z);
}
} // namespace ns3

View File

@@ -22,6 +22,7 @@
#include <ns3/ptr.h>
#include <ns3/position-allocator.h>
#include <ns3/node-container.h>
namespace ns3 {
@@ -82,6 +83,29 @@ private:
};
/**
* Walks a given NodeContainer sequentially, and for each node allocate a new
* position randomly in the same room of that node
*
*/
class SameRoomPositionAllocator : public PositionAllocator
{
public:
SameRoomPositionAllocator ();
SameRoomPositionAllocator (NodeContainer c);
// inherited from Object
static TypeId GetTypeId (void);
// inherited from PositionAllocator
virtual Vector GetNext (void) const;
private:
NodeContainer m_nodes;
mutable NodeContainer::Iterator m_nodeIt;
};
} // namespace ns3

View File

@@ -25,10 +25,7 @@ IMAGES_EPS = \
$(FIGURES)/MCS_2_test.eps \
$(FIGURES)/MCS_12_test.eps \
$(FIGURES)/MCS_14_test.eps \
$(FIGURES)/lena-dual-stripe.eps
# specify figures for build process (figures for which both a .pdf and a .png files are provided)
GRAPHS_EPS = \
$(FIGURES)/lena-dual-stripe.eps \
$(FIGURES)/lte-mcs-index.eps \
$(FIGURES)/lenaThrTestCase1.eps \
$(FIGURES)/lenaThrTestCase2.eps \
@@ -118,10 +115,6 @@ IMAGES = $(IMAGES_EPS) $(IMAGES_PNG) $(IMAGES_PDF) $(IMAGES_OTHER)
%.pdf : %.seqdiag; $(SEQDIAG) -Tpdf -o $@ $< ; if test x$($@_width) != x; then TMPFILE=`mktemp`; ./rescale-pdf.sh $($@_width) $@ $${TMPFILE} && mv $${TMPFILE} $@; fi
%.pdf : %.eps; $(EPSTOPDF) $< -o=$@; if test x$($@_width) != x; then TMPFILE=`mktemp`; ./rescale-pdf.sh $($@_width) $@ $${TMPFILE} && mv $${TMPFILE} $@; fi
GRAPHS_PNG = ${GRAPHS_EPS:.eps=.png}
GRAPHS_PDF = ${GRAPHS_EPS:.eps=.pdf}
GRAPHS = $(GRAPHS_EPS) $(GRAPHS_PNG) $(GRAPHS_PDF)
%.png : %.eps; $(CONVERT) $< $@
%.pdf : %.eps; $(EPSTOPDF) $< -o=$@; if test x$($@_width) != x; then TMPFILE=`mktemp`; ./rescale-pdf.sh $($@_width) $@ $${TMPFILE} && mv $${TMPFILE} $@; fi
@@ -162,15 +155,13 @@ clean:
-rm -rf $(BUILDDIR)/*
-rm -f $(IMAGES_PNG)
-rm -f $(IMAGES_PDF)
-rm -f $(GRAPHS_PNG)
-rm -f $(GRAPHS_PDF)
frag: pickle
@if test ! -d $(BUILDDIR)/frag; then mkdir $(BUILDDIR)/frag; fi
pushd $(BUILDDIR)/frag && ../../pickle-to-xml.py ../pickle/index.fpickle > navigation.xml && popd
cp -r $(BUILDDIR)/pickle/_images $(BUILDDIR)/frag
html: $(IMAGES) ${GRAPHS}
html: $(IMAGES)
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
@@ -224,14 +215,14 @@ epub: $(IMAGES)
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex: $(IMAGES) ${GRAPHS}
latex: $(IMAGES)
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf: $(IMAGES) ${GRAPHS}
latexpdf: $(IMAGES)
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
make -C $(BUILDDIR)/latex all-pdf

View File

@@ -411,9 +411,9 @@ process in order to reach its destination UE.
-----------------------------
Description of the components
-----------------------------
-----------------------------------------
Detailed description of protocol elements
-----------------------------------------
@@ -602,7 +602,7 @@ on resource block :math:`k` at subframe :math:`t` is defined as
R_{i}(k,t) = \frac{S\left( M_{i,k}(t), 1\right)}{\tau}
where :math:`\tau` is the TTI duration.
At the start of each subframe :math:`t`, all the RBs are assigned to a certain user.
At the start of each subframe :math:`t`, each RB is assigned to a certain user.
In detail, the index :math:`\widehat{i}_{k}(t)` to which RB :math:`k` is assigned at time
:math:`t` is determined as

View File

@@ -1,14 +0,0 @@
.. only:: html or latex
######################################
LTE Simulator RLC Layer Documentation
######################################
.. toctree::
:maxdepth: 5
lte-rlc-design
lte-references

View File

@@ -43,19 +43,152 @@ using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("LenaDualStripe");
bool AreOverlapping (Box a, Box b)
{
return !((a.xMin > b.xMax) || (b.xMin > a.xMax) || (a.yMin > b.yMax) || (b.yMin > a.yMax));
}
class FemtocellBlockAllocator
{
public:
FemtocellBlockAllocator (Box area, uint32_t nApartmentsX, uint32_t nFloors);
void Create (uint32_t n);
void Create ();
private:
bool OverlapsWithAnyPrevious (Box);
Box m_area;
uint32_t m_nApartmentsX;
uint32_t m_nFloors;
std::list<Box> m_previousBlocks;
double m_xSize;
double m_ySize;
UniformVariable m_xMinVar;
UniformVariable m_yMinVar;
};
FemtocellBlockAllocator::FemtocellBlockAllocator (Box area, uint32_t nApartmentsX, uint32_t nFloors)
: m_area (area),
m_nApartmentsX (nApartmentsX),
m_nFloors (nFloors),
m_xSize (nApartmentsX*10 + 20),
m_ySize (70),
m_xMinVar (area.xMin, area.xMax - m_xSize),
m_yMinVar (area.yMin, area.yMax - m_ySize)
{
}
void
FemtocellBlockAllocator::Create (uint32_t n)
{
for (uint32_t i = 0; i < n; ++i)
{
Create ();
}
}
void
FemtocellBlockAllocator::Create ()
{
Box box;
uint32_t attempt = 0;
do
{
NS_ASSERT_MSG (attempt < 100, "Too many failed attemtps to position apartment block. Too many blocks? Too small area?");
box.xMin = m_xMinVar.GetValue ();
box.xMax = box.xMin + m_xSize;
box.yMin = m_yMinVar.GetValue ();
box.yMax = box.yMin + m_ySize;
++attempt;
}
while (OverlapsWithAnyPrevious (box));
NS_LOG_LOGIC ("allocated non overlapping block " << box);
m_previousBlocks.push_back (box);
Ptr<GridBuildingAllocator> gridBuildingAllocator;
gridBuildingAllocator = CreateObject<GridBuildingAllocator> ();
gridBuildingAllocator->SetAttribute ("GridWidth", UintegerValue (1));
gridBuildingAllocator->SetAttribute ("LengthX", DoubleValue (10*m_nApartmentsX));
gridBuildingAllocator->SetAttribute ("LengthY", DoubleValue (10*2));
gridBuildingAllocator->SetAttribute ("DeltaX", DoubleValue (10));
gridBuildingAllocator->SetAttribute ("DeltaY", DoubleValue (10));
gridBuildingAllocator->SetAttribute ("Height", DoubleValue (3*m_nFloors));
gridBuildingAllocator->SetBuildingAttribute ("NRoomsX", UintegerValue (m_nApartmentsX));
gridBuildingAllocator->SetBuildingAttribute ("NRoomsY", UintegerValue (2));
gridBuildingAllocator->SetBuildingAttribute ("NFloors", UintegerValue (m_nFloors));
gridBuildingAllocator->SetAttribute ("MinX", DoubleValue (box.xMin + 10));
gridBuildingAllocator->SetAttribute ("MinY", DoubleValue (box.yMin + 10));
gridBuildingAllocator->Create (2);
}
bool
FemtocellBlockAllocator::OverlapsWithAnyPrevious (Box box)
{
for (std::list<Box>::iterator it = m_previousBlocks.begin (); it != m_previousBlocks.end (); ++it)
{
if (AreOverlapping (*it, box))
{
return true;
}
}
return false;
}
int
main (int argc, char *argv[])
{
// scenario parameters
uint32_t nBlocks = 2;
uint32_t nApartamentsX = 10;
uint32_t nApartamentsY = 2;
uint32_t nBlocks = 10;
uint32_t nApartmentsX = 10;
uint32_t nFloors = 1;
uint32_t heightPerFloor = 3;
double deploymentRatio = 0.4;
double ueHenbRatio = 10;
uint32_t nMacroEnbSites = 3;
uint32_t nMacroEnbSitesX = 1;
double interSiteDistance = 500;
double areaMarginFactor = 0.5;
double macroUeDensity = 0.0001;
double homeEnbDeploymentRatio = 0.2;
double homeEnbActivationRatio = 0.5;
double homeUesHomeEnbRatio = 1;
double macroEnbTxPowerDbm = 46.0;
double homeEnbTxPowerDbm = 20.0;
uint16_t macroEnbDlEarfcn = 100;
uint16_t homeEnbDlEarfcn = 100;
uint8_t macroEnbBandwidth = 25;
uint8_t homeEnbBandwidth = 25;
double simTime = 0.01;
bool generateRem = false;
CommandLine cmd;
cmd.AddValue ("nBlocks", "Number of femtocell blocks", nBlocks);
cmd.AddValue ("nApartmentsX", "Number of apartments along the X axis in a femtocell block", nApartmentsX);
cmd.AddValue ("nFloors", "Number of floors", nFloors);
cmd.AddValue ("nMacroEnbSites", "How many macro sites there are", nMacroEnbSites);
cmd.AddValue ("nMacroEnbSitesX",
"(minimum) number of sites along the X-axis of the hex grid", nMacroEnbSitesX);
cmd.AddValue ("interSiteDistance", "min distance between two nearby macro cell sites", interSiteDistance);
cmd.AddValue ("areaMarginFactor", "how much the UE area extends outside the macrocell grid, "
"expressed as fraction of the interSiteDistance", areaMarginFactor);
cmd.AddValue ("macroUeDensity", "How many macrocell UEs there are per square meter", macroUeDensity);
cmd.AddValue ("homeEnbDeploymentRatio",
"The HeNB deployment ratio as per 3GPP R4-092042", homeEnbDeploymentRatio);
cmd.AddValue ("homeEnbActivationRatio",
"The HeNB activation ratio as per 3GPP R4-092042", homeEnbActivationRatio);
cmd.AddValue ("homeUesHomeEnbRatio",
"How many (on average) home UEs per HeNB there are in the simulation",
homeUesHomeEnbRatio);
cmd.AddValue ("macroEnbTxPowerDbm", "TX power [dBm] used by macro eNBs", macroEnbTxPowerDbm);
cmd.AddValue ("homeEnbTxPowerDbm", "TX power [dBm] used by HeNBs", homeEnbTxPowerDbm);
cmd.AddValue ("macroEnbDlEarfcn", "DL EARFCN used by macro eNBs", macroEnbDlEarfcn);
cmd.AddValue ("homeEnbDlEarfcn", "DL EARFCN used by HeNBs", homeEnbDlEarfcn);
cmd.AddValue ("macroEnbBandwidth", "bandwdith [num RBs] used by macro eNBs", macroEnbBandwidth);
cmd.AddValue ("homeEnbBandwidth", "bandwdith [num RBs] used by HeNBs", homeEnbBandwidth);
cmd.AddValue ("simTime", "Total duration of the simulation [s]", simTime);
cmd.AddValue ("generateRem", "if true, will generate a REM and then abort the simulation;"
"if false, will run the simulation normally (without generating any REM)", generateRem);
cmd.Parse (argc, argv);
ConfigStore inputConfig;
@@ -63,122 +196,142 @@ main (int argc, char *argv[])
cmd.Parse (argc, argv);
uint32_t currentSite = nMacroEnbSites -1;
uint32_t biRowIndex = (currentSite / (nMacroEnbSitesX + nMacroEnbSitesX + 1));
uint32_t biRowRemainder = currentSite % (nMacroEnbSitesX + nMacroEnbSitesX + 1);
uint32_t rowIndex = biRowIndex*2 + 1;
if (biRowRemainder >= nMacroEnbSitesX)
{
++rowIndex;
}
uint32_t nMacroEnbSitesY = rowIndex;
NS_LOG_LOGIC ("nMacroEnbSitesY = " << nMacroEnbSitesY);
Ptr<GridBuildingAllocator> gridBuildingAllocator = CreateObject<GridBuildingAllocator> ();
gridBuildingAllocator->SetAttribute ("GridWidth", UintegerValue (1));
gridBuildingAllocator->SetAttribute ("MinX", DoubleValue (0));
gridBuildingAllocator->SetAttribute ("MinY", DoubleValue (0));
gridBuildingAllocator->SetAttribute ("LengthX", DoubleValue (10*nApartamentsX));
gridBuildingAllocator->SetAttribute ("LengthY", DoubleValue (10*nApartamentsY));
gridBuildingAllocator->SetAttribute ("DeltaX", DoubleValue (10));
gridBuildingAllocator->SetAttribute ("DeltaY", DoubleValue (10));
gridBuildingAllocator->SetAttribute ("Height", DoubleValue (heightPerFloor*nFloors));
gridBuildingAllocator->SetBuildingAttribute ("NRoomsX", UintegerValue (nApartamentsX));
gridBuildingAllocator->SetBuildingAttribute ("NRoomsY", UintegerValue (nApartamentsY));
gridBuildingAllocator->SetBuildingAttribute ("NFloors", UintegerValue (nFloors));
gridBuildingAllocator->SetBuildingAttribute ("ExternalWallsType", EnumValue (Building::StoneBlocks));
gridBuildingAllocator->Create (nBlocks);
uint32_t nHenbs = round (nApartamentsX * nApartamentsY * nBlocks * nFloors * deploymentRatio);
NS_LOG_LOGIC ("nHenbs = " << nHenbs);
uint32_t nUes = round (nHenbs*ueHenbRatio);
NS_LOG_LOGIC ("nUes = " << nUes);
Box macroUeBox (-areaMarginFactor*interSiteDistance,
(nMacroEnbSitesX + areaMarginFactor)*interSiteDistance,
-areaMarginFactor*interSiteDistance,
(nMacroEnbSitesY -1)*interSiteDistance*sqrt(0.75) + areaMarginFactor*interSiteDistance,
1.0, 2.0);
NodeContainer henbs;
henbs.Create (nHenbs);
FemtocellBlockAllocator blockAllocator (macroUeBox, nApartmentsX, nFloors);
blockAllocator.Create (nBlocks);
uint32_t nHomeEnbs = round (4 * nApartmentsX * nBlocks * nFloors * homeEnbDeploymentRatio * homeEnbActivationRatio);
NS_LOG_LOGIC ("nHomeEnbs = " << nHomeEnbs);
uint32_t nHomeUes = round (nHomeEnbs * homeUesHomeEnbRatio);
NS_LOG_LOGIC ("nHomeUes = " << nHomeUes);
double macroUeAreaSize = (macroUeBox.xMax - macroUeBox.xMin) * (macroUeBox.yMax - macroUeBox.yMin);
uint32_t nMacroUes = round (macroUeAreaSize * macroUeDensity) ;
NS_LOG_LOGIC ("nMacroUes = " << nMacroUes);
NodeContainer homeEnbs;
homeEnbs.Create (nHomeEnbs);
NodeContainer macroEnbs;
macroEnbs.Create (3);
NodeContainer ues;
ues.Create (nUes);
macroEnbs.Create (3 * nMacroEnbSites);
NodeContainer homeUes;
homeUes.Create (nHomeUes);
NodeContainer macroUes;
macroUes.Create (nMacroUes);
MobilityHelper mobility;
mobility.SetMobilityModel ("ns3::BuildingsMobilityModel");
mobility.EnableAsciiAll (std::cout);
// HeNBs placed indoor
Ptr<PositionAllocator> positionAlloc = CreateObject<RandomRoomPositionAllocator> ();
mobility.SetPositionAllocator (positionAlloc);
mobility.Install (henbs);
// Macro eNB placed at fixed coordinates
Ptr<ListPositionAllocator> listPositionAlloc = CreateObject<ListPositionAllocator> ();
listPositionAlloc->Add (Vector (-50, 0, 30));
listPositionAlloc->Add (Vector (-50.01, 0.01, 30));
listPositionAlloc->Add (Vector (-50.01, -0.01, 30));
mobility.SetPositionAllocator (listPositionAlloc);
mobility.Install (macroEnbs);
// UEs randomly located in the whole simulation area
double xmin = -100;
double xmax = nApartamentsX*10+10;
double ymin = -50;
double ymax = (nApartamentsY*10+10)*nBlocks;
double zmin = 0;
double zmax = heightPerFloor*nFloors;
NS_LOG_LOGIC ("randomly allocating users in "
<< " (" << xmin << "," << xmax << ") "
<< "x (" << ymin << "," << ymax << ") "
<< "x (" << zmin << "," << zmax << ") ");
positionAlloc = CreateObject<RandomBoxPositionAllocator> ();
positionAlloc->SetAttribute ("X", RandomVariableValue (UniformVariable (xmin, xmax)));
positionAlloc->SetAttribute ("Y", RandomVariableValue (UniformVariable (ymin, ymax)));
positionAlloc->SetAttribute ("Z", RandomVariableValue (UniformVariable (zmin, zmax)));
mobility.SetPositionAllocator (positionAlloc);
mobility.Install (ues);
Ptr <LteHelper> lteHelper = CreateObject<LteHelper> ();
// //lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisPropagationLossModel"));
lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::HybridBuildingsPropagationLossModel"));
lteHelper->SetPathlossModelAttribute ("ShadowSigmaExtWalls", DoubleValue (0));
lteHelper->SetPathlossModelAttribute ("ShadowSigmaOutdoor", DoubleValue (1));
lteHelper->SetPathlossModelAttribute ("ShadowSigmaIndoor", DoubleValue (1.5));
// use always LOS model
lteHelper->SetPathlossModelAttribute ("Los2NlosThr", DoubleValue (1e6));
lteHelper->SetSpectrumChannelType ("ns3::MultiModelSpectrumChannel");
// Macro eNBs in 3-sector hex grid
mobility.Install (macroEnbs);
Ptr<LteHexGridEnbTopologyHelper> lteHexGridEnbTopologyHelper = CreateObject<LteHexGridEnbTopologyHelper> ();
lteHexGridEnbTopologyHelper->SetLteHelper (lteHelper);
lteHexGridEnbTopologyHelper->SetAttribute ("InterSiteDistance", DoubleValue (interSiteDistance));
lteHexGridEnbTopologyHelper->SetAttribute ("MinX", DoubleValue (interSiteDistance/2));
lteHexGridEnbTopologyHelper->SetAttribute ("GridWidth", UintegerValue (nMacroEnbSitesX));
Config::SetDefault ("ns3::LteEnbPhy::TxPower", DoubleValue (macroEnbTxPowerDbm));
lteHelper->SetEnbAntennaModelType ("ns3::ParabolicAntennaModel");
lteHelper->SetEnbAntennaModelAttribute ("Beamwidth", DoubleValue (70));
lteHelper->SetEnbAntennaModelAttribute ("MaxAttenuation", DoubleValue (20.0));
lteHelper->SetEnbDeviceAttribute ("DlEarfcn", UintegerValue (macroEnbDlEarfcn));
lteHelper->SetEnbDeviceAttribute ("UlEarfcn", UintegerValue (macroEnbDlEarfcn + 18000));
lteHelper->SetEnbDeviceAttribute ("DlBandwidth", UintegerValue (macroEnbBandwidth));
lteHelper->SetEnbDeviceAttribute ("UlBandwidth", UintegerValue (macroEnbBandwidth));
NetDeviceContainer macroEnbDevs = lteHexGridEnbTopologyHelper->SetPositionAndInstallEnbDevice (macroEnbs);
// Create Devices and install them in the Nodes (eNB and UE)
NetDeviceContainer enbDevs;
NetDeviceContainer ueDevs;
// HomeEnbs randomly indoor
Ptr<PositionAllocator> positionAlloc = CreateObject<RandomRoomPositionAllocator> ();
mobility.SetPositionAllocator (positionAlloc);
mobility.Install (homeEnbs);
Config::SetDefault ("ns3::LteEnbPhy::TxPower", DoubleValue (homeEnbTxPowerDbm));
lteHelper->SetEnbAntennaModelType ("ns3::IsotropicAntennaModel");
lteHelper->SetEnbDeviceAttribute ("DlEarfcn", UintegerValue (homeEnbDlEarfcn));
lteHelper->SetEnbDeviceAttribute ("UlEarfcn", UintegerValue (homeEnbDlEarfcn + 18000));
lteHelper->SetEnbDeviceAttribute ("DlBandwidth", UintegerValue (homeEnbBandwidth));
lteHelper->SetEnbDeviceAttribute ("UlBandwidth", UintegerValue (homeEnbBandwidth));
NetDeviceContainer homeEnbDevs = lteHelper->InstallEnbDevice (homeEnbs);
// power setting in dBm for HeNBs
Config::SetDefault ("ns3::LteEnbPhy::TxPower", DoubleValue (10.0));
enbDevs.Add (lteHelper->InstallEnbDevice (henbs));
// macro Ues
NS_LOG_LOGIC ("randomly allocating macro UEs in " << macroUeBox);
positionAlloc = CreateObject<RandomBoxPositionAllocator> ();
positionAlloc->SetAttribute ("X", RandomVariableValue (UniformVariable (macroUeBox.xMin, macroUeBox.xMax)));
positionAlloc->SetAttribute ("Y", RandomVariableValue (UniformVariable (macroUeBox.yMin, macroUeBox.yMax)));
positionAlloc->SetAttribute ("Z", RandomVariableValue (UniformVariable (macroUeBox.zMin, macroUeBox.zMax)));
mobility.SetPositionAllocator (positionAlloc);
mobility.Install (macroUes);
NetDeviceContainer macroUeDevs = lteHelper->InstallUeDevice (macroUes);
lteHelper->AttachToClosestEnb (macroUeDevs, macroEnbDevs);
// power setting in dBm for macro eNB
Config::SetDefault ("ns3::LteEnbPhy::TxPower", DoubleValue (30.0));
lteHelper->SetEnbAntennaModelType ("ns3::CosineAntennaModel");
lteHelper->SetEnbAntennaModelAttribute ("Beamwidth", DoubleValue (65));
lteHelper->SetEnbAntennaModelAttribute ("MaxGain", DoubleValue (0.0));
lteHelper->SetEnbAntennaModelAttribute ("Orientation", DoubleValue (0));
enbDevs.Add (lteHelper->InstallEnbDevice (macroEnbs.Get (0)));
lteHelper->SetEnbAntennaModelAttribute ("Orientation", DoubleValue (+120));
enbDevs.Add (lteHelper->InstallEnbDevice (macroEnbs.Get (1)));
lteHelper->SetEnbAntennaModelAttribute ("Orientation", DoubleValue (-120));
enbDevs.Add (lteHelper->InstallEnbDevice (macroEnbs.Get (2)));
// home UEs located in the same apartment in which there are the Home eNBs
positionAlloc = CreateObject<SameRoomPositionAllocator> (homeEnbs);
mobility.Install (homeUes);
NetDeviceContainer homeUeDevs = lteHelper->InstallUeDevice (homeUes);
lteHelper->AttachToClosestEnb (homeUeDevs, homeEnbDevs);
ueDevs = lteHelper->InstallUeDevice (ues);
lteHelper->AttachToClosestEnb (ueDevs, enbDevs);
// activate bearer for all UEs
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
EpsBearer bearer (q);
lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
lteHelper->ActivateEpsBearer (homeUeDevs, bearer, EpcTft::Default ());
lteHelper->ActivateEpsBearer (macroUeDevs, bearer, EpcTft::Default ());
BuildingsHelper::MakeMobilityModelConsistent ();
// by default, simulation will anyway stop right after the REM has been generated
Simulator::Stop (Seconds (0.0069));
Ptr<RadioEnvironmentMapHelper> remHelper = CreateObject<RadioEnvironmentMapHelper> ();
remHelper->SetAttribute ("ChannelPath", StringValue ("/ChannelList/0"));
remHelper->SetAttribute ("OutputFile", StringValue ("lena-dual-stripe.rem"));
remHelper->SetAttribute ("XMin", DoubleValue (-70));
remHelper->SetAttribute ("XMax", DoubleValue (xmax));
remHelper->SetAttribute ("YMin", DoubleValue (-10));
remHelper->SetAttribute ("YMax", DoubleValue (ymax));
remHelper->SetAttribute ("Z", DoubleValue (1.5));
remHelper->Install ();
Ptr<RadioEnvironmentMapHelper> remHelper;
if (generateRem)
{
remHelper = CreateObject<RadioEnvironmentMapHelper> ();
remHelper->SetAttribute ("ChannelPath", StringValue ("/ChannelList/0"));
remHelper->SetAttribute ("OutputFile", StringValue ("lena-dual-stripe.rem"));
remHelper->SetAttribute ("XMin", DoubleValue (macroUeBox.xMin));
remHelper->SetAttribute ("XMax", DoubleValue (macroUeBox.xMax));
remHelper->SetAttribute ("YMin", DoubleValue (macroUeBox.yMin));
remHelper->SetAttribute ("YMax", DoubleValue (macroUeBox.yMax));
remHelper->SetAttribute ("Z", DoubleValue (1.5));
remHelper->Install ();
// simulation will stop right after the REM has been generated
}
else
{
Simulator::Stop (Seconds (simTime));
}
Simulator::Run ();

View File

@@ -29,7 +29,7 @@
#include <iomanip>
#include <string>
#include <vector>
#include "ns3/gtk-config-store.h"
//#include "ns3/gtk-config-store.h"
using namespace ns3;
using std::vector;

View File

@@ -108,8 +108,6 @@ int main (int argc, char *argv[])
BuildingsHelper::MakeMobilityModelConsistent ();
// by default, simulation will anyway stop right after the REM has been generated
Simulator::Stop (Seconds (0.0069));
Simulator::Run ();

View File

@@ -62,14 +62,15 @@ LteHelper::LteHelper (void)
m_enbNetDeviceFactory.SetTypeId (LteEnbNetDevice::GetTypeId ());
m_enbAntennaModelFactory.SetTypeId (IsotropicAntennaModel::GetTypeId ());
m_ueAntennaModelFactory.SetTypeId (IsotropicAntennaModel::GetTypeId ());
m_channelFactory.SetTypeId (SingleModelSpectrumChannel::GetTypeId ());
}
void
LteHelper::DoStart (void)
{
NS_LOG_FUNCTION (this);
m_downlinkChannel = CreateObject<SingleModelSpectrumChannel> ();
m_uplinkChannel = CreateObject<SingleModelSpectrumChannel> ();
m_downlinkChannel = m_channelFactory.Create<SpectrumChannel> ();
m_uplinkChannel = m_channelFactory.Create<SpectrumChannel> ();
m_downlinkPathlossModel = m_dlPathlossModelFactory.Create ();
Ptr<SpectrumPropagationLossModel> dlSplm = m_downlinkPathlossModel->GetObject<SpectrumPropagationLossModel> ();
@@ -101,7 +102,6 @@ LteHelper::DoStart (void)
m_uplinkChannel->AddPropagationLossModel (ulPlm);
}
//if (m_fadingModelFactory.GetTypeId ().GetName ().compare ( "ns3::TraceFadingLossModel") == 0)
if (m_fadingModelType.compare ( "ns3::TraceFadingLossModel") == 0)
{
m_fadingModule = m_fadingModelFactory.Create<TraceFadingLossModel> ();
@@ -265,6 +265,19 @@ LteHelper::SetFadingModelAttribute (std::string n, const AttributeValue &v)
m_fadingModelFactory.Set (n, v);
}
void
LteHelper::SetSpectrumChannelType (std::string type)
{
NS_LOG_FUNCTION (this << type);
m_channelFactory.SetTypeId (type);
}
void
LteHelper::SetSpectrumChannelAttribute (std::string n, const AttributeValue &v)
{
m_channelFactory.Set (n, v);
}
NetDeviceContainer
LteHelper::InstallEnbDevice (NodeContainer c)
@@ -317,7 +330,6 @@ LteHelper::InstallSingleEnbDevice (Ptr<Node> n)
NS_ASSERT_MSG (mm, "MobilityModel needs to be set on node before calling LteHelper::InstallUeDevice ()");
dlPhy->SetMobility (mm);
ulPhy->SetMobility (mm);
m_uplinkChannel->AddRx (ulPhy);
Ptr<AntennaModel> antenna = (m_enbAntennaModelFactory.Create ())->GetObject<AntennaModel> ();
NS_ASSERT_MSG (antenna, "error in creating the AntennaModel object");
@@ -378,6 +390,8 @@ LteHelper::InstallSingleEnbDevice (Ptr<Node> n)
dev->Start ();
m_uplinkChannel->AddRx (ulPhy);
if (m_epcHelper != 0)
{
NS_LOG_INFO ("adding this eNB to the EPC");
@@ -410,7 +424,6 @@ LteHelper::InstallSingleUeDevice (Ptr<Node> n)
dlPhy->SetMobility (mm);
ulPhy->SetMobility (mm);
m_downlinkChannel->AddRx (dlPhy);
Ptr<AntennaModel> antenna = (m_ueAntennaModelFactory.Create ())->GetObject<AntennaModel> ();
NS_ASSERT_MSG (antenna, "error in creating the AntennaModel object");
@@ -470,7 +483,6 @@ LteHelper::Attach (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice)
Ptr<LteUePhy> uePhy = ueDevice->GetObject<LteUeNetDevice> ()->GetPhy ();
enbPhy->AddUePhy (rnti, uePhy);
//if (m_fadingModelFactory.GetTypeId ().GetName ().compare ( "ns3::TraceFadingLossModel") == 0)
if (m_fadingModelType.compare ( "ns3::TraceFadingLossModel") == 0)
{
Ptr<MobilityModel> mm_enb_dl = enbPhy->GetDownlinkSpectrumPhy ()->GetMobility ()->GetObject<MobilityModel> ();
@@ -491,6 +503,8 @@ LteHelper::Attach (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice)
enbDevice->GetObject<LteEnbNetDevice> ()->GetUlEarfcn ());
ueDevice->Start ();
m_downlinkChannel->AddRx (uePhy->GetDownlinkSpectrumPhy ());
}
void
@@ -614,32 +628,6 @@ LteHelper::EnableLogComponents (void)
LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL);
std::string propModelStr = m_dlPathlossModelFactory.GetTypeId ().GetName ().erase (0,5).c_str ();
/*
const char* propModel = m_dlPathlossModelFactory.GetTypeId ().GetName ().erase (0,5).c_str ();
if (propModelStr.compare ("RandomPropagationLossModel") ||
propModelStr.compare ("FriisPropagationLossModel")||
propModelStr.compare ("TwoRayGroundPropagationLossModel")||
propModelStr.compare ("LogDistancePropagationLossModel")||
propModelStr.compare ("ThreeLogDistancePropagationLossModel")||
propModelStr.compare ("NakagamiPropagationLossModel")||
propModelStr.compare ("FixedRssLossModel")||
propModelStr.compare ("MatrixPropagationLossModel")||
propModelStr.compare ("RangePropagationLossModel"))
{
LogComponentEnable ("PropagationLossModel", LOG_LEVEL_ALL);
}
else
{
LogComponentEnable (propModel, LOG_LEVEL_ALL);
}
if (m_fadingModelType.compare ("ns3::TraceFadingLossModel") == 0)
{
const char* fadingModel = m_fadingModelType.erase (0,5).c_str ();
LogComponentEnable (fadingModel, LOG_LEVEL_ALL);
}
LogComponentEnable ("SingleModelSpectrumChannel", LOG_LEVEL_ALL);
*/
LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL);
LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL);
LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL);

View File

@@ -138,6 +138,19 @@ public:
*/
void SetUeAntennaModelAttribute (std::string n, const AttributeValue &v);
/**
*
* \param type the type of SpectrumChannel to be used for the UEs
*/
void SetSpectrumChannelType (std::string type);
/**
* set an attribute for the SpectrumChannel to be used for the UEs
*
* \param n the name of the attribute
* \param v the value of the attribute
*/
void SetSpectrumChannelAttribute (std::string n, const AttributeValue &v);
/**
* create a set of eNB devices
*
@@ -322,6 +335,8 @@ private:
ObjectFactory m_dlPathlossModelFactory;
ObjectFactory m_ulPathlossModelFactory;
ObjectFactory m_channelFactory;
std::string m_fadingModelType;
ObjectFactory m_fadingModelFactory;

View File

@@ -0,0 +1,171 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright 2012 Centre Tecnologic de Telecomunicacions de Catalunya (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 "lte-hex-grid-enb-topology-helper.h"
#include <ns3/double.h>
#include <ns3/log.h>
#include <ns3/abort.h>
#include <ns3/pointer.h>
#include <ns3/epc-helper.h>
#include <iostream>
NS_LOG_COMPONENT_DEFINE ("LteHexGridEnbTopologyHelper");
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (LteHexGridEnbTopologyHelper);
LteHexGridEnbTopologyHelper::LteHexGridEnbTopologyHelper ()
{
NS_LOG_FUNCTION (this);
}
LteHexGridEnbTopologyHelper::~LteHexGridEnbTopologyHelper (void)
{
NS_LOG_FUNCTION (this);
}
TypeId LteHexGridEnbTopologyHelper::GetTypeId (void)
{
static TypeId
tid =
TypeId ("ns3::LteHexGridEnbTopologyHelper")
.SetParent<Object> ()
.AddConstructor<LteHexGridEnbTopologyHelper> ()
.AddAttribute ("InterSiteDistance",
"The distance [m] between nearby sites",
DoubleValue (500),
MakeDoubleAccessor (&LteHexGridEnbTopologyHelper::m_d),
MakeDoubleChecker<double> ())
.AddAttribute ("SectorOffset",
"The offset [m] in the position for the node of each sector with respect "
"to the center of the three-sector site",
DoubleValue (0.5),
MakeDoubleAccessor (&LteHexGridEnbTopologyHelper::m_offset),
MakeDoubleChecker<double> ())
.AddAttribute ("SiteHeight",
"The height [m] of each site",
DoubleValue (30),
MakeDoubleAccessor (&LteHexGridEnbTopologyHelper::m_siteHeight),
MakeDoubleChecker<double> ())
.AddAttribute ("MinX", "The x coordinate where the hex grid starts.",
DoubleValue (0.0),
MakeDoubleAccessor (&LteHexGridEnbTopologyHelper::m_xMin),
MakeDoubleChecker<double> ())
.AddAttribute ("MinY", "The y coordinate where the hex grid starts.",
DoubleValue (0.0),
MakeDoubleAccessor (&LteHexGridEnbTopologyHelper::m_yMin),
MakeDoubleChecker<double> ())
.AddAttribute ("GridWidth", "The number of sites in even rows (odd rows will have one additional site).",
UintegerValue (1),
MakeUintegerAccessor (&LteHexGridEnbTopologyHelper::m_gridWidth),
MakeUintegerChecker<uint32_t> ())
;
return tid;
}
void
LteHexGridEnbTopologyHelper::DoDispose ()
{
NS_LOG_FUNCTION (this);
Object::DoDispose ();
}
void
LteHexGridEnbTopologyHelper::SetLteHelper (Ptr<LteHelper> h)
{
NS_LOG_FUNCTION (this << h);
m_lteHelper = h;
}
NetDeviceContainer
LteHexGridEnbTopologyHelper::SetPositionAndInstallEnbDevice (NodeContainer c)
{
NS_LOG_FUNCTION (this);
NetDeviceContainer enbDevs;
const double xydfactor = sqrt (0.75);
double yd = xydfactor*m_d;
for (uint32_t n = 0; n < c.GetN (); ++n)
{
uint32_t currentSite = n / 3;
uint32_t biRowIndex = (currentSite / (m_gridWidth + m_gridWidth + 1));
uint32_t biRowRemainder = currentSite % (m_gridWidth + m_gridWidth + 1);
uint32_t rowIndex = biRowIndex*2;
uint32_t colIndex = biRowRemainder;
if (biRowRemainder >= m_gridWidth)
{
++rowIndex;
colIndex -= m_gridWidth;
}
NS_LOG_LOGIC ("node " << n << " site " << currentSite
<< " rowIndex " << rowIndex
<< " colIndex " << colIndex
<< " biRowIndex " << biRowIndex
<< " biRowRemainder " << biRowRemainder);
double y = m_yMin + yd * rowIndex;
double x;
double antennaOrientation;
if ((rowIndex % 2) == 0)
{
x = m_xMin + m_d * colIndex;
}
else // row is odd
{
x = m_xMin -(0.5*m_d) + m_d * colIndex;
}
switch (n%3)
{
case 0:
antennaOrientation = 0;
x += m_offset;
break;
case 1:
antennaOrientation = 120;
x -= m_offset/2.0;
y += m_offset*xydfactor;
break;
case 2:
antennaOrientation = -120;
x -= m_offset/2.0;
y -= m_offset*xydfactor;
break;
default:
break;
}
Ptr<Node> node = c.Get (n);
Ptr<MobilityModel> mm = node->GetObject<MobilityModel> ();
Vector pos (x, y, m_siteHeight);
NS_LOG_LOGIC ("node " << n << " at " << pos << " antennaOrientation " << antennaOrientation);
mm->SetPosition (Vector (x, y, m_siteHeight));
m_lteHelper->SetEnbAntennaModelAttribute ("Orientation", DoubleValue (antennaOrientation));
enbDevs.Add (m_lteHelper->InstallEnbDevice (node));
}
return enbDevs;
}
} // namespace ns3

View File

@@ -0,0 +1,87 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (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 LTE_HEX_GRID_ENB_TOPOLOGY_HELPER_H
#define LTE_HEX_GRID_ENB_TOPOLOGY_HELPER_H
#include <ns3/lte-helper.h>
namespace ns3 {
/**
* This helper class allows to easily create a topology with eNBs
* grouped in three-sector sites layed out on an hexagonal grid. The
* layout is done row-wise.
*
*/
class LteHexGridEnbTopologyHelper : public Object
{
public:
LteHexGridEnbTopologyHelper (void);
virtual ~LteHexGridEnbTopologyHelper (void);
static TypeId GetTypeId (void);
virtual void DoDispose (void);
/**
* Set the LteHelper to be used to actually create the EnbNetDevices
*
* \note if no EpcHelper is ever set, then LteHexGridEnbTopologyHelper will default
* to creating an LTE-only simulation with no EPC, using LteRlcSm as
* the RLC model, and without supporting any IP networking. In other
* words, it will be a radio-level simulation involving only LTE PHY
* and MAC and the FF Scheduler, with a saturation traffic model for
* the RLC.
*
* \param h a pointer to the EpcHelper to be used
*/
void SetLteHelper (Ptr<LteHelper> h);
/**
* Position the nodes on a hex grid and install the corresponding
* EnbNetDevices with antenna boresight configured properly
*
* \param c the node container where the devices are to be installed
*
* \return the NetDeviceContainer with the newly created devices
*/
NetDeviceContainer SetPositionAndInstallEnbDevice (NodeContainer c);
private:
Ptr<LteHelper> m_lteHelper;
double m_offset;
double m_d;
double m_xMin;
double m_yMin;
uint32_t m_gridWidth;
uint32_t m_siteHeight;
};
} // namespace ns3
#endif // LTE_HEX_GRID_ENB_TOPOLOGY_HELPER_H

View File

@@ -34,6 +34,7 @@
#include <ns3/simulator.h>
#include <ns3/node.h>
#include <ns3/buildings-helper.h>
#include <ns3/lte-spectrum-value-helper.h>
#include <fstream>
#include <limits>
@@ -101,7 +102,7 @@ RadioEnvironmentMapHelper::GetTypeId (void)
.AddAttribute ("YRes", "The resolution (number of points) of the map along the y axis.",
UintegerValue (100),
MakeUintegerAccessor (&RadioEnvironmentMapHelper::m_yRes),
MakeUintegerChecker<uint32_t> (2,std::numeric_limits<uint16_t>::max ()))
MakeUintegerChecker<uint16_t> (2,std::numeric_limits<uint16_t>::max ()))
.AddAttribute ("Z", "The value of the z coordinate for which the map is to be generated",
DoubleValue (0.0),
MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_z),
@@ -115,11 +116,53 @@ RadioEnvironmentMapHelper::GetTypeId (void)
DoubleValue (1.4230e-10),
MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_noisePower),
MakeDoubleChecker<double> ())
.AddAttribute ("MaxPointsPerIteration", "Maximum number of REM points to be calculated per iteration. Every point consumes approximately 5KB of memory.",
UintegerValue (20000),
MakeUintegerAccessor (&RadioEnvironmentMapHelper::m_maxPointsPerIteration),
MakeUintegerChecker<uint32_t> (1,std::numeric_limits<uint32_t>::max ()))
.AddAttribute ("Earfcn",
"E-UTRA Absolute Radio Frequency Channel Number (EARFCN) "
"as per 3GPP 36.101 Section 5.7.3. ",
UintegerValue (100),
MakeUintegerAccessor (&RadioEnvironmentMapHelper::m_earfcn),
MakeUintegerChecker<uint16_t> ())
.AddAttribute ("Bandwidth",
"Transmission Bandwidth Configuration (in number of RBs) over which the SINR will be calculated",
UintegerValue (25),
MakeUintegerAccessor (&RadioEnvironmentMapHelper::SetBandwidth,
&RadioEnvironmentMapHelper::GetBandwidth),
MakeUintegerChecker<uint16_t> ())
;
return tid;
}
uint8_t
RadioEnvironmentMapHelper::GetBandwidth () const
{
return m_bandwidth;
}
void
RadioEnvironmentMapHelper::SetBandwidth (uint8_t bw)
{
switch (bw)
{
case 6:
case 15:
case 25:
case 50:
case 75:
case 100:
m_bandwidth = bw;
break;
default:
NS_FATAL_ERROR ("invalid bandwidth value " << (uint16_t) bw);
break;
}
}
void
@@ -138,66 +181,145 @@ RadioEnvironmentMapHelper::Install ()
m_channel = match.Get (0)->GetObject<SpectrumChannel> ();
NS_ABORT_MSG_IF (m_channel == 0, "object at " << m_channelPath << "is not of type SpectrumChannel");
double xStep = (m_xMax - m_xMin)/(m_xRes-1);
double yStep = (m_yMax - m_yMin)/(m_yRes-1);
for (double x = m_xMin; x < m_xMax + 0.5*xStep; x += xStep)
{
for (double y = m_yMin; y < m_yMax + 0.5*yStep ; y += yStep)
{
RemPoint p;
p.phy = CreateObject<RemSpectrumPhy> ();
p.bmm = CreateObject<BuildingsMobilityModel> ();
p.phy->SetMobility (p.bmm);
p.bmm->SetPosition (Vector (x, y, m_z));
BuildingsHelper::MakeConsistent (p.bmm);
m_rem.push_back (p);
}
}
Simulator::Schedule (Seconds (0.0055), &RadioEnvironmentMapHelper::Connect, this);
Simulator::Schedule (Seconds (0.0065), &RadioEnvironmentMapHelper::PrintAndDeactivate, this);
}
void
RadioEnvironmentMapHelper::Connect ()
{
NS_LOG_FUNCTION (this);
for (std::list<RemPoint>::iterator it = m_rem.begin ();
it != m_rem.end ();
++it)
{
NS_LOG_LOGIC ("adding phy " << it->phy);
m_channel->AddRx (it->phy);
}
}
void
RadioEnvironmentMapHelper::PrintAndDeactivate ()
{
NS_LOG_FUNCTION (this);
std::ofstream outFile;
outFile.open (m_outputFile.c_str ());
if (!outFile.is_open ())
m_outFile.open (m_outputFile.c_str ());
if (!m_outFile.is_open ())
{
NS_FATAL_ERROR ("Can't open file " << (m_outputFile));
return;
}
Simulator::Schedule (Seconds (0.0016),
&RadioEnvironmentMapHelper::DelayedInstall,
this);
}
void
RadioEnvironmentMapHelper::DelayedInstall ()
{
NS_LOG_FUNCTION (this);
m_xStep = (m_xMax - m_xMin)/(m_xRes-1);
m_yStep = (m_yMax - m_yMin)/(m_yRes-1);
if ((double)m_xRes * (double) m_yRes < (double) m_maxPointsPerIteration)
{
m_maxPointsPerIteration = m_xRes * m_yRes;
}
for (uint32_t i = 0; i < m_maxPointsPerIteration; ++i)
{
RemPoint p;
p.phy = CreateObject<RemSpectrumPhy> ();
p.bmm = CreateObject<BuildingsMobilityModel> ();
p.phy->SetRxSpectrumModel (LteSpectrumValueHelper::GetSpectrumModel (m_earfcn, m_bandwidth));
p.phy->SetMobility (p.bmm);
m_channel->AddRx (p.phy);
m_rem.push_back (p);
}
double remIterationStartTime = 0.0001;
double xMinNext = m_xMin;
double yMinNext = m_yMin;
uint32_t numPointsCurrentIteration = 0;
bool justScheduled = false;
for (double x = m_xMin; x < m_xMax + 0.5*m_xStep; x += m_xStep)
{
for (double y = m_yMin; y < m_yMax + 0.5*m_yStep ; y += m_yStep)
{
if (justScheduled)
{
xMinNext = x;
yMinNext = y;
justScheduled = false;
}
++numPointsCurrentIteration;
if ((numPointsCurrentIteration == m_maxPointsPerIteration)
|| ((x > m_xMax - 0.5*m_xStep) && (y > m_yMax - 0.5*m_yStep)) )
{
Simulator::Schedule (Seconds (remIterationStartTime),
&RadioEnvironmentMapHelper::RunOneIteration,
this, xMinNext, x, yMinNext, y);
remIterationStartTime += 0.001;
justScheduled = true;
numPointsCurrentIteration = 0;
}
}
}
Simulator::Schedule (Seconds (remIterationStartTime),
&RadioEnvironmentMapHelper::Finalize,
this);
}
void
RadioEnvironmentMapHelper::RunOneIteration (double xMin, double xMax, double yMin, double yMax)
{
NS_LOG_FUNCTION (this << xMin << xMax << yMin << yMax);
std::list<RemPoint>::iterator remIt = m_rem.begin ();
double x;
double y;
for (x = xMin; x < xMax + 0.5*m_xStep; x += m_xStep)
{
for (y = (x == xMin) ? yMin : m_yMin;
y < ((x == xMax) ? yMax : m_yMax) + 0.5*m_yStep;
y += m_yStep)
{
NS_ASSERT (remIt != m_rem.end ());
remIt->bmm->SetPosition (Vector (x, y, m_z));
BuildingsHelper::MakeConsistent (remIt->bmm);
++remIt;
}
}
if (remIt != m_rem.end ())
{
NS_ASSERT ((x > m_xMax - 0.5*m_xStep) && (y > m_yMax - 0.5*m_yStep));
NS_LOG_LOGIC ("deactivating RemSpectrumPhys that are unneeded in the last iteration");
while (remIt != m_rem.end ())
{
remIt->phy->Deactivate ();
++remIt;
}
}
Simulator::Schedule (Seconds (0.0005), &RadioEnvironmentMapHelper::PrintAndReset, this);
}
void
RadioEnvironmentMapHelper::PrintAndReset ()
{
NS_LOG_FUNCTION (this);
for (std::list<RemPoint>::iterator it = m_rem.begin ();
it != m_rem.end ();
++it)
{
if (!(it->phy->IsActive ()))
{
// should occur only upon last iteration when some RemPoint
// at the end of the list can be unused
break;
}
Vector pos = it->bmm->GetPosition ();
outFile << pos.x << "\t"
<< pos.y << "\t"
<< pos.z << "\t"
<< it->phy->GetSinr (m_noisePower)
<< std::endl;
it->phy->Deactivate ();
NS_LOG_LOGIC ("output: " << pos.x << "\t"
<< pos.y << "\t"
<< pos.z << "\t"
<< it->phy->GetSinr (m_noisePower));
m_outFile << pos.x << "\t"
<< pos.y << "\t"
<< pos.z << "\t"
<< it->phy->GetSinr (m_noisePower)
<< std::endl;
it->phy->Reset ();
}
outFile.close ();
}
void
RadioEnvironmentMapHelper::Finalize ()
{
NS_LOG_FUNCTION (this);
m_outFile.close ();
if (m_stopWhenDone)
{
Simulator::Stop ();

View File

@@ -24,7 +24,7 @@
#include <ns3/object.h>
#include <fstream>
namespace ns3 {
@@ -36,7 +36,7 @@ class SpectrumChannel;
class BuildingsMobilityModel;
/**
* Generates a 2D map of the SINR from the strongest transmitter.
* Generates a 2D map of the SINR from the strongest transmitter in the downlink of an LTE FDD system.
*
*/
class RadioEnvironmentMapHelper : public Object
@@ -44,19 +44,35 @@ class RadioEnvironmentMapHelper : public Object
public:
RadioEnvironmentMapHelper ();
virtual ~RadioEnvironmentMapHelper ();
// inherited from Object
virtual void DoDispose (void);
static TypeId GetTypeId (void);
/**
* \return the bandwidth (in num of RBs) over which SINR is calculated
*/
uint8_t GetBandwidth () const;
/**
*
* \param bw the bandwidth (in num of RBs) over which SINR is calculated
*/
void SetBandwidth (uint8_t bw);
/**
* Deploy the RemSpectrumPhy objects that generate the map according to the specified settings.
*
*/
void Install ();
private:
void Connect ();
void PrintAndDeactivate ();
void DelayedInstall ();
void RunOneIteration (double xMin, double xMax, double yMin, double yMax);
void PrintAndReset ();
void Finalize ();
struct RemPoint
@@ -70,11 +86,18 @@ private:
double m_xMin;
double m_xMax;
uint16_t m_xRes;
double m_xStep;
double m_yMin;
double m_yMax;
uint16_t m_yRes;
double m_yStep;
uint32_t m_maxPointsPerIteration;
uint16_t m_earfcn;
uint16_t m_bandwidth;
double m_z;
std::string m_channelPath;
@@ -85,6 +108,9 @@ private:
Ptr<SpectrumChannel> m_channel;
double m_noisePower;
std::ofstream m_outFile;
};

View File

@@ -87,36 +87,6 @@ IdealControlMessage::GetMessageType (void)
}
// ----------------------------------------------------------------------------------------------------------
PdcchMapIdealControlMessage::PdcchMapIdealControlMessage (void)
{
m_idealPdcchMessage = new IdealPdcchMessage ();
SetMessageType (IdealControlMessage::ALLOCATION_MAP);
}
PdcchMapIdealControlMessage::~PdcchMapIdealControlMessage (void)
{
delete m_idealPdcchMessage;
}
void
PdcchMapIdealControlMessage::AddNewRecord (Direction direction,
int subChannel, Ptr<LteNetDevice> ue, double mcs)
{
}
PdcchMapIdealControlMessage::IdealPdcchMessage*
PdcchMapIdealControlMessage::GetMessage (void)
{
return m_idealPdcchMessage;
}
// ----------------------------------------------------------------------------------------------------------

View File

@@ -99,95 +99,6 @@ private:
// ----------------------------------------------------------------------------------------------------------
#ifndef PDCCH_MAP_IDEAL_CONTROL_MESSAGES_H
#define PDCCH_MAP_IDEAL_CONTROL_MESSAGES_H
#include "ns3/object.h"
#include <list>
namespace ns3 {
class LteNetDevice;
/**
* \ingroup lte
*
* \brief The PdcchMapIdealControlMessage defines an ideal allocation map
* for both UL and DL sends by the eNodeB to all UE,
* using an ideal PDCCH control channel.
* IdealPdcchMessage is composed by a list of IdealPdcchRecord
* where is indicated the UE that can use a particular sub channel
* with a proper MCS scheme.
* This records are the same for both UL and DL, and are created by the
* packet scheduler at the beginning of each sub frame.
* When the IdealPdcchMessage is sent under an ideal control channel,
* all UE stores into a proper variables the informations about
* the resource mapping.
*/
class PdcchMapIdealControlMessage : public IdealControlMessage
{
public:
PdcchMapIdealControlMessage (void);
virtual ~PdcchMapIdealControlMessage (void);
/**
* Direction for which the message is created
*/
enum Direction
{
DOWNLINK, UPLINK
};
/**
* The PDCCH ideal record
*/
struct IdealPdcchRecord
{
/** the direction */
Direction m_direction;
/** the sub channel */
int m_idSubChannel;
/** the ue that receive the mapping */
Ptr<LteNetDevice> m_ue;
/** the selected msc */
double m_mcsIndex;
};
/**
* The PDCCH ideal message
*/
typedef std::list<struct IdealPdcchRecord> IdealPdcchMessage;
/**
* \brief add a PDCCH record into the message.
* \param direction the direction of the map
* \param subChannel the scheduled sub channel
* \param ue the ue the can use the sub channel for transmission
* \param mcs the selected MCS scheme
*/
void AddNewRecord (Direction direction,
int subChannel, Ptr<LteNetDevice> ue, double mcs);
/**
* \brief Get the message
* \return the pointer to the message
*/
IdealPdcchMessage* GetMessage (void);
private:
IdealPdcchMessage *m_idealPdcchMessage;
};
} // namespace ns3
#endif /* PDCCH_MAP_IDEAL_CONTROL_MESSAGES_H */
// ----------------------------------------------------------------------------------------------------------
@@ -201,9 +112,10 @@ private:
namespace ns3 {
/**
* The Downlink Data Control Indicator messages defines the RB allocation for the
* users
*/
* \ingroup lte
* The Downlink Data Control Indicator messages defines the RB allocation for the
* users in the downlink
*/
class DlDciIdealControlMessage : public IdealControlMessage
{
public:
@@ -243,9 +155,10 @@ private:
namespace ns3 {
/**
* The Uplink Data Control Indicator messages defines the RB allocation for the
* users
*/
* \ingroup lte
* The Uplink Data Control Indicator messages defines the RB allocation for the
* users in the uplink
*/
class UlDciIdealControlMessage : public IdealControlMessage
{
public:
@@ -289,9 +202,10 @@ namespace ns3 {
class LteNetDevice;
/**
* The downlink CqiIdealControlMessage defines an ideal list of
* feedback about the channel quality sent by the UE to the eNodeB.
*/
* \ingroup lte
* The downlink CqiIdealControlMessage defines an ideal list of
* feedback about the channel quality sent by the UE to the eNodeB.
*/
class DlCqiIdealControlMessage : public IdealControlMessage
{
public:
@@ -332,9 +246,10 @@ namespace ns3 {
class LteNetDevice;
/**
* The uplink BsrIdealControlMessage defines the specific
* extension of the CE element for reporting the buffer status report
*/
* \ingroup lte
* The uplink BsrIdealControlMessage defines the specific
* extension of the CE element for reporting the buffer status report
*/
class BsrIdealControlMessage : public IdealControlMessage
{
public:

View File

@@ -99,13 +99,13 @@ TypeId LteEnbNetDevice::GetTypeId (void)
"as per 3GPP 36.101 Section 5.7.3. ",
UintegerValue (100),
MakeUintegerAccessor (&LteEnbNetDevice::m_dlEarfcn),
MakeUintegerChecker<uint16_t> ())
MakeUintegerChecker<uint16_t> (0, 6149))
.AddAttribute ("UlEarfcn",
"Uplink E-UTRA Absolute Radio Frequency Channel Number (EARFCN) "
"as per 3GPP 36.101 Section 5.7.3. ",
UintegerValue (18100),
MakeUintegerAccessor (&LteEnbNetDevice::m_ulEarfcn),
MakeUintegerChecker<uint16_t> ())
MakeUintegerChecker<uint16_t> (18000, 24149))
;
return tid;
}

View File

@@ -167,14 +167,7 @@ LteSpectrumPhy::SetChannel (Ptr<SpectrumChannel> c)
Ptr<const SpectrumModel>
LteSpectrumPhy::GetRxSpectrumModel () const
{
if (m_txPsd)
{
return m_txPsd->GetSpectrumModel ();
}
else
{
return 0;
}
return m_rxSpectrumModel;
}
@@ -192,6 +185,7 @@ LteSpectrumPhy::SetNoisePowerSpectralDensity (Ptr<const SpectrumValue> noisePsd)
{
NS_LOG_FUNCTION (this << noisePsd);
NS_ASSERT (noisePsd);
m_rxSpectrumModel = noisePsd->GetSpectrumModel ();
m_interference->SetNoisePowerSpectralDensity (noisePsd);
}

View File

@@ -197,6 +197,7 @@ private:
Ptr<SpectrumChannel> m_channel;
Ptr<const SpectrumModel> m_rxSpectrumModel;
Ptr<SpectrumValue> m_txPsd;
Ptr<PacketBurst> m_txPacketBurst;
std::list<Ptr<PacketBurst> > m_rxPacketBurstList;

View File

@@ -105,8 +105,7 @@ RemSpectrumPhy::GetDevice ()
Ptr<const SpectrumModel>
RemSpectrumPhy::GetRxSpectrumModel () const
{
// supports any SpectrumModel
return 0;
return m_rxSpectrumModel;
}
Ptr<AntennaModel>
@@ -133,6 +132,13 @@ RemSpectrumPhy::StartRx (Ptr<SpectrumSignalParameters> params)
}
}
void
RemSpectrumPhy::SetRxSpectrumModel (Ptr<const SpectrumModel> m)
{
NS_LOG_FUNCTION (this << m);
m_rxSpectrumModel = m;
}
double
RemSpectrumPhy::GetSinr (double noisePower)
{
@@ -145,5 +151,18 @@ RemSpectrumPhy::Deactivate ()
m_active = false;
}
bool
RemSpectrumPhy::IsActive ()
{
return m_active;
}
void
RemSpectrumPhy::Reset ()
{
m_referenceSignalPower = 0;
m_sumPower = 0;
}
} // namespace ns3

View File

@@ -70,21 +70,39 @@ public:
void StartRx (Ptr<SpectrumSignalParameters> params);
/**
* set the RX spectrum model to be used
*
* \param m
*/
void SetRxSpectrumModel (Ptr<const SpectrumModel> m);
/**
*
* \return the Signal to Noise Ratio calculated
*/
double GetSinr (double noisePower);
/**
* make StartRx a no-op from now on
* make StartRx a no-op from now on, and mark instance as inactive
*
*/
void Deactivate ();
/**
*
* \return true if active
*/
bool IsActive ();
/**
* Reset the SINR calculator
*
*/
void Reset ();
private:
Ptr<MobilityModel> m_mobility;
Ptr<const SpectrumModel> m_rxSpectrumModel;
double m_referenceSignalPower;
double m_sumPower;

View File

@@ -39,6 +39,7 @@ def build(bld):
'helper/radio-bearer-stats-calculator.cc',
'helper/mac-stats-calculator.cc',
'helper/radio-environment-map-helper.cc',
'helper/lte-hex-grid-enb-topology-helper.cc',
'model/rem-spectrum-phy.cc',
'model/ff-mac-csched-sap.cc',
'model/ff-mac-sched-sap.cc',
@@ -132,6 +133,7 @@ def build(bld):
'helper/mac-stats-calculator.h',
'helper/radio-bearer-stats-calculator.h',
'helper/radio-environment-map-helper.h',
'helper/lte-hex-grid-enb-topology-helper.h',
'model/rem-spectrum-phy.h',
'model/ff-mac-common.h',
'model/ff-mac-csched-sap.h',