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

(-)a/src/uan/model/uan-phy-gen.cc (-26 / +168 lines)
 Lines 46-51    Link Here 
46
NS_OBJECT_ENSURE_REGISTERED (UanPhyCalcSinrDefault);
46
NS_OBJECT_ENSURE_REGISTERED (UanPhyCalcSinrDefault);
47
NS_OBJECT_ENSURE_REGISTERED (UanPhyCalcSinrFhFsk);
47
NS_OBJECT_ENSURE_REGISTERED (UanPhyCalcSinrFhFsk);
48
NS_OBJECT_ENSURE_REGISTERED (UanPhyPerUmodem);
48
NS_OBJECT_ENSURE_REGISTERED (UanPhyPerUmodem);
49
NS_OBJECT_ENSURE_REGISTERED (UanPhyPerCommonModes);
49
50
50
51
51
/*************** UanPhyCalcSinrDefault definition *****************/
52
/*************** UanPhyCalcSinrDefault definition *****************/
 Lines 130-142    Link Here 
130
                                 UanPdp pdp,
131
                                 UanPdp pdp,
131
                                 const UanTransducer::ArrivalList &arrivalList) const
132
                                 const UanTransducer::ArrivalList &arrivalList) const
132
{
133
{
133
  if (mode.GetModType () != UanTxMode::FSK)
134
  if ((mode.GetModType () != UanTxMode::FSK) && (mode.GetConstellationSize () != 13))
134
    {
135
    {
135
      NS_LOG_WARN ("Calculating SINR for unsupported mode type");
136
      NS_FATAL_ERROR ("Calculating SINR for unsupported mode type");
136
    }
137
    }
137
138
138
139
140
  double ts = 1.0 / mode.GetPhyRateSps ();
139
  double ts = 1.0 / mode.GetPhyRateSps ();
141
  double clearingTime = (m_hops - 1.0) * ts;
140
  double clearingTime = (m_hops - 1.0) * ts;
142
  double csp = pdp.SumTapsFromMaxNc (Seconds (0), Seconds (ts));
141
  double csp = pdp.SumTapsFromMaxNc (Seconds (0), Seconds (ts));
 Lines 243-248    Link Here 
243
    }
242
    }
244
}
243
}
245
244
245
/*************** UanPhyPerCommonModes definition *****************/
246
UanPhyPerCommonModes::UanPhyPerCommonModes ()
247
  : UanPhyPer ()
