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 //
38 {
39 public:
42 
43 private:
44  virtual void DoRun (void);
45 
46  typedef struct {
47  Vector m_position;
48  double m_pt; // dBm
49  double m_pr; // W
50  double m_tolerance;
51  } TestVector;
52 
54 };
55 
57  : TestCase ("Check to see that the ns-3 Friis propagation loss model provides correct received power"), m_testVectors ()
58 {
59 }
60 
62 {
63 }
64 
65 void
67 {
68  // The ns-3 testing manual gives more background on the values selected
69  // for this test. First, set a few defaults.
70 
71  // the test vectors have been determined for a wavelength of 0.125 m
72  // which corresponds to a frequency of 2398339664.0 Hz in the vacuum
73  Config::SetDefault ("ns3::FriisPropagationLossModel::Frequency", DoubleValue (2398339664.0));
74  Config::SetDefault ("ns3::FriisPropagationLossModel::SystemLoss", DoubleValue (1.0));
75 
76  // Select a reference transmit power
77  // Pt = 10^(17.0206/10)/10^3 = .05035702 W
78  double txPowerW = 0.05035702;
79  double txPowerdBm = 10 * std::log10 (txPowerW) + 30;
80 
81  //
82  // We want to test the propagation loss model calculations at a few chosen
83  // distances and compare the results to those we have manually calculated
84  // according to the model documentation. The model reference specifies,
85  // for instance, that the received power at 100m according to the provided
86  // input power will be 4.98265e-10 W. Since this value specifies the power
87  // to 1e-15 significance, we test the ns-3 calculated value for agreement
88  // within 5e-16.
89  //
90  TestVector testVector;
91 
92  testVector.m_position = Vector (100, 0, 0);
93  testVector.m_pt = txPowerdBm;
94  testVector.m_pr = 4.98265e-10;
95  testVector.m_tolerance = 5e-16;
96  m_testVectors.Add (testVector);
97 
98  testVector.m_position = Vector (500, 0, 0);
99  testVector.m_pt = txPowerdBm;
100  testVector.m_pr = 1.99306e-11;
101  testVector.m_tolerance = 5e-17;
102  m_testVectors.Add (testVector);
103 
104  testVector.m_position = Vector (1000, 0, 0);
105  testVector.m_pt = txPowerdBm;
106  testVector.m_pr = 4.98265e-12;
107  testVector.m_tolerance = 5e-18;
108  m_testVectors.Add (testVector);
109 
110  testVector.m_position = Vector (2000, 0, 0);
111  testVector.m_pt = txPowerdBm;
112  testVector.m_pr = 1.24566e-12;
113  testVector.m_tolerance = 5e-18;
114  m_testVectors.Add (testVector);
115 
116  // Now, check that the received power values are expected
117 
118  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
119  a->SetPosition (Vector (0,0,0));
120  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
121 
122  Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
123  for (uint32_t i = 0; i < m_testVectors.GetN (); ++i)
124  {
125  testVector = m_testVectors.Get (i);
126  b->SetPosition (testVector.m_position);
127  double resultdBm = lossModel->CalcRxPower (testVector.m_pt, a, b);
128  double resultW = std::pow (10.0, resultdBm/10.0)/1000;
129  NS_TEST_EXPECT_MSG_EQ_TOL (resultW, testVector.m_pr, testVector.m_tolerance, "Got unexpected rcv power");
130  }
131 }
132 
133 // Added for Two-Ray Ground Model - tomhewer@mac.com
134 
136 {
137 public:
140 
141 private:
142  virtual void DoRun (void);
143 
144  typedef struct
145  {
146  Vector m_position;
147  double m_pt; // dBm
148  double m_pr; // W
149  double m_tolerance;
150  } TestVector;
151 
153 };
154 
156  : TestCase ("Check to see that the ns-3 TwoRayGround propagation loss model provides correct received power"),
157  m_testVectors ()
158 {
159 }
160 
162 {
163 }
164 
165 void
167 {
168  // the test vectors have been determined for a wavelength of 0.125 m
169  // which corresponds to a frequency of 2398339664.0 Hz in the vacuum
170  Config::SetDefault ("ns3::TwoRayGroundPropagationLossModel::Frequency", DoubleValue (2398339664.0));
171  Config::SetDefault ("ns3::TwoRayGroundPropagationLossModel::SystemLoss", DoubleValue (1.0));
172 
173  // set antenna height to 1.5m above z coordinate
174  Config::SetDefault ("ns3::TwoRayGroundPropagationLossModel::HeightAboveZ", DoubleValue (1.5));
175 
176  // Select a reference transmit power of 17.0206 dBm
177  // Pt = 10^(17.0206/10)/10^3 = .05035702 W
178  double txPowerW = 0.05035702;
179  double txPowerdBm = 10 * std::log10 (txPowerW) + 30;
180 
181  //
182  // As with the Friis tests above, we want to test the propagation loss
183  // model calculations at a few chosen distances and compare the results
184  // to those we can manually calculate. Let us test the ns-3 calculated
185  // value for agreement to be within 5e-16, as above.
186  //
187  TestVector testVector;
188 
189  // Below the Crossover distance use Friis so this test should be the same as that above
190  // Crossover = (4 * PI * TxAntennaHeight * RxAntennaHeight) / Lamdba
191  // Crossover = (4 * PI * 1.5 * 1.5) / 0.125 = 226.1946m
192 
193  testVector.m_position = Vector (100, 0, 0);
194  testVector.m_pt = txPowerdBm;
195  testVector.m_pr = 4.98265e-10;
196  testVector.m_tolerance = 5e-16;
197  m_testVectors.Add (testVector);
198 
199  // These values are above the crossover distance and therefore use the Two Ray calculation
200 
201  testVector.m_position = Vector (500, 0, 0);
202  testVector.m_pt = txPowerdBm;
203  testVector.m_pr = 4.07891862e-12;
204  testVector.m_tolerance = 5e-16;
205  m_testVectors.Add (testVector);
206 
207  testVector.m_position = Vector (1000, 0, 0);
208  testVector.m_pt = txPowerdBm;
209  testVector.m_pr = 2.5493241375e-13;
210  testVector.m_tolerance = 5e-16;
211  m_testVectors.Add (testVector);
212 
213  testVector.m_position = Vector (2000, 0, 0);
214  testVector.m_pt = txPowerdBm;
215  testVector.m_pr = 1.593327585938e-14;
216  testVector.m_tolerance = 5e-16;
217  m_testVectors.Add (testVector);
218 
219  // Repeat the tests for non-zero z coordinates
220 
221  // Pr = (0.05035702 * (1.5*1.5) * (2.5*2.5)) / (500*500*500*500) = 1.13303295e-11
222  // dCross = (4 * pi * 1.5 * 2.5) / 0.125 = 376.99m
223  testVector.m_position = Vector (500, 0, 1);
224  testVector.m_pt = txPowerdBm;
225  testVector.m_pr = 1.13303295e-11;
226  testVector.m_tolerance = 5e-16;
227  m_testVectors.Add (testVector);
228 
229  // Pr = (0.05035702 * (1.5*1.5) * (5.5*5.5)) / (1000*1000*1000*1000) = 3.42742467375e-12
230  // dCross = (4 * pi * 1.5 * 5.5) / 0.125 = 829.38m
231  testVector.m_position = Vector (1000, 0, 4);
232  testVector.m_pt = txPowerdBm;
233  testVector.m_pr = 3.42742467375e-12;
234  testVector.m_tolerance = 5e-16;
235  m_testVectors.Add (testVector);
236 
237  // Pr = (0.05035702 * (1.5*1.5) * (11.5*11.5)) / (2000*2000*2000*2000) = 9.36522547734e-13
238  // dCross = (4 * pi * 1.5 * 11.5) / 0.125 = 1734.15m
239  testVector.m_position = Vector (2000, 0, 10);
240  testVector.m_pt = txPowerdBm;
241  testVector.m_pr = 9.36522547734e-13;
242  testVector.m_tolerance = 5e-16;
243  m_testVectors.Add (testVector);
244 
245 
246  // Now, check that the received power values are expected
247 
248  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
249  a->SetPosition (Vector (0,0,0));
250  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
251 
252  Ptr<TwoRayGroundPropagationLossModel> lossModel = CreateObject<TwoRayGroundPropagationLossModel> ();
253  for (uint32_t i = 0; i < m_testVectors.GetN (); ++i)
254  {
255  testVector = m_testVectors.Get (i);
256  b->SetPosition (testVector.m_position);
257  double resultdBm = lossModel->CalcRxPower (testVector.m_pt, a, b);
258  double resultW = std::pow (10.0, resultdBm / 10.0) / 1000;
259  NS_TEST_EXPECT_MSG_EQ_TOL (resultW, testVector.m_pr, testVector.m_tolerance, "Got unexpected rcv power");
260  }
261 }
262 
263 
265 {
266 public:
269 
270 private:
271  virtual void DoRun (void);
272 
273  typedef struct {
274  Vector m_position;
275  double m_pt; // dBm
276  double m_pr; // W
277  double m_tolerance;
278  } TestVector;
279 
281 };
282 
284  : TestCase ("Check to see that the ns-3 Log Distance propagation loss model provides correct received power"), m_testVectors ()
285 {
286 }
287 
289 {
290 }
291 
292 void
294 {
295  // reference loss at 2.4 GHz is 40.045997
296  Config::SetDefault ("ns3::LogDistancePropagationLossModel::ReferenceLoss", DoubleValue (40.045997));
297  Config::SetDefault ("ns3::LogDistancePropagationLossModel::Exponent", DoubleValue (3));
298 
299  // Select a reference transmit power
300  // Pt = 10^(17.0206/10)/10^3 = .05035702 W
301  double txPowerW = 0.05035702;
302  double txPowerdBm = 10 * std::log10 (txPowerW) + 30;
303 
304  //
305  // We want to test the propagation loss model calculations at a few chosen
306  // distances and compare the results to those we have manually calculated
307  // according to the model documentation. The following "TestVector" objects
308  // will drive the test.
309  //
310  TestVector testVector;
311 
312  testVector.m_position = Vector (10, 0, 0);
313  testVector.m_pt = txPowerdBm;
314  testVector.m_pr = 4.98265e-9;
315  testVector.m_tolerance = 5e-15;
316  m_testVectors.Add (testVector);
317 
318  testVector.m_position = Vector (20, 0, 0);
319  testVector.m_pt = txPowerdBm;
320  testVector.m_pr = 6.22831e-10;
321  testVector.m_tolerance = 5e-16;
322  m_testVectors.Add (testVector);
323 
324  testVector.m_position = Vector (40, 0, 0);
325  testVector.m_pt = txPowerdBm;
326  testVector.m_pr = 7.78539e-11;
327  testVector.m_tolerance = 5e-17;
328  m_testVectors.Add (testVector);
329 
330  testVector.m_position = Vector (80, 0, 0);
331  testVector.m_pt = txPowerdBm;
332  testVector.m_pr = 9.73173e-12;
333  testVector.m_tolerance = 5e-17;
334  m_testVectors.Add (testVector);
335 
336  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
337  a->SetPosition (Vector (0,0,0));
338  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
339 
340  Ptr<LogDistancePropagationLossModel> lossModel = CreateObject<LogDistancePropagationLossModel> ();
341  for (uint32_t i = 0; i < m_testVectors.GetN (); ++i)
342  {
343  testVector = m_testVectors.Get (i);
344  b->SetPosition (testVector.m_position);
345  double resultdBm = lossModel->CalcRxPower (testVector.m_pt, a, b);
346  double resultW = std::pow (10.0, resultdBm/10.0)/1000;
347  NS_TEST_EXPECT_MSG_EQ_TOL (resultW, testVector.m_pr, testVector.m_tolerance, "Got unexpected rcv power");
348  }
349 }
350 
352 {
353 public:
356 
357 private:
358  virtual void DoRun (void);
359 };
360 
362  : TestCase ("Test MatrixPropagationLossModel")
363 {
364 }
365 
367 {
368 }
369 
370 void
372 {
373  Ptr<MobilityModel> m[3];
374  for (int i = 0; i < 3; ++i)
375  {
376  m[i] = CreateObject<ConstantPositionMobilityModel> ();
377  }
378 
380  // no loss by default
381  loss.SetDefaultLoss (0);
382  // -10 dB for 0 -> 1 and 1 -> 0
383  loss.SetLoss (m[0], m[1], 10);
384  // -30 dB from 0 to 2 and -100 dB from 2 to 0
385  loss.SetLoss (m[0], m[2], 30, /*symmetric = */ false);
386  loss.SetLoss (m[2], m[0], 100, /*symmetric = */ false);
387  // default from 1 to 2
388 
389  NS_TEST_ASSERT_MSG_EQ (loss.CalcRxPower (0, m[0], m[1]), -10, "Loss 0 -> 1 incorrect");
390  NS_TEST_ASSERT_MSG_EQ (loss.CalcRxPower (0, m[1], m[0]), -10, "Loss 1 -> 0 incorrect");
391  NS_TEST_ASSERT_MSG_EQ (loss.CalcRxPower (0, m[0], m[2]), -30, "Loss 0 -> 2 incorrect");
392  NS_TEST_ASSERT_MSG_EQ (loss.CalcRxPower (0, m[2], m[0]), -100, "Loss 2 -> 0 incorrect");
393  NS_TEST_ASSERT_MSG_EQ (loss.CalcRxPower (0, m[1], m[2]), 0, "Loss 1 -> 2 incorrect");
394  NS_TEST_ASSERT_MSG_EQ (loss.CalcRxPower (0, m[2], m[1]), 0, "Loss 2 -> 1 incorrect");
395 
396  Simulator::Destroy ();
397 }
398 
400 {
401 public:
404 
405 private:
406  virtual void DoRun (void);
407 };
408 
410  : TestCase ("Test RangePropagationLossModel")
411 {
412 }
413 
415 {
416 }
417 
418 void
420 {
421  Config::SetDefault ("ns3::RangePropagationLossModel::MaxRange", DoubleValue (127.2));
422  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
423  a->SetPosition (Vector (0,0,0));
424  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
425  b->SetPosition (Vector (127.1,0,0)); // within range
426 
427  Ptr<RangePropagationLossModel> lossModel = CreateObject<RangePropagationLossModel> ();
428 
429  double txPwrdBm = -80.0;
430  double tolerance = 1e-6;
431  double resultdBm = lossModel->CalcRxPower (txPwrdBm, a, b);
432  NS_TEST_EXPECT_MSG_EQ_TOL (resultdBm, txPwrdBm, tolerance, "Got unexpected rcv power");
433  b->SetPosition (Vector (127.25,0,0)); // beyond range
434  resultdBm = lossModel->CalcRxPower (txPwrdBm, a, b);
435  NS_TEST_EXPECT_MSG_EQ_TOL (resultdBm, -1000.0, tolerance, "Got unexpected rcv power");
436  Simulator::Destroy ();
437 }
438 
440 {
441 public:
443 };
444 
446  : TestSuite ("propagation-loss-model", UNIT)
447 {
448  AddTestCase (new FriisPropagationLossModelTestCase, TestCase::QUICK);
451  AddTestCase (new MatrixPropagationLossModelTestCase, TestCase::QUICK);
452  AddTestCase (new RangePropagationLossModelTestCase, TestCase::QUICK);
453 }
454 
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...
void SetDefaultLoss(double defaultLoss)
Set the default propagation loss (in dB, positive) to be used, infinity if not set.
A suite of tests to run.
Definition: test.h:1342
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:204
virtual void DoRun(void)
Implementation to actually run this TestCase.
encapsulates test code
Definition: test.h:1155
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1404
static PropagationLossModelsTestSuite propagationLossModelsTestSuite
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
#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:168
#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:565
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SetPosition(const Vector &position)
virtual void DoRun(void)
Implementation to actually run this TestCase.
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:810
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).
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
virtual void DoRun(void)
Implementation to actually run this TestCase.
The propagation loss is fixed for each pair of nodes and doesn&#39;t depend on their actual positions...
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.