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 UpdateOnChange Test Case
199 */
201{
202 public:
203 /**
204 * The constructor of the test case
205 * @param element the antenna element
206 * @param name the test case name
207 */
208 UpdateOnChangeTestCase(Ptr<AntennaModel> element, std::string name)
209 : TestCase(name),
210 m_element(element){};
211
212 private:
213 /**
214 * Run the test
215 */
216 void DoRun() override;
217 Ptr<AntennaModel> m_element; //!< the antenna element
218};
219
220void
222{
224 ant->SetAttribute("AntennaElement", PointerValue(m_element));
225 ant->SetAttribute("NumRows", UintegerValue(10));
226 ant->SetAttribute("NumColumns", UintegerValue(10));
227 ant->SetAttribute("AntennaVerticalSpacing", DoubleValue(0.5));
228 ant->SetAttribute("AntennaHorizontalSpacing", DoubleValue(0.5));
229 ant->SetAttribute("BearingAngle", DoubleValue(DegreesToRadians(0)));
230 ant->SetAttribute("DowntiltAngle", DoubleValue(DegreesToRadians(45)));
231
233 ant2->SetAttribute("AntennaElement", PointerValue(m_element));
234 ant2->SetAttribute("NumRows", UintegerValue(10));
235 ant2->SetAttribute("NumColumns", UintegerValue(10));
236 ant2->SetAttribute("AntennaVerticalSpacing", DoubleValue(0.5));
237 ant2->SetAttribute("AntennaHorizontalSpacing", DoubleValue(0.5));
238 ant2->SetAttribute("BearingAngle", DoubleValue(DegreesToRadians(0)));
239 ant2->SetAttribute("DowntiltAngle", DoubleValue(DegreesToRadians(45)));
240
241 NS_TEST_ASSERT_MSG_EQ(ant.operator bool(), true, "AntennaModel is not a PhasedArrayModel");
242
243 // Initial state of array requires a channel update
244 NS_TEST_ASSERT_MSG_EQ(ant->IsChannelOutOfDate(ant2),
245 true,
246 "Expecting update, since the pair was never setup");
248 ant2->IsChannelOutOfDate(ant),
249 false,
250 "Not expecting update, since the pair was just updated and no settings changed");
251 ant->SetAlpha(DegreesToRadians(90));
252 NS_TEST_ASSERT_MSG_EQ(ant2->IsChannelOutOfDate(ant),
253 true,
254 "Expecting update, antenna parameter changed");
256 ant->IsChannelOutOfDate(ant2),
257 false,
258 "Not expecting update, since the pair was just updated and no settings changed");
259 ant->SetAlpha(DegreesToRadians(90));
260 NS_TEST_ASSERT_MSG_EQ(ant->IsChannelOutOfDate(ant2),
261 true,
262 "Expecting update, antenna parameter changed");
263}
264
265/**
266 * @ingroup antenna-tests
267 *
268 * @brief UniformPlanarArray Test Suite
269 */
271{
272 public:
274};
275
277 : TestSuite("uniform-planar-array-test", Type::UNIT)
278{
281
282 // element, rows, cols, rowSpace, colSpace, bearing,
283 // tilting, direction (azimuth,
284 // inclination), expectedGainDb
285 // Single element arrays: check if bearing/tilting works on antenna element
287 1,
288 1,
289 0.5,
290 0.5,
294 0.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,
314 8.0),
315 TestCase::Duration::QUICK);
317 1,
318 1,
319 0.5,
320 0.5,
321 DegreesToRadians(-90),
324 8.0),
325 TestCase::Duration::QUICK);
327 1,
328 1,
329 0.5,
330 0.5,
331 DegreesToRadians(180),
334 8.0),
335 TestCase::Duration::QUICK);
337 1,
338 1,
339 0.5,
340 0.5,
341 DegreesToRadians(-180),
344 8.0),
345 TestCase::Duration::QUICK);
347 1,
348 1,
349 0.5,
350 0.5,
354 8.0),
355 TestCase::Duration::QUICK);
357 1,
358 1,
359 0.5,
360 0.5,
362 DegreesToRadians(-45),
364 8.0),
365 TestCase::Duration::QUICK);
367 1,
368 1,
369 0.5,
370 0.5,
374 8.0),
375 TestCase::Duration::QUICK);
377 1,
378 1,
379 0.5,
380 0.5,
382 DegreesToRadians(-90),
384 8.0),
385 TestCase::Duration::QUICK);
386
387 // linear array
389 10,
390 1,
391 0.5,
392 0.5,
396 18.0),
397 TestCase::Duration::QUICK);
399 10,
400 1,
401 0.5,
402 0.5,
406 18.0),
407 TestCase::Duration::QUICK);
409 10,
410 1,
411 0.5,
412 0.5,
416 18.0),
417 TestCase::Duration::QUICK);
418
419 // planar array
421 10,
422 10,
423 0.5,
424 0.5,
428 28.0),
429 TestCase::Duration::QUICK);
431 10,
432 10,
433 0.5,
434 0.5,
438 28.0),
439 TestCase::Duration::QUICK);
441 10,
442 10,
443 0.5,
444 0.5,
448 28.0),
449 TestCase::Duration::QUICK);
451 "Test IsChannelOutOfDate() and InvalidateChannels() for "
452 "UniformPlanarArray with 3GPP antenna element"),
453 TestCase::Duration::QUICK);
454}
455
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.
UpdateOnChange Test Case.
UpdateOnChangeTestCase(Ptr< AntennaModel > element, std::string name)
The constructor of the test case.
Ptr< AntennaModel > m_element
the antenna element
void DoRun() override
Run the test.
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_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition test.h:134
#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