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, bearing=" << RadiansToDegrees(alpha) << " deg"
112 << ", tilting=" << RadiansToDegrees(beta) << " deg"
113 << ", element=" << element->GetInstanceTypeId().GetName() << ", direction=" << direction;
114 return oss.str();
115}
116
118 uint32_t rows,
119 uint32_t cols,
120 double rowSpace,
121 double colSpace,
122 double alpha,
123 double beta,
124 Angles direction,
125 double expectedGainDb)
126 : TestCase(BuildNameString(element, rows, cols, rowSpace, colSpace, alpha, beta, direction)),
127 m_element(element),
128 m_rows(rows),
129 m_cols(cols),
130 m_rowSpace(rowSpace),
131 m_colSpace(colSpace),
132 m_alpha(alpha),
133 m_beta(beta),
134 m_direction(direction),
135 m_expectedGain(expectedGainDb)
136{
137}
138
139double
141{
142 // compute gain
143 PhasedArrayModel::ComplexVector sv = a->GetSteeringVector(m_direction);
144 NS_TEST_EXPECT_MSG_EQ(sv.GetSize(), a->GetNumElems(), "steering vector of wrong size");
145 PhasedArrayModel::ComplexVector bf = a->GetBeamformingVector(m_direction);
146 NS_TEST_EXPECT_MSG_EQ(bf.GetSize(), a->GetNumElems(), "beamforming vector of wrong size");
147 std::pair<double, double> fp = a->GetElementFieldPattern(m_direction);
148
149 // scalar product dot (sv, bf)
150 std::complex<double> prod{0};
151 for (size_t i = 0; i < sv.GetSize(); i++)
152 {
153 prod += sv[i] * bf[i];
154 }
155 double bfGain = std::pow(std::abs(prod), 2);
156 double bfGainDb = 10 * std::log10(bfGain);
157
158 // power gain from two polarizations
159 double elementPowerGain = std::pow(std::get<0>(fp), 2) + std::pow(std::get<1>(fp), 2);
160 double elementPowerGainDb = 10 * std::log10(elementPowerGain);
161
162 // sum BF and element gains
163 return bfGainDb + elementPowerGainDb;
164}
165
166void
168{
170 m_rows,
171 m_cols,
174 m_alpha,
175 m_beta,
176 m_direction));
177
179 a->SetAttribute("AntennaElement", PointerValue(m_element));
180 a->SetAttribute("NumRows", UintegerValue(m_rows));
181 a->SetAttribute("NumColumns", UintegerValue(m_cols));
182 a->SetAttribute("AntennaVerticalSpacing", DoubleValue(m_rowSpace));
183 a->SetAttribute("AntennaHorizontalSpacing", DoubleValue(m_colSpace));
184 a->SetAttribute("BearingAngle", DoubleValue(m_alpha));
185 a->SetAttribute("DowntiltAngle", DoubleValue(m_beta));
186
187 double actualGainDb = ComputeGain(a);
188 NS_TEST_EXPECT_MSG_EQ_TOL(actualGainDb,
190 0.001,
191 "wrong value of the radiation pattern");
192}
193
194/**
195 * @ingroup antenna-tests
196 *
197 * @brief UpdateOnChange Test Case
198 */
200{
201 public:
202 /**
203 * The constructor of the test case
204 * @param element the antenna element
205 * @param name the test case name
206 */
207 UpdateOnChangeTestCase(Ptr<AntennaModel> element, std::string name)
208 : TestCase(name),
209 m_element(element)
210 {
211 }
212
213 private:
214 /**
215 * Run the test
216 */
217 void DoRun() override;
218 Ptr<AntennaModel> m_element; //!< the antenna element
219};
220
221void
223{
225 ant->SetAttribute("AntennaElement", PointerValue(m_element));
226 ant->SetAttribute("NumRows", UintegerValue(10));
227 ant->SetAttribute("NumColumns", UintegerValue(10));
228 ant->SetAttribute("AntennaVerticalSpacing", DoubleValue(0.5));
229 ant->SetAttribute("AntennaHorizontalSpacing", DoubleValue(0.5));
230 ant->SetAttribute("BearingAngle", DoubleValue(DegreesToRadians(0)));
231 ant->SetAttribute("DowntiltAngle", DoubleValue(DegreesToRadians(45)));
232
234 ant2->SetAttribute("AntennaElement", PointerValue(m_element));
235 ant2->SetAttribute("NumRows", UintegerValue(10));
236 ant2->SetAttribute("NumColumns", UintegerValue(10));
237 ant2->SetAttribute("AntennaVerticalSpacing", DoubleValue(0.5));
238 ant2->SetAttribute("AntennaHorizontalSpacing", DoubleValue(0.5));
239 ant2->SetAttribute("BearingAngle", DoubleValue(DegreesToRadians(0)));
240 ant2->SetAttribute("DowntiltAngle", DoubleValue(DegreesToRadians(45)));
241
242 NS_TEST_ASSERT_MSG_EQ(ant.operator bool(), true, "AntennaModel is not a PhasedArrayModel");
243
244 // Initial state of array requires a channel update
245 NS_TEST_ASSERT_MSG_EQ(ant->IsChannelOutOfDate(ant2),
246 true,
247 "Expecting update, since the pair was never setup");
249 ant2->IsChannelOutOfDate(ant),
250 false,
251 "Not expecting update, since the pair was just updated and no settings changed");
252 ant->SetAlpha(DegreesToRadians(90));
253 NS_TEST_ASSERT_MSG_EQ(ant2->IsChannelOutOfDate(ant),
254 true,
255 "Expecting update, antenna parameter changed");
257 ant->IsChannelOutOfDate(ant2),
258 false,
259 "Not expecting update, since the pair was just updated and no settings changed");
260 ant->SetAlpha(DegreesToRadians(90));
261 NS_TEST_ASSERT_MSG_EQ(ant->IsChannelOutOfDate(ant2),
262 true,
263 "Expecting update, antenna parameter changed");
264}
265
266/**
267 * @ingroup antenna-tests
268 *
269 * @brief UniformPlanarArray Test Suite
270 */
272{
273 public:
275};
276
278 : TestSuite("uniform-planar-array-test", Type::UNIT)
279{
282
283 // element, rows, cols, rowSpace, colSpace, bearing,
284 // tilting, direction (azimuth,
285 // inclination), expectedGainDb
286 // Single element arrays: check if bearing/tilting works on antenna element
288 1,
289 1,
290 0.5,
291 0.5,
295 0.0),
296 TestCase::Duration::QUICK);
298 1,
299 1,
300 0.5,
301 0.5,
305 8.0),
306 TestCase::Duration::QUICK);
308 1,
309 1,
310 0.5,
311 0.5,
315 8.0),
316 TestCase::Duration::QUICK);
318 1,
319 1,
320 0.5,
321 0.5,
322 DegreesToRadians(-90),
325 8.0),
326 TestCase::Duration::QUICK);
328 1,
329 1,
330 0.5,
331 0.5,
332 DegreesToRadians(180),
335 8.0),
336 TestCase::Duration::QUICK);
338 1,
339 1,
340 0.5,
341 0.5,
342 DegreesToRadians(-180),
345 8.0),
346 TestCase::Duration::QUICK);
348 1,
349 1,
350 0.5,
351 0.5,
355 8.0),
356 TestCase::Duration::QUICK);
358 1,
359 1,
360 0.5,
361 0.5,
363 DegreesToRadians(-45),
365 8.0),
366 TestCase::Duration::QUICK);
368 1,
369 1,
370 0.5,
371 0.5,
375 8.0),
376 TestCase::Duration::QUICK);
378 1,
379 1,
380 0.5,
381 0.5,
383 DegreesToRadians(-90),
385 8.0),
386 TestCase::Duration::QUICK);
387
388 // linear array
390 10,
391 1,
392 0.5,
393 0.5,
397 18.0),
398 TestCase::Duration::QUICK);
400 10,
401 1,
402 0.5,
403 0.5,
407 18.0),
408 TestCase::Duration::QUICK);
410 10,
411 1,
412 0.5,
413 0.5,
417 18.0),
418 TestCase::Duration::QUICK);
419
420 // planar array
422 10,
423 10,
424 0.5,
425 0.5,
429 28.0),
430 TestCase::Duration::QUICK);
432 10,
433 10,
434 0.5,
435 0.5,
439 28.0),
440 TestCase::Duration::QUICK);
442 10,
443 10,
444 0.5,
445 0.5,
449 28.0),
450 TestCase::Duration::QUICK);
452 "Test IsChannelOutOfDate() and InvalidateChannels() for "
453 "UniformPlanarArray with 3GPP antenna element"),
454 TestCase::Duration::QUICK);
455}
456
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