View | Details | Raw Unified | Return to bug 787
Collapse All | Expand All

(-)a/src/devices/wifi/propagation-loss-model-test-suite.cc (+130 lines)
 Lines 145-150    Link Here 
145
  return GetErrorStatus ();
145
  return GetErrorStatus ();
146
}
146
}
147
147
148
// Added for Two-Ray Ground Model - tomhewer@mac.com
149
150
class TwoRayGroundPropagationLossModelTestCase : public TestCase
151
{
152
public:
153
  TwoRayGroundPropagationLossModelTestCase ();
154
  virtual ~TwoRayGroundPropagationLossModelTestCase ();
155
  
156
private:
157
  virtual bool DoRun (void);
158
  
159
  typedef struct {
160
    Vector m_position;
161
    double m_pt;  // dBm
162
    double m_pr;  // W
163
    double m_tolerance;
164
  } TestVector;
165
  
166
  TestVectors<TestVector> m_testVectors;
167
};
168
169
TwoRayGroundPropagationLossModelTestCase::TwoRayGroundPropagationLossModelTestCase ()
170
: TestCase ("Check to see that the ns-3 TwoRayGround propagation loss model provides correct received power"), m_testVectors ()
171
{
172
}
173
174
TwoRayGroundPropagationLossModelTestCase::~TwoRayGroundPropagationLossModelTestCase ()
175
{
176
}
177
178
bool
179
TwoRayGroundPropagationLossModelTestCase::DoRun (void)
180
{
181
  // wavelength at 2.4 GHz is 0.125m
182
  Config::SetDefault ("ns3::TwoRayGroundPropagationLossModel::Lambda", DoubleValue (0.125));
183
  Config::SetDefault ("ns3::TwoRayGroundPropagationLossModel::SystemLoss", DoubleValue (1.0));
184
  
185
  // set antenna height to 1.5m above z coordinate
186
  Config::SetDefault ("ns3::TwoRayGroundPropagationLossModel::HeightAboveZ", DoubleValue (1.5));
187
  
188
  // Select a reference transmit power of 17.0206 dBm
189
  // Pt = 10^(17.0206/10)/10^3 = .05035702 W
190
  double txPowerW = 0.05035702;
191
  double txPowerdBm = 10 * log10 (txPowerW) + 30;
192
  
193
  //
194
  // As with the Friis tests above, we want to test the propagation loss 
195
  // model calculations at a few chosen distances and compare the results 
196
  // to those we can manually calculate. Let us test the ns-3 calculated 
197
  // value for agreement to be within 5e-16, as above.
198
  //
199
  TestVector testVector;
200
  
201
  // Below the Crossover distance use Friis so this test should be the same as that above
202
  // Crossover = (4 * PI * TxAntennaHeight * RxAntennaHeight) / Lamdba
203
  // Crossover = (4 * PI * 1.5 * 1.5) / 0.125 = 226.1946m
204
  
205
  testVector.m_position = Vector (100, 0, 0);
206
  testVector.m_pt = txPowerdBm;
207
  testVector.m_pr = 4.98265e-10;
208
  testVector.m_tolerance = 5e-16;
209
  m_testVectors.Add (testVector);
210
  
211
  // These values are above the crossover distance and therefore use the Two Ray calculation
212
  
213
  testVector.m_position = Vector (500, 0, 0);
214
  testVector.m_pt = txPowerdBm;
215
  testVector.m_pr = 4.07891862e-12;
216
  testVector.m_tolerance = 5e-16;
217
  m_testVectors.Add (testVector);
218
  
219
  testVector.m_position = Vector (1000, 0, 0);
220
  testVector.m_pt = txPowerdBm;
221
  testVector.m_pr = 2.5493241375e-13;
222
  testVector.m_tolerance = 5e-16;
223
  m_testVectors.Add (testVector);
224
  
225
  testVector.m_position = Vector (2000, 0, 0);
226
  testVector.m_pt = txPowerdBm;
227
  testVector.m_pr = 1.593327585938e-14;
228
  testVector.m_tolerance = 5e-16;
229
  m_testVectors.Add (testVector);
230
  
231
  // Repeat the tests for non-zero z coordinates
232
  
233
  // Pr = (0.05035702 * (1.5*1.5) * (2.5*2.5)) / (500*500*500*500) = 1.13303295e-11
234
  // dCross = (4 * pi * 1.5 * 2.5) / 0.125 = 376.99m
235
  testVector.m_position = Vector (500, 0, 1);
236
  testVector.m_pt = txPowerdBm;
237
  testVector.m_pr = 1.13303295e-11;
238
  testVector.m_tolerance = 5e-16;
239
  m_testVectors.Add (testVector);
240
  
241
  // Pr = (0.05035702 * (1.5*1.5) * (5.5*5.5)) / (1000*1000*1000*1000) = 3.42742467375e-12
242
  // dCross = (4 * pi * 1.5 * 5.5) / 0.125 = 829.38m
243
  testVector.m_position = Vector (1000, 0, 4);
244
  testVector.m_pt = txPowerdBm;
245
  testVector.m_pr = 3.42742467375e-12;
246
  testVector.m_tolerance = 5e-16;
247
  m_testVectors.Add (testVector);
248
  
249
  // Pr = (0.05035702 * (1.5*1.5) * (11.5*11.5)) / (2000*2000*2000*2000) = 9.36522547734e-13
250
  // dCross = (4 * pi * 1.5 * 11.5) / 0.125 = 1734.15m
251
  testVector.m_position = Vector (2000, 0, 10);
252
  testVector.m_pt = txPowerdBm;
253
  testVector.m_pr = 9.36522547734e-13;
254
  testVector.m_tolerance = 5e-16;
255
  m_testVectors.Add (testVector);
256
  
257
  
258
  // Now, check that the received power values are expected
259
  
260
  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> (); 
261
  a->SetPosition (Vector (0,0,0));
262
  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> (); 
263
  
264
  Ptr<TwoRayGroundPropagationLossModel> lossModel = CreateObject<TwoRayGroundPropagationLossModel> (); 
265
  for (uint32_t i = 0; i < m_testVectors.GetN (); ++i)
266
  {
267
    testVector = m_testVectors.Get (i);
268
    b->SetPosition (testVector.m_position);
269
    double resultdBm = lossModel->CalcRxPower (testVector.m_pt, a, b);
270
    double resultW =   pow (10.0, resultdBm/10.0)/1000;
271
    NS_TEST_EXPECT_MSG_EQ_TOL (resultW, testVector.m_pr, testVector.m_tolerance, "Got unexpected rcv power");
272
  }
273
  
274
  return GetErrorStatus ();
275
}
276
148
class LogDistancePropagationLossModelTestCase : public TestCase
277
class LogDistancePropagationLossModelTestCase : public TestCase
149
{
278
{
150
public:
279
public:
 Lines 244-249    Link Here 
244
  : TestSuite ("propagation-loss-model", UNIT)
373
  : TestSuite ("propagation-loss-model", UNIT)
245
{
374
{
246
  AddTestCase (new FriisPropagationLossModelTestCase);
375
  AddTestCase (new FriisPropagationLossModelTestCase);
376
  AddTestCase (new TwoRayGroundPropagationLossModelTestCase);
247
  AddTestCase (new LogDistancePropagationLossModelTestCase);
377
  AddTestCase (new LogDistancePropagationLossModelTestCase);
248
}
378
}
249
379
(-)a/src/devices/wifi/propagation-loss-model.cc (+167 lines)
 Lines 17-22    Link Here 
17
 *
17
 *
18
 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18
 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19
 * Contributions: Timo Bingmann <timo.bingmann@student.kit.edu>
19
 * Contributions: Timo Bingmann <timo.bingmann@student.kit.edu>
20
 * Contributions: Tom Hewer <tomhewer@mac.com> for Two Ray Ground Model
20
 */
21
 */
21
22
22
#include "propagation-loss-model.h"
23
#include "propagation-loss-model.h"
 Lines 230-235    Link Here 
230
  double pr = 10 * log10 (numerator / denominator);
231
  double pr = 10 * log10 (numerator / denominator);
231
  NS_LOG_DEBUG ("distance="<<distance<<"m, attenuation coefficient="<<pr<<"dB");
232
  NS_LOG_DEBUG ("distance="<<distance<<"m, attenuation coefficient="<<pr<<"dB");
232
  return txPowerDbm + pr;
233
  return txPowerDbm + pr;
234
}
235
236
// ------------------------------------------------------------------------- //
237
// -- Two-Ray Ground Model ported from NS-2 -- tomhewer@mac.com -- Nov09 //
238
239
NS_OBJECT_ENSURE_REGISTERED (TwoRayGroundPropagationLossModel);
240
241
const double TwoRayGroundPropagationLossModel::PI = 3.14159265358979323846;
242
243
TypeId 
244
TwoRayGroundPropagationLossModel::GetTypeId (void)
245
{
246
  static TypeId tid = TypeId ("ns3::TwoRayGroundPropagationLossModel")
247
  .SetParent<PropagationLossModel> ()
248
  .AddConstructor<TwoRayGroundPropagationLossModel> ()
249
  .AddAttribute ("Lambda", 
250
                 "The wavelength  (default is 5.15 GHz at 300 000 km/s).",
251
                 DoubleValue (300000000.0 / 5.150e9),
252
                 MakeDoubleAccessor (&TwoRayGroundPropagationLossModel::m_lambda),
253
                 MakeDoubleChecker<double> ())
254
  .AddAttribute ("SystemLoss", "The system loss",
255
                 DoubleValue (1.0),
256
                 MakeDoubleAccessor (&TwoRayGroundPropagationLossModel::m_systemLoss),
257
                 MakeDoubleChecker<double> ())
258
  .AddAttribute ("MinDistance", 
259
                 "The distance under which the propagation model refuses to give results (m)",
260
                 DoubleValue (0.5),
261
                 MakeDoubleAccessor (&TwoRayGroundPropagationLossModel::SetMinDistance,
262
                                     &TwoRayGroundPropagationLossModel::GetMinDistance),
263
                 MakeDoubleChecker<double> ())
264
  .AddAttribute ("HeightAboveZ", 
265
                 "The height of the antenna (m) above the node's Z coordinate",
266
                 DoubleValue (0),
267
                 MakeDoubleAccessor (&TwoRayGroundPropagationLossModel::m_heightAboveZ),
268
                 MakeDoubleChecker<double> ())
269
  ;
270
  return tid;
271
}
272
273
TwoRayGroundPropagationLossModel::TwoRayGroundPropagationLossModel ()
274
{}
275
void 
276
TwoRayGroundPropagationLossModel::SetSystemLoss (double systemLoss)
277
{
278
  m_systemLoss = systemLoss;
279
}
280
double 
281
TwoRayGroundPropagationLossModel::GetSystemLoss (void) const
282
{
283
  return m_systemLoss;
284
}
285
void 
286
TwoRayGroundPropagationLossModel::SetMinDistance (double minDistance)
287
{
288
  m_minDistance = minDistance;
289
}
290
double 
291
TwoRayGroundPropagationLossModel::GetMinDistance (void) const
292
{
293
  return m_minDistance;
294
}
295
void
296
TwoRayGroundPropagationLossModel::SetHeightAboveZ (double heightAboveZ)
297
{
298
  m_heightAboveZ = heightAboveZ;
299
}
300
void 
301
TwoRayGroundPropagationLossModel::SetLambda (double frequency, double speed)
302
{
303
  m_lambda = speed / frequency;
304
}
305
void 
306
TwoRayGroundPropagationLossModel::SetLambda (double lambda)
307
{
308
  m_lambda = lambda;
309
}
310
double 
311
TwoRayGroundPropagationLossModel::GetLambda (void) const
312
{
313
  return m_lambda;
314
}
315
316
double 
317
TwoRayGroundPropagationLossModel::DbmToW (double dbm) const
318
{
319
  double mw = pow(10.0,dbm/10.0);
320
  return mw / 1000.0;
321
}
322
323
double
324
TwoRayGroundPropagationLossModel::DbmFromW (double w) const
325
{
326
  double dbm = log10 (w * 1000.0) * 10.0;
327
  return dbm;
328
}
329
330
double 
331
TwoRayGroundPropagationLossModel::DoCalcRxPower (double txPowerDbm,
332
                                                 Ptr<MobilityModel> a,
333
                                                 Ptr<MobilityModel> b) const
334
{
335
  /*
336
   * Two-Ray Ground equation:
337
   *
338
   * where Pt, Gt and Gr are in dBm units
339
   * L, Ht and Hr are in meter units.
340
   *
341
   *   Pr      Gt * Gr * (Ht^2 * Hr^2)
342
   *   -- =  (-------------------------)
343
   *	 Pt            d^4 * L
344
   *
345
   * Gt: tx gain (unit-less)
346
   * Gr: rx gain (unit-less)
347
   * Pt: tx power (dBm)
348
   * d: distance (m)
349
   * L: system loss
350
   * Ht: Tx antenna height (m)
351
   * Hr: Rx antenna height (m)
352
   * lambda: wavelength (m)
353
   *
354
   * As with the Friis model we ignore tx and rx gain and output values
355
   * are in dB or dBm
356
   *
357
   *						  (Ht * Ht) * (Hr * Hr)
358
   * rx = tx + 10 log10	(-----------------------)
359
   *						   (d * d * d * d) * L
360
   */
361
  double distance = a->GetDistanceFrom (b);
362
  if (distance <= m_minDistance)
363
  {
364
    return txPowerDbm;
365
  }
366
  
367
  // Set the height of the Tx and Rx antennae
368
  double txAntHeight = a->GetPosition().z + m_heightAboveZ;
369
  double rxAntHeight = b->GetPosition().z + m_heightAboveZ;
370
  
371
  // Calculate a crossover distance, under which we use Friis
372
  /*
373
   * 
374
   * dCross = (4 * pi * Ht * Hr) / lambda
375
   *
376
   */
377
  
378
  double dCross = (4 * PI * txAntHeight * rxAntHeight) / GetLambda();
379
  double tmp = 0;
380
  if (distance <= dCross) {
381
    // We use Friis
382
    double numerator = m_lambda * m_lambda;
383
    tmp = PI * distance;
384
    double denominator = 16 * tmp * tmp * m_systemLoss;
385
    double pr = 10 * log10 (numerator / denominator);
386
    NS_LOG_DEBUG ("Receiver within crossover ("<<dCross<<"m) for Two_ray path; using Friis");
387
    NS_LOG_DEBUG ("distance="<<distance<<"m, attenuation coefficient="<<pr<<"dB");
388
    return txPowerDbm + pr;
389
  }
390
  else { // Use Two-Ray Pathloss  
391
    double txTmp = txAntHeight * txAntHeight;
392
    double rxTmp = rxAntHeight * rxAntHeight;
393
    double rayNumerator = txTmp * rxTmp;
394
    tmp = distance * distance * distance * distance;
395
    double rayDenominator = tmp * m_systemLoss;
396
    double rayPr = 10 * log10 (rayNumerator / rayDenominator);
397
    NS_LOG_DEBUG ("distance="<<distance<<"m, attenuation coefficient="<<rayPr<<"dB");
398
    return txPowerDbm + rayPr;
399
  }
233
}
400
}
234
401
235
// ------------------------------------------------------------------------- //
402
// ------------------------------------------------------------------------- //
(-)a/src/devices/wifi/propagation-loss-model.h (+90 lines)
 Lines 18-23    Link Here 
