A Discrete-Event Network Simulator
API
test-uniform-planar-array.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 University of Padova, Dep. of Information Engineering, SIGNET lab.
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 
18 #include "cmath"
19 #include "iostream"
20 #include "sstream"
21 #include "string"
22 
23 #include "ns3/double.h"
24 #include "ns3/isotropic-antenna-model.h"
25 #include "ns3/log.h"
26 #include "ns3/pointer.h"
27 #include "ns3/simulator.h"
28 #include "ns3/test.h"
29 #include "ns3/three-gpp-antenna-model.h"
30 #include "ns3/uinteger.h"
31 #include "ns3/uniform-planar-array.h"
32 
33 using namespace ns3;
34 
35 NS_LOG_COMPONENT_DEFINE("TestUniformPlanarArray");
36 
43 {
44  public:
57  static std::string BuildNameString(Ptr<AntennaModel> element,
58  uint32_t rows,
59  uint32_t cols,
60  double rowSpace,
61  double colSpace,
62  double alpha,
63  double beta,
64  Angles direction);
78  uint32_t rows,
79  uint32_t cols,
80  double rowSpace,
81  double colSpace,
82  double alpha,
83  double beta,
84  Angles direction,
85  double expectedGainDb);
86 
87  private:
91  void DoRun() override;
97  double ComputeGain(Ptr<UniformPlanarArray> a);
98 
100  uint32_t m_rows;
101  uint32_t m_cols;
102  double m_rowSpace;
103  double m_colSpace;
104  double m_alpha;
105  double m_beta;
107  double m_expectedGain;
108 };
109 
110 std::string
112  uint32_t rows,
113  uint32_t cols,
114  double rowSpace,
115  double colSpace,
116  double alpha,
117  double beta,
118  Angles direction)
119 {
120  std::ostringstream oss;
121  oss << "UPA=" << rows << "x" << cols << ", row spacing=" << rowSpace << "*lambda"
122  << ", col spacing=" << colSpace << "*lambda"
123  << ", bearing=" << RadiansToDegrees(alpha) << " deg"
124  << ", tilting=" << RadiansToDegrees(beta) << " deg"
125  << ", element=" << element->GetInstanceTypeId().GetName() << ", direction=" << direction;
126  return oss.str();
127 }
128 
130  uint32_t rows,
131  uint32_t cols,
132  double rowSpace,
133  double colSpace,
134  double alpha,
135  double beta,
136  Angles direction,
137  double expectedGainDb)
138  : TestCase(BuildNameString(element, rows, cols, rowSpace, colSpace, alpha, beta, direction)),
139  m_element(element),
140  m_rows(rows),
141  m_cols(cols),
142  m_rowSpace(rowSpace),
143  m_colSpace(colSpace),
144  m_alpha(alpha),
145  m_beta(beta),
146  m_direction(direction),
147  m_expectedGain(expectedGainDb)
148 {
149 }
150 
151 double
153 {
154  // compute gain
155  PhasedArrayModel::ComplexVector sv = a->GetSteeringVector(m_direction);
156  NS_TEST_EXPECT_MSG_EQ(sv.GetSize(), a->GetNumElems(), "steering vector of wrong size");
157  PhasedArrayModel::ComplexVector bf = a->GetBeamformingVector(m_direction);
158  NS_TEST_EXPECT_MSG_EQ(bf.GetSize(), a->GetNumElems(), "beamforming vector of wrong size");
159  std::pair<double, double> fp = a->GetElementFieldPattern(m_direction);
160 
161  // scalar product dot (sv, bf)
162  std::complex<double> prod{0};
163  for (size_t i = 0; i < sv.GetSize(); i++)
164  {
165  prod += sv[i] * bf[i];
166  }
167  double bfGain = std::pow(std::abs(prod), 2);
168  double bfGainDb = 10 * std::log10(bfGain);
169 
170  // power gain from two polarizations
171  double elementPowerGain = std::pow(std::get<0>(fp), 2) + std::pow(std::get<1>(fp), 2);
172  double elementPowerGainDb = 10 * std::log10(elementPowerGain);
173 
174  // sum BF and element gains
175  return bfGainDb + elementPowerGainDb;
176 }
177 
178 void
180 {
182  m_rows,
183  m_cols,
184  m_rowSpace,
185  m_colSpace,
186  m_alpha,
187  m_beta,
188  m_direction));
189 
190  Ptr<UniformPlanarArray> a = CreateObject<UniformPlanarArray>();
191  a->SetAttribute("AntennaElement", PointerValue(m_element));
192  a->SetAttribute("NumRows", UintegerValue(m_rows));
193  a->SetAttribute("NumColumns", UintegerValue(m_cols));
194  a->SetAttribute("AntennaVerticalSpacing", DoubleValue(m_rowSpace));
195  a->SetAttribute("AntennaHorizontalSpacing", DoubleValue(m_colSpace));
196  a->SetAttribute("BearingAngle", DoubleValue(m_alpha));
197  a->SetAttribute("DowntiltAngle", DoubleValue(m_beta));
198 
199  double actualGainDb = ComputeGain(a);
200  NS_TEST_EXPECT_MSG_EQ_TOL(actualGainDb,
202  0.001,
203  "wrong value of the radiation pattern");
204 }
205 
212 {
213  public:
215 };
216 
218  : TestSuite("uniform-planar-array-test", UNIT)
219 {
220  Ptr<AntennaModel> isotropic = CreateObject<IsotropicAntennaModel>();
221  Ptr<AntennaModel> tgpp = CreateObject<ThreeGppAntennaModel>();
222 
223  // element, rows, cols, rowSpace, colSpace, bearing,
224  // tilting, direction (azimuth,
225  // inclination), expectedGainDb
226  // Single element arrays: check if bearing/tilting works on antenna element
228  1,
229  1,
230  0.5,
231  0.5,
232  DegreesToRadians(0),
233  DegreesToRadians(0),
235  0.0),
236  TestCase::QUICK);
238  1,
239  1,
240  0.5,
241  0.5,
242  DegreesToRadians(0),
243  DegreesToRadians(0),
245  8.0),
246  TestCase::QUICK);
248  1,
249  1,
250  0.5,
251  0.5,
252  DegreesToRadians(90),
253  DegreesToRadians(0),
255  8.0),
256  TestCase::QUICK);
258  1,
259  1,
260  0.5,
261  0.5,
262  DegreesToRadians(-90),
263  DegreesToRadians(0),
265  8.0),
266  TestCase::QUICK);
268  1,
269  1,
270  0.5,
271  0.5,
272  DegreesToRadians(180),
273  DegreesToRadians(0),
275  8.0),
276  TestCase::QUICK);
278  1,
279  1,
280  0.5,
281  0.5,
282  DegreesToRadians(-180),
283  DegreesToRadians(0),
285  8.0),
286  TestCase::QUICK);
288  1,
289  1,
290  0.5,
291  0.5,
292  DegreesToRadians(0),
293  DegreesToRadians(45),
295  8.0),
296  TestCase::QUICK);
298  1,
299  1,
300  0.5,
301  0.5,
302  DegreesToRadians(0),
303  DegreesToRadians(-45),
305  8.0),
306  TestCase::QUICK);
308  1,
309  1,
310  0.5,
311  0.5,
312  DegreesToRadians(0),
313  DegreesToRadians(90),
315  8.0),
316  TestCase::QUICK);
318  1,
319  1,
320  0.5,
321  0.5,
322  DegreesToRadians(0),
323  DegreesToRadians(-90),
325  8.0),
326  TestCase::QUICK);
327 
328  // linear array
330  10,
331  1,
332  0.5,
333  0.5,
334  DegreesToRadians(0),
335  DegreesToRadians(0),
337  18.0),
338  TestCase::QUICK);
340  10,
341  1,
342  0.5,
343  0.5,
344  DegreesToRadians(90),
345  DegreesToRadians(0),
347  18.0),
348  TestCase::QUICK);
350  10,
351  1,
352  0.5,
353  0.5,
354  DegreesToRadians(0),
355  DegreesToRadians(45),
357  18.0),
358  TestCase::QUICK);
359 
360  // planar array
362  10,
363  10,
364  0.5,
365  0.5,
366  DegreesToRadians(0),
367  DegreesToRadians(0),
369  28.0),
370  TestCase::QUICK);
372  10,
373  10,
374  0.5,
375  0.5,
376  DegreesToRadians(90),
377  DegreesToRadians(0),
379  28.0),
380  TestCase::QUICK);
382  10,
383  10,
384  0.5,
385  0.5,
386  DegreesToRadians(0),
387  DegreesToRadians(45),
389  28.0),
390  TestCase::QUICK);
391 }
392 
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.
double ComputeGain(Ptr< UniformPlanarArray > a)
Compute the gain of the antenna array.
Angles m_direction
the testing direction
void DoRun() override
Run the test.
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:118
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
MatrixArray class inherits ValArray class and provides additional interfaces to ValArray which enable...
Definition: matrix-array.h:83
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
Definition: object.cc:82
Hold objects of type Ptr<T>.
Definition: pointer.h:37
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
std::string GetName() const
Get the name.
Definition: type-id.cc:991
Hold an unsigned integer type.
Definition: uinteger.h:45
size_t GetSize() const
Definition: val-array.h:400
#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_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:251
#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:510
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double DegreesToRadians(double degrees)
converts degrees to radians
Definition: angles.cc:39
double RadiansToDegrees(double radians)
converts radians to degrees
Definition: angles.cc:45
static UniformPlanarArrayTestSuite staticUniformPlanarArrayTestSuiteInstance