A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
propagation-loss-model-test-suite.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 The Boeing Company
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7#include "ns3/abort.h"
8#include "ns3/config.h"
9#include "ns3/constant-position-mobility-model.h"
10#include "ns3/double.h"
11#include "ns3/log.h"
12#include "ns3/propagation-loss-model.h"
13#include "ns3/simulator.h"
14#include "ns3/test.h"
15
16using namespace ns3;
17
18NS_LOG_COMPONENT_DEFINE("PropagationLossModelsTest");
19
20// ===========================================================================
21// This is a simple test to validate propagation loss models of ns-3 wifi.
22// See the chapter in the ns-3 testing and validation guide for more detail
23// ===========================================================================
24
25/**
26 * \ingroup propagation
27 * \defgroup propagation-test Propagation module tests
28 */
29
30/**
31 * \ingroup propagation-tests
32 *
33 * \brief FriisPropagationLossModel Test
34 */
36{
37 public:
40
41 private:
42 void DoRun() override;
43
44 /// Test vector
46 {
47 Vector m_position; //!< Test node position
48 double m_pt; //!< Tx power [dBm]
49 double m_pr; //!< Rx power [W]
50 double m_tolerance; //!< Tolerance
51 };
52
53 /// Test vectors
55};
56
58 : TestCase("Check to see that the ns-3 Friis propagation loss model provides correct received "
59 "power"),
60 m_testVectors()
61{
62}
63
67
68void
70{
71 // The ns-3 testing manual gives more background on the values selected
72 // for this test. First, set a few defaults.
73
74 // the test vectors have been determined for a wavelength of 0.125 m
75 // which corresponds to a frequency of 2398339664.0 Hz in the vacuum
76 Config::SetDefault("ns3::FriisPropagationLossModel::Frequency", DoubleValue(2398339664.0));
77 Config::SetDefault("ns3::FriisPropagationLossModel::SystemLoss", DoubleValue(1.0));
78
79 // Select a reference transmit power
80 // Pt = 10^(17.0206/10)/10^3 = .05035702 W
81 double txPowerW = 0.05035702;
82 double txPowerdBm = 10 * std::log10(txPowerW) + 30;
83
84 //
85 // We want to test the propagation loss model calculations at a few chosen
86 // distances and compare the results to those we have manually calculated
87 // according to the model documentation. The model reference specifies,
88 // for instance, that the received power at 100m according to the provided
89 // input power will be 4.98265e-10 W. Since this value specifies the power
90 // to 1e-15 significance, we test the ns-3 calculated value for agreement
91 // within 5e-16.
92 //
93 TestVector testVector;
94
95 testVector.m_position = Vector(100, 0, 0);
96 testVector.m_pt = txPowerdBm;
97 testVector.m_pr = 4.98265e-10;
98 testVector.m_tolerance = 5e-16;
99 m_testVectors.Add(testVector);
100
101 testVector.m_position = Vector(500, 0, 0);
102 testVector.m_pt = txPowerdBm;
103 testVector.m_pr = 1.99306e-11;
104 testVector.m_tolerance = 5e-17;
105 m_testVectors.Add(testVector);
106
107 testVector.m_position = Vector(1000, 0, 0);
108 testVector.m_pt = txPowerdBm;
109 testVector.m_pr = 4.98265e-12;
110 testVector.m_tolerance = 5e-18;
111 m_testVectors.Add(testVector);
112
113 testVector.m_position = Vector(2000, 0, 0);
114 testVector.m_pt = txPowerdBm;
115 testVector.m_pr = 1.24566e-12;
116 testVector.m_tolerance = 5e-18;
117 m_testVectors.Add(testVector);
118
119 // Now, check that the received power values are expected
120
122 a->SetPosition(Vector(0, 0, 0));
124
126 for (uint32_t i = 0; i < m_testVectors.GetN(); ++i)
127 {
128 testVector = m_testVectors.Get(i);
129 b->SetPosition(testVector.m_position);
130 double resultdBm = lossModel->CalcRxPower(testVector.m_pt, a, b);
131 double resultW = std::pow(10.0, resultdBm / 10.0) / 1000;
133 testVector.m_pr,
134 testVector.m_tolerance,
135 "Got unexpected rcv power");
136 }
137}
138
139// Added for Two-Ray Ground Model - tomhewer@mac.com
140
141/**
142 * \ingroup propagation-tests
143 *
144 * \brief TwoRayGroundPropagationLossModel Test
145 */
147{
148 public:
151
152 private:
153 void DoRun() override;
154
155 /// Test vector
157 {
158 Vector m_position; //!< Test node position
159 double m_pt; //!< Tx power [dBm]
160 double m_pr; //!< Rx power [W]
161 double m_tolerance; //!< Tolerance
162 };
163
164 /// Test vectors
166};
167
169 : TestCase("Check to see that the ns-3 TwoRayGround propagation loss model provides correct "
170 "received power"),
171 m_testVectors()
172{
173}
174
178
179void
181{
182 // the test vectors have been determined for a wavelength of 0.125 m
183 // which corresponds to a frequency of 2398339664.0 Hz in the vacuum
184 Config::SetDefault("ns3::TwoRayGroundPropagationLossModel::Frequency",
185 DoubleValue(2398339664.0));
186 Config::SetDefault("ns3::TwoRayGroundPropagationLossModel::SystemLoss", DoubleValue(1.0));
187
188 // set antenna height to 1.5m above z coordinate
189 Config::SetDefault("ns3::TwoRayGroundPropagationLossModel::HeightAboveZ", DoubleValue(1.5));
190
191 // Select a reference transmit power of 17.0206 dBm
192 // Pt = 10^(17.0206/10)/10^3 = .05035702 W
193 double txPowerW = 0.05035702;
194 double txPowerdBm = 10 * std::log10(txPowerW) + 30;
195
196 //
197 // As with the Friis tests above, we want to test the propagation loss
198 // model calculations at a few chosen distances and compare the results
199 // to those we can manually calculate. Let us test the ns-3 calculated
200 // value for agreement to be within 5e-16, as above.
201 //
202 TestVector testVector;
203
204 // Below the Crossover distance use Friis so this test should be the same as that above
205 // Crossover = (4 * PI * TxAntennaHeight * RxAntennaHeight) / Lamdba
206 // Crossover = (4 * PI * 1.5 * 1.5) / 0.125 = 226.1946m
207
208 testVector.m_position = Vector(100, 0, 0);
209 testVector.m_pt = txPowerdBm;
210 testVector.m_pr = 4.98265e-10;
211 testVector.m_tolerance = 5e-16;
212 m_testVectors.Add(testVector);
213
214 // These values are above the crossover distance and therefore use the Two Ray calculation
215
216 testVector.m_position = Vector(500, 0, 0);
217 testVector.m_pt = txPowerdBm;
218 testVector.m_pr = 4.07891862e-12;
219 testVector.m_tolerance = 5e-16;
220 m_testVectors.Add(testVector);
221
222 testVector.m_position = Vector(1000, 0, 0);
223 testVector.m_pt = txPowerdBm;
224 testVector.m_pr = 2.5493241375e-13;
225 testVector.m_tolerance = 5e-16;
226 m_testVectors.Add(testVector);
227
228 testVector.m_position = Vector(2000, 0, 0);
229 testVector.m_pt = txPowerdBm;
230 testVector.m_pr = 1.593327585938e-14;
231 testVector.m_tolerance = 5e-16;
232 m_testVectors.Add(testVector);
233
234 // Repeat the tests for non-zero z coordinates
235
236 // Pr = (0.05035702 * (1.5*1.5) * (2.5*2.5)) / (500*500*500*500) = 1.13303295e-11
237 // dCross = (4 * pi * 1.5 * 2.5) / 0.125 = 376.99m
238 testVector.m_position = Vector(500, 0, 1);
239 testVector.m_pt = txPowerdBm;
240 testVector.m_pr = 1.13303295e-11;
241 testVector.m_tolerance = 5e-16;
242 m_testVectors.Add(testVector);
243
244 // Pr = (0.05035702 * (1.5*1.5) * (5.5*5.5)) / (1000*1000*1000*1000) = 3.42742467375e-12
245 // dCross = (4 * pi * 1.5 * 5.5) / 0.125 = 829.38m
246 testVector.m_position = Vector(1000, 0, 4);
247 testVector.m_pt = txPowerdBm;
248 testVector.m_pr = 3.42742467375e-12;
249 testVector.m_tolerance = 5e-16;
250 m_testVectors.Add(testVector);
251
252 // Pr = (0.05035702 * (1.5*1.5) * (11.5*11.5)) / (2000*2000*2000*2000) = 9.36522547734e-13
253 // dCross = (4 * pi * 1.5 * 11.5) / 0.125 = 1734.15m
254 testVector.m_position = Vector(2000, 0, 10);
255 testVector.m_pt = txPowerdBm;
256 testVector.m_pr = 9.36522547734e-13;
257 testVector.m_tolerance = 5e-16;
258 m_testVectors.Add(testVector);
259
260 // Now, check that the received power values are expected
261
263 a->SetPosition(Vector(0, 0, 0));
265
268 for (uint32_t i = 0; i < m_testVectors.GetN(); ++i)
269 {
270 testVector = m_testVectors.Get(i);
271 b->SetPosition(testVector.m_position);
272 double resultdBm = lossModel->CalcRxPower(testVector.m_pt, a, b);
273 double resultW = std::pow(10.0, resultdBm / 10.0) / 1000;
275 testVector.m_pr,
276 testVector.m_tolerance,
277 "Got unexpected rcv power");
278 }
279}
280
281/**
282 * \ingroup propagation-tests
283 *
284 * \brief LogDistancePropagationLossModel Test
285 */
287{
288 public:
291
292 private:
293 void DoRun() override;
294
295 /// Test vector
297 {
298 Vector m_position; //!< Test node position
299 double m_pt; //!< Tx power [dBm]
300 double m_pr; //!< Rx power [W]
301 double m_tolerance; //!< Tolerance
302 };
303
304 /// Test vectors
306};
307
309 : TestCase("Check to see that the ns-3 Log Distance propagation loss model provides correct "
310 "received power"),
311 m_testVectors()
312{
313}
314
318
319void
321{
322 // reference loss at 2.4 GHz is 40.045997
323 Config::SetDefault("ns3::LogDistancePropagationLossModel::ReferenceLoss",
324 DoubleValue(40.045997));
325 Config::SetDefault("ns3::LogDistancePropagationLossModel::Exponent", DoubleValue(3));
326
327 // Select a reference transmit power
328 // Pt = 10^(17.0206/10)/10^3 = .05035702 W
329 double txPowerW = 0.05035702;
330 double txPowerdBm = 10 * std::log10(txPowerW) + 30;
331
332 //
333 // We want to test the propagation loss model calculations at a few chosen
334 // distances and compare the results to those we have manually calculated
335 // according to the model documentation. The following "TestVector" objects
336 // will drive the test.
337 //
338 TestVector testVector;
339
340 testVector.m_position = Vector(10, 0, 0);
341 testVector.m_pt = txPowerdBm;
342 testVector.m_pr = 4.98265e-9;
343 testVector.m_tolerance = 5e-15;
344 m_testVectors.Add(testVector);
345
346 testVector.m_position = Vector(20, 0, 0);
347 testVector.m_pt = txPowerdBm;
348 testVector.m_pr = 6.22831e-10;
349 testVector.m_tolerance = 5e-16;
350 m_testVectors.Add(testVector);
351
352 testVector.m_position = Vector(40, 0, 0);
353 testVector.m_pt = txPowerdBm;
354 testVector.m_pr = 7.78539e-11;
355 testVector.m_tolerance = 5e-17;
356 m_testVectors.Add(testVector);
357
358 testVector.m_position = Vector(80, 0, 0);
359 testVector.m_pt = txPowerdBm;
360 testVector.m_pr = 9.73173e-12;
361 testVector.m_tolerance = 5e-17;
362 m_testVectors.Add(testVector);
363
365 a->SetPosition(Vector(0, 0, 0));
367
370 for (uint32_t i = 0; i < m_testVectors.GetN(); ++i)
371 {
372 testVector = m_testVectors.Get(i);
373 b->SetPosition(testVector.m_position);
374 double resultdBm = lossModel->CalcRxPower(testVector.m_pt, a, b);
375 double resultW = std::pow(10.0, resultdBm / 10.0) / 1000;
377 testVector.m_pr,
378 testVector.m_tolerance,
379 "Got unexpected rcv power");
380 }
381}
382
383/**
384 * \ingroup propagation-tests
385 *
386 * \brief MatrixPropagationLossModel Test
387 */
389{
390 public:
393
394 private:
395 void DoRun() override;
396};
397
399 : TestCase("Test MatrixPropagationLossModel")
400{
401}
402
406
407void
409{
411 for (int i = 0; i < 3; ++i)
412 {
414 }
415
417 // no loss by default
418 loss.SetDefaultLoss(0);
419 // -10 dB for 0 -> 1 and 1 -> 0
420 loss.SetLoss(m[0], m[1], 10);
421 // -30 dB from 0 to 2 and -100 dB from 2 to 0
422 loss.SetLoss(m[0], m[2], 30, /*symmetric = */ false);
423 loss.SetLoss(m[2], m[0], 100, /*symmetric = */ false);
424 // default from 1 to 2
425
426 NS_TEST_ASSERT_MSG_EQ(loss.CalcRxPower(0, m[0], m[1]), -10, "Loss 0 -> 1 incorrect");
427 NS_TEST_ASSERT_MSG_EQ(loss.CalcRxPower(0, m[1], m[0]), -10, "Loss 1 -> 0 incorrect");
428 NS_TEST_ASSERT_MSG_EQ(loss.CalcRxPower(0, m[0], m[2]), -30, "Loss 0 -> 2 incorrect");
429 NS_TEST_ASSERT_MSG_EQ(loss.CalcRxPower(0, m[2], m[0]), -100, "Loss 2 -> 0 incorrect");
430 NS_TEST_ASSERT_MSG_EQ(loss.CalcRxPower(0, m[1], m[2]), 0, "Loss 1 -> 2 incorrect");
431 NS_TEST_ASSERT_MSG_EQ(loss.CalcRxPower(0, m[2], m[1]), 0, "Loss 2 -> 1 incorrect");
432
434}
435
436/**
437 * \ingroup propagation-tests
438 *
439 * \brief RangePropagationLossModel Test
440 */
442{
443 public:
446
447 private:
448 void DoRun() override;
449};
450
452 : TestCase("Test RangePropagationLossModel")
453{
454}
455
459
460void
462{
463 Config::SetDefault("ns3::RangePropagationLossModel::MaxRange", DoubleValue(127.2));
465 a->SetPosition(Vector(0, 0, 0));
467 b->SetPosition(Vector(127.1, 0, 0)); // within range
468
470
471 double txPwrdBm = -80.0;
472 double tolerance = 1e-6;
473 double resultdBm = lossModel->CalcRxPower(txPwrdBm, a, b);
474 NS_TEST_EXPECT_MSG_EQ_TOL(resultdBm, txPwrdBm, tolerance, "Got unexpected rcv power");
475 b->SetPosition(Vector(127.25, 0, 0)); // beyond range
476 resultdBm = lossModel->CalcRxPower(txPwrdBm, a, b);
477 NS_TEST_EXPECT_MSG_EQ_TOL(resultdBm, -1000.0, tolerance, "Got unexpected rcv power");
479}
480
481/**
482 * \ingroup propagation-tests
483 *
484 * \brief Propagation models TestSuite
485 *
486 * This TestSuite tests the following models:
487 * - FriisPropagationLossModel
488 * - TwoRayGroundPropagationLossModel
489 * - LogDistancePropagationLossModel
490 * - MatrixPropagationLossModel
491 * - RangePropagationLossModel
492 */
498
500 : TestSuite("propagation-loss-model", Type::UNIT)
501{
502 AddTestCase(new FriisPropagationLossModelTestCase, TestCase::Duration::QUICK);
503 AddTestCase(new TwoRayGroundPropagationLossModelTestCase, TestCase::Duration::QUICK);
504 AddTestCase(new LogDistancePropagationLossModelTestCase, TestCase::Duration::QUICK);
505 AddTestCase(new MatrixPropagationLossModelTestCase, TestCase::Duration::QUICK);
506 AddTestCase(new RangePropagationLossModelTestCase, TestCase::Duration::QUICK);
507}
508
509/// Static variable for test initialization
void DoRun() override
Implementation to actually run this TestCase.
TestVectors< TestVector > m_testVectors
Test vectors.
TestVectors< TestVector > m_testVectors
Test vectors.
void DoRun() override
Implementation to actually run this TestCase.
void DoRun() override
Implementation to actually run this TestCase.
void DoRun() override
Implementation to actually run this TestCase.
void DoRun() override
Implementation to actually run this TestCase.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
The propagation loss is fixed for each pair of nodes and doesn't depend on their actual positions.
void SetLoss(Ptr< MobilityModel > a, Ptr< MobilityModel > b, double loss, bool symmetric=true)
Set loss (in dB, positive) between pair of ns-3 objects (typically, nodes).
void SetDefaultLoss(double defaultLoss)
Set the default propagation loss (in dB, positive) to be used, infinity if not set.
double CalcRxPower(double txPowerDbm, Ptr< MobilityModel > a, Ptr< MobilityModel > b) const
Returns the Rx Power taking into account all the PropagationLossModel(s) chained to the current one.
Smart pointer class similar to boost::intrusive_ptr.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
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
A simple way to store test vectors (for stimulus or from responses)
Definition test.h:1348
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:883
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
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_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.
static PropagationLossModelsTestSuite g_propagationLossModelsTestSuite
Static variable for test initialization.