248
{
249
250
}
251
252
UanPhyPerCommonModes::~UanPhyPerCommonModes ()
253
{
254
255
}
256
257
TypeId
258
UanPhyPerCommonModes::GetTypeId (void)
259
{
260
  static TypeId tid = TypeId ("ns3::UanPhyPerCommonModes")
261
    .SetParent<UanPhyPer> ()
262
    .SetGroupName ("Uan")
263
    .AddConstructor<UanPhyPerCommonModes> ();
264
265
  return tid;
266
}
267
268
double
269
UanPhyPerCommonModes::CalcPer (Ptr<Packet> pkt, double sinrDb, UanTxMode mode)
270
{
271
  NS_LOG_FUNCTION (this);
272
273
  double EbNo = std::pow (10.0, sinrDb / 10.0);
274
  double BER = 1.0;
275
  double PER = 0.0;
276
277
  switch (mode.GetModType ())
278
    {
279
    case UanTxMode::PSK:
280
      switch (mode.GetConstellationSize ())
281
        {
282
        case 2:         // BPSK
283
          {
284
            BER = 0.5 * erfc (sqrt (EbNo));
285
            break;
286
          }
287
        case 4:         // QPSK, half BPSK EbNo
288
          {
289
            BER = 0.5 * erfc (sqrt (0.5 * EbNo));
290
            break;
291
          }
292
293
        default:
294
          NS_FATAL_ERROR ("constellation " << mode.GetConstellationSize () << " not supported");
295
          break;
296
        }
297
298
    // taken from Ronell B. Sicat, "Bit Error Probability Computations for M-ary Quadrature Amplitude Modulation",
299
    // EE 242 Digital Communications and Codings, 2009
300
    case UanTxMode::QAM:
301
      {
302
        // generic EbNo
303
        EbNo *= mode.GetDataRateBps () / mode.GetBandwidthHz ();
304
305
        double M = (double) mode.GetConstellationSize ();
306
307
        // standard squared quantized QAM, even number of bits per symbol supported
308
        int log2sqrtM = (int) ::std::log2 ( sqrt (M));
309
310
        double log2M = ::std::log2 (M);
311
312
        if ((int)log2M % 2)
313
          {
314
            NS_FATAL_ERROR ("constellation " << M << " not supported");
315
          }
316
317
        double sqrtM = ::std::sqrt (M);
318
319
        NS_LOG_DEBUG ("M=" << M << "; log2sqrtM=" << log2sqrtM << "; log2M=" << log2M << "; sqrtM=" << sqrtM);
320
321
        BER = 0.0;
322
323
        // Eq (75)
324
        for (int k = 0; k < log2sqrtM; k++)
325
          {
326
            int sum_items = (int) ((1.0 - ::std::pow ( 2.0, (-1.0) * (double) k)) * ::std::sqrt (M) - 1.0);
327
            double pow2k = ::std::pow (2.0, (double) k - 1.0);
328
329
            NS_LOG_DEBUG ("k=" << k << "; sum_items=" << sum_items << "; pow2k=" << pow2k);
330
331
            double PbK = 0;
332
333
            // Eq (74)
334
            for (int j = 0; j < sum_items; ++j)
335
              {
336
                PbK += ::std::pow (-1.0, (double) j * pow2k / sqrtM)
337
                  * (pow2k - ::std::floor ( (double) (j * pow2k / sqrtM) - 0.5))
338
                  * erfc ((2.0 * (double)j + 1.0) * ::std::sqrt (3.0 * (log2M * EbNo) / (2.0 * (M - 1.0))));
339
340
                NS_LOG_DEBUG ("j=" << j << "; PbK=" << PbK);
341
342
              }
343
            PbK *= 1.0 / sqrtM;
344
345
            BER += PbK;
346
347
            NS_LOG_DEBUG ("k=" << k << "; PbK=" << PbK << "; BER=" << BER);
348
          }
349
350
        BER *= 1.0 / (double) log2sqrtM;
351
352
        break;
353
      }
354
355
    case UanTxMode::FSK:
356
      switch (mode.GetConstellationSize ())
357
        {
358
        case 2:
359
          {
360
            BER = 0.5 * erfc (sqrt (0.5 * EbNo));
361
            break;
362
          }
363
364
        default:
365
          NS_FATAL_ERROR ("constellation " << mode.GetConstellationSize () << " not supported");
366
          break;
367
        }
368
369
    default:     // OTHER and error
370
      NS_FATAL_ERROR ("Mode " << mode.GetModType () << " not supported");
371
      break;
372
    }
373
374
  PER = (1.0 - pow (1.0 - BER, (double) pkt->GetSize () * 8.0));
375
376
  NS_LOG_DEBUG ("BER=" << BER << "; PER=" << PER);
377
378
  return PER;
379
}
380
246
/*************** UanPhyPerUmodem definition *****************/
381
/*************** UanPhyPerUmodem definition *****************/
247
UanPhyPerUmodem::UanPhyPerUmodem ()
382
UanPhyPerUmodem::UanPhyPerUmodem ()
248
{
383
{
 Lines 299-304    Link Here 
299
  double perror = 1.0 / (2.0 + ebno);
434
  double perror = 1.0 / (2.0 + ebno);
300
  double P[9];
435
  double P[9];
301
436
437
  if ((mode.GetModType () != UanTxMode::FSK) && (mode.GetConstellationSize () != 13))
438
    {
439
      NS_FATAL_ERROR ("Calculating SINR for unsupported mode type");
440
    }
302
  if (sinr >= 10)
441
  if (sinr >= 10)
303
    {
442
    {
304
      return 0;
443
      return 0;
 Lines 425-434    Link Here 
425
UanPhyGen::GetDefaultModes (void)
564
UanPhyGen::GetDefaultModes (void)
426
{
565
{
427
  UanModesList l;
566
  UanModesList l;
428
  l.AppendMode (UanTxModeFactory::CreateMode (UanTxMode::FSK,80,80,22000,4000,13,"FSK"));
567
  l.AppendMode (UanTxModeFactory::CreateMode (UanTxMode::FSK, 80,  80,  22000, 4000, 13, "FH-FSK")); // micromodem only
429
  l.AppendMode (UanTxModeFactory::CreateMode (UanTxMode::PSK,200, 200, 22000, 4000, 4, "QPSK"));
568
  l.AppendMode (UanTxModeFactory::CreateMode (UanTxMode::PSK, 200, 200, 22000, 4000, 4,  "QPSK"));
569
  l.AppendMode (UanTxModeFactory::CreateMode (UanTxMode::PSK, 5000, 5000, 25000, 5000, 4,  "QPSK")); // micromodem2
570
430
  return l;
571
  return l;
431
}
572
}
573
432
TypeId
574
TypeId
433
UanPhyGen::GetTypeId (void)
575
UanPhyGen::GetTypeId (void)
434
{
576
{
 Lines 513-527    Link Here 
513
  NS_LOG_FUNCTION (this);
655
  NS_LOG_FUNCTION (this);
514
  NS_LOG_DEBUG ("Energy depleted at node " << m_device->GetNode ()->GetId () <<
656
  NS_LOG_DEBUG ("Energy depleted at node " << m_device->GetNode ()->GetId () <<
515
                ", stopping rx/tx activities");
657
                ", stopping rx/tx activities");
516
  
658
517
  m_state = DISABLED;
659
  m_state = DISABLED;
518
  if(m_txEndEvent.IsRunning ())
660
  if (m_txEndEvent.IsRunning ())
519
    {
661
    {
520
      Simulator::Cancel (m_txEndEvent);
662
      Simulator::Cancel (m_txEndEvent);
521
      NotifyTxDrop (m_pktTx);
663
      NotifyTxDrop (m_pktTx);
522
      m_pktTx = 0;
664
      m_pktTx = 0;
523
    }
665
    }
524
  if(m_rxEndEvent.IsRunning ())
666
  if (m_rxEndEvent.IsRunning ())
525
    {
667
    {
526
      Simulator::Cancel (m_rxEndEvent);
668
      Simulator::Cancel (m_rxEndEvent);
527
      NotifyRxDrop (m_pktRx);
669
      NotifyRxDrop (m_pktRx);
 Lines 602-608    Link Here 
602
}
744
}
603
745
604
void
746
void
605
UanPhyGen::RegisterListener (UanPhyListener *listener)
747
UanPhyGen::RegisterListener (UanPhyListener * listener)
606
{
748
{
607
  m_listeners.push_back (listener);
749
  m_listeners.push_back (listener);
608
}
750
}
 Lines 618-627    Link Here 
618
    {
760
    {
619
    case DISABLED:
761
    case DISABLED:
620
      NS_LOG_DEBUG ("Energy depleted, node cannot receive any packet. Dropping.");
762
      NS_LOG_DEBUG ("Energy depleted, node cannot receive any packet. Dropping.");
621
      NotifyRxDrop(pkt);    // traced source netanim
763
      NotifyRxDrop (pkt); // traced source netanim
622
      return;
764
      return;
623
    case TX:
765
    case TX:
624
      NotifyRxDrop(pkt);    // traced source netanim
766
      NotifyRxDrop (pkt); // traced source netanim
625
      NS_ASSERT (false);
767
      NS_ASSERT (false);
626
      break;
768
      break;
627
    case RX:
769
    case RX:
 Lines 630-636    Link Here 
630
        double newSinrDb = CalculateSinrDb (m_pktRx, m_pktRxArrTime, m_rxRecvPwrDb, m_pktRxMode, m_pktRxPdp);
772
        double newSinrDb = CalculateSinrDb (m_pktRx, m_pktRxArrTime, m_rxRecvPwrDb, m_pktRxMode, m_pktRxPdp);
631
        m_minRxSinrDb  =  (newSinrDb < m_minRxSinrDb) ? newSinrDb : m_minRxSinrDb;
773
        m_minRxSinrDb  =  (newSinrDb < m_minRxSinrDb) ? newSinrDb : m_minRxSinrDb;
632
        NS_LOG_DEBUG ("PHY " << m_mac->GetAddress () << ": Starting RX in RX mode.  SINR of pktRx = " << m_minRxSinrDb);
774
        NS_LOG_DEBUG ("PHY " << m_mac->GetAddress () << ": Starting RX in RX mode.  SINR of pktRx = " << m_minRxSinrDb);
633
        NotifyRxBegin(pkt);    // traced source netanim
775
        NotifyRxBegin (pkt); // traced source netanim
634
      }
776
      }
635
      break;
777
      break;
636
778
 Lines 659-665    Link Here 
659
          {
801
          {
660
            m_state = RX;
802
            m_state = RX;
661
            UpdatePowerConsumption (RX);
803
            UpdatePowerConsumption (RX);
662
            NotifyRxBegin(pkt);    // traced source netanim
804
            NotifyRxBegin (pkt); // traced source netanim
663
            m_rxRecvPwrDb = rxPowerDb;
805
            m_rxRecvPwrDb = rxPowerDb;
664
            m_minRxSinrDb = newsinr;
806
            m_minRxSinrDb = newsinr;
665
            m_pktRx = pkt;
807
            m_pktRx = pkt;
 Lines 675-681    Link Here 
675
      break;
817
      break;
676
    case SLEEP:
818
    case SLEEP:
677
      NS_LOG_DEBUG ("Sleep mode. Dropping packet.");
819
      NS_LOG_DEBUG ("Sleep mode. Dropping packet.");
678
      NotifyRxDrop(pkt);    // traced source netanim
820
      NotifyRxDrop (pkt); // traced source netanim
679
      break;
821
      break;
680
    }
822
    }
681
823
 Lines 699-709    Link Here 
699
    {
841
    {
700
      NS_LOG_DEBUG ("Sleep mode or dead. Dropping packet");
842
      NS_LOG_DEBUG ("Sleep mode or dead. Dropping packet");
701
      m_pktRx = 0;
843
      m_pktRx = 0;
702
      NotifyRxDrop(pkt);    // traced source netanim
844
      NotifyRxDrop (pkt); // traced source netanim
703
      return;
845
      return;
704
    }
846
    }
705
847
706
  NotifyRxEnd(pkt);    // traced source netanim
848
  NotifyRxEnd (pkt); // traced source netanim
707
  if (GetInterferenceDb ( (Ptr<Packet>) 0) > m_ccaThreshDb)
849
  if (GetInterferenceDb ( (Ptr<Packet>) 0) > m_ccaThreshDb)
708
    {
850
    {
709
      m_state = CCABUSY;
851
      m_state = CCABUSY;
 Lines 868-883    Link Here 
868
}
1010
}
869
1011
870
void
1012
void
871
UanPhyGen::SetSleepMode (bool sleep)
1013
UanPhyGen::SetSleepMode (bool sleep )
872
{
1014
{
873
  if (sleep)
1015
  if (sleep )
874
    {
1016
  {
875
      m_state = SLEEP;
1017
    m_state = SLEEP;
876
      if (!m_energyCallback.IsNull ())
1018
    if (!m_energyCallback.IsNull ())
877
        {
1019
      {
878
          m_energyCallback (SLEEP);
1020
        m_energyCallback (SLEEP);
879
        }
1021
      }
880
    }
1022
  }
881
  else if (m_state == SLEEP)
1023
  else if (m_state == SLEEP)
882
    {
1024
    {
883
      if (GetInterferenceDb ((Ptr<Packet>) 0) > m_ccaThreshDb)
1025
      if (GetInterferenceDb ((Ptr<Packet>) 0) > m_ccaThreshDb)
(-)a/src/uan/model/uan-phy-gen.h (-10 / +47 lines)
 Lines 54-72    Link Here 
54
   * \return The TypeId.
54
   * \return The TypeId.
55
   */
55
   */
56
  static TypeId GetTypeId (void);
56
  static TypeId GetTypeId (void);
57
  
57
58
  virtual double CalcPer (Ptr<Packet> pkt, double sinrDb, UanTxMode mode);
58
  virtual double CalcPer (Ptr<Packet> pkt, double sinrDb, UanTxMode mode);
59
private:
59
private:
60
  
61
  double m_thresh;  //!< SINR threshold.
60
  double m_thresh;  //!< SINR threshold.
62
61
63
};  // class UanPhyPerGenDefault
62
};  // class UanPhyPerGenDefault
64
63
65
  
64
66
/**
65
/**
67
 * \ingroup uan
66
 * \ingroup uan
68
 *
67
 *
69
 * Packet error rate calculation assuming WHOI Micromodem-like PHY.
68
 * Packet error rate calculation assuming WHOI Micromodem-like PHY (FH-FSK)
70
 *
69
 *
71
 * Calculates PER assuming rate 1/2 convolutional code with
70
 * Calculates PER assuming rate 1/2 convolutional code with
72
 * constraint length 9 with soft decision viterbi decoding and
71
 * constraint length 9 with soft decision viterbi decoding and
 Lines 119-124    Link Here 
119
/**
118
/**
120
 * \ingroup uan
119
 * \ingroup uan
121
 *
120
 *
121
 * Packet error rate calculation for common tx modes based on UanPhyPerUmodem
122
 *
123
 * Calculates PER for common UanTxMode modulations, by deriving
124
 * PER from the BER taken from well known literature's formulas.
125
 */
126
class UanPhyPerCommonModes : public UanPhyPer
127
{
128
public:
129
  /** Constructor */
130
  UanPhyPerCommonModes ();
131
  /** Destructor */
132
  virtual ~UanPhyPerCommonModes ();
133
134
  /**
135
   * Register this type.
136
   * \return The TypeId.
137
   */
138
  static TypeId GetTypeId (void);
139
140
  /**
141
   * Calculate the Packet ERror probability based on
142
   * SINR at the receiver and a tx mode.
143
   *
144
   * This implementation calculates PER for common UanTxMode modulations,
145
   * by deriving PER from the BER taken from literature's formulas.
146
   *
147
   * \param pkt Packet which is under consideration.
148
   * \param sinrDb SINR at receiver.
149
   * \param mode TX mode used to transmit packet.
150
   * \return Probability of packet error.
151
   */
152
  virtual double CalcPer (Ptr<Packet> pkt, double sinrDb, UanTxMode mode);
153
154
};  // class UanPhyPerCommonModes
155
156
157
/**
158
 * \ingroup uan
159
 *
122
 * Default SINR calculator for UanPhyGen.
160
 * Default SINR calculator for UanPhyGen.
123
 *
161
 *
124
 * The default ignores mode data and assumes that all rxpower transmitted is
162
 * The default ignores mode data and assumes that all rxpower transmitted is
 Lines 133-145    Link Here 
133
  UanPhyCalcSinrDefault ();
171
  UanPhyCalcSinrDefault ();
134
  /** Destructor */
172
  /** Destructor */
135
  virtual ~UanPhyCalcSinrDefault ();
173
  virtual ~UanPhyCalcSinrDefault ();
136
  
174
137
  /**
175
  /**
138
   * Register this type.
176
   * Register this type.
139
   * \return The TypeId.
177
   * \return The TypeId.
140
   */
178
   */
141
  static TypeId GetTypeId (void);
179
  static TypeId GetTypeId (void);
142
  
180
143
  /**
181
  /**
144
   * Calculate the SINR value for a packet.
182
   * Calculate the SINR value for a packet.
145
   *
183
   *
 Lines 186-192    Link Here 
186
  UanPhyCalcSinrFhFsk ();
224
  UanPhyCalcSinrFhFsk ();
187
  /** Destructor */
225
  /** Destructor */
188
  virtual ~UanPhyCalcSinrFhFsk ();
226
  virtual ~UanPhyCalcSinrFhFsk ();
189
  
227
190
  /**
228
  /**
191
   * Register this type.
229
   * Register this type.
192
   * \return The TypeId.
230
   * \return The TypeId.
 Lines 231-237    Link Here 
231
   */
269
   */
232
  static UanModesList GetDefaultModes (void);
270
  static UanModesList GetDefaultModes (void);
233
271
234
  
235
  /**
272
  /**
236
   * Register this type.
273
   * Register this type.
237
   * \return The TypeId.
274
   * \return The TypeId.
 Lines 308-314    Link Here 
308
  UanTxMode m_pktRxMode;            //!< Packet transmission mode at receiver.
345
  UanTxMode m_pktRxMode;            //!< Packet transmission mode at receiver.
309
346
310
  bool m_cleared;                   //!< Flag when we've been cleared.
347
  bool m_cleared;                   //!< Flag when we've been cleared.
311
  
348
312
  EventId m_txEndEvent;             //!< Tx event
349
  EventId m_txEndEvent;             //!< Tx event
313
  EventId m_rxEndEvent;             //!< Rx event
350
  EventId m_rxEndEvent;             //!< Rx event
314
351
 Lines 385-391    Link Here 
385
422
386
423
387
  /** Call UanListener::NotifyRxStart on all listeners. */
424
  /** Call UanListener::NotifyRxStart on all listeners. */
388
  void NotifyListenersRxStart (void);  
425
  void NotifyListenersRxStart (void);
389
  /** Call UanListener::NotifyRxEndOk on all listeners. */
426
  /** Call UanListener::NotifyRxEndOk on all listeners. */
390
  void NotifyListenersRxGood (void);
427
  void NotifyListenersRxGood (void);
391
  /** Call UanListener::NotifyRxEndError on all listeners. */
428
  /** Call UanListener::NotifyRxEndError on all listeners. */

Return to bug 2588