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/node-container.h"
13#include "ns3/propagation-loss-model.h"
14#include "ns3/simulator.h"
15#include "ns3/test.h"
16
17using namespace ns3;
18
19NS_LOG_COMPONENT_DEFINE("PropagationLossModelsTest");
20
21// ===========================================================================
22// This is a simple test to validate propagation loss models of ns-3 wifi.
23// See the chapter in the ns-3 testing and validation guide for more detail
24// ===========================================================================
25
26/**
27 * @ingroup propagation
28 * @defgroup propagation-test Propagation module tests
29 */
30
31/**
32 * @ingroup propagation-tests
33 *
34 * @brief FriisPropagationLossModel Test
35 */
37{
38 public:
41
42 private:
43 void DoRun() override;
44
45 /// Test vector
47 {
48 Vector m_position; //!< Test node position
49 double m_pt; //!< Tx power [dBm]
50 double m_pr; //!< Rx power [W]
51 double m_tolerance; //!< Tolerance
52 };
53
54 /// Test vectors
56};
57
59 : TestCase("Check to see that the ns-3 Friis propagation loss model provides correct received "
60 "power"),
62{
63}
64
68
69void
71{
72 // The ns-3 testing manual gives more background on the values selected
73 // for this test. First, set a few defaults.
74
75 // the test vectors have been determined for a wavelength of 0.125 m
76 // which corresponds to a frequency of 2398339664.0 Hz in the vacuum
77 Config::SetDefault("ns3::FriisPropagationLossModel::Frequency", DoubleValue(2398339664.0));
78 Config::SetDefault("ns3::FriisPropagationLossModel::SystemLoss", DoubleValue(1.0));
79
80 // Select a reference transmit power
81 // Pt = 10^(17.0206/10)/10^3 = .05035702 W
82 double txPowerW = 0.05035702;
83 double txPowerdBm = 10 * std::log10(txPowerW) + 30;
84
85 //
86 // We want to test the propagation loss model calculations at a few chosen
87 // distances and compare the results to those we have manually calculated
88 // according to the model documentation. The model reference specifies,
89 // for instance, that the received power at 100m according to the provided
90 // input power will be 4.98265e-10 W. Since this value specifies the power
91 // to 1e-15 significance, we test the ns-3 calculated value for agreement
92 // within 5e-16.
93 //
94 TestVector testVector;
95
96 testVector.m_position = Vector(100, 0, 0);
97 testVector.m_pt = txPowerdBm;
98 testVector.m_pr = 4.98265e-10;
99 testVector.m_tolerance = 5e-16;
100 m_testVectors.Add(testVector);
101
102 testVector.m_position = Vector(500, 0, 0);
103 testVector.m_pt = txPowerdBm;
104 testVector.m_pr = 1.99306e-11;
105 testVector.m_tolerance = 5e-17;
106 m_testVectors.Add(testVector);
107
108 testVector.m_position = Vector(1000, 0, 0);
109 testVector.m_pt = txPowerdBm;
110 testVector.m_pr = 4.98265e-12;
111 testVector.m_tolerance = 5e-18;
112 m_testVectors.Add(testVector);
113
114 testVector.m_position = Vector(2000, 0, 0);
115 testVector.m_pt = txPowerdBm;
116 testVector.m_pr = 1.24566e-12;
117 testVector.m_tolerance = 5e-18;
118 m_testVectors.Add(testVector);
119
120 // Now, check that the received power values are expected
121
123 a->SetPosition(Vector(0, 0, 0));
125
127 for (uint32_t i = 0; i < m_testVectors.GetN(); ++i)
128 {
129 testVector = m_testVectors.Get(i);
130 b->SetPosition(testVector.m_position);
131 double resultdBm = lossModel->CalcRxPower(testVector.m_pt, a, b);
132 double resultW = std::pow(10.0, resultdBm / 10.0) / 1000;
134 testVector.m_pr,
135 testVector.m_tolerance,
136 "Got unexpected rcv power");
137 }
138}
139
140// Added for Two-Ray Ground Model - tomhewer@mac.com
141
142/**
143 * @ingroup propagation-tests
144 *
145 * @brief TwoRayGroundPropagationLossModel Test
146 */
148{
149 public:
152
153 private:
154 void DoRun() override;
155
156 /// Test vector
158 {
159 Vector m_position; //!< Test node position
160 double m_pt; //!< Tx power [dBm]
161 double m_pr; //!< Rx power [W]
162 double m_tolerance; //!< Tolerance
163 };
164
165 /// Test vectors
167};
168
170 : TestCase("Check to see that the ns-3 TwoRayGround propagation loss model provides correct "
171 "received power"),
173{
174}
175
179
180void
182{
183 // the test vectors have been determined for a wavelength of 0.125 m
184 // which corresponds to a frequency of 2398339664.0 Hz in the vacuum
185 Config::SetDefault("ns3::TwoRayGroundPropagationLossModel::Frequency",
186 DoubleValue(2398339664.0));
187 Config::SetDefault("ns3::TwoRayGroundPropagationLossModel::SystemLoss", DoubleValue(1.0));
188
189 // set antenna height to 1.5m above z coordinate
190 Config::SetDefault("ns3::TwoRayGroundPropagationLossModel::HeightAboveZ", DoubleValue(1.5));
191
192 // Select a reference transmit power of 17.0206 dBm
193 // Pt = 10^(17.0206/10)/10^3 = .05035702 W
194 double txPowerW = 0.05035702;
195 double txPowerdBm = 10 * std::log10(txPowerW) + 30;
196
197 //
198 // As with the Friis tests above, we want to test the propagation loss
199 // model calculations at a few chosen distances and compare the results
200 // to those we can manually calculate. Let us test the ns-3 calculated
201 // value for agreement to be within 5e-16, as above.
202 //
203 TestVector testVector;
204
205 // Below the Crossover distance use Friis so this test should be the same as that above
206 // Crossover = (4 * PI * TxAntennaHeight * RxAntennaHeight) / Lamdba
207 // Crossover = (4 * PI * 1.5 * 1.5) / 0.125 = 226.1946m
208
209 testVector.m_position = Vector(100, 0, 0);
210 testVector.m_pt = txPowerdBm;
211 testVector.m_pr = 4.98265e-10;
212 testVector.m_tolerance = 5e-16;
213 m_testVectors.Add(testVector);
214
215 // These values are above the crossover distance and therefore use the Two Ray calculation
216
217 testVector.m_position = Vector(500, 0, 0);
218 testVector.m_pt = txPowerdBm;
219 testVector.m_pr = 4.07891862e-12;
220 testVector.m_tolerance = 5e-16;
221 m_testVectors.Add(testVector);
222
223 testVector.m_position = Vector(1000, 0, 0);
224 testVector.m_pt = txPowerdBm;
225 testVector.m_pr = 2.5493241375e-13;
226 testVector.m_tolerance = 5e-16;
227 m_testVectors.Add(testVector);
228
229 testVector.m_position = Vector(2000, 0, 0);
230 testVector.m_pt = txPowerdBm;
231 testVector.m_pr = 1.593327585938e-14;
232 testVector.m_tolerance = 5e-16;
233 m_testVectors.Add(testVector);
234
235 // Repeat the tests for non-zero z coordinates
236
237 // Pr = (0.05035702 * (1.5*1.5) * (2.5*2.5)) / (500*500*500*500) = 1.13303295e-11
238 // dCross = (4 * pi * 1.5 * 2.5) / 0.125 = 376.99m
239 testVector.m_position = Vector(500, 0, 1);
240 testVector.m_pt = txPowerdBm;
241 testVector.m_pr = 1.13303295e-11;
242 testVector.m_tolerance = 5e-16;
243 m_testVectors.Add(testVector);
244
245 // Pr = (0.05035702 * (1.5*1.5) * (5.5*5.5)) / (1000*1000*1000*1000) = 3.42742467375e-12
246 // dCross = (4 * pi * 1.5 * 5.5) / 0.125 = 829.38m
247 testVector.m_position = Vector(1000, 0, 4);
248 testVector.m_pt = txPowerdBm;
249 testVector.m_pr = 3.42742467375e-12;
250 testVector.m_tolerance = 5e-16;
251 m_testVectors.Add(testVector);
252
253 // Pr = (0.05035702 * (1.5*1.5) * (11.5*11.5)) / (2000*2000*2000*2000) = 9.36522547734e-13
254 // dCross = (4 * pi * 1.5 * 11.5) / 0.125 = 1734.15m
255 testVector.m_position = Vector(2000, 0, 10);
256 testVector.m_pt = txPowerdBm;
257 testVector.m_pr = 9.36522547734e-13;
258 testVector.m_tolerance = 5e-16;
259 m_testVectors.Add(testVector);
260
261 // Now, check that the received power values are expected
262
264 a->SetPosition(Vector(0, 0, 0));
266
269 for (uint32_t i = 0; i < m_testVectors.GetN(); ++i)
270 {
271 testVector = m_testVectors.Get(i);
272 b->SetPosition(testVector.m_position);
273 double resultdBm = lossModel->CalcRxPower(testVector.m_pt, a, b);
274 double resultW = std::pow(10.0, resultdBm / 10.0) / 1000;
276 testVector.m_pr,
277 testVector.m_tolerance,
278 "Got unexpected rcv power");
279 }
280}
281
282/**
283 * @ingroup propagation-tests
284 *
285 * @brief LogDistancePropagationLossModel Test
286 */
288{
289 public:
292
293 private:
294 void DoRun() override;
295
296 /// Test vector
298 {
299 Vector m_position; //!< Test node position
300 double m_pt; //!< Tx power [dBm]
301 double m_pr; //!< Rx power [W]
302 double m_tolerance; //!< Tolerance
303 };
304
305 /// Test vectors
307};
308
310 : TestCase("Check to see that the ns-3 Log Distance propagation loss model provides correct "
311 "received power"),
313{
314}
315
319
320void
322{
323 // reference loss at 2.4 GHz is 40.045997
324 Config::SetDefault("ns3::LogDistancePropagationLossModel::ReferenceLoss",
325 DoubleValue(40.045997));
326 Config::SetDefault("ns3::LogDistancePropagationLossModel::Exponent", DoubleValue(3));
327
328 // Select a reference transmit power
329 // Pt = 10^(17.0206/10)/10^3 = .05035702 W
330 double txPowerW = 0.05035702;
331 double txPowerdBm = 10 * std::log10(txPowerW) + 30;
332
333 //
334 // We want to test the propagation loss model calculations at a few chosen
335 // distances and compare the results to those we have manually calculated
336 // according to the model documentation. The following "TestVector" objects
337 // will drive the test.
338 //
339 TestVector testVector;
340
341 testVector.m_position = Vector(10, 0, 0);
342 testVector.m_pt = txPowerdBm;
343 testVector.m_pr = 4.98265e-9;
344 testVector.m_tolerance = 5e-15;
345 m_testVectors.Add(testVector);
346
347 testVector.m_position = Vector(20, 0, 0);
348 testVector.m_pt = txPowerdBm;
349 testVector.m_pr = 6.22831e-10;
350 testVector.m_tolerance = 5e-16;
351 m_testVectors.Add(testVector);
352
353 testVector.m_position = Vector(40, 0, 0);
354 testVector.m_pt = txPowerdBm;
355 testVector.m_pr = 7.78539e-11;
356 testVector.m_tolerance = 5e-17;
357 m_testVectors.Add(testVector);
358
359 testVector.m_position = Vector(80, 0, 0);
360 testVector.m_pt = txPowerdBm;
361 testVector.m_pr = 9.73173e-12;
362 testVector.m_tolerance = 5e-17;
363 m_testVectors.Add(testVector);
364
366 a->SetPosition(Vector(0, 0, 0));
368
371 for (uint32_t i = 0; i < m_testVectors.GetN(); ++i)
372 {
373 testVector = m_testVectors.Get(i);
374 b->SetPosition(testVector.m_position);
375 double resultdBm = lossModel->CalcRxPower(testVector.m_pt, a, b);
376 double resultW = std::pow(10.0, resultdBm / 10.0) / 1000;
378 testVector.m_pr,
379 testVector.m_tolerance,
380 "Got unexpected rcv power");
381 }
382}
383
384/**
385 * @ingroup propagation-tests
386 *
387 * @brief MatrixPropagationLossModel Test
388 */
390{
391 public:
394
395 private:
396 void DoRun() override;
397};
398
400 : TestCase("Test MatrixPropagationLossModel")
401{
402}
403
407
408void
410{
411 NodeContainer nc(3);
413 for (int i = 0; i < 3; ++i)
414 {
416 nc.Get(i)->AggregateObject(m[i]);
417 }
418
420 // no loss by default
421 loss.SetDefaultLoss(0);
422 // -10 dB for 0 -> 1 and 1 -> 0
423 loss.SetLoss(m[0], m[1], 10);
424 // -30 dB from 0 to 2 and -100 dB from 2 to 0
425 loss.SetLoss(m[0], m[2], 30, /*symmetric = */ false);
426 loss.SetLoss(m[2], m[0], 100, /*symmetric = */ false);
427 // default from 1 to 2
428
429 NS_TEST_ASSERT_MSG_EQ(loss.CalcRxPower(0, m[0], m[1]), -10, "Loss 0 -> 1 incorrect");
430 NS_TEST_ASSERT_MSG_EQ(loss.CalcRxPower(0, m[1], m[0]), -10, "Loss 1 -> 0 incorrect");
431 NS_TEST_ASSERT_MSG_EQ(loss.CalcRxPower(0, m[0], m[2]), -30, "Loss 0 -> 2 incorrect");
432 NS_TEST_ASSERT_MSG_EQ(loss.CalcRxPower(0, m[2], m[0]), -100, "Loss 2 -> 0 incorrect");
433 NS_TEST_ASSERT_MSG_EQ(loss.CalcRxPower(0, m[1], m[2]), 0, "Loss 1 -> 2 incorrect");
434 NS_TEST_ASSERT_MSG_EQ(loss.CalcRxPower(0, m[2], m[1]), 0, "Loss 2 -> 1 incorrect");
435
437}
438
439/**
440 * @ingroup propagation-tests
441 *
442 * @brief RangePropagationLossModel Test
443 */
445{
446 public:
449
450 private:
451 void DoRun() override;
452};
453
455 : TestCase("Test RangePropagationLossModel")
456{
457}
458
462
463void
465{
466 Config::SetDefault("ns3::RangePropagationLossModel::MaxRange", DoubleValue(127.2));
468 a->SetPosition(Vector(0, 0, 0));
470 b->SetPosition(Vector(127.1, 0, 0)); // within range
471
473
474 double txPwrdBm = -80.0;
475 double tolerance = 1e-6;
476 double resultdBm = lossModel->CalcRxPower(txPwrdBm, a, b);
477 NS_TEST_EXPECT_MSG_EQ_TOL(resultdBm, txPwrdBm, tolerance, "Got unexpected rcv power");
478 b->SetPosition(Vector(127.25, 0, 0)); // beyond range
479 resultdBm = lossModel->CalcRxPower(txPwrdBm, a, b);
480 NS_TEST_EXPECT_MSG_EQ_TOL(resultdBm, -1000.0, tolerance, "Got unexpected rcv power");
482}
483
484/**
485 * @ingroup propagation-tests
486 *
487 * @brief Propagation models TestSuite
488 *
489 * This TestSuite tests the following models:
490 * - FriisPropagationLossModel
491 * - TwoRayGroundPropagationLossModel
492 * - LogDistancePropagationLossModel
493 * - MatrixPropagationLossModel
494 * - RangePropagationLossModel
495 */
501
511
512/// 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.
keep track of a set of node pointers.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition object.cc:298
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.
Definition ptr.h:67
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
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:1054
TestCase(const TestCase &)=delete
Type
Type of test.
Definition test.h:1257
@ UNIT
This test suite implements a Unit Test.
Definition test.h:1259
TestSuite(std::string name, Type type=Type::UNIT)
Construct a new test suite.
Definition test.cc:490
A simple way to store test vectors (for stimulus or from responses)
Definition test.h:1313
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:886
#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:133
#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:499
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static PropagationLossModelsTestSuite g_propagationLossModelsTestSuite
Static variable for test initialization.