A Discrete-Event Network Simulator
API
propagation-loss-model-test-suite.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 The Boeing Company
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */
18 
19 #include "ns3/log.h"
20 #include "ns3/abort.h"
21 #include "ns3/test.h"
22 #include "ns3/config.h"
23 #include "ns3/double.h"
24 #include "ns3/propagation-loss-model.h"
25 #include "ns3/constant-position-mobility-model.h"
26 #include "ns3/simulator.h"
27 
28 using namespace ns3;
29 
30 NS_LOG_COMPONENT_DEFINE ("PropagationLossModelsTest");
31 
32 // ===========================================================================
33 // This is a simple test to validate propagation loss models of ns-3 wifi.
34 // See the chapter in the ns-3 testing and validation guide for more detail
35 // ===========================================================================
36 
37 
50 {
51 public:
54 
55 private:
56  virtual void DoRun (void);
57 
59  typedef struct {
60  Vector m_position;
61  double m_pt;
62  double m_pr;
63  double m_tolerance;
64  } TestVector;
65 
68 };
69 
71  : TestCase ("Check to see that the ns-3 Friis propagation loss model provides correct received power"), 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;
143  NS_TEST_EXPECT_MSG_EQ_TOL (resultW, testVector.m_pr, testVector.m_tolerance, "Got unexpected rcv power");
144  }
145 }
146 
147 // Added for Two-Ray Ground Model - tomhewer@mac.com
148 
155 {
156 public:
159 
160 private:
161  virtual void DoRun (void);
162 
164  typedef struct {
165  Vector m_position;
166  double m_pt;
167  double m_pr;
168  double m_tolerance;
169  } TestVector;
170 
173 };
174 
176  : TestCase ("Check to see that the ns-3 TwoRayGround propagation loss model provides correct received power"),
177  m_testVectors ()
178 {
179 }
180 
182 {
183 }
184 
185 void
187 {
188  // the test vectors have been determined for a wavelength of 0.125 m
189  // which corresponds to a frequency of 2398339664.0 Hz in the vacuum
190  Config::SetDefault ("ns3::TwoRayGroundPropagationLossModel::Frequency", DoubleValue (2398339664.0));
191  Config::SetDefault ("ns3::TwoRayGroundPropagationLossModel::SystemLoss", DoubleValue (1.0));
192 
193  // set antenna height to 1.5m above z coordinate
194  Config::SetDefault ("ns3::TwoRayGroundPropagationLossModel::HeightAboveZ", DoubleValue (1.5));
195 
196  // Select a reference transmit power of 17.0206 dBm
197  // Pt = 10^(17.0206/10)/10^3 = .05035702 W
198  double txPowerW = 0.05035702;
199  double txPowerdBm = 10 * std::log10 (txPowerW) + 30;
200 
201  //
202  // As with the Friis tests above, we want to test the propagation loss
203  // model calculations at a few chosen distances and compare the results
204  // to those we can manually calculate. Let us test the ns-3 calculated
205  // value for agreement to be within 5e-16, as above.
206  //
207  TestVector testVector;
208 
209  // Below the Crossover distance use Friis so this test should be the same as that above
210  // Crossover = (4 * PI * TxAntennaHeight * RxAntennaHeight) / Lamdba
211  // Crossover = (4 * PI * 1.5 * 1.5) / 0.125 = 226.1946m
212 
213  testVector.m_position = Vector (100, 0, 0);
214  testVector.m_pt = txPowerdBm;
215  testVector.m_pr = 4.98265e-10;
216  testVector.m_tolerance = 5e-16;
217  m_testVectors.Add (testVector);
218 
219  // These values are above the crossover distance and therefore use the Two Ray calculation
220 
221  testVector.m_position = Vector (500, 0, 0);
222  testVector.m_pt = txPowerdBm;
223  testVector.m_pr = 4.07891862e-12;
224  testVector.m_tolerance = 5e-16;
225  m_testVectors.Add (testVector);
226 
227  testVector.m_position = Vector (1000, 0, 0);
228  testVector.m_pt = txPowerdBm;
229  testVector.m_pr = 2.5493241375e-13;
230  testVector.m_tolerance = 5e-16;
231  m_testVectors.Add (testVector);
232 
233  testVector.m_position = Vector (2000, 0, 0);
234  testVector.m_pt = txPowerdBm;
235  testVector.m_pr = 1.593327585938e-14;
236  testVector.m_tolerance = 5e-16;
237  m_testVectors.Add (testVector);
238 
239  // Repeat the tests for non-zero z coordinates
240 
241  // Pr = (0.05035702 * (1.5*1.5) * (2.5*2.5)) / (500*500*500*500) = 1.13303295e-11
242  // dCross = (4 * pi * 1.5 * 2.5) / 0.125 = 376.99m
243  testVector.m_position = Vector (500, 0, 1);
244  testVector.m_pt = txPowerdBm;
245  testVector.m_pr = 1.13303295e-11;
246  testVector.m_tolerance = 5e-16;
247  m_testVectors.Add (testVector);
248 
249  // Pr = (0.05035702 * (1.5*1.5) * (5.5*5.5)) / (1000*1000*1000*1000) = 3.42742467375e-12
250  // dCross = (4 * pi * 1.5 * 5.5) / 0.125 = 829.38m
251  testVector.m_position = Vector (1000, 0, 4);
252  testVector.m_pt = txPowerdBm;
253  testVector.m_pr = 3.42742467375e-12;
254  testVector.m_tolerance = 5e-16;
255  m_testVectors.Add (testVector);
256 
257  // Pr = (0.05035702 * (1.5*1.5) * (11.5*11.5)) / (2000*2000*2000*2000) = 9.36522547734e-13
258  // dCross = (4 * pi * 1.5 * 11.5) / 0.125 = 1734.15m
259  testVector.m_position = Vector (2000, 0, 10);
260  testVector.m_pt = txPowerdBm;
261  testVector.m_pr = 9.36522547734e-13;
262  testVector.m_tolerance = 5e-16;
263  m_testVectors.Add (testVector);
264 
265 
266  // Now, check that the received power values are expected
267 
268  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
269  a->SetPosition (Vector (0,0,0));
270  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
271 
272  Ptr<TwoRayGroundPropagationLossModel> lossModel = CreateObject<TwoRayGroundPropagationLossModel> ();
273  for (uint32_t i = 0; i < m_testVectors.GetN (); ++i)
274  {
275  testVector = m_testVectors.Get (i);
276  b->SetPosition (testVector.m_position);
277  double resultdBm = lossModel->CalcRxPower (testVector.m_pt, a, b);
278  double resultW = std::pow (10.0, resultdBm / 10.0) / 1000;
279  NS_TEST_EXPECT_MSG_EQ_TOL (resultW, testVector.m_pr, testVector.m_tolerance, "Got unexpected rcv power");
280  }
281 }
282 
283 
290 {
291 public:
294 
295 private:
296  virtual void DoRun (void);
297 
299  typedef struct {
300  Vector m_position;
301  double m_pt;
302  double m_pr;
303  double m_tolerance;
304  } TestVector;
305 
308 };
309 
311  : TestCase ("Check to see that the ns-3 Log Distance propagation loss model provides correct received power"), m_testVectors ()
312 {
313 }
314 
316 {
317 }
318 
319 void
321 {
322  // reference loss at 2.4 GHz is 40.045997
323  Config::SetDefault ("ns3::LogDistancePropagationLossModel::ReferenceLoss", DoubleValue (40.045997));
324  Config::SetDefault ("ns3::LogDistancePropagationLossModel::Exponent", DoubleValue (3));
325 
326  // Select a reference transmit power
327  // Pt = 10^(17.0206/10)/10^3 = .05035702 W
328  double txPowerW = 0.05035702;
329  double txPowerdBm = 10 * std::log10 (txPowerW) + 30;
330 
331  //
332  // We want to test the propagation loss model calculations at a few chosen
333  // distances and compare the results to those we have manually calculated
334  // according to the model documentation. The following "TestVector" objects
335  // will drive the test.
336  //
337  TestVector testVector;
338 
339  testVector.m_position = Vector (10, 0, 0);
340  testVector.m_pt = txPowerdBm;
341  testVector.m_pr = 4.98265e-9;
342  testVector.m_tolerance = 5e-15;
343  m_testVectors.Add (testVector);
344 
345  testVector.m_position = Vector (20, 0, 0);
346  testVector.m_pt = txPowerdBm;
347  testVector.m_pr = 6.22831e-10;
348  testVector.m_tolerance = 5e-16;
349  m_testVectors.Add (testVector);
350 
351  testVector.m_position = Vector (40, 0, 0);
352  testVector.m_pt = txPowerdBm;
353  testVector.m_pr = 7.78539e-11;
354  testVector.m_tolerance = 5e-17;
355  m_testVectors.Add (testVector);
356 
357  testVector.m_position = Vector (80, 0, 0);
358  testVector.m_pt = txPowerdBm;
359  testVector.m_pr = 9.73173e-12;
360  testVector.m_tolerance = 5e-17;
361  m_testVectors.Add (testVector);
362 
363  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
364  a->SetPosition (Vector (0,0,0));
365  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
366 
367  Ptr<LogDistancePropagationLossModel> lossModel = CreateObject<LogDistancePropagationLossModel> ();
368  for (uint32_t i = 0; i < m_testVectors.GetN (); ++i)
369  {
370  testVector = m_testVectors.Get (i);
371  b->SetPosition (testVector.m_position);
372  double resultdBm = lossModel->CalcRxPower (testVector.m_pt, a, b);
373  double resultW = std::pow (10.0, resultdBm/10.0)/1000;
374  NS_TEST_EXPECT_MSG_EQ_TOL (resultW, testVector.m_pr, testVector.m_tolerance, "Got unexpected rcv power");
375  }
376 }
377 
384 {
385 public:
388 
389 private:
390  virtual void DoRun (void);
391 };
392 
394  : TestCase ("Test MatrixPropagationLossModel")
395 {
396 }
397 
399 {
400 }
401 
402 void
404 {
405  Ptr<MobilityModel> m[3];
406  for (int i = 0; i < 3; ++i)
407  {
408  m[i] = CreateObject<ConstantPositionMobilityModel> ();
409  }
410 
412  // no loss by default
413  loss.SetDefaultLoss (0);
414  // -10 dB for 0 -> 1 and 1 -> 0
415  loss.SetLoss (m[0], m[1], 10);
416  // -30 dB from 0 to 2 and -100 dB from 2 to 0
417  loss.SetLoss (m[0], m[2], 30, /*symmetric = */ false);
418  loss.SetLoss (m[2], m[0], 100, /*symmetric = */ false);
419  // default from 1 to 2
420 
421  NS_TEST_ASSERT_MSG_EQ (loss.CalcRxPower (0, m[0], m[1]), -10, "Loss 0 -> 1 incorrect");
422  NS_TEST_ASSERT_MSG_EQ (loss.CalcRxPower (0, m[1], m[0]), -10, "Loss 1 -> 0 incorrect");
423  NS_TEST_ASSERT_MSG_EQ (loss.CalcRxPower (0, m[0], m[2]), -30, "Loss 0 -> 2 incorrect");
424  NS_TEST_ASSERT_MSG_EQ (loss.CalcRxPower (0, m[2], m[0]), -100, "Loss 2 -> 0 incorrect");
425  NS_TEST_ASSERT_MSG_EQ (loss.CalcRxPower (0, m[1], m[2]), 0, "Loss 1 -> 2 incorrect");
426  NS_TEST_ASSERT_MSG_EQ (loss.CalcRxPower (0, m[2], m[1]), 0, "Loss 2 -> 1 incorrect");
427 
428  Simulator::Destroy ();
429 }
430 
437 {
438 public:
441 
442 private:
443  virtual void DoRun (void);
444 };
445 
447  : TestCase ("Test RangePropagationLossModel")
448 {
449 }
450 
452 {
453 }
454 
455 void
457 {
458  Config::SetDefault ("ns3::RangePropagationLossModel::MaxRange", DoubleValue (127.2));
459  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
460  a->SetPosition (Vector (0,0,0));
461  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
462  b->SetPosition (Vector (127.1,0,0)); // within range
463 
464  Ptr<RangePropagationLossModel> lossModel = CreateObject<RangePropagationLossModel> ();
465 
466  double txPwrdBm = -80.0;
467  double tolerance = 1e-6;
468  double resultdBm = lossModel->CalcRxPower (txPwrdBm, a, b);
469  NS_TEST_EXPECT_MSG_EQ_TOL (resultdBm, txPwrdBm, tolerance, "Got unexpected rcv power");
470  b->SetPosition (Vector (127.25,0,0)); // beyond range
471  resultdBm = lossModel->CalcRxPower (txPwrdBm, a, b);
472  NS_TEST_EXPECT_MSG_EQ_TOL (resultdBm, -1000.0, tolerance, "Got unexpected rcv power");
473  Simulator::Destroy ();
474 }
475 
489 {
490 public:
492 };
493 
495  : TestSuite ("propagation-loss-model", UNIT)
496 {
497  AddTestCase (new FriisPropagationLossModelTestCase, TestCase::QUICK);
500  AddTestCase (new MatrixPropagationLossModelTestCase, TestCase::QUICK);
501  AddTestCase (new RangePropagationLossModelTestCase, TestCase::QUICK);
502 }
503 
virtual void DoRun(void)
Implementation to actually run this TestCase.
TestVectors< TestVector > m_testVectors
Test vectors.
virtual void DoRun(void)
Implementation to actually run this TestCase.
TestVectors< TestVector > m_testVectors
Test vectors.
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
TestVectors< TestVector > m_testVectors
Test vectors.
virtual void DoRun(void)
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:41
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:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1251
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#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:141
#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:491
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static PropagationLossModelsTestSuite g_propagationLossModelsTestSuite
Static variable for test initialization.