A Discrete-Event Network Simulator
API
buildings-shadowing-test.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
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  * Author: Marco Miozzo <marco.miozzo@cttc.es>
19  * Nicola Baldo <nbaldo@cttc.es>
20  */
21 
22 #include <ns3/simulator.h>
23 #include <ns3/log.h>
24 #include <ns3/hybrid-buildings-propagation-loss-model.h>
25 #include <ns3/string.h>
26 #include <ns3/double.h>
27 #include <ns3/building.h>
28 #include <ns3/enum.h>
29 #include <ns3/buildings-helper.h>
30 #include <ns3/mobility-model.h>
31 #include <ns3/mobility-building-info.h>
32 #include <ns3/constant-position-mobility-model.h>
33 
35 
36 using namespace ns3;
37 
38 NS_LOG_COMPONENT_DEFINE ("BuildingsShadowingTest");
39 
40 
52  : TestSuite ("buildings-shadowing-test", SYSTEM)
53 {
54 
55  LogComponentEnable ("BuildingsShadowingTest", LOG_LEVEL_ALL);
56 
57  // Test #1 Outdoor Model
58  AddTestCase (new BuildingsShadowingTestCase (1, 2, 148.86, 7.0, "Outdoor Shadowing"), TestCase::QUICK);
59 
60  // Test #2 Indoor model
61  AddTestCase (new BuildingsShadowingTestCase (5, 6, 88.5724, 8.0, "Indoor Shadowing"), TestCase::QUICK);
62 
63  // Test #3 Indoor -> Outdoor
64  AddTestCase (new BuildingsShadowingTestCase (9, 10, 85.0012, 8.6, "Indoor -> Outdoor Shadowing"), TestCase::QUICK);
65 
66 }
67 
69 
70 
75 BuildingsShadowingTestCase::BuildingsShadowingTestCase ( uint16_t m1, uint16_t m2, double refValue, double sigmaRef, std::string name)
76  : TestCase ("SHADOWING calculation: " + name),
77  m_mobilityModelIndex1 (m1),
78  m_mobilityModelIndex2 (m2),
79  m_lossRef (refValue),
80  m_sigmaRef (sigmaRef)
81 {
82 }
83 
85 {
86 }
87 
88 void
90 {
91  NS_LOG_FUNCTION (this);
92 
93  // the building basically occupies the negative x plane, so any node
94  // in this area will fall in the building
95  Ptr<Building> building1 = CreateObject<Building> ();
96  building1->SetBoundaries (Box (-3000, -1, -4000, 4000.0, 0.0, 12));
97  building1->SetBuildingType (Building::Residential);
98  building1->SetExtWallsType (Building::ConcreteWithWindows);
99  building1->SetNFloors (3);
100 
101  Ptr<HybridBuildingsPropagationLossModel> propagationLossModel = CreateObject<HybridBuildingsPropagationLossModel> ();
102 
103  std::vector<double> loss;
104  double sum = 0.0;
105  double sumSquared = 0.0;
106  int samples = 1000;
107  for (int i = 0; i < samples; i++)
108  {
111  double shadowingLoss = propagationLossModel->DoCalcRxPower (0.0, mma, mmb) + m_lossRef;
112  double shadowingLoss2 = propagationLossModel->DoCalcRxPower (0.0, mma, mmb) + m_lossRef;
113  NS_TEST_ASSERT_MSG_EQ_TOL (shadowingLoss, shadowingLoss2, 0.001,
114  "Shadowing is not constant for the same mobility model pair!");
115  loss.push_back (shadowingLoss);
116  sum += shadowingLoss;
117  sumSquared += (shadowingLoss * shadowingLoss);
118  }
119  double sampleMean = sum / samples;
120  double sampleVariance = (sumSquared - (sum * sum / samples)) / (samples - 1);
121  double sampleStd = std::sqrt (sampleVariance);
122 
123  // test whether the sample mean falls in the 99% confidence interval
124  const double zn995 = 2.575829303549; // 99.5 quantile of the normal distribution
125  double ci = (zn995 * sampleStd) / std::sqrt (samples);
126  NS_LOG_INFO ("SampleMean from simulation " << sampleMean << ", sampleStd " << sampleStd << ", reference value " << m_sigmaRef << ", CI(99%) " << ci);
127  NS_TEST_ASSERT_MSG_EQ_TOL (std::fabs (sampleMean), 0.0, ci, "Wrong shadowing distribution !");
128 
129  // test whether the sample variance falls in the 99% confidence interval
130  // since the shadowing is gaussian, its sample variance follows the
131  // chi2 distribution with samples-1 degrees of freedom
132  double chi2 = (samples - 1) * sampleVariance / (m_sigmaRef*m_sigmaRef);
133  const double zchi2_005 = 887.621135217515; // 0.5% quantile of the chi2 distribution
134  const double zchi2_995 = 1117.89045267865; // 99.5% quantile of the chi2 distribution
135  NS_TEST_ASSERT_MSG_GT (chi2, zchi2_005, "sample variance lesser than expected");
136  NS_TEST_ASSERT_MSG_LT (chi2, zchi2_995, "sample variance greater than expected");
137 
138  Simulator::Destroy ();
139 }
140 
141 
142 
145 {
146 
147  /*
148  * The purpose of this method is to defer the creation of the
149  * MobilityModel instances to when DoRun() is called. In a previous
150  * version, MobilityModel instances where created directly in the
151  * constructor of the test suite, which caused subtle bugs due to
152  * "static initialization order fiasco". An example of such a subtle
153  * bug is that logging via NS_LOG failed for some modules.
154  *
155  */
156 
157  double hm = 1;
158  double hb = 30;
159  double henbHeight = 10.0;
160 
162 
163  switch (index)
164  {
165  case 1:
166  mm = CreateObject<ConstantPositionMobilityModel> ();
167  mm->SetPosition (Vector (0.0, 0.0, hb));
168  break;
169 
170  case 2:
171  mm = CreateObject<ConstantPositionMobilityModel> ();
172  mm->SetPosition (Vector (2000, 0.0, hm));
173  break;
174 
175  case 3:
176  mm = CreateObject<ConstantPositionMobilityModel> ();
177  mm->SetPosition (Vector (100, 0.0, hm));
178  break;
179 
180  case 4:
181  mm = CreateObject<ConstantPositionMobilityModel> ();
182  mm->SetPosition (Vector (900, 0.0, hm));
183  break;
184 
185  case 5:
186  mm = CreateObject<ConstantPositionMobilityModel> ();
187  mm->SetPosition (Vector (-5, 0.0, hm));
188  break;
189 
190  case 6:
191  mm = CreateObject<ConstantPositionMobilityModel> ();
192  mm->SetPosition (Vector (-5, 30, henbHeight));
193  break;
194 
195  case 7:
196  mm = CreateObject<ConstantPositionMobilityModel> ();
197  mm->SetPosition (Vector (-2000, 0.0, hm));
198  break;
199 
200  case 8:
201  mm = CreateObject<ConstantPositionMobilityModel> ();
202  mm->SetPosition (Vector (-100, 0.0, hm));
203  break;
204 
205  case 9:
206  mm = CreateObject<ConstantPositionMobilityModel> ();
207  mm->SetPosition (Vector (0, 0.0, hm));
208  break;
209 
210  case 10:
211  mm = CreateObject<ConstantPositionMobilityModel> ();
212  mm->SetPosition (Vector (-100, 0.0, henbHeight));
213  break;
214 
215  case 11:
216  mm = CreateObject<ConstantPositionMobilityModel> ();
217  mm->SetPosition (Vector (-500, 0.0, henbHeight));
218  break;
219 
220  default:
221  mm = 0;
222  break;
223  }
224  Ptr<MobilityBuildingInfo> buildingInfo = CreateObject<MobilityBuildingInfo> ();
225  mm->AggregateObject (buildingInfo); // operation usually done by BuildingsHelper::Install
226  BuildingsHelper::MakeConsistent (mm);
227  return mm;
228 }
static BuildingsShadowingTestSuite buildingsShadowingTestSuite
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
virtual double DoCalcRxPower(double txPowerDbm, Ptr< MobilityModel > a, Ptr< MobilityModel > b) const
Returns the Rx Power taking into account only the particular PropagatinLossModel. ...
A suite of tests to run.
Definition: test.h:1333
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:252
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
encapsulates test code
Definition: test.h:1147
BuildingsShadowingTestCase(uint16_t m1, uint16_t m2, double refValue, double sigmaRef, std::string name)
TestCase.
a 3d box
Definition: box.h:34
void LogComponentEnable(char const *name, enum LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:351
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:298
Test shadowing calculation.
void SetNFloors(uint16_t nfloors)
Definition: building.cc:160
#define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report and...
Definition: test.h:373
BuildingsShadowingTestSuite()
Test 1.1 Shadowing compound test.
void SetExtWallsType(Building::ExtWallsType_t t)
Definition: building.cc:153
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SetPosition(const Vector &position)
Ptr< MobilityModel > CreateMobilityModel(uint16_t index)
const double m2
Second component modulus, 232 - 22853.
Definition: rng-stream.cc:58
Print everything.
Definition: log.h:112
virtual void DoRun(void)
Implementation to actually run this TestCase.
#define NS_TEST_ASSERT_MSG_GT(actual, limit, msg)
Test that an actual value is greater than a limit and report and abort if not.
Definition: test.h:990
const double m1
First component modulus, 232 - 209.
Definition: rng-stream.cc:54
void SetBoundaries(Box box)
Set the boundaries of the building.
Definition: building.cc:139
#define NS_TEST_ASSERT_MSG_LT(actual, limit, msg)
Test that an actual value is less than a limit and report and abort if not.
Definition: test.h:804
void SetBuildingType(Building::BuildingType_t t)
Definition: building.cc:146