A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
buildings-shadowing-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
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 * Author: Marco Miozzo <marco.miozzo@cttc.es>
18 * Nicola Baldo <nbaldo@cttc.es>
19 */
20
22
23#include <ns3/building.h>
24#include <ns3/buildings-helper.h>
25#include <ns3/constant-position-mobility-model.h>
26#include <ns3/double.h>
27#include <ns3/enum.h>
28#include <ns3/hybrid-buildings-propagation-loss-model.h>
29#include <ns3/log.h>
30#include <ns3/mobility-building-info.h>
31#include <ns3/mobility-model.h>
32#include <ns3/ptr.h>
33#include <ns3/simulator.h>
34#include <ns3/string.h>
35
36using namespace ns3;
37
38NS_LOG_COMPONENT_DEFINE("BuildingsShadowingTest");
39
40/*
41 * Test 1.1 Shadowing compound test
42 *
43 * This TestSuite tests the shadowing model of BuildingPathlossModel
44 * by reproducing several communication scenarios
45 */
46
48 : TestSuite("buildings-shadowing-test", Type::SYSTEM)
49{
50 LogComponentEnable("BuildingsShadowingTest", LOG_LEVEL_ALL);
51
52 // Test #1 Outdoor Model
53 AddTestCase(new BuildingsShadowingTestCase(1, 2, 148.86, 7.0, "Outdoor Shadowing"),
54 TestCase::Duration::QUICK);
55
56 // Test #2 Indoor model
57 AddTestCase(new BuildingsShadowingTestCase(5, 6, 88.5724, 8.0, "Indoor Shadowing"),
58 TestCase::Duration::QUICK);
59
60 // Test #3 Indoor -> Outdoor
61 AddTestCase(new BuildingsShadowingTestCase(9, 10, 85.0012, 8.6, "Indoor -> Outdoor Shadowing"),
62 TestCase::Duration::QUICK);
63}
64
65/// Static variable for test initialization
67
68/*
69 * TestCase
70 */
71
73 uint16_t m2,
74 double refValue,
75 double sigmaRef,
76 std::string name)
77 : TestCase("SHADOWING calculation: " + name),
78 m_mobilityModelIndex1(m1),
79 m_mobilityModelIndex2(m2),
80 m_lossRef(refValue),
81 m_sigmaRef(sigmaRef)
82{
83}
84
86{
87}
88
89void
91{
92 NS_LOG_FUNCTION(this);
93
94 // the building basically occupies the negative x plane, so any node
95 // in this area will fall in the building
96 Ptr<Building> building1 = CreateObject<Building>();
97 building1->SetBoundaries(Box(-3000, -1, -4000, 4000.0, 0.0, 12));
98 building1->SetBuildingType(Building::Residential);
99 building1->SetExtWallsType(Building::ConcreteWithWindows);
100 building1->SetNFloors(3);
101
102 Ptr<HybridBuildingsPropagationLossModel> propagationLossModel =
103 CreateObject<HybridBuildingsPropagationLossModel>();
104
105 std::vector<double> loss;
106 double sum = 0.0;
107 double sumSquared = 0.0;
108 int samples = 1000;
109 for (int i = 0; i < samples; i++)
110 {
113 double shadowingLoss = propagationLossModel->DoCalcRxPower(0.0, mma, mmb) + m_lossRef;
114 double shadowingLoss2 = propagationLossModel->DoCalcRxPower(0.0, mma, mmb) + m_lossRef;
115 NS_TEST_ASSERT_MSG_EQ_TOL(shadowingLoss,
116 shadowingLoss2,
117 0.001,
118 "Shadowing is not constant for the same mobility model pair!");
119 loss.push_back(shadowingLoss);
120 sum += shadowingLoss;
121 sumSquared += (shadowingLoss * shadowingLoss);
122 }
123 double sampleMean = sum / samples;
124 double sampleVariance = (sumSquared - (sum * sum / samples)) / (samples - 1);
125 double sampleStd = std::sqrt(sampleVariance);
126
127 // test whether the sample mean falls in the 99% confidence interval
128 const double zn995 = 2.575829303549; // 99.5 quantile of the normal distribution
129 double ci = (zn995 * sampleStd) / std::sqrt(samples);
130 NS_LOG_INFO("SampleMean from simulation " << sampleMean << ", sampleStd " << sampleStd
131 << ", reference value " << m_sigmaRef << ", CI(99%) "
132 << ci);
133 NS_TEST_ASSERT_MSG_EQ_TOL(std::fabs(sampleMean), 0.0, ci, "Wrong shadowing distribution !");
134
135 // test whether the sample variance falls in the 99% confidence interval
136 // since the shadowing is gaussian, its sample variance follows the
137 // chi2 distribution with samples-1 degrees of freedom
138 double chi2 = (samples - 1) * sampleVariance / (m_sigmaRef * m_sigmaRef);
139 const double zchi2_005 = 887.621135217515; // 0.5% quantile of the chi2 distribution
140 const double zchi2_995 = 1117.89045267865; // 99.5% quantile of the chi2 distribution
141 NS_TEST_ASSERT_MSG_GT(chi2, zchi2_005, "sample variance lesser than expected");
142 NS_TEST_ASSERT_MSG_LT(chi2, zchi2_995, "sample variance greater than expected");
143
145}
146
149{
150 /*
151 * The purpose of this method is to defer the creation of the
152 * MobilityModel instances to when DoRun() is called. In a previous
153 * version, MobilityModel instances where created directly in the
154 * constructor of the test suite, which caused subtle bugs due to
155 * "static initialization order fiasco". An example of such a subtle
156 * bug is that logging via NS_LOG failed for some modules.
157 *
158 */
159
160 double hm = 1;
161 double hb = 30;
162 double henbHeight = 10.0;
163
165
166 switch (index)
167 {
168 case 1:
169 mm = CreateObject<ConstantPositionMobilityModel>();
170 mm->SetPosition(Vector(0.0, 0.0, hb));
171 break;
172
173 case 2:
174 mm = CreateObject<ConstantPositionMobilityModel>();
175 mm->SetPosition(Vector(2000, 0.0, hm));
176 break;
177
178 case 3:
179 mm = CreateObject<ConstantPositionMobilityModel>();
180 mm->SetPosition(Vector(100, 0.0, hm));
181 break;
182
183 case 4:
184 mm = CreateObject<ConstantPositionMobilityModel>();
185 mm->SetPosition(Vector(900, 0.0, hm));
186 break;
187
188 case 5:
189 mm = CreateObject<ConstantPositionMobilityModel>();
190 mm->SetPosition(Vector(-5, 0.0, hm));
191 break;
192
193 case 6:
194 mm = CreateObject<ConstantPositionMobilityModel>();
195 mm->SetPosition(Vector(-5, 30, henbHeight));
196 break;
197
198 case 7:
199 mm = CreateObject<ConstantPositionMobilityModel>();
200 mm->SetPosition(Vector(-2000, 0.0, hm));
201 break;
202
203 case 8:
204 mm = CreateObject<ConstantPositionMobilityModel>();
205 mm->SetPosition(Vector(-100, 0.0, hm));
206 break;
207
208 case 9:
209 mm = CreateObject<ConstantPositionMobilityModel>();
210 mm->SetPosition(Vector(0, 0.0, hm));
211 break;
212
213 case 10:
214 mm = CreateObject<ConstantPositionMobilityModel>();
215 mm->SetPosition(Vector(-100, 0.0, henbHeight));
216 break;
217
218 case 11:
219 mm = CreateObject<ConstantPositionMobilityModel>();
220 mm->SetPosition(Vector(-500, 0.0, henbHeight));
221 break;
222
223 default:
224 mm = nullptr;
225 break;
226 }
227 Ptr<MobilityBuildingInfo> buildingInfo = CreateObject<MobilityBuildingInfo>();
228 mm->AggregateObject(buildingInfo); // operation usually done by BuildingsHelper::Install
229 buildingInfo->MakeConsistent(mm);
230 return mm;
231}
static BuildingsShadowingTestSuite buildingsShadowingTestSuite
Static variable for test initialization.
uint16_t m_mobilityModelIndex2
Second MobilityModel Index.
Ptr< MobilityModel > CreateMobilityModel(uint16_t index)
Create a mobility model based on its index.
uint16_t m_mobilityModelIndex1
First MobilityModel Index.
double m_lossRef
pathloss value (without shadowing)
void DoRun() override
Implementation to actually run this TestCase.
BuildingsShadowingTestCase(uint16_t m1, uint16_t m2, double refValue, double sigmaRef, std::string name)
Constructor.
double m_sigmaRef
pathloss standard deviation value reference value
a 3d box
Definition: box.h:35
@ ConcreteWithWindows
Definition: building.h:69
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
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#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:710
#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:875
#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:338
const double m1
First component modulus, 232 - 209.
Definition: rng-stream.cc:60
const double m2
Second component modulus, 232 - 22853.
Definition: rng-stream.cc:63
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void LogComponentEnable(const std::string &name, LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:302
@ LOG_LEVEL_ALL
Print everything.
Definition: log.h:116