18
 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18
 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19
 * Contributions: Timo Bingmann <timo.bingmann@student.kit.edu>
19
 * Contributions: Timo Bingmann <timo.bingmann@student.kit.edu>
20
 * Contributions: Gary Pei <guangyu.pei@boeing.com> for fixed RSS
20
 * Contributions: Gary Pei <guangyu.pei@boeing.com> for fixed RSS
21
 * Contributions: Tom Hewer <tomhewer@mac.com> for porting Two Ray Ground
21
 */
22
 */
22
23
23
#ifndef PROPAGATION_LOSS_MODEL_H
24
#ifndef PROPAGATION_LOSS_MODEL_H
 Lines 180-185    Link Here 
180
  double m_lambda;
181
  double m_lambda;
181
  double m_systemLoss;
182
  double m_systemLoss;
182
  double m_minDistance;
183
  double m_minDistance;
184
};
185
186
/*
187
 *
188
 * \brief a Two-Ray Ground propagation loss model ported from NS2
189
 *
190
 * Two-ray ground reflection model.
191
 *
192
 * \f$ Pr = \frac{Pt * Gt * Gr * (ht^2 * hr^2)}{d^4 * L} \f$
193
 *
194
 * The original equation in Rappaport's book assumes L = 1.
195
 * To be consistant with the free space equation, L is added here.	 
196
 *
197
 * Ht and Hr are set at the respective nodes z coordinate plus a model parameter
198
 * set via SetHeightAboveZ.
199
 *
200
 * The two-ray model does not give a good result for short distances, due to the
201
 * oscillation caused by constructive and destructive combination of the two
202
 * rays. Instead the Friis free-space model is used for small distances. 
203
 *
204
 * The crossover distance, below which Friis is used, is calculated as follows:
205
 *
206
 * \f$ dCross = \frac{(4 * pi * Ht * Hr)}{lambda} \f$
207
 */
