|
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/pcap-file.h" |
|
23 #include "ns3/config.h" |
|
24 #include "ns3/string.h" |
|
25 #include "ns3/uinteger.h" |
|
26 #include "ns3/double.h" |
|
27 #include "ns3/data-rate.h" |
|
28 #include "ns3/inet-socket-address.h" |
|
29 #include "ns3/internet-stack-helper.h" |
|
30 #include "ns3/ipv4-address-helper.h" |
|
31 #include "ns3/tcp-socket-factory.h" |
|
32 #include "ns3/yans-wifi-helper.h" |
|
33 #include "ns3/propagation-loss-model.h" |
|
34 #include "ns3/propagation-delay-model.h" |
|
35 #include "ns3/yans-wifi-channel.h" |
|
36 #include "ns3/yans-wifi-phy.h" |
|
37 #include "ns3/wifi-net-device.h" |
|
38 #include "ns3/mobility-helper.h" |
|
39 #include "ns3/constant-position-mobility-model.h" |
|
40 #include "ns3/nqos-wifi-mac-helper.h" |
|
41 #include "ns3/simulator.h" |
|
42 |
|
43 using namespace ns3; |
|
44 |
|
45 NS_LOG_COMPONENT_DEFINE ("PropagationLossModelsTest"); |
|
46 |
|
47 // =========================================================================== |
|
48 // This is a simple test to validate propagation loss models of ns-3 wifi. |
|
49 // See the chapter in the ns-3 testing and validation guide for more detail |
|
50 // =========================================================================== |
|
51 // |
|
52 class FriisPropagationLossModelTestCase : public TestCase |
|
53 { |
|
54 public: |
|
55 FriisPropagationLossModelTestCase (); |
|
56 virtual ~FriisPropagationLossModelTestCase (); |
|
57 |
|
58 private: |
|
59 virtual bool DoRun (void); |
|
60 |
|
61 typedef struct { |
|
62 Vector m_position; |
|
63 double m_pt; // dBm |
|
64 double m_pr; // W |
|
65 double m_tolerance; |
|
66 } TestVector; |
|
67 |
|
68 TestVectors<TestVector> m_testVectors; |
|
69 }; |
|
70 |
|
71 FriisPropagationLossModelTestCase::FriisPropagationLossModelTestCase () |
|
72 : TestCase ("Check to see that the ns-3 Friis propagation loss model provides correct received power"), m_testVectors () |
|
73 { |
|
74 } |
|
75 |
|
76 FriisPropagationLossModelTestCase::~FriisPropagationLossModelTestCase () |
|
77 { |
|
78 } |
|
79 |
|
80 bool |
|
81 FriisPropagationLossModelTestCase::DoRun (void) |
|
82 { |
|
83 // The ns-3 testing manual gives more background on the values selected |
|
84 // for this test. First, set a few defaults. |
|
85 |
|
86 // wavelength at 2.4 GHz is 0.125m |
|
87 Config::SetDefault ("ns3::FriisPropagationLossModel::Lambda", DoubleValue (0.125)); |
|
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 * 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 = 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 return GetErrorStatus (); |
|
147 } |
|
148 |
|
149 // Added for Two-Ray Ground Model - tomhewer@mac.com |
|
150 |
|
151 class TwoRayGroundPropagationLossModelTestCase : public TestCase |
|
152 { |
|
153 public: |
|
154 TwoRayGroundPropagationLossModelTestCase (); |
|
155 virtual ~TwoRayGroundPropagationLossModelTestCase (); |
|
156 |
|
157 private: |
|
158 virtual bool DoRun (void); |
|
159 |
|
160 typedef struct |
|
161 { |
|
162 Vector m_position; |
|
163 double m_pt; // dBm |
|
164 double m_pr; // W |
|
165 double m_tolerance; |
|
166 } TestVector; |
|
167 |
|
168 TestVectors<TestVector> m_testVectors; |
|
169 }; |
|
170 |
|
171 TwoRayGroundPropagationLossModelTestCase::TwoRayGroundPropagationLossModelTestCase () |
|
172 : TestCase ("Check to see that the ns-3 TwoRayGround propagation loss model provides correct received power"), |
|
173 m_testVectors () |
|
174 { |
|
175 } |
|
176 |
|
177 TwoRayGroundPropagationLossModelTestCase::~TwoRayGroundPropagationLossModelTestCase () |
|
178 { |
|
179 } |
|
180 |
|
181 bool |
|
182 TwoRayGroundPropagationLossModelTestCase::DoRun (void) |
|
183 { |
|
184 // wavelength at 2.4 GHz is 0.125m |
|
185 Config::SetDefault ("ns3::TwoRayGroundPropagationLossModel::Lambda", DoubleValue (0.125)); |
|
186 Config::SetDefault ("ns3::TwoRayGroundPropagationLossModel::SystemLoss", DoubleValue (1.0)); |
|
187 |
|
188 // set antenna height to 1.5m above z coordinate |
|
189 Config::SetDefault ("ns3::TwoRayGroundPropagationLossModel::HeightAboveZ", DoubleValue (1.5)); |
|
190 |
|
191 // Select a reference transmit power of 17.0206 dBm |
|
192 // Pt = 10^(17.0206/10)/10^3 = .05035702 W |
|
193 double txPowerW = 0.05035702; |
|
194 double txPowerdBm = 10 * log10 (txPowerW) + 30; |
|
195 |
|
196 // |
|
197 // As with the Friis tests above, we want to test the propagation loss |
|
198 // model calculations at a few chosen distances and compare the results |
|
199 // to those we can manually calculate. Let us test the ns-3 calculated |
|
200 // value for agreement to be within 5e-16, as above. |
|
201 // |
|
202 TestVector testVector; |
|
203 |
|
204 // Below the Crossover distance use Friis so this test should be the same as that above |
|
205 // Crossover = (4 * PI * TxAntennaHeight * RxAntennaHeight) / Lamdba |
|
206 // Crossover = (4 * PI * 1.5 * 1.5) / 0.125 = 226.1946m |
|
207 |
|
208 testVector.m_position = Vector (100, 0, 0); |
|
209 testVector.m_pt = txPowerdBm; |
|
210 testVector.m_pr = 4.98265e-10; |
|
211 testVector.m_tolerance = 5e-16; |
|
212 m_testVectors.Add (testVector); |
|
213 |
|
214 // These values are above the crossover distance and therefore use the Two Ray calculation |
|
215 |
|
216 testVector.m_position = Vector (500, 0, 0); |
|
217 testVector.m_pt = txPowerdBm; |
|
218 testVector.m_pr = 4.07891862e-12; |
|
219 testVector.m_tolerance = 5e-16; |
|
220 m_testVectors.Add (testVector); |
|
221 |
|
222 testVector.m_position = Vector (1000, 0, 0); |
|
223 testVector.m_pt = txPowerdBm; |
|
224 testVector.m_pr = 2.5493241375e-13; |
|
225 testVector.m_tolerance = 5e-16; |
|
226 m_testVectors.Add (testVector); |
|
227 |
|
228 testVector.m_position = Vector (2000, 0, 0); |
|
229 testVector.m_pt = txPowerdBm; |
|
230 testVector.m_pr = 1.593327585938e-14; |
|
231 testVector.m_tolerance = 5e-16; |
|
232 m_testVectors.Add (testVector); |
|
233 |
|
234 // Repeat the tests for non-zero z coordinates |
|
235 |
|
236 // Pr = (0.05035702 * (1.5*1.5) * (2.5*2.5)) / (500*500*500*500) = 1.13303295e-11 |
|
237 // dCross = (4 * pi * 1.5 * 2.5) / 0.125 = 376.99m |
|
238 testVector.m_position = Vector (500, 0, 1); |
|
239 testVector.m_pt = txPowerdBm; |
|
240 testVector.m_pr = 1.13303295e-11; |
|
241 testVector.m_tolerance = 5e-16; |
|
242 m_testVectors.Add (testVector); |
|
243 |
|
244 // Pr = (0.05035702 * (1.5*1.5) * (5.5*5.5)) / (1000*1000*1000*1000) = 3.42742467375e-12 |
|
245 // dCross = (4 * pi * 1.5 * 5.5) / 0.125 = 829.38m |
|
246 testVector.m_position = Vector (1000, 0, 4); |
|
247 testVector.m_pt = txPowerdBm; |
|
248 testVector.m_pr = 3.42742467375e-12; |
|
249 testVector.m_tolerance = 5e-16; |
|
250 m_testVectors.Add (testVector); |
|
251 |
|
252 // Pr = (0.05035702 * (1.5*1.5) * (11.5*11.5)) / (2000*2000*2000*2000) = 9.36522547734e-13 |
|
253 // dCross = (4 * pi * 1.5 * 11.5) / 0.125 = 1734.15m |
|
254 testVector.m_position = Vector (2000, 0, 10); |
|
255 testVector.m_pt = txPowerdBm; |
|
256 testVector.m_pr = 9.36522547734e-13; |
|
257 testVector.m_tolerance = 5e-16; |
|
258 m_testVectors.Add (testVector); |
|
259 |
|
260 |
|
261 // Now, check that the received power values are expected |
|
262 |
|
263 Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> (); |
|
264 a->SetPosition (Vector (0,0,0)); |
|
265 Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> (); |
|
266 |
|
267 Ptr<TwoRayGroundPropagationLossModel> lossModel = CreateObject<TwoRayGroundPropagationLossModel> (); |
|
268 for (uint32_t i = 0; i < m_testVectors.GetN (); ++i) |
|
269 { |
|
270 testVector = m_testVectors.Get (i); |
|
271 b->SetPosition (testVector.m_position); |
|
272 double resultdBm = lossModel->CalcRxPower (testVector.m_pt, a, b); |
|
273 double resultW = pow (10.0, resultdBm / 10.0) / 1000; |
|
274 NS_TEST_EXPECT_MSG_EQ_TOL (resultW, testVector.m_pr, testVector.m_tolerance, "Got unexpected rcv power"); |
|
275 } |
|
276 |
|
277 return GetErrorStatus (); |
|
278 } |
|
279 |
|
280 |
|
281 class LogDistancePropagationLossModelTestCase : public TestCase |
|
282 { |
|
283 public: |
|
284 LogDistancePropagationLossModelTestCase (); |
|
285 virtual ~LogDistancePropagationLossModelTestCase (); |
|
286 |
|
287 private: |
|
288 virtual bool DoRun (void); |
|
289 |
|
290 typedef struct { |
|
291 Vector m_position; |
|
292 double m_pt; // dBm |
|
293 double m_pr; // W |
|
294 double m_tolerance; |
|
295 } TestVector; |
|
296 |
|
297 TestVectors<TestVector> m_testVectors; |
|
298 }; |
|
299 |
|
300 LogDistancePropagationLossModelTestCase::LogDistancePropagationLossModelTestCase () |
|
301 : TestCase ("Check to see that the ns-3 Log Distance propagation loss model provides correct received power"), m_testVectors () |
|
302 { |
|
303 } |
|
304 |
|
305 LogDistancePropagationLossModelTestCase::~LogDistancePropagationLossModelTestCase () |
|
306 { |
|
307 } |
|
308 |
|
309 bool |
|
310 LogDistancePropagationLossModelTestCase::DoRun (void) |
|
311 { |
|
312 // reference loss at 2.4 GHz is 40.045997 |
|
313 Config::SetDefault ("ns3::LogDistancePropagationLossModel::ReferenceLoss", DoubleValue (40.045997)); |
|
314 Config::SetDefault ("ns3::LogDistancePropagationLossModel::Exponent", DoubleValue (3)); |
|
315 |
|
316 // Select a reference transmit power |
|
317 // Pt = 10^(17.0206/10)/10^3 = .05035702 W |
|
318 double txPowerW = 0.05035702; |
|
319 double txPowerdBm = 10 * log10 (txPowerW) + 30; |
|
320 |
|
321 // |
|
322 // We want to test the propagation loss model calculations at a few chosen |
|
323 // distances and compare the results to those we have manually calculated |
|
324 // according to the model documentation. The following "TestVector" objects |
|
325 // will drive the test. |
|
326 // |
|
327 TestVector testVector; |
|
328 |
|
329 testVector.m_position = Vector (10, 0, 0); |
|
330 testVector.m_pt = txPowerdBm; |
|
331 testVector.m_pr = 4.98265e-9; |
|
332 testVector.m_tolerance = 5e-15; |
|
333 m_testVectors.Add (testVector); |
|
334 |
|
335 testVector.m_position = Vector (20, 0, 0); |
|
336 testVector.m_pt = txPowerdBm; |
|
337 testVector.m_pr = 6.22831e-10; |
|
338 testVector.m_tolerance = 5e-16; |
|
339 m_testVectors.Add (testVector); |
|
340 |
|
341 testVector.m_position = Vector (40, 0, 0); |
|
342 testVector.m_pt = txPowerdBm; |
|
343 testVector.m_pr = 7.78539e-11; |
|
344 testVector.m_tolerance = 5e-17; |
|
345 m_testVectors.Add (testVector); |
|
346 |
|
347 testVector.m_position = Vector (80, 0, 0); |
|
348 testVector.m_pt = txPowerdBm; |
|
349 testVector.m_pr = 9.73173e-12; |
|
350 testVector.m_tolerance = 5e-17; |
|
351 m_testVectors.Add (testVector); |
|
352 |
|
353 Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> (); |
|
354 a->SetPosition (Vector (0,0,0)); |
|
355 Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> (); |
|
356 |
|
357 Ptr<LogDistancePropagationLossModel> lossModel = CreateObject<LogDistancePropagationLossModel> (); |
|
358 for (uint32_t i = 0; i < m_testVectors.GetN (); ++i) |
|
359 { |
|
360 testVector = m_testVectors.Get (i); |
|
361 b->SetPosition (testVector.m_position); |
|
362 double resultdBm = lossModel->CalcRxPower (testVector.m_pt, a, b); |
|
363 double resultW = pow (10.0, resultdBm/10.0)/1000; |
|
364 NS_TEST_EXPECT_MSG_EQ_TOL (resultW, testVector.m_pr, testVector.m_tolerance, "Got unexpected rcv power"); |
|
365 } |
|
366 |
|
367 return GetErrorStatus (); |
|
368 } |
|
369 |
|
370 class PropagationLossModelsTestSuite : public TestSuite |
|
371 { |
|
372 public: |
|
373 PropagationLossModelsTestSuite (); |
|
374 }; |
|
375 |
|
376 PropagationLossModelsTestSuite::PropagationLossModelsTestSuite () |
|
377 : TestSuite ("propagation-loss-model", UNIT) |
|
378 { |
|
379 AddTestCase (new FriisPropagationLossModelTestCase); |
|
380 AddTestCase (new TwoRayGroundPropagationLossModelTestCase); |
|
381 AddTestCase (new LogDistancePropagationLossModelTestCase); |
|
382 } |
|
383 |
|
384 PropagationLossModelsTestSuite WifiPropagationLossModelsTestSuite; |