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