208
209
class TwoRayGroundPropagationLossModel : public PropagationLossModel
210
{
211
public:
212
  static TypeId GetTypeId (void);
213
  TwoRayGroundPropagationLossModel ();
214
  /**
215
   * \param frequency (Hz)
216
   * \param speed (m/s)
217
   *
218
   * Set the main wavelength used in the TwoRayGround model 
219
   * calculation.
220
   */
221
  void SetLambda (double frequency, double speed);
222
  /**
223
   * \param lambda (m) the wavelength
224
   *
225
   * Set the main wavelength used in the TwoRayGround model 
226
   * calculation.
227
   */
228
  void SetLambda (double lambda);
229
  /**
230
   * \param systemLoss (dimension-less)
231
   *
232
   * Set the system loss used by the TwoRayGround propagation model.
233
   */
234
  void SetSystemLoss (double systemLoss);
235
  /**
236
   * \param minDistance the minimum distance
237
   *
238
   * Below this distance, the txpower is returned
239
   * unmodified as the rxpower.
240
   */
241
  void SetMinDistance (double minDistance);
242
  /**
243
   * \returns the minimum distance.
244
   */
245
  double GetMinDistance (void) const;
246
  /**
247
   * \returns the current wavelength (m)
248
   */
249
  double GetLambda (void) const;
250
  /**
251
   * \returns the current system loss (dimention-less)
252
   */
253
  double GetSystemLoss (void) const;
254
  /**
255
   * \Set the model antenna height above the node's Z coordinate
256
   */
257
  void SetHeightAboveZ (double heightAboveZ);
258
  
259
private:
260
  TwoRayGroundPropagationLossModel (const TwoRayGroundPropagationLossModel &o);
261
  TwoRayGroundPropagationLossModel & operator = (const TwoRayGroundPropagationLossModel &o);
262
  virtual double DoCalcRxPower (double txPowerDbm,
263
                                Ptr<MobilityModel> a,
264
                                Ptr<MobilityModel> b) const;
265
  double DbmToW (double dbm) const;
266
  double DbmFromW (double w) const;
267
  
268
  static const double PI;
269
  double m_lambda;
270
  double m_systemLoss;
271
  double m_minDistance;
272
  double m_heightAboveZ;
183
};
273
};
184
274
185
/**
275
/**

Return to bug 787