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 * 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
37/**
38 * \ingroup antenna-tests
39 *
40 * \brief UniformPlanarArray Test Case
41 */
43{
44 public:
45 /**
46 * Generate a string containing all relevant parameters
47 * \param element the antenna element
48 * \param rows the number of rows
49 * \param cols the number of columns
50 * \param rowSpace the row spacing
51 * \param colSpace the column spacing
52 * \param alpha the bearing angle
53 * \param beta the tilting angle
54 * \param direction the direction
55 * \return the string containing all relevant parameters
56 */
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);
65 /**
66 * The constructor of the test case
67 * \param element the antenna element
68 * \param rows the number of rows
69 * \param cols the number of columns
70 * \param rowSpace the row spacing
71 * \param colSpace the column spacing
72 * \param alpha the bearing angle
73 * \param beta the tilting angle
74 * \param direction the direction
75 * \param expectedGainDb the expected antenna gain [dB]
76 */
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:
88 /**
89 * Run the test
90 */
91 void DoRun() override;
92 /**
93 * Compute the gain of the antenna array
94 * \param a the antenna array
95 * \return the gain of the antenna array [dB]
96 */
98
99 Ptr<AntennaModel> m_element; //!< the antenna element
100 uint32_t m_rows; //!< the number of rows
101 uint32_t m_cols; //!< the number of columns
102 double m_rowSpace; //!< the row spacing
103 double m_colSpace; //!< the column spacing
104 double m_alpha; //!< the bearing angle [rad]
105 double m_beta; //!< the titling angle [rad]
106 Angles m_direction; //!< the testing direction
107 double m_expectedGain; //!< the expected antenna gain [dB]
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->GetNumElems(), "steering vector of wrong size");
157 PhasedArrayModel::ComplexVector bf = a->GetBeamformingVector(m_direction);
158 NS_TEST_EXPECT_MSG_EQ(bf.GetSize(), a->GetNumElems(), "beamforming vector of wrong size");
159 std::pair<double, double> fp = a->GetElementFieldPattern(m_direction);
160
161 // scalar product dot (sv, bf)
162 std::complex<double> prod{0};
163 for (size_t i = 0; i < sv.GetSize(); i++)
164 {
165 prod += sv[i] * bf[i];
166 }
167 double bfGain = std::pow(std::abs(prod), 2);
168 double bfGainDb = 10 * std::log10(bfGain);
169
170 // power gain from two polarizations
171 double elementPowerGain = std::pow(std::get<0>(fp), 2) + std::pow(std::get<1>(fp), 2);
172 double elementPowerGainDb = 10 * std::log10(elementPowerGain);
173
174 // sum BF and element gains
175 return bfGainDb + elementPowerGainDb;
176}
177
178void
180{
182 m_rows,
183 m_cols,
186 m_alpha,
187 m_beta,
188 m_direction));
189
190 Ptr<UniformPlanarArray> a = CreateObject<UniformPlanarArray>();
191 a->SetAttribute("AntennaElement", PointerValue(m_element));
192 a->SetAttribute("NumRows", UintegerValue(m_rows));
193 a->SetAttribute("NumColumns", UintegerValue(m_cols));
194 a->SetAttribute("AntennaVerticalSpacing", DoubleValue(m_rowSpace));
195 a->SetAttribute("AntennaHorizontalSpacing", DoubleValue(m_colSpace));
196 a->SetAttribute("BearingAngle", DoubleValue(m_alpha));
197 a->SetAttribute("DowntiltAngle", DoubleValue(m_beta));
198
199 double actualGainDb = ComputeGain(a);
200 NS_TEST_EXPECT_MSG_EQ_TOL(actualGainDb,
202 0.001,
203 "wrong value of the radiation pattern");
204}
205
206/**
207 * \ingroup antenna-tests
208 *
209 * \brief UniformPlanarArray Test Suite
210 */
212{
213 public:
215};
216
218 : TestSuite("uniform-planar-array-test", Type::UNIT)
219{
220 Ptr<AntennaModel> isotropic = CreateObject<IsotropicAntennaModel>();
221 Ptr<AntennaModel> tgpp = CreateObject<ThreeGppAntennaModel>();
222
223 // element, rows, cols, rowSpace, colSpace, bearing,
224 // tilting, direction (azimuth,
225 // inclination), expectedGainDb
226 // Single element arrays: check if bearing/tilting works on antenna element
228 1,
229 1,
230 0.5,
231 0.5,
235 0.0),
236 TestCase::Duration::QUICK);
238 1,
239 1,
240 0.5,
241 0.5,
245 8.0),
246 TestCase::Duration::QUICK);
248 1,
249 1,
250 0.5,
251 0.5,
255 8.0),
256 TestCase::Duration::QUICK);
258 1,
259 1,
260 0.5,
261 0.5,
262 DegreesToRadians(-90),
265 8.0),
266 TestCase::Duration::QUICK);
268 1,
269 1,
270 0.5,
271 0.5,
272 DegreesToRadians(180),
275 8.0),
276 TestCase::Duration::QUICK);
278 1,
279 1,
280 0.5,
281 0.5,
282 DegreesToRadians(-180),
285 8.0),
286 TestCase::Duration::QUICK);
288 1,
289 1,
290 0.5,
291 0.5,
295 8.0),
296 TestCase::Duration::QUICK);
298 1,
299 1,
300 0.5,
301 0.5,
303 DegreesToRadians(-45),
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,
323 DegreesToRadians(-90),
325 8.0),
326 TestCase::Duration::QUICK);
327
328 // linear array
330 10,
331 1,
332 0.5,
333 0.5,
337 18.0),
338 TestCase::Duration::QUICK);
340 10,
341 1,
342 0.5,
343 0.5,
347 18.0),
348 TestCase::Duration::QUICK);
350 10,
351 1,
352 0.5,
353 0.5,
357 18.0),
358 TestCase::Duration::QUICK);
359
360 // planar array
362 10,
363 10,
364 0.5,
365 0.5,
369 28.0),
370 TestCase::Duration::QUICK);
372 10,
373 10,
374 0.5,
375 0.5,
379 28.0),
380 TestCase::Duration::QUICK);
382 10,
383 10,
384 0.5,
385 0.5,
389 28.0),
390 TestCase::Duration::QUICK);
391}
392
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
AttributeValue implementation for Pointer.
Definition: pointer.h:48
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
encapsulates test code
Definition: test.h:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
Hold an unsigned integer type.
Definition: uinteger.h:45
size_t GetSize() const
Definition: val-array.h:405
#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:252
#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:511
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