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
33using namespace ns3;
34
35NS_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;
98
102 double m_rowSpace;
103 double m_colSpace;
104 double m_alpha;
105 double m_beta;
108};
109
110std::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
151double
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
180void
182{
184 m_rows,
185 m_cols,
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,
237 0.0),
238 TestCase::QUICK);
240 1,
241 1,
242 0.5,
243 0.5,
247 8.0),
248 TestCase::QUICK);
250 1,
251 1,
252 0.5,
253 0.5,
257 8.0),
258 TestCase::QUICK);
260 1,
261 1,
262 0.5,
263 0.5,
264 DegreesToRadians(-90),
267 8.0),
268 TestCase::QUICK);
270 1,
271 1,
272 0.5,
273 0.5,
274 DegreesToRadians(180),
277 8.0),
278 TestCase::QUICK);
280 1,
281 1,
282 0.5,
283 0.5,
284 DegreesToRadians(-180),
287 8.0),
288 TestCase::QUICK);
290 1,
291 1,
292 0.5,
293 0.5,
297 8.0),
298 TestCase::QUICK);
300 1,
301 1,
302 0.5,
303 0.5,
305 DegreesToRadians(-45),
307 8.0),
308 TestCase::QUICK);
310 1,
311 1,
312 0.5,
313 0.5,
317 8.0),
318 TestCase::QUICK);
320 1,
321 1,
322 0.5,
323 0.5,
325 DegreesToRadians(-90),
327 8.0),
328 TestCase::QUICK);
329
330 // linear array
332 10,
333 1,
334 0.5,
335 0.5,
339 18.0),
340 TestCase::QUICK);
342 10,
343 1,
344 0.5,
345 0.5,
349 18.0),
350 TestCase::QUICK);
352 10,
353 1,
354 0.5,
355 0.5,
359 18.0),
360 TestCase::QUICK);
361
362 // planar array
364 10,
365 10,
366 0.5,
367 0.5,
371 28.0),
372 TestCase::QUICK);
374 10,
375 10,
376 0.5,
377 0.5,
381 28.0),
382 TestCase::QUICK);
384 10,
385 10,
386 0.5,
387 0.5,
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