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 
34 using namespace ns3;
35 
36 NS_LOG_COMPONENT_DEFINE ("TestUniformPlanarArray");
37 
44 {
45 public:
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 
75 private:
79  virtual void DoRun (void);
85  double ComputeGain (Ptr<UniformPlanarArray> a);
86 
88  uint32_t m_rows;
89  uint32_t m_cols;
90  double m_rowSpace;
91  double m_colSpace;
92  double m_alpha;
93  double m_beta;
95  double m_expectedGain;
96 };
97 
98 std::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 
113 UniformPlanarArrayTestCase::UniformPlanarArrayTestCase (Ptr<AntennaModel> element, uint32_t rows, uint32_t cols, double rowSpace, double colSpace,
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 
128 double
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 
156 void
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 {
182 public:
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