A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7#include "cmath"
8#include "iostream"
9#include "sstream"
10#include "string"
11
12#include "ns3/double.h"
13#include "ns3/isotropic-antenna-model.h"
14#include "ns3/log.h"
15#include "ns3/pointer.h"
16#include "ns3/simulator.h"
17#include "ns3/test.h"
18#include "ns3/three-gpp-antenna-model.h"
19#include "ns3/uinteger.h"
20#include "ns3/uniform-planar-array.h"
21
22using namespace ns3;
23
24NS_LOG_COMPONENT_DEFINE("TestUniformPlanarArray");
25
26/**
27 * \ingroup antenna-tests
28 *
29 * \brief UniformPlanarArray Test Case
30 */
32{
33 public:
34 /**
35 * Generate a string containing all relevant parameters
36 * \param element the antenna element
37 * \param rows the number of rows
38 * \param cols the number of columns
39 * \param rowSpace the row spacing
40 * \param colSpace the column spacing
41 * \param alpha the bearing angle
42 * \param beta the tilting angle
43 * \param direction the direction
44 * \return the string containing all relevant parameters
45 */
46 static std::string BuildNameString(Ptr<AntennaModel> element,
47 uint32_t rows,
48 uint32_t cols,
49 double rowSpace,
50 double colSpace,
51 double alpha,
52 double beta,
53 Angles direction);
54 /**
55 * The constructor of the test case
56 * \param element the antenna element
57 * \param rows the number of rows
58 * \param cols the number of columns
59 * \param rowSpace the row spacing
60 * \param colSpace the column spacing
61 * \param alpha the bearing angle
62 * \param beta the tilting angle
63 * \param direction the direction
64 * \param expectedGainDb the expected antenna gain [dB]
65 */
67 uint32_t rows,
68 uint32_t cols,
69 double rowSpace,
70 double colSpace,
71 double alpha,
72 double beta,
73 Angles direction,
74 double expectedGainDb);
75
76 private:
77 /**
78 * Run the test
79 */
80 void DoRun() override;
81 /**
82 * Compute the gain of the antenna array
83 * \param a the antenna array
84 * \return the gain of the antenna array [dB]
85 */
87
88 Ptr<AntennaModel> m_element; //!< the antenna element
89 uint32_t m_rows; //!< the number of rows
90 uint32_t m_cols; //!< the number of columns
91 double m_rowSpace; //!< the row spacing
92 double m_colSpace; //!< the column spacing
93 double m_alpha; //!< the bearing angle [rad]
94 double m_beta; //!< the titling angle [rad]
95 Angles m_direction; //!< the testing direction
96 double m_expectedGain; //!< the expected antenna gain [dB]
97};
98
99std::string
101 uint32_t rows,
102 uint32_t cols,
103 double rowSpace,
104 double colSpace,
105 double alpha,
106 double beta,
107 Angles direction)
108{
109 std::ostringstream oss;
110 oss << "UPA=" << rows << "x" << cols << ", row spacing=" << rowSpace << "*lambda"
111 << ", col spacing=" << colSpace << "*lambda"
112 << ", bearing=" << RadiansToDegrees(alpha) << " deg"
113 << ", tilting=" << RadiansToDegrees(beta) << " deg"
114 << ", element=" << element->GetInstanceTypeId().GetName() << ", direction=" << direction;
115 return oss.str();
116}
117
119 uint32_t rows,
120 uint32_t cols,
121 double rowSpace,
122 double colSpace,
123 double alpha,
124 double beta,
125 Angles direction,
126 double expectedGainDb)
127 : TestCase(BuildNameString(element, rows, cols, rowSpace, colSpace, alpha, beta, direction)),
128 m_element(element),
129 m_rows(rows),
130 m_cols(cols),
131 m_rowSpace(rowSpace),
132 m_colSpace(colSpace),
133 m_alpha(alpha),
134 m_beta(beta),
135 m_direction(direction),
136 m_expectedGain(expectedGainDb)
137{
138}
139
140double
142{
143 // compute gain
144 PhasedArrayModel::ComplexVector sv = a->GetSteeringVector(m_direction);
145 NS_TEST_EXPECT_MSG_EQ(sv.GetSize(), a->GetNumElems(), "steering vector of wrong size");
146 PhasedArrayModel::ComplexVector bf = a->GetBeamformingVector(m_direction);
147 NS_TEST_EXPECT_MSG_EQ(bf.GetSize(), a->GetNumElems(), "beamforming vector of wrong size");
148 std::pair<double, double> fp = a->GetElementFieldPattern(m_direction);
149
150 // scalar product dot (sv, bf)
151 std::complex<double> prod{0};
152 for (size_t i = 0; i < sv.GetSize(); i++)
153 {
154 prod += sv[i] * bf[i];
155 }
156 double bfGain = std::pow(std::abs(prod), 2);
157 double bfGainDb = 10 * std::log10(bfGain);
158
159 // power gain from two polarizations
160 double elementPowerGain = std::pow(std::get<0>(fp), 2) + std::pow(std::get<1>(fp), 2);
161 double elementPowerGainDb = 10 * std::log10(elementPowerGain);
162
163 // sum BF and element gains
164 return bfGainDb + elementPowerGainDb;
165}
166
167void
169{
171 m_rows,
172 m_cols,
175 m_alpha,
176 m_beta,
177 m_direction));
178
180 a->SetAttribute("AntennaElement", PointerValue(m_element));
181 a->SetAttribute("NumRows", UintegerValue(m_rows));
182 a->SetAttribute("NumColumns", UintegerValue(m_cols));
183 a->SetAttribute("AntennaVerticalSpacing", DoubleValue(m_rowSpace));
184 a->SetAttribute("AntennaHorizontalSpacing", DoubleValue(m_colSpace));
185 a->SetAttribute("BearingAngle", DoubleValue(m_alpha));
186 a->SetAttribute("DowntiltAngle", DoubleValue(m_beta));
187
188 double actualGainDb = ComputeGain(a);
189 NS_TEST_EXPECT_MSG_EQ_TOL(actualGainDb,
191 0.001,
192 "wrong value of the radiation pattern");
193}
194
195/**
196 * \ingroup antenna-tests
197 *
198 * \brief UniformPlanarArray Test Suite
199 */
201{
202 public:
204};
205
207 : TestSuite("uniform-planar-array-test", Type::UNIT)
208{
211
212 // element, rows, cols, rowSpace, colSpace, bearing,
213 // tilting, direction (azimuth,
214 // inclination), expectedGainDb
215 // Single element arrays: check if bearing/tilting works on antenna element
217 1,
218 1,
219 0.5,
220 0.5,
224 0.0),
225 TestCase::Duration::QUICK);
227 1,
228 1,
229 0.5,
230 0.5,
234 8.0),
235 TestCase::Duration::QUICK);
237 1,
238 1,
239 0.5,
240 0.5,
244 8.0),
245 TestCase::Duration::QUICK);
247 1,
248 1,
249 0.5,
250 0.5,
251 DegreesToRadians(-90),
254 8.0),
255 TestCase::Duration::QUICK);
257 1,
258 1,
259 0.5,
260 0.5,
261 DegreesToRadians(180),
264 8.0),
265 TestCase::Duration::QUICK);
267 1,
268 1,
269 0.5,
270 0.5,
271 DegreesToRadians(-180),
274 8.0),
275 TestCase::Duration::QUICK);
277 1,
278 1,
279 0.5,
280 0.5,
284 8.0),
285 TestCase::Duration::QUICK);
287 1,
288 1,
289 0.5,
290 0.5,
292 DegreesToRadians(-45),
294 8.0),
295 TestCase::Duration::QUICK);
297 1,
298 1,
299 0.5,
300 0.5,
304 8.0),
305 TestCase::Duration::QUICK);
307 1,
308 1,
309 0.5,
310 0.5,
312 DegreesToRadians(-90),
314 8.0),
315 TestCase::Duration::QUICK);
316
317 // linear array
319 10,
320 1,
321 0.5,
322 0.5,
326 18.0),
327 TestCase::Duration::QUICK);
329 10,
330 1,
331 0.5,
332 0.5,
336 18.0),
337 TestCase::Duration::QUICK);
339 10,
340 1,
341 0.5,
342 0.5,
346 18.0),
347 TestCase::Duration::QUICK);
348
349 // planar array
351 10,
352 10,
353 0.5,
354 0.5,
358 28.0),
359 TestCase::Duration::QUICK);
361 10,
362 10,
363 0.5,
364 0.5,
368 28.0),
369 TestCase::Duration::QUICK);
371 10,
372 10,
373 0.5,
374 0.5,
378 28.0),
379 TestCase::Duration::QUICK);
380}
381
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:107
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
Hold an unsigned integer type.
Definition uinteger.h:34
size_t GetSize() const
Definition val-array.h:394
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#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:241
#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:500
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double DegreesToRadians(double degrees)
converts degrees to radians
Definition angles.cc:28
double RadiansToDegrees(double radians)
converts radians to degrees
Definition angles.cc:34
static UniformPlanarArrayTestSuite staticUniformPlanarArrayTestSuiteInstance