A Discrete-Event Network Simulator
API
test-uniform-planar-array.cc
Go to the documentation of this file.
1/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2/*
3* Copyright (c) 2020 University of Padova, Dep. of Information Engineering, SIGNET lab.
4*
5* This program is free software; you can redistribute it and/or modify
6* it under the terms of the GNU General Public License version 2 as
7* published by the Free Software Foundation;
8*
9* This program is distributed in the hope that it will be useful,
10* but WITHOUT ANY WARRANTY; without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12* GNU General Public License for more details.
13*
14* You should have received a copy of the GNU General Public License
15* along with this program; if not, write to the Free Software
16* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17*/
18
19#include "ns3/log.h"
20#include "ns3/test.h"
21#include "ns3/double.h"
22#include "ns3/uinteger.h"
23#include "ns3/pointer.h"
24#include "ns3/uniform-planar-array.h"
25#include "ns3/isotropic-antenna-model.h"
26#include "ns3/three-gpp-antenna-model.h"
27#include "ns3/simulator.h"
28#include "cmath"
29#include "string"
30#include "iostream"
31#include "sstream"
32
33
34using namespace ns3;
35
36NS_LOG_COMPONENT_DEFINE ("TestUniformPlanarArray");
37
44{
45public:
58 static std::string BuildNameString (Ptr<AntennaModel> element, uint32_t rows, uint32_t cols,double rowSpace, double colSpace,
59 double alpha, double beta, Angles direction);
72 UniformPlanarArrayTestCase (Ptr<AntennaModel> element, uint32_t rows, uint32_t cols, double rowSpace, double colSpace,
73 double alpha, double beta, Angles direction, double expectedGainDb);
74
75private:
79 virtual void DoRun (void);
86
90 double m_rowSpace;
91 double m_colSpace;
92 double m_alpha;
93 double m_beta;
96};
97
98std::string UniformPlanarArrayTestCase::BuildNameString (Ptr<AntennaModel> element, uint32_t rows, uint32_t cols, double rowSpace, double colSpace,
99 double alpha, double beta, Angles direction)
100{
101 std::ostringstream oss;
102 oss << "UPA=" << rows << "x" << cols
103 << ", row spacing=" << rowSpace << "*lambda"
104 << ", col spacing=" << colSpace << "*lambda"
105 << ", bearing=" << RadiansToDegrees (alpha) << " deg"
106 << ", tilting=" << RadiansToDegrees (beta) << " deg"
107 << ", element=" << element->GetInstanceTypeId ().GetName ()
108 << ", direction=" << direction;
109 return oss.str ();
110}
111
112
114 double alpha, double beta, Angles direction, double expectedGainDb)
115 : TestCase (BuildNameString (element, rows, cols, rowSpace, colSpace, alpha, beta, direction)),
116 m_element (element),
117 m_rows (rows),
118 m_cols (cols),
119 m_rowSpace (rowSpace),
120 m_colSpace (colSpace),
121 m_alpha (alpha),
122 m_beta (beta),
123 m_direction (direction),
124 m_expectedGain (expectedGainDb)
125{}
126
127
128double
130{
131 // compute gain
132 PhasedArrayModel::ComplexVector sv = a->GetSteeringVector (m_direction);
133 NS_TEST_EXPECT_MSG_EQ (sv.size (), a->GetNumberOfElements (), "steering vector of wrong size");
134 PhasedArrayModel::ComplexVector bf = a->GetBeamformingVector (m_direction);
135 NS_TEST_EXPECT_MSG_EQ (bf.size (), a->GetNumberOfElements (), "beamforming vector of wrong size");
136 std::pair<double, double> fp = a->GetElementFieldPattern (m_direction);
137
138 // scalar product dot (sv, bf)
139 std::complex<double> prod {0};
140 for (size_t i = 0; i < sv.size (); i++)
141 {
142 prod += sv[i] * bf[i];
143 }
144 double bfGain = std::pow (std::abs (prod), 2);
145 double bfGainDb = 10 * std::log10 (bfGain);
146
147 // power gain from two polarizations
148 double elementPowerGain = std::pow (std::get<0> (fp), 2) + std::pow (std::get<1> (fp), 2);
149 double elementPowerGainDb = 10 * std::log10 (elementPowerGain);
150
151 // sum BF and element gains
152 return bfGainDb + elementPowerGainDb;
153}
154
155
156void
158{
160
161 Ptr<UniformPlanarArray> a = CreateObject<UniformPlanarArray> ();
162 a->SetAttribute ("AntennaElement", PointerValue (m_element));
163 a->SetAttribute ("NumRows", UintegerValue (m_rows));
164 a->SetAttribute ("NumColumns", UintegerValue (m_cols));
165 a->SetAttribute ("AntennaVerticalSpacing", DoubleValue (m_rowSpace));
166 a->SetAttribute ("AntennaHorizontalSpacing", DoubleValue (m_colSpace));
167 a->SetAttribute ("BearingAngle", DoubleValue (m_alpha));
168 a->SetAttribute ("DowntiltAngle", DoubleValue (m_beta));
169
170 double actualGainDb = ComputeGain (a);
171 NS_TEST_EXPECT_MSG_EQ_TOL (actualGainDb, m_expectedGain, 0.001, "wrong value of the radiation pattern");
172}
173
174
181{
182public:
184};
185
187 : TestSuite ("uniform-planar-array-test", UNIT)
188{
189 Ptr<AntennaModel> isotropic = CreateObject<IsotropicAntennaModel> ();
190 Ptr<AntennaModel> tgpp = CreateObject<ThreeGppAntennaModel> ();
191
192 // element, rows, cols, rowSpace, colSpace, bearing, tilting, direction (azimuth, inclination), expectedGainDb
193 // Single element arrays: check if bearing/tilting works on antenna element
194 AddTestCase (new UniformPlanarArrayTestCase (isotropic, 1, 1, 0.5, 0.5, DegreesToRadians (0), DegreesToRadians (0), Angles (DegreesToRadians (0), DegreesToRadians (90)), 0.0), TestCase::QUICK);
195 AddTestCase (new UniformPlanarArrayTestCase ( tgpp, 1, 1, 0.5, 0.5, DegreesToRadians (0), DegreesToRadians (0), Angles (DegreesToRadians (0), DegreesToRadians (90)), 8.0), TestCase::QUICK);
196 AddTestCase (new UniformPlanarArrayTestCase ( tgpp, 1, 1, 0.5, 0.5, DegreesToRadians (90), DegreesToRadians (0), Angles (DegreesToRadians (90), DegreesToRadians (90)), 8.0), TestCase::QUICK);
197 AddTestCase (new UniformPlanarArrayTestCase ( tgpp, 1, 1, 0.5, 0.5, DegreesToRadians (-90), DegreesToRadians (0), Angles (DegreesToRadians (-90), DegreesToRadians (90)), 8.0), TestCase::QUICK);
198 AddTestCase (new UniformPlanarArrayTestCase ( tgpp, 1, 1, 0.5, 0.5, DegreesToRadians (180), DegreesToRadians (0), Angles (DegreesToRadians (180), DegreesToRadians (90)), 8.0), TestCase::QUICK);
199 AddTestCase (new UniformPlanarArrayTestCase ( tgpp, 1, 1, 0.5, 0.5, DegreesToRadians (-180), DegreesToRadians (0), Angles (DegreesToRadians (-180), DegreesToRadians (90)), 8.0), TestCase::QUICK);
200 AddTestCase (new UniformPlanarArrayTestCase ( tgpp, 1, 1, 0.5, 0.5, DegreesToRadians (0), DegreesToRadians (45), Angles (DegreesToRadians (0), DegreesToRadians (135)), 8.0), TestCase::QUICK);
201 AddTestCase (new UniformPlanarArrayTestCase ( tgpp, 1, 1, 0.5, 0.5, DegreesToRadians (0), DegreesToRadians (-45), Angles (DegreesToRadians (0), DegreesToRadians (45)), 8.0), TestCase::QUICK);
202 AddTestCase (new UniformPlanarArrayTestCase ( tgpp, 1, 1, 0.5, 0.5, DegreesToRadians (0), DegreesToRadians (90), Angles (DegreesToRadians (0), DegreesToRadians (180)), 8.0), TestCase::QUICK);
203 AddTestCase (new UniformPlanarArrayTestCase ( tgpp, 1, 1, 0.5, 0.5, DegreesToRadians (0), DegreesToRadians (-90), Angles (DegreesToRadians (0), DegreesToRadians (0)), 8.0), TestCase::QUICK);
204
205 // linear array
206 AddTestCase (new UniformPlanarArrayTestCase ( tgpp, 10, 1, 0.5, 0.5, DegreesToRadians (0), DegreesToRadians (0), Angles (DegreesToRadians (0), DegreesToRadians (90)), 18.0), TestCase::QUICK);
207 AddTestCase (new UniformPlanarArrayTestCase ( tgpp, 10, 1, 0.5, 0.5, DegreesToRadians (90), DegreesToRadians (0), Angles (DegreesToRadians (90), DegreesToRadians (90)), 18.0), TestCase::QUICK);
208 AddTestCase (new UniformPlanarArrayTestCase ( tgpp, 10, 1, 0.5, 0.5, DegreesToRadians (0), DegreesToRadians (45), Angles (DegreesToRadians (0), DegreesToRadians (135)), 18.0), TestCase::QUICK);
209
210 // planar array
211 AddTestCase (new UniformPlanarArrayTestCase ( tgpp, 10, 10, 0.5, 0.5, DegreesToRadians (0), DegreesToRadians (0), Angles (DegreesToRadians (0), DegreesToRadians (90)), 28.0), TestCase::QUICK);
212 AddTestCase (new UniformPlanarArrayTestCase ( tgpp, 10, 10, 0.5, 0.5, DegreesToRadians (90), DegreesToRadians (0), Angles (DegreesToRadians (90), DegreesToRadians (90)), 28.0), TestCase::QUICK);
213 AddTestCase (new UniformPlanarArrayTestCase ( tgpp, 10, 10, 0.5, 0.5, DegreesToRadians (0), DegreesToRadians (45), Angles (DegreesToRadians (0), DegreesToRadians (135)), 28.0), TestCase::QUICK);
214}
215
UniformPlanarArray Test Case.
double m_expectedGain
the expected antenna gain [dB]
Ptr< AntennaModel > m_element
the antenna element
double m_colSpace
the column spacing
UniformPlanarArrayTestCase(Ptr< AntennaModel > element, uint32_t rows, uint32_t cols, double rowSpace, double colSpace, double alpha, double beta, Angles direction, double expectedGainDb)
The constructor of the test case.
virtual void DoRun(void)
Run the test.
double ComputeGain(Ptr< UniformPlanarArray > a)
Compute the gain of the antenna array.
Angles m_direction
the testing direction
uint32_t m_cols
the number of columns
uint32_t m_rows
the number of rows
static std::string BuildNameString(Ptr< AntennaModel > element, uint32_t rows, uint32_t cols, double rowSpace, double colSpace, double alpha, double beta, Angles direction)
Generate a string containing all relevant parameters.
double m_alpha
the bearing angle [rad]
double m_beta
the titling angle [rad]
UniformPlanarArray Test Suite.
Class holding the azimuth and inclination angles of spherical coordinates.
Definition: angles.h:119
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
Definition: object.cc:79
std::vector< std::complex< double > > ComplexVector
type definition for complex vectors
Hold objects of type Ptr<T>.
Definition: pointer.h:37
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
std::string GetName(void) const
Get the name.
Definition: type-id.cc:976
Hold an unsigned integer type.
Definition: uinteger.h:44
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:240
#define NS_TEST_EXPECT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report if ...
Definition: test.h:491
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double DegreesToRadians(double degrees)
converts degrees to radians
Definition: angles.cc:40
double RadiansToDegrees(double radians)
converts radians to degrees
Definition: angles.cc:47
float alpha
Plot alpha value (transparency)
static UniformPlanarArrayTestSuite staticUniformPlanarArrayTestSuiteInstance