A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
test-angles.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011 CTTC
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Nicola Baldo <nbaldo@cttc.es>
7 */
8
9#include "ns3/antenna-model.h"
10#include "ns3/log.h"
11#include "ns3/test.h"
12
13#include <cmath>
14#include <iostream>
15#include <sstream>
16#include <string>
17
18using namespace ns3;
19
20/**
21 * @ingroup tests
22 *
23 * @brief Angles Test using one vector for initialization
24 */
26{
27 public:
28 /**
29 * Build the test name
30 * @param v test parameter
31 * @return the test name
32 */
33 static std::string BuildNameString(Vector v);
34 /**
35 * Constructor
36 * @param v vector
37 * @param a expected angle
38 */
40
41 private:
42 void DoRun() override;
43
44 Vector m_v; //!< vector
45 Angles m_a; //!< expected angle
46};
47
48std::string
50{
51 std::ostringstream oss;
52 oss << " v = " << v;
53 return oss.str();
54}
55
62
63void
65{
66 Angles a(m_v);
67 NS_TEST_EXPECT_MSG_EQ_TOL(a.GetAzimuth(), m_a.GetAzimuth(), 1e-10, "incorrect phi");
68 NS_TEST_EXPECT_MSG_EQ_TOL(a.GetInclination(), m_a.GetInclination(), 1e-10, "incorrect theta");
69}
70
71/**
72 * @ingroup tests
73 *
74 * @brief Angles Test using two vectors for initialization
75 */
77{
78 public:
79 /**
80 * Build the test name
81 * @param v test parameter
82 * @param o test parameter
83 * @return the test name
84 */
85 static std::string BuildNameString(Vector v, Vector o);
86 /**
87 * Constructor
88 * @param v point
89 * @param o origin
90 * @param a expected angle
91 */
92 TwoVectorsConstructorTestCase(Vector v, Vector o, Angles a);
93
94 private:
95 void DoRun() override;
96
97 Vector m_v; //!< point
98 Vector m_o; //!< origin
99 Angles m_a; //!< expected angle
100};
101
102std::string
104{
105 std::ostringstream oss;
106 oss << " v = " << v << ", o = " << o;
107 return oss.str();
108}
109
111 : TestCase(BuildNameString(v, o)),
112 m_v(v),
113 m_o(o),
114 m_a(a)
115{
116}
117
118void
120{
121 Angles a(m_v, m_o);
122 NS_TEST_EXPECT_MSG_EQ_TOL(a.GetAzimuth(), m_a.GetAzimuth(), 1e-10, "incorrect phi");
123 NS_TEST_EXPECT_MSG_EQ_TOL(a.GetInclination(), m_a.GetInclination(), 1e-10, "incorrect theta");
124}
125
126using WrapToRangeFunction = std::function<double(double)>;
127
128/**
129 * @ingroup tests
130 *
131 * @brief Test bounds for various WrapTo... methods (WrapTo180, WrapTo360, WrapToPi, and WrapTo2Pi)
132 * by using a std::function wrapper
133 */
135{
136 public:
137 /**
138 * Build the test name
139 * @param lowerBound the lower bound of the WrapTo... function
140 * @param upperBound the upper bound of the WrapTo... function
141 * @return the test name
142 */
143 static std::string BuildNameString(double lowerBound, double upperBound);
144 /**
145 * Constructor
146 * @param wrapper for one of WrapTo180, WrapTo360, WrapToPi, and WrapTo2Pi
147 * @param lowerBound the corresponding lower bound
148 * @param upperBound the corresponding upper bound
149 */
150 WrapToRangeTestCase(WrapToRangeFunction wrapper, double lowerBound, double upperBound);
151
152 protected:
153 /**
154 * The given wrapper shall wrap an angle into the expected range
155 * @param wrapPoint an angle
156 */
157 void CheckWrappingPoint(double wrapPoint);
158
159 private:
160 void DoRun() override;
161
162 WrapToRangeFunction m_wrapper; //!< the wrapper function
163 double m_lowerBound; //!< the corresponding lower bound
164 double m_upperBound; //!< the corresponding upper bound
165};
166
167std::string
168WrapToRangeTestCase::BuildNameString(double lowerBound, double upperBound)
169{
170 std::ostringstream oss;
171 oss << "WrapTo [" << lowerBound << ", " << upperBound << ")";
172 return oss.str();
173}
174
176 double lowerBound,
177 double upperBound)
178 : TestCase(BuildNameString(lowerBound, upperBound)),
179 m_wrapper(wrapper),
180 m_lowerBound(lowerBound),
181 m_upperBound(upperBound)
182{
183}
184
185void
191
192void
194{
195 constexpr int STEP_NUM = 100;
196 double directions[] = {std::numeric_limits<double>::lowest(),
197 std::numeric_limits<double>::max()};
198 for (double dir : directions)
199 {
200 int i = 0;
201 for (double x = wrapPoint; i < STEP_NUM; x = std::nextafter(x, dir), ++i)
202 {
203 // If asserts are enabled, this test will crash with an assert instead of failing
204 double result = m_wrapper(x);
206 true,
207 "Invalid wrap (too low) " << x << " maps to " << result << " and "
208 << result - m_lowerBound);
210 true,
211 "Invalid wrap (too high) " << x << " maps to " << result
212 << " and " << result - m_lowerBound);
213 }
214 }
215}
216
217/**
218 * @ingroup tests
219 *
220 * @brief Test the output for WrapToRangeFunction
221 */
223{
224 public:
225 /**
226 * Build the test name
227 * @param angle the angle
228 * @param wrappedAngle the expected result
229 * @return the test name
230 */
231 static std::string BuildNameString(double angle, double wrappedAngle);
232 /**
233 * Constructor
234 * @param wrapper one WrapToRangeFunction
235 * @param angle the angle
236 * @param wrappedAngle the expected result
237 */
238 WrapToRangeFunctionalTestCase(WrapToRangeFunction wrapper, double angle, double wrappedAngle);
239
240 private:
241 void DoRun() override;
242
243 WrapToRangeFunction m_wrapper; //!< the wrapper function
244 double m_angle; //!< the input angle
245 double m_wrappedAngle; //!< the expected wrapper angle
246};
247
248std::string
249WrapToRangeFunctionalTestCase::BuildNameString(double angle, double wrappedAngle)
250{
251 std::ostringstream oss;
252 oss << "Wrap " << angle << " to " << wrappedAngle;
253 return oss.str();
254}
255
257 double angle,
258 double wrappedAngle)
259 : TestCase(BuildNameString(angle, wrappedAngle)),
260 m_wrapper(wrapper),
261 m_angle(angle),
262 m_wrappedAngle(wrappedAngle)
263{
264}
265
266void
268{
271 1e-6,
272 "Invalid wrap " << m_angle << " wrapped to " << m_wrapper(m_angle)
273 << " instead of " << m_wrappedAngle);
274}
275
276/**
277 * @ingroup tests
278 *
279 * @brief Angles TestSuite
280 */
282{
283 public:
285};
286
288 : TestSuite("angles", Type::UNIT)
289{
290 AddTestCase(new OneVectorConstructorTestCase(Vector(1, 0, 0), Angles(0, M_PI_2)),
292 AddTestCase(new OneVectorConstructorTestCase(Vector(-1, 0, 0), Angles(M_PI, M_PI_2)),
294 AddTestCase(new OneVectorConstructorTestCase(Vector(0, 1, 0), Angles(M_PI_2, M_PI_2)),
296 AddTestCase(new OneVectorConstructorTestCase(Vector(0, -1, 0), Angles(-M_PI_2, M_PI_2)),
298 AddTestCase(new OneVectorConstructorTestCase(Vector(0, 0, 1), Angles(0, 0)),
300 AddTestCase(new OneVectorConstructorTestCase(Vector(0, 0, -1), Angles(0, M_PI)),
302
303 AddTestCase(new OneVectorConstructorTestCase(Vector(2, 0, 0), Angles(0, M_PI_2)),
305 AddTestCase(new OneVectorConstructorTestCase(Vector(-2, 0, 0), Angles(M_PI, M_PI_2)),
307 AddTestCase(new OneVectorConstructorTestCase(Vector(0, 2, 0), Angles(M_PI_2, M_PI_2)),
309 AddTestCase(new OneVectorConstructorTestCase(Vector(0, -2, 0), Angles(-M_PI_2, M_PI_2)),
311 AddTestCase(new OneVectorConstructorTestCase(Vector(0, 0, 2), Angles(0, 0)),
313 AddTestCase(new OneVectorConstructorTestCase(Vector(0, 0, -2), Angles(0, M_PI)),
315
316 AddTestCase(new OneVectorConstructorTestCase(Vector(1, 0, 1), Angles(0, M_PI_4)),
318 AddTestCase(new OneVectorConstructorTestCase(Vector(1, 0, -1), Angles(0, 3 * M_PI_4)),
320 AddTestCase(new OneVectorConstructorTestCase(Vector(1, 1, 0), Angles(M_PI_4, M_PI_2)),
322 AddTestCase(new OneVectorConstructorTestCase(Vector(1, -1, 0), Angles(-M_PI_4, M_PI_2)),
324 AddTestCase(new OneVectorConstructorTestCase(Vector(-1, 0, 1), Angles(M_PI, M_PI_4)),
326 AddTestCase(new OneVectorConstructorTestCase(Vector(-1, 0, -1), Angles(M_PI, 3 * M_PI_4)),
328 AddTestCase(new OneVectorConstructorTestCase(Vector(-1, 1, 0), Angles(3 * M_PI_4, M_PI_2)),
330 AddTestCase(new OneVectorConstructorTestCase(Vector(-1, -1, 0), Angles(-3 * M_PI_4, M_PI_2)),
332 AddTestCase(new OneVectorConstructorTestCase(Vector(0, 1, 1), Angles(M_PI_2, M_PI_4)),
334 AddTestCase(new OneVectorConstructorTestCase(Vector(0, 1, -1), Angles(M_PI_2, 3 * M_PI_4)),
336 AddTestCase(new OneVectorConstructorTestCase(Vector(0, -1, 1), Angles(-M_PI_2, M_PI_4)),
338 AddTestCase(new OneVectorConstructorTestCase(Vector(0, -1, -1), Angles(-M_PI_2, 3 * M_PI_4)),
340
342 new OneVectorConstructorTestCase(Vector(1, 1, std::sqrt(2)), Angles(M_PI_4, M_PI_4)),
345 new OneVectorConstructorTestCase(Vector(1, 1, -std::sqrt(2)), Angles(M_PI_4, 3 * M_PI_4)),
348 new OneVectorConstructorTestCase(Vector(1, -1, std::sqrt(2)), Angles(-M_PI_4, M_PI_4)),
351 new OneVectorConstructorTestCase(Vector(-1, 1, std::sqrt(2)), Angles(3 * M_PI_4, M_PI_4)),
353
355 new TwoVectorsConstructorTestCase(Vector(1, 0, 0), Vector(0, 0, 0), Angles(0, M_PI_2)),
358 new TwoVectorsConstructorTestCase(Vector(-1, 0, 0), Vector(0, 0, 0), Angles(M_PI, M_PI_2)),
361 new TwoVectorsConstructorTestCase(Vector(0, 1, 0), Vector(0, 0, 0), Angles(M_PI_2, M_PI_2)),
363 AddTestCase(new TwoVectorsConstructorTestCase(Vector(0, -1, 0),
364 Vector(0, 0, 0),
365 Angles(-M_PI_2, M_PI_2)),
367 AddTestCase(new TwoVectorsConstructorTestCase(Vector(0, 0, 1), Vector(0, 0, 0), Angles(0, 0)),
370 new TwoVectorsConstructorTestCase(Vector(0, 0, -1), Vector(0, 0, 0), Angles(0, M_PI)),
372
374 new TwoVectorsConstructorTestCase(Vector(2, 0, 0), Vector(0, 0, 0), Angles(0, M_PI_2)),
377 new TwoVectorsConstructorTestCase(Vector(-2, 0, 0), Vector(0, 0, 0), Angles(M_PI, M_PI_2)),
380 new TwoVectorsConstructorTestCase(Vector(0, 2, 0), Vector(0, 0, 0), Angles(M_PI_2, M_PI_2)),
382 AddTestCase(new TwoVectorsConstructorTestCase(Vector(0, -2, 0),
383 Vector(0, 0, 0),
384 Angles(-M_PI_2, M_PI_2)),
386 AddTestCase(new TwoVectorsConstructorTestCase(Vector(0, 0, 2), Vector(0, 0, 0), Angles(0, 0)),
389 new TwoVectorsConstructorTestCase(Vector(0, 0, -2), Vector(0, 0, 0), Angles(0, M_PI)),
391
393 new TwoVectorsConstructorTestCase(Vector(1, 0, 1), Vector(0, 0, 0), Angles(0, M_PI_4)),
396 new TwoVectorsConstructorTestCase(Vector(1, 0, -1), Vector(0, 0, 0), Angles(0, 3 * M_PI_4)),
399 new TwoVectorsConstructorTestCase(Vector(1, 1, 0), Vector(0, 0, 0), Angles(M_PI_4, M_PI_2)),
401 AddTestCase(new TwoVectorsConstructorTestCase(Vector(1, -1, 0),
402 Vector(0, 0, 0),
403 Angles(-M_PI_4, M_PI_2)),
406 new TwoVectorsConstructorTestCase(Vector(-1, 0, 1), Vector(0, 0, 0), Angles(M_PI, M_PI_4)),
408 AddTestCase(new TwoVectorsConstructorTestCase(Vector(-1, 0, -1),
409 Vector(0, 0, 0),
410 Angles(M_PI, 3 * M_PI_4)),
412 AddTestCase(new TwoVectorsConstructorTestCase(Vector(-1, 1, 0),
413 Vector(0, 0, 0),
414 Angles(3 * M_PI_4, M_PI_2)),
416 AddTestCase(new TwoVectorsConstructorTestCase(Vector(-1, -1, 0),
417 Vector(0, 0, 0),
418 Angles(-3 * M_PI_4, M_PI_2)),
421 new TwoVectorsConstructorTestCase(Vector(0, 1, 1), Vector(0, 0, 0), Angles(M_PI_2, M_PI_4)),
423 AddTestCase(new TwoVectorsConstructorTestCase(Vector(0, 1, -1),
424 Vector(0, 0, 0),
425 Angles(M_PI_2, 3 * M_PI_4)),
427 AddTestCase(new TwoVectorsConstructorTestCase(Vector(0, -1, 1),
428 Vector(0, 0, 0),
429 Angles(-M_PI_2, M_PI_4)),
431 AddTestCase(new TwoVectorsConstructorTestCase(Vector(0, -1, -1),
432 Vector(0, 0, 0),
433 Angles(-M_PI_2, 3 * M_PI_4)),
435
436 AddTestCase(new TwoVectorsConstructorTestCase(Vector(1, 1, std::sqrt(2)),
437 Vector(0, 0, 0),
438 Angles(M_PI_4, M_PI_4)),
440 AddTestCase(new TwoVectorsConstructorTestCase(Vector(1, 1, -std::sqrt(2)),
441 Vector(0, 0, 0),
442 Angles(M_PI_4, 3 * M_PI_4)),
444 AddTestCase(new TwoVectorsConstructorTestCase(Vector(1, -1, std::sqrt(2)),
445 Vector(0, 0, 0),
446 Angles(-M_PI_4, M_PI_4)),
448 AddTestCase(new TwoVectorsConstructorTestCase(Vector(-1, 1, std::sqrt(2)),
449 Vector(0, 0, 0),
450 Angles(3 * M_PI_4, M_PI_4)),
452
454 new TwoVectorsConstructorTestCase(Vector(3, 2, 2), Vector(2, 2, 2), Angles(0, M_PI_2)),
457 new TwoVectorsConstructorTestCase(Vector(1, 2, 2), Vector(2, 2, 2), Angles(M_PI, M_PI_2)),
460 new TwoVectorsConstructorTestCase(Vector(2, 3, 2), Vector(2, 2, 2), Angles(M_PI_2, M_PI_2)),
462 AddTestCase(new TwoVectorsConstructorTestCase(Vector(-1, 2, 2),
463 Vector(-1, 3, 2),
464 Angles(-M_PI_2, M_PI_2)),
466 AddTestCase(new TwoVectorsConstructorTestCase(Vector(4, -2, 7), Vector(4, -2, 6), Angles(0, 0)),
469 new TwoVectorsConstructorTestCase(Vector(0, -5, -1), Vector(0, -5, 0), Angles(0, M_PI)),
471
473 new TwoVectorsConstructorTestCase(Vector(-2, 2, -1), Vector(-4, 2, -1), Angles(0, M_PI_2)),
476 new TwoVectorsConstructorTestCase(Vector(2, 2, 0), Vector(4, 2, 0), Angles(M_PI, M_PI_2)),
478
480 new TwoVectorsConstructorTestCase(Vector(-1, 4, 4), Vector(-2, 4, 3), Angles(0, M_PI_4)),
482 AddTestCase(new TwoVectorsConstructorTestCase(Vector(0, -2, -6),
483 Vector(-1, -2, -5),
484 Angles(0, 3 * M_PI_4)),
486 AddTestCase(new TwoVectorsConstructorTestCase(Vector(77, 3, 43),
487 Vector(78, 2, 43),
488 Angles(3 * M_PI_4, M_PI_2)),
490
491 AddTestCase(new TwoVectorsConstructorTestCase(Vector(24, -2, -6 - std::sqrt(2)),
492 Vector(23, -3, -6),
493 Angles(M_PI_4, 3 * M_PI_4)),
495 AddTestCase(new TwoVectorsConstructorTestCase(Vector(0.5, 11.45, std::sqrt(2) - 1),
496 Vector(-0.5, 12.45, -1),
497 Angles(-M_PI_4, M_PI_4)),
516}
517
518/// Static variable for test initialization
Angles TestSuite.
Angles Test using one vector for initialization.
void DoRun() override
Implementation to actually run this TestCase.
OneVectorConstructorTestCase(Vector v, Angles a)
Constructor.
Angles m_a
expected angle
static std::string BuildNameString(Vector v)
Build the test name.
Angles Test using two vectors for initialization.
TwoVectorsConstructorTestCase(Vector v, Vector o, Angles a)
Constructor.
void DoRun() override
Implementation to actually run this TestCase.
Angles m_a
expected angle
static std::string BuildNameString(Vector v, Vector o)
Build the test name.
Test the output for WrapToRangeFunction.
WrapToRangeFunctionalTestCase(WrapToRangeFunction wrapper, double angle, double wrappedAngle)
Constructor.
double m_angle
the input angle
double m_wrappedAngle
the expected wrapper angle
static std::string BuildNameString(double angle, double wrappedAngle)
Build the test name.
void DoRun() override
Implementation to actually run this TestCase.
WrapToRangeFunction m_wrapper
the wrapper function
Test bounds for various WrapTo... methods (WrapTo180, WrapTo360, WrapToPi, and WrapTo2Pi) by using a ...
void CheckWrappingPoint(double wrapPoint)
The given wrapper shall wrap an angle into the expected range.
double m_lowerBound
the corresponding lower bound
WrapToRangeFunction m_wrapper
the wrapper function
WrapToRangeTestCase(WrapToRangeFunction wrapper, double lowerBound, double upperBound)
Constructor.
void DoRun() override
Implementation to actually run this TestCase.
static std::string BuildNameString(double lowerBound, double upperBound)
Build the test name.
double m_upperBound
the corresponding upper bound
Class holding the azimuth and inclination angles of spherical coordinates.
Definition angles.h:107
double GetInclination() const
Getter for inclination angle.
Definition angles.cc:236
double GetAzimuth() const
Getter for azimuth angle.
Definition angles.cc:230
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
#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 WrapToPi(double a)
Wrap angle in [-M_PI, M_PI)
Definition angles.cc:127
double WrapTo180(double a)
Wrap angle in [-180, 180)
Definition angles.cc:85
double WrapTo360(double a)
Wrap angle in [0, 360)
Definition angles.cc:64
double WrapTo2Pi(double a)
Wrap angle in [0, 2*M_PI)
Definition angles.cc:106
std::string dir
static AnglesTestSuite g_staticAnglesTestSuiteInstance
Static variable for test initialization.
std::function< double(double)> WrapToRangeFunction