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

(-)a/src/common/propagation-loss-model-test-suite.cc (+133 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
  {
161
    Vector m_position;
162
    double m_pt;  // dBm
163
    double m_pr;  // W
164
    double m_tolerance;
165
  } TestVector;
166
  
167
  TestVectors<TestVector> m_testVectors;
168
};
169
170
TwoRayGroundPropagationLossModelTestCase::TwoRayGroundPropagationLossModelTestCase ()
171
: TestCase ("Check to see that the ns-3 TwoRayGround propagation loss model provides correct received power"),
172
m_testVectors ()
173
{
174
}
175
176
TwoRayGroundPropagationLossModelTestCase::~TwoRayGroundPropagationLossModelTestCase ()
177
{
178
}
179
180
bool
181
TwoRayGroundPropagationLossModelTestCase::DoRun (void)
182
{
183
  // wavelength at 2.4 GHz is 0.125m
184
  Config::SetDefault ("ns3::TwoRayGroundPropagationLossModel::Lambda", DoubleValue (0.125));
185
  Config::SetDefault ("ns3::TwoRayGroundPropagationLossModel::SystemLoss", DoubleValue (1.0));
186
  
187
  // set antenna height to 1.5m above z coordinate
188
  Config::SetDefault ("ns3::TwoRayGroundPropagationLossModel::HeightAboveZ", DoubleValue (1.5));
189
  
190
  // Select a reference transmit power of 17.0206 dBm
191
  // Pt = 10^(17.0206/10)/10^3 = .05035702 W
192
  double txPowerW = 0.05035702;
193
  double txPowerdBm = 10 * log10 (txPowerW) + 30;
194
  
195
  //
196
  // As with the Friis tests above, we want to test the propagation loss 
197
  // model calculations at a few chosen distances and compare the results 
198
  // to those we can manually calculate. Let us test the ns-3 calculated 
199
  // value for agreement to be within 5e-16, as above.
200
  //
201
  TestVector testVector;
202
  
203
  // Below the Crossover distance use Friis so this test should be the same as that above
204
  // Crossover = (4 * PI * TxAntennaHeight * RxAntennaHeight) / Lamdba
205
  // Crossover = (4 * PI * 1.5 * 1.5) / 0.125 = 226.1946m
206
  
207
  testVector.m_position = Vector (100, 0, 0);
208
  testVector.m_pt = txPowerdBm;
209
  testVector.m_pr = 4.98265e-10;
210
  testVector.m_tolerance = 5e-16;
211
  m_testVectors.Add (testVector);
212
  
213
  // These values are above the crossover distance and therefore use the Two Ray calculation
214
  
215
  testVector.m_position = Vector (500, 0, 0);
216
  testVector.m_pt = txPowerdBm;
217
  testVector.m_pr = 4.07891862e-12;
218
  testVector.m_tolerance = 5e-16;
219
  m_testVectors.Add (testVector);
220
  
221
  testVector.m_position = Vector (1000, 0, 0);
222
  testVector.m_pt = txPowerdBm;
223
  testVector.m_pr = 2.5493241375e-13;
224
  testVector.m_tolerance = 5e-16;
225
  m_testVectors.Add (testVector);
226
  
227
  testVector.m_position = Vector (2000, 0, 0);
228
  testVector.m_pt = txPowerdBm;
229
  testVector.m_pr = 1.593327585938e-14;
230
  testVector.m_tolerance = 5e-16;
231
  m_testVectors.Add (testVector);
232
  
233
  // Repeat the tests for non-zero z coordinates
234
  
235
  // Pr = (0.05035702 * (1.5*1.5) * (2.5*2.5)) / (500*500*500*500) = 1.13303295e-11
236
  // dCross = (4 * pi * 1.5 * 2.5) / 0.125 = 376.99m
237
  testVector.m_position = Vector (500, 0, 1);
238
  testVector.m_pt = txPowerdBm;
239
  testVector.m_pr = 1.13303295e-11;
240
  testVector.m_tolerance = 5e-16;
241
  m_testVectors.Add (testVector);
242
  
243
  // Pr = (0.05035702 * (1.5*1.5) * (5.5*5.5)) / (1000*1000*1000*1000) = 3.42742467375e-12
244
  // dCross = (4 * pi * 1.5 * 5.5) / 0.125 = 829.38m
245
  testVector.m_position = Vector (1000, 0, 4);
246
  testVector.m_pt = txPowerdBm;
247
  testVector.m_pr = 3.42742467375e-12;
248
  testVector.m_tolerance = 5e-16;
249
  m_testVectors.Add (testVector);
250
  
251
  // Pr = (0.05035702 * (1.5*1.5) * (11.5*11.5)) / (2000*2000*2000*2000) = 9.36522547734e-13
252
  // dCross = (4 * pi * 1.5 * 11.5) / 0.125 = 1734.15m
253
  testVector.m_position = Vector (2000, 0, 10);
254
  testVector.m_pt = txPowerdBm;
255
  testVector.m_pr = 9.36522547734e-13;
256
  testVector.m_tolerance = 5e-16;
257
  m_testVectors.Add (testVector);
258
  
259
  
260
  // Now, check that the received power values are expected
261
  
262
  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> (); 
263
  a->SetPosition (Vector (0,0,0));
264
  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> (); 
265
  
266
  Ptr<TwoRayGroundPropagationLossModel> lossModel = CreateObject<TwoRayGroundPropagationLossModel> (); 
267
  for (uint32_t i = 0; i < m_testVectors.GetN (); ++i)
268
  {
269
    testVector = m_testVectors.Get (i);
270
    b->SetPosition (testVector.m_position);
271
    double resultdBm = lossModel->CalcRxPower (testVector.m_pt, a, b);
272
    double resultW =   pow (10.0, resultdBm / 10.0) / 1000;
273
    NS_TEST_EXPECT_MSG_EQ_TOL (resultW, testVector.m_pr, testVector.m_tolerance, "Got unexpected rcv power");
274
  }
275
  
276
  return GetErrorStatus ();
277
}
278
279
148
class LogDistancePropagationLossModelTestCase : public TestCase
280
class LogDistancePropagationLossModelTestCase : public TestCase
149
{
281
{
150
public:
282
public:
 Lines 244-249    Link Here 
244
  : TestSuite ("propagation-loss-model", UNIT)
376
  : TestSuite ("propagation-loss-model", UNIT)
245
{
377
{
246
  AddTestCase (new FriisPropagationLossModelTestCase);
378
  AddTestCase (new FriisPropagationLossModelTestCase);
379
  AddTestCase (new TwoRayGroundPropagationLossModelTestCase);
247
  AddTestCase (new LogDistancePropagationLossModelTestCase);
380
  AddTestCase (new LogDistancePropagationLossModelTestCase);
248
}
381
}
249
382
(-)a/src/common/propagation-loss-model.cc (+171 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 231-236    Link Here 
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;
233
}
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
}
276
void
277
TwoRayGroundPropagationLossModel::SetSystemLoss (double systemLoss)
278
{
279
  m_systemLoss = systemLoss;
280
}
281
double
282
TwoRayGroundPropagationLossModel::GetSystemLoss (void) const
283
{
284
  return m_systemLoss;
285
}
286
void
287
TwoRayGroundPropagationLossModel::SetMinDistance (double minDistance)
288
{
289
  m_minDistance = minDistance;
290
}
291
double
292
TwoRayGroundPropagationLossModel::GetMinDistance (void) const
293
{
294
  return m_minDistance;
295
}
296
void
297
TwoRayGroundPropagationLossModel::SetHeightAboveZ (double heightAboveZ)
298
{
299
  m_heightAboveZ = heightAboveZ;
300
}
301
void 
302
TwoRayGroundPropagationLossModel::SetLambda (double frequency, double speed)
303
{
304
  m_lambda = speed / frequency;
305
}
306
void 
307
TwoRayGroundPropagationLossModel::SetLambda (double lambda)
308
{
309
  m_lambda = lambda;
310
}
311
double 
312
TwoRayGroundPropagationLossModel::GetLambda (void) const
313
{
314
  return m_lambda;
315
}
316
317
double 
318
TwoRayGroundPropagationLossModel::DbmToW (double dbm) const
319
{
320
  double mw = pow (10.0,dbm / 10.0);
321
  return mw / 1000.0;
322
}
323
324
double
325
TwoRayGroundPropagationLossModel::DbmFromW (double w) const
326
{
327
  double dbm = log10 (w * 1000.0) * 10.0;
328
  return dbm;
329
}
330
331
double 
332
TwoRayGroundPropagationLossModel::DoCalcRxPower (double txPowerDbm,
333
                                                 Ptr<MobilityModel> a,
334
                                                 Ptr<MobilityModel> b) const
335
{
336
  /*
337
   * Two-Ray Ground equation:
338
   *
339
   * where Pt, Gt and Gr are in dBm units
340
   * L, Ht and Hr are in meter units.
341
   *
342
   *   Pr      Gt * Gr * (Ht^2 * Hr^2)
343
   *   -- =  (-------------------------)
344
   *   Pt            d^4 * L
345
   *
346
   * Gt: tx gain (unit-less)
347
   * Gr: rx gain (unit-less)
348
   * Pt: tx power (dBm)
349
   * d: distance (m)
350
   * L: system loss
351
   * Ht: Tx antenna height (m)
352
   * Hr: Rx antenna height (m)
353
   * lambda: wavelength (m)
354
   *
355
   * As with the Friis model we ignore tx and rx gain and output values
356
   * are in dB or dBm
357
   *
358
   *                      (Ht * Ht) * (Hr * Hr)
359
   * rx = tx + 10 log10 (-----------------------)
360
   *                      (d * d * d * d) * L
361
   */
362
  double distance = a->GetDistanceFrom (b);
363
  if (distance <= m_minDistance)
364
    {
365
      return txPowerDbm;
366
    }
367
368
  // Set the height of the Tx and Rx antennae
369
  double txAntHeight = a->GetPosition ().z + m_heightAboveZ;
370
  double rxAntHeight = b->GetPosition ().z + m_heightAboveZ;
371
372
  // Calculate a crossover distance, under which we use Friis
373
  /*
374
   * 
375
   * dCross = (4 * pi * Ht * Hr) / lambda
376
   *
377
   */
378
379
  double dCross = (4 * PI * txAntHeight * rxAntHeight) / GetLambda ();
380
  double tmp = 0;
381
  if (distance <= dCross)
382
    {
383
      // We use Friis
384
      double numerator = m_lambda * m_lambda;
385
      tmp = PI * distance;
386
      double denominator = 16 * tmp * tmp * m_systemLoss;
387
      double pr = 10 * log10 (numerator / denominator);
388
      NS_LOG_DEBUG ("Receiver within crossover (" << dCross << "m) for Two_ray path; using Friis");
389
      NS_LOG_DEBUG ("distance=" << distance << "m, attenuation coefficient=" << pr << "dB");
390
      return txPowerDbm + pr;
391
    }
392
  else   // Use Two-Ray Pathloss
393
    {
394
      tmp = txAntHeight * rxAntHeight;
395
      double rayNumerator = tmp * tmp;
396
      tmp = distance * distance;
397
      double rayDenominator = tmp * tmp * m_systemLoss;
398
      double rayPr = 10 * log10 (rayNumerator / rayDenominator);
399
      NS_LOG_DEBUG ("distance=" << distance << "m, attenuation coefficient=" << rayPr << "dB");
400
      return txPowerDbm + rayPr;
401
402
    }
403
}
404
234
405
235
// ------------------------------------------------------------------------- //
406
// ------------------------------------------------------------------------- //
236
407
(-)a/src/common/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 two ray ground model
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 consistent 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