A Discrete-Event Network Simulator
API
test-lte-antenna.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011, 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Manuel Requena <manuel.requena@cttc.es>
18  * Nicola Baldo <nbaldo@cttc.es>
19  */
20 
21 #include "ns3/boolean.h"
22 #include "ns3/double.h"
23 #include "ns3/enum.h"
24 #include "ns3/ff-mac-scheduler.h"
25 #include "ns3/log.h"
26 #include "ns3/lte-enb-net-device.h"
27 #include "ns3/lte-enb-phy.h"
28 #include "ns3/lte-global-pathloss-database.h"
29 #include "ns3/lte-helper.h"
30 #include "ns3/lte-ue-net-device.h"
31 #include "ns3/lte-ue-phy.h"
32 #include "ns3/mobility-helper.h"
33 #include "ns3/simulator.h"
34 #include "ns3/string.h"
35 #include "ns3/test.h"
36 #include <ns3/lte-chunk-processor.h>
37 
38 using namespace ns3;
39 
40 NS_LOG_COMPONENT_DEFINE("LteAntennaTest");
41 
51 {
52  public:
61  static std::string BuildNameString(double orientationDegrees,
62  double beamwidthDegrees,
63  double x,
64  double y);
74  LteEnbAntennaTestCase(double orientationDegrees,
75  double beamwidthDegrees,
76  double x,
77  double y,
78  double antennaGainDb);
80  ~LteEnbAntennaTestCase() override;
81 
82  private:
83  void DoRun() override;
84 
87  double m_x;
88  double m_y;
89  double m_antennaGainDb;
90 };
91 
92 std::string
93 LteEnbAntennaTestCase::BuildNameString(double orientationDegrees,
94  double beamwidthDegrees,
95  double x,
96  double y)
97 {
98  std::ostringstream oss;
99  oss << "o=" << orientationDegrees << ", bw=" << beamwidthDegrees << ", x=" << x << ", y=" << y;
100  return oss.str();
101 }
102 
104  double beamwidthDegrees,
105  double x,
106  double y,
107  double antennaGainDb)
108  : TestCase(BuildNameString(orientationDegrees, beamwidthDegrees, x, y)),
109  m_orientationDegrees(orientationDegrees),
110  m_beamwidthDegrees(beamwidthDegrees),
111  m_x(x),
112  m_y(y),
113  m_antennaGainDb(antennaGainDb)
114 {
115  NS_LOG_FUNCTION(this);
116 }
117 
119 {
120 }
121 
122 void
124 {
125  Config::Reset();
126  Config::SetDefault("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue(false));
127  Config::SetDefault("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue(false));
128  Config::SetDefault("ns3::LteHelper::UseIdealRrc", BooleanValue(true));
129 
130  // Disable Uplink Power Control
131  Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
132 
133  Ptr<LteHelper> lteHelper = CreateObject<LteHelper>();
134 
135  // use 0dB Pathloss, since we are testing only the antenna gain
136  lteHelper->SetAttribute("PathlossModel",
137  StringValue("ns3::ConstantSpectrumPropagationLossModel"));
138  lteHelper->SetPathlossModelAttribute("Loss", DoubleValue(0.0));
139 
140  // Create Nodes: eNodeB and UE
141  NodeContainer enbNodes;
142  NodeContainer ueNodes;
143  enbNodes.Create(1);
144  ueNodes.Create(1);
145  NodeContainer allNodes = NodeContainer(enbNodes, ueNodes);
146 
147  // Install Mobility Model
148  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
149  positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // eNB
150  positionAlloc->Add(Vector(m_x, m_y, 0.0)); // UE
152  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
153  mobility.SetPositionAllocator(positionAlloc);
154  mobility.Install(allNodes);
155 
156  // Create Devices and install them in the Nodes (eNB and UE)
157  NetDeviceContainer enbDevs;
158  NetDeviceContainer ueDevs;
159  lteHelper->SetSchedulerType("ns3::RrFfMacScheduler");
160  lteHelper->SetSchedulerAttribute("UlCqiFilter", EnumValue(FfMacScheduler::PUSCH_UL_CQI));
161  lteHelper->SetEnbAntennaModelType("ns3::CosineAntennaModel");
163  lteHelper->SetEnbAntennaModelAttribute("HorizontalBeamwidth", DoubleValue(m_beamwidthDegrees));
164  lteHelper->SetEnbAntennaModelAttribute("MaxGain", DoubleValue(0.0));
165 
166  // set DL and UL bandwidth.
167  lteHelper->SetEnbDeviceAttribute("DlBandwidth", UintegerValue(25));
168  lteHelper->SetEnbDeviceAttribute("UlBandwidth", UintegerValue(25));
169 
170  enbDevs = lteHelper->InstallEnbDevice(enbNodes);
171  ueDevs = lteHelper->InstallUeDevice(ueNodes);
172 
173  // Attach a UE to a eNB
174  lteHelper->Attach(ueDevs, enbDevs.Get(0));
175 
176  // Activate the default EPS bearer
177  EpsBearer::Qci q = EpsBearer::NGBR_VIDEO_TCP_DEFAULT;
178  EpsBearer bearer(q);
179  lteHelper->ActivateDataRadioBearer(ueDevs, bearer);
180 
181  // Use testing chunk processor in the PHY layer
182  // It will be used to test that the SNR is as intended
183  Ptr<LtePhy> uePhy = ueDevs.Get(0)->GetObject<LteUeNetDevice>()->GetPhy()->GetObject<LtePhy>();
184  Ptr<LteChunkProcessor> testDlSinr = Create<LteChunkProcessor>();
185  LteSpectrumValueCatcher dlSinrCatcher;
186  testDlSinr->AddCallback(MakeCallback(&LteSpectrumValueCatcher::ReportValue, &dlSinrCatcher));
187  uePhy->GetDownlinkSpectrumPhy()->AddDataSinrChunkProcessor(testDlSinr);
188 
189  Ptr<LtePhy> enbphy =
190  enbDevs.Get(0)->GetObject<LteEnbNetDevice>()->GetPhy()->GetObject<LtePhy>();
191  Ptr<LteChunkProcessor> testUlSinr = Create<LteChunkProcessor>();
192  LteSpectrumValueCatcher ulSinrCatcher;
193  testUlSinr->AddCallback(MakeCallback(&LteSpectrumValueCatcher::ReportValue, &ulSinrCatcher));
194  enbphy->GetUplinkSpectrumPhy()->AddDataSinrChunkProcessor(testUlSinr);
195 
196  // keep track of all path loss values in two centralized objects
198  UplinkLteGlobalPathlossDatabase ulPathlossDb;
199  // we rely on the fact that LteHelper creates the DL channel object first, then the UL channel
200  // object, hence the former will have index 0 and the latter 1
202  "/ChannelList/0/PathLoss",
203  MakeCallback(&DownlinkLteGlobalPathlossDatabase::UpdatePathloss, &dlPathlossDb));
204  Config::Connect("/ChannelList/1/PathLoss",
205  MakeCallback(&UplinkLteGlobalPathlossDatabase::UpdatePathloss, &ulPathlossDb));
206 
207  Simulator::Stop(Seconds(0.035));
208  Simulator::Run();
209 
210  const double enbTxPowerDbm = 30; // default eNB TX power over whole bandwidth
211  const double ueTxPowerDbm = 10; // default UE TX power over whole bandwidth
212  const double ktDbm = -174; // reference LTE noise PSD
213  const double noisePowerDbm =
214  ktDbm + 10 * std::log10(25 * 180000); // corresponds to kT*bandwidth in linear units
215  const double ueNoiseFigureDb = 9.0; // default UE noise figure
216  const double enbNoiseFigureDb = 5.0; // default eNB noise figure
217  double tolerance = (m_antennaGainDb != 0) ? std::abs(m_antennaGainDb) * 0.001 : 0.001;
218 
219  // first test with SINR from LteChunkProcessor
220  // this can only be done for not-too-bad SINR otherwise the measurement won't be available
221  double expectedSinrDl = enbTxPowerDbm + m_antennaGainDb - noisePowerDbm + ueNoiseFigureDb;
222  if (expectedSinrDl > 0)
223  {
224  double calculatedSinrDbDl = -INFINITY;
225  if (dlSinrCatcher.GetValue())
226  {
227  calculatedSinrDbDl = 10.0 * std::log10(dlSinrCatcher.GetValue()->operator[](0));
228  }
229  // remember that propagation loss is 0dB
230  double calculatedAntennaGainDbDl =
231  -(enbTxPowerDbm - calculatedSinrDbDl - noisePowerDbm - ueNoiseFigureDb);
232  NS_LOG_INFO("expected " << m_antennaGainDb << " actual " << calculatedAntennaGainDbDl
233  << " tol " << tolerance);
234  NS_TEST_ASSERT_MSG_EQ_TOL(calculatedAntennaGainDbDl,
236  tolerance,
237  "Wrong DL antenna gain!");
238  }
239  double expectedSinrUl = ueTxPowerDbm + m_antennaGainDb - noisePowerDbm + enbNoiseFigureDb;
240  if (expectedSinrUl > 0)
241  {
242  double calculatedSinrDbUl = -INFINITY;
243  if (ulSinrCatcher.GetValue())
244  {
245  calculatedSinrDbUl = 10.0 * std::log10(ulSinrCatcher.GetValue()->operator[](0));
246  }
247  double calculatedAntennaGainDbUl =
248  -(ueTxPowerDbm - calculatedSinrDbUl - noisePowerDbm - enbNoiseFigureDb);
249  NS_TEST_ASSERT_MSG_EQ_TOL(calculatedAntennaGainDbUl,
251  tolerance,
252  "Wrong UL antenna gain!");
253  }
254 
255  // repeat the same tests with the LteGlobalPathlossDatabases
256  double measuredLossDl = dlPathlossDb.GetPathloss(1, 1);
257  NS_TEST_ASSERT_MSG_EQ_TOL(measuredLossDl, -m_antennaGainDb, tolerance, "Wrong DL loss!");
258  double measuredLossUl = ulPathlossDb.GetPathloss(1, 1);
259  NS_TEST_ASSERT_MSG_EQ_TOL(measuredLossUl, -m_antennaGainDb, tolerance, "Wrong UL loss!");
260 
261  Simulator::Destroy();
262 }
263 
270 {
271  public:
273 };
274 
276  : TestSuite("lte-antenna", SYSTEM)
277 {
278  NS_LOG_FUNCTION(this);
279 
280  // orientation beamwidth x y gain
281  AddTestCase(new LteEnbAntennaTestCase(0.0, 90.0, 1.0, 0.0, 0.0), TestCase::QUICK);
282  AddTestCase(new LteEnbAntennaTestCase(0.0, 90.0, 1.0, 1.0, -3.0), TestCase::QUICK);
283  AddTestCase(new LteEnbAntennaTestCase(0.0, 90.0, 1.0, -1.0, -3.0), TestCase::QUICK);
284  AddTestCase(new LteEnbAntennaTestCase(0.0, 90.0, -1.0, -1.0, -36.396), TestCase::QUICK);
285  AddTestCase(new LteEnbAntennaTestCase(0.0, 90.0, -1.0, -0.0, -1414.6), TestCase::QUICK);
286  AddTestCase(new LteEnbAntennaTestCase(0.0, 90.0, -1.0, 1.0, -36.396), TestCase::QUICK);
287  AddTestCase(new LteEnbAntennaTestCase(45.0, 90.0, 1.0, 1.0, 0.0), TestCase::QUICK);
288  AddTestCase(new LteEnbAntennaTestCase(-45.0, 90.0, 1.0, -1.0, 0.0), TestCase::QUICK);
289  AddTestCase(new LteEnbAntennaTestCase(90.0, 90.0, 1.0, 1.0, -3.0), TestCase::QUICK);
290  AddTestCase(new LteEnbAntennaTestCase(-90.0, 90.0, 1.0, -1.0, -3.0), TestCase::QUICK);
291 
292  AddTestCase(new LteEnbAntennaTestCase(0.0, 120.0, 1.0, 0.0, 0.0), TestCase::QUICK);
293  AddTestCase(new LteEnbAntennaTestCase(0.0, 120.0, 0.5, sin(M_PI / 3), -3.0), TestCase::QUICK);
294  AddTestCase(new LteEnbAntennaTestCase(0.0, 120.0, 0.5, -sin(M_PI / 3), -3.0), TestCase::QUICK);
295  AddTestCase(new LteEnbAntennaTestCase(0.0, 120.0, -1.0, -2.0, -13.410), TestCase::QUICK);
296  AddTestCase(new LteEnbAntennaTestCase(0.0, 120.0, -1.0, 1.0, -20.034), TestCase::QUICK);
297  AddTestCase(new LteEnbAntennaTestCase(60.0, 120.0, 0.5, sin(M_PI / 3), 0.0), TestCase::QUICK);
298  AddTestCase(new LteEnbAntennaTestCase(-60.0, 120.0, 0.5, -sin(M_PI / 3), 0.0), TestCase::QUICK);
299  AddTestCase(new LteEnbAntennaTestCase(-60.0, 120.0, 0.5, -sin(M_PI / 3), 0.0), TestCase::QUICK);
300  AddTestCase(new LteEnbAntennaTestCase(-120.0, 120.0, -0.5, -sin(M_PI / 3), 0.0),
301  TestCase::QUICK);
302  AddTestCase(new LteEnbAntennaTestCase(-120.0, 120.0, 0.5, -sin(M_PI / 3), -3.0),
303  TestCase::QUICK);
304  AddTestCase(new LteEnbAntennaTestCase(-120.0, 120.0, -1, 0, -3.0), TestCase::QUICK);
305  AddTestCase(new LteEnbAntennaTestCase(-120.0, 120.0, -1, 2, -15.578), TestCase::QUICK);
306  AddTestCase(new LteEnbAntennaTestCase(-120.0, 120.0, 1, 0, -14.457), TestCase::QUICK);
307  AddTestCase(new LteEnbAntennaTestCase(-120.0, 120.0, 1, 2, -73.154), TestCase::QUICK);
308  AddTestCase(new LteEnbAntennaTestCase(-120.0, 120.0, 1, -0.1, -12.754), TestCase::QUICK);
309 }
310 
Lte Enb Antenna Test Suite.
Tests that the propagation model and the antenna parameters are generate the correct values.
double m_orientationDegrees
antenna orientation in degrees
double m_antennaGainDb
antenna gain in dB
static std::string BuildNameString(double orientationDegrees, double beamwidthDegrees, double x, double y)
Build name string.
double m_x
x position of the UE
double m_beamwidthDegrees
antenna beamwidth in degrees
double m_y
y position of the UE
void DoRun() override
Implementation to actually run this TestCase.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
Hold variables of type enum.
Definition: enum.h:62
This class contains the specification of EPS Bearers.
Definition: eps-bearer.h:91
Qci
QoS Class Indicator.
Definition: eps-bearer.h:106
The eNodeB device implementation.
double GetPathloss(uint16_t cellId, uint64_t imsi)
void SetSchedulerAttribute(std::string n, const AttributeValue &v)
Set an attribute for the scheduler to be created.
Definition: lte-helper.cc:306
NetDeviceContainer InstallEnbDevice(NodeContainer c)
Create a set of eNodeB devices.
Definition: lte-helper.cc:485
void SetEnbAntennaModelType(std::string type)
Set the type of antenna model to be used by eNodeB devices.
Definition: lte-helper.cc:419
void SetSchedulerType(std::string type)
Set the type of scheduler to be used by eNodeB devices.
Definition: lte-helper.cc:292
void Attach(NetDeviceContainer ueDevices)
Enables automatic attachment of a set of UE devices to a suitable cell using Idle mode initial cell s...
Definition: lte-helper.cc:1039
void SetPathlossModelAttribute(std::string n, const AttributeValue &v)
Set an attribute for the path loss models to be created.
Definition: lte-helper.cc:405
void SetEnbAntennaModelAttribute(std::string n, const AttributeValue &v)
Set an attribute for the eNodeB antenna model to be created.
Definition: lte-helper.cc:426
void SetEnbDeviceAttribute(std::string n, const AttributeValue &v)
Set an attribute for the eNodeB devices (LteEnbNetDevice) to be created.
Definition: lte-helper.cc:412
void ActivateDataRadioBearer(NetDeviceContainer ueDevices, EpsBearer bearer)
Activate a Data Radio Bearer on a given UE devices (for LTE-only simulation).
Definition: lte-helper.cc:1436
NetDeviceContainer InstallUeDevice(NodeContainer c)
Create a set of UE devices.
Definition: lte-helper.cc:500
The LtePhy models the physical layer of LTE.
Definition: lte-phy.h:51
A sink to be plugged to the callback of LteChunkProcessor allowing to save and later retrieve the lat...
Ptr< SpectrumValue > GetValue()
The LteUeNetDevice class implements the UE net device.
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:204
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
Hold variables of type string.
Definition: string.h:56
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
Hold an unsigned integer type.
Definition: uinteger.h:45
void Reset()
Reset the initial value of every attribute as well as the value of every global to what they were bef...
Definition: config.cc:855
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:974
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
static LteAntennaTestSuite g_lteAntennaTestSuite
Static variable for test initialization.
#define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report and...
Definition: test.h:337
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
mobility
Definition: third.py:105