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));
262 ant->IsChannelOutOfDate(ant2),
263 false,
264 "Not expecting update, since the pair was just updated and angle was not changed");
265 ant->SetAlpha(DegreesToRadians(85));
266 NS_TEST_ASSERT_MSG_EQ(ant2->IsChannelOutOfDate(ant),
267 true,
268 "Expecting update, antenna parameter changed");
270 ant->IsChannelOutOfDate(ant2),
271 false,
272 "Not expecting update, since the pair was just updated and angle was not changed");
273 ant->SetAlpha(DegreesToRadians(80));
274 NS_TEST_ASSERT_MSG_EQ(ant->IsChannelOutOfDate(ant2),
275 true,
276 "Expecting update, antenna parameter changed");
277}
278
279/**
280 * @ingroup antenna-tests
281 *
282 * @brief UniformPlanarArray Test Suite
283 */
285{
286 public:
288};
289
291 : TestSuite("uniform-planar-array-test", Type::UNIT)
292{
295
296 // element, rows, cols, rowSpace, colSpace, bearing,
297 // tilting, direction (azimuth,
298 // inclination), expectedGainDb
299 // Single element arrays: check if bearing/tilting works on antenna element
301 1,
302 1,
303 0.5,
304 0.5,
308 0.0),
311 1,
312 1,
313 0.5,
314 0.5,
318 8.0),
321 1,
322 1,
323 0.5,
324 0.5,
328 8.0),
331 1,
332 1,
333 0.5,
334 0.5,
335 DegreesToRadians(-90),
338 8.0),
341 1,
342 1,
343 0.5,
344 0.5,
345 DegreesToRadians(180),
348 8.0),
351 1,
352 1,
353 0.5,
354 0.5,
355 DegreesToRadians(-180),
358 8.0),
361 1,
362 1,
363 0.5,
364 0.5,
368 8.0),
371 1,
372 1,
373 0.5,
374 0.5,
376 DegreesToRadians(-45),
378 8.0),
381 1,
382 1,
383 0.5,
384 0.5,
388 8.0),
391 1,
392 1,
393 0.5,
394 0.5,
396 DegreesToRadians(-90),
398 8.0),
400
401 // linear array
403 10,
404 1,
405 0.5,
406 0.5,
410 18.0),
413 10,
414 1,
415 0.5,
416 0.5,
420 18.0),
423 10,
424 1,
425 0.5,
426 0.5,
430 18.0),
432
433 // planar array
435 10,
436 10,
437 0.5,
438 0.5,
442 28.0),
445 10,
446 10,
447 0.5,
448 0.5,
452 28.0),
455 10,
456 10,
457 0.5,
458 0.5,
462 28.0),
465 "Test IsChannelOutOfDate() and InvalidateChannels() for "
466 "UniformPlanarArray with 3GPP antenna element"),
468}
469
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
ComplexMatrixArray ComplexVector
the underlying Valarray
AttributeValue implementation for Pointer.
Definition pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
@ QUICK
Fast test.
Definition test.h:1055
TestCase(const TestCase &)=delete
Type
Type of test.
Definition test.h:1274
TestSuite(std::string name, Type type=Type::UNIT)
Construct a new test suite.
Definition test.cc:490
static constexpr auto UNIT
Definition test.h:1291
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