A Discrete-Event Network Simulator
API
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 
27 using namespace ns3;
28 
29 NS_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 
47 {
48  public:
51 
52  private:
53  void DoRun() override;
54 
56  struct TestVector
57  {
58  Vector m_position;
59  double m_pt;
60  double m_pr;
61  double m_tolerance;
62  };
63 
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 
79 void
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 
158 {
159  public:
162 
163  private:
164  void DoRun() override;
165 
167  struct TestVector
168  {
169  Vector m_position;
170  double m_pt;
171  double m_pr;
172  double m_tolerance;
173  };
174 
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 
190 void
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 
298 {
299  public:
302 
303  private:
304  void DoRun() override;
305 
307  struct TestVector
308  {
309  Vector m_position;
310  double m_pt;
311  double m_pr;
312  double m_tolerance;
313  };
314 
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 
330 void
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 
400 {
401  public:
404 
405  private:
406  void DoRun() override;
407 };
408 
410  : TestCase("Test MatrixPropagationLossModel")
411 {
412 }
413 
415 {
416 }
417 
418 void
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 
444  Simulator::Destroy();
445 }
446 
453 {
454  public:
457 
458  private:
459  void DoRun() override;
460 };
461 
463  : TestCase("Test RangePropagationLossModel")
464 {
465 }
466 
468 {
469 }
470 
471 void
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");
489  Simulator::Destroy();
490 }
491 
505 {
506  public:
508 };
509 
511  : TestSuite("propagation-loss-model", UNIT)
512 {
513  AddTestCase(new FriisPropagationLossModelTestCase, TestCase::QUICK);
516  AddTestCase(new MatrixPropagationLossModelTestCase, TestCase::QUICK);
517  AddTestCase(new RangePropagationLossModelTestCase, TestCase::QUICK);
518 }
519 
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.
void SetPosition(const Vector &position)
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.
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1319
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
#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:144
#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:510
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static PropagationLossModelsTestSuite g_propagationLossModelsTestSuite
Static variable for test initialization.