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->GetNumberOfElements(), "steering vector of wrong size");
157  PhasedArrayModel::ComplexVector bf = a->GetBeamformingVector(m_direction);
159  a->GetNumberOfElements(),
160  "beamforming vector of wrong size");
161  std::pair<double, double> fp = a->GetElementFieldPattern(m_direction);
162 
163  // scalar product dot (sv, bf)
164  std::complex<double> prod{0};
165  for (size_t i = 0; i < sv.GetSize(); i++)
166  {
167  prod += sv[i] * bf[i];
168  }
169  double bfGain = std::pow(std::abs(prod), 2);
170  double bfGainDb = 10 * std::log10(bfGain);
171 
172  // power gain from two polarizations
173  double elementPowerGain = std::pow(std::get<0>(fp), 2) + std::pow(std::get<1>(fp), 2);
174  double elementPowerGainDb = 10 * std::log10(elementPowerGain);
175 
176  // sum BF and element gains
177  return bfGainDb + elementPowerGainDb;
178 }
179 
180 void
182 {
184  m_rows,
185  m_cols,
186  m_rowSpace,
187  m_colSpace,
188  m_alpha,
189  m_beta,
190  m_direction));
191 
192  Ptr<UniformPlanarArray> a = CreateObject<UniformPlanarArray>();
193  a->SetAttribute("AntennaElement", PointerValue(m_element));
194  a->SetAttribute("NumRows", UintegerValue(m_rows));
195  a->SetAttribute("NumColumns", UintegerValue(m_cols));
196  a->SetAttribute("AntennaVerticalSpacing", DoubleValue(m_rowSpace));
197  a->SetAttribute("AntennaHorizontalSpacing", DoubleValue(m_colSpace));
198  a->SetAttribute("BearingAngle", DoubleValue(m_alpha));
199  a->SetAttribute("DowntiltAngle", DoubleValue(m_beta));
200 
201  double actualGainDb = ComputeGain(a);
202  NS_TEST_EXPECT_MSG_EQ_TOL(actualGainDb,
204  0.001,
205  "wrong value of the radiation pattern");
206 }
207 
214 {
215  public:
217 };
218 
220  : TestSuite("uniform-planar-array-test", UNIT)
221 {
222  Ptr<AntennaModel> isotropic = CreateObject<IsotropicAntennaModel>();
223  Ptr<AntennaModel> tgpp = CreateObject<ThreeGppAntennaModel>();
224 
225  // element, rows, cols, rowSpace, colSpace, bearing,
226  // tilting, direction (azimuth,
227  // inclination), expectedGainDb
228  // Single element arrays: check if bearing/tilting works on antenna element
230  1,
231  1,
232  0.5,
233  0.5,
234  DegreesToRadians(0),
235  DegreesToRadians(0),
237  0.0),
238  TestCase::QUICK);
240  1,
241  1,
242  0.5,
243  0.5,
244  DegreesToRadians(0),
245  DegreesToRadians(0),
247  8.0),
248  TestCase::QUICK);
250  1,
251  1,
252  0.5,
253  0.5,
254  DegreesToRadians(90),
255  DegreesToRadians(0),
257  8.0),
258  TestCase::QUICK);
260  1,
261  1,
262  0.5,
263  0.5,
264  DegreesToRadians(-90),
265  DegreesToRadians(0),
267  8.0),
268  TestCase::QUICK);
270  1,
271  1,
272  0.5,
273  0.5,
274  DegreesToRadians(180),
275  DegreesToRadians(0),
277  8.0),
278  TestCase::QUICK);
280  1,
281  1,
282  0.5,
283  0.5,
284  DegreesToRadians(-180),
285  DegreesToRadians(0),
287  8.0),
288  TestCase::QUICK);
290  1,
291  1,
292  0.5,
293  0.5,
294  DegreesToRadians(0),
295  DegreesToRadians(45),
297  8.0),
298  TestCase::QUICK);
300  1,
301  1,
302  0.5,
303  0.5,
304  DegreesToRadians(0),
305  DegreesToRadians(-45),
307  8.0),
308  TestCase::QUICK);
310  1,
311  1,
312  0.5,
313  0.5,
314  DegreesToRadians(0),
315  DegreesToRadians(90),
317  8.0),
318  TestCase::QUICK);
320  1,
321  1,
322  0.5,
323  0.5,
324  DegreesToRadians(0),
325  DegreesToRadians(-90),
327  8.0),
328  TestCase::QUICK);
329 
330  // linear array
332  10,
333  1,
334  0.5,
335  0.5,
336  DegreesToRadians(0),
337  DegreesToRadians(0),
339  18.0),
340  TestCase::QUICK);
342  10,
343  1,
344  0.5,
345  0.5,
346  DegreesToRadians(90),
347  DegreesToRadians(0),
349  18.0),
350  TestCase::QUICK);
352  10,
353  1,
354  0.5,
355  0.5,
356  DegreesToRadians(0),
357  DegreesToRadians(45),
359  18.0),
360  TestCase::QUICK);
361 
362  // planar array
364  10,
365  10,
366  0.5,
367  0.5,
368  DegreesToRadians(0),
369  DegreesToRadians(0),
371  28.0),
372  TestCase::QUICK);
374  10,
375  10,
376  0.5,
377  0.5,
378  DegreesToRadians(90),
379  DegreesToRadians(0),
381  28.0),
382  TestCase::QUICK);
384  10,
385  10,
386  0.5,
387  0.5,
388  DegreesToRadians(0),
389  DegreesToRadians(45),
391  28.0),
392  TestCase::QUICK);
393 }
394 
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:305
A suite of tests to run.
Definition: test.h:1256
std::string GetName() const
Get the name.
Definition: type-id.cc:995
Hold an unsigned integer type.
Definition: uinteger.h:45
size_t GetSize() const
Definition: val-array.h:403
#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