1.1 --- a/src/devices/uan/uan-phy-gen.cc Wed Apr 01 01:35:43 2009 -0700
1.2 +++ b/src/devices/uan/uan-phy-gen.cc Wed Apr 01 16:00:30 2009 -0700
1.3 @@ -31,6 +31,7 @@
1.4 #include "ns3/log.h"
1.5 #include "ns3/uan-tx-mode.h"
1.6 #include "ns3/node.h"
1.7 +#include "ns3/uinteger.h"
1.8
1.9 #include <iostream>
1.10 NS_LOG_COMPONENT_DEFINE("UanPhyGen");
1.11 @@ -41,6 +42,8 @@
1.12 NS_OBJECT_ENSURE_REGISTERED (UanPhyGen);
1.13 NS_OBJECT_ENSURE_REGISTERED (UanPhyPerGenDefault);
1.14 NS_OBJECT_ENSURE_REGISTERED (UanPhyCalcSinrDefault);
1.15 +NS_OBJECT_ENSURE_REGISTERED (UanPhyCalcSinrFhFsk);
1.16 +NS_OBJECT_ENSURE_REGISTERED (UanPhyPerUmodem);
1.17
1.18 UanPhyCalcSinrDefault::UanPhyCalcSinrDefault()
1.19 {
1.20 @@ -61,80 +64,92 @@
1.21 return tid;
1.22 }
1.23
1.24 -//Model of interference calculation for FH-FSK wherein all nodes
1.25 -//use an identical hopping pattern. In this case, there is an (M-1)*SymbolTime
1.26 -//clearing time between symbols transmitted on the same frequency.
1.27 -//This clearing time combats ISI from channel delay spread and also has
1.28 -//a byproduct of possibly reducing interference from other transmitted packets.
1.29 -//double
1.30 -//UanPhyCalcSinrFhFsk::CalcSinrDb(Ptr<Packet> pkt,
1.31 -// Time arrTime,
1.32 -// double rxPowerDb,
1.33 -// double ambNoiseDb,
1.34 -// UanTxMode mode,
1.35 -// UanPdp pdp,
1.36 -// const UanTransducer::ArrivalList &arrivalList) const
1.37 -//{
1.38 -// if(mode.GetModType() == UanTxMode::OTHER)
1.39 -// NS_LOG_WARN("Calculating SINR for unsupported modulation type");
1.40 -//
1.41 -//
1.42 -//
1.43 -//
1.44 -// double intKp = -DbToKp(rxPowerDb); //This packet is in the arrivalList
1.45 -// UanTransducer::ArrivalList::const_iterator it = arrivalList.begin();
1.46 -// for(;it != arrivalList.end();it++)
1.47 -// {
1.48 -// UanPdp intPdp = it->GetPdp();
1.49 -// double tDelta = arrTime.GetSeconds() - it->GetArrivalTime().GetSeconds();
1.50 -// //We want tDelta in terms of a single symbol (i.e. if tDelta = 7.3 symbol+clearing
1.51 -// //times, the offset in terms of the currently arriving symbol is still
1.52 -// //0.3 symbol+clearing times.
1.53 -// int16_t sign = (arrTime>0) ? 1 : -1;
1.54 -// double symTime = it->GetMode()->GetSymbolTime().GetSeconds() + it->GetMode()->GetClearingTime().GetSeconds();
1.55 -// int32_t syms = abs(tDelta / symTime);
1.56 -// tDelta = tDelta - sign*syms*symTime;
1.57 -//
1.58 -// double power = 0.0;
1.59 -// if(tDelta > 0)
1.60 -// {
1.61 -// if(tDelta < mode.GetSymbolTime())
1.62 -// {
1.63 -// power += intPdp.SumTapsNc(0, mode->GetSymbolTime() - Seconds(tDelta));
1.64 -// power += intPdp.SumTapsNc(mode->GetSymbolTime() - Seconds(tDelta) + mode->GetClearingTime(),
1.65 -// 2*mode->GetSymbolTime() - Seconds(tDelta) + mode->GetClearingTime());
1.66 -// }
1.67 -// else
1.68 -// {
1.69 -// Time start = mode->GetSymbolTime() + mode->GetClearingTime() - Seconds(tDelta);
1.70 -// Time end = start + mode->GetSymbolTime();
1.71 -// power += intPdp.SumTapsNc(start, end);
1.72 -//
1.73 -// start = start + mode->GetSymbolTime() + mode->GetClearingTime();
1.74 -// end = start + mode->GetSymbolTime();
1.75 -// power += intPdp.SumTapsNc(start, end);
1.76 -// }
1.77 -// }
1.78 -// else
1.79 -// {
1.80 -// tDelta = abs(tDelta);
1.81 -// if(tDelta < mode->GetClearingTime())
1.82 -// {
1.83 -// Time start = Seconds(tDelta);
1.84 -// Time end = mode->GetSymbolTime();
1.85 -// power += intPdp.SumTapsNc(start, end);
1.86 -//
1.87 -// Time
1.88 -// }
1.89 -// }
1.90 -// intKp += DbToKp(it->GetRxPowerDb());
1.91 -// }
1.92 -//
1.93 -// double totalIntDb = KpToDb(intKp + DbToKp(ambNoiseDb));
1.94 -//
1.95 -// NS_LOG_DEBUG("Calculating SINR: RxPower = " << rxPowerDb << " dB. Number of interferers = " << arrivalList.size() << " Interference + noise power = " << totalIntDb << " dB. SINR = " << rxPowerDb - totalIntDb << " dB.");
1.96 -// return rxPowerDb - totalIntDb;
1.97 -//}
1.98 +UanPhyCalcSinrFhFsk::UanPhyCalcSinrFhFsk()
1.99 +{
1.100 +
1.101 +}
1.102 +UanPhyCalcSinrFhFsk::~UanPhyCalcSinrFhFsk()
1.103 +{
1.104 +
1.105 +}
1.106 +
1.107 +TypeId
1.108 +UanPhyCalcSinrFhFsk::GetTypeId(void)
1.109 +{
1.110 + static TypeId tid = TypeId("ns3::UanPhyCalcSinrFhFsk")
1.111 + .SetParent<Object>()
1.112 + .AddConstructor<UanPhyCalcSinrFhFsk>()
1.113 + .AddAttribute("NumberOfHops",
1.114 + "Number of frequencies in hopping pattern",
1.115 + UintegerValue(13),
1.116 + MakeUintegerAccessor(&UanPhyCalcSinrFhFsk::m_hops),
1.117 + MakeUintegerChecker<uint32_t>())
1.118 + ;
1.119 + return tid;
1.120 +}
1.121 +double
1.122 +UanPhyCalcSinrFhFsk::CalcSinrDb(Ptr<Packet> pkt,
1.123 + Time arrTime,
1.124 + double rxPowerDb,
1.125 + double ambNoiseDb,
1.126 + UanTxMode mode,
1.127 + UanPdp pdp,
1.128 + const UanTransducer::ArrivalList &arrivalList) const
1.129 +{
1.130 + if(mode.GetModType() != UanTxMode::FSK)
1.131 + NS_LOG_WARN("Calculating SINR for unsupported mode type");
1.132 +
1.133 +
1.134 +
1.135 + double ts = 1.0 / mode.GetPhyRateSps();
1.136 + double clearingTime = (m_hops-1.0)*ts;
1.137 +
1.138 + double effRxPowerDb = rxPowerDb + KpToDb(pdp.SumTapsNc(Seconds(0), Seconds(ts)));
1.139 + double isiKpa = DbToKp(rxPowerDb)*pdp.SumTapsNc(Seconds(ts+clearingTime), Seconds(2.0*ts+clearingTime));
1.140 +
1.141 + UanTransducer::ArrivalList::const_iterator it = arrivalList.begin();
1.142 + double intKp = 0;
1.143 + for(;it != arrivalList.end();it++)
1.144 + {
1.145 + UanPdp intPdp = it->GetPdp();
1.146 + double tDelta = abs(arrTime.GetSeconds() - it->GetArrivalTime().GetSeconds());
1.147 + //We want tDelta in terms of a single symbol (i.e. if tDelta = 7.3 symbol+clearing
1.148 + //times, the offset in terms of the arriving symbol power is
1.149 + //0.3 symbol+clearing times.
1.150 +
1.151 + int32_t syms = (uint32_t) ( (double) tDelta / (ts + clearingTime));
1.152 + tDelta = tDelta - syms*(ts + clearingTime);
1.153 +
1.154 + if(arrTime < it->GetArrivalTime())
1.155 + tDelta = ts+clearingTime - tDelta;
1.156 +
1.157 + double intPower = 0.0;
1.158 + if(tDelta < ts)
1.159 + {
1.160 + intPower += intPdp.SumTapsNc(Seconds(0), Seconds(ts - tDelta));
1.161 + intPower += intPdp.SumTapsNc(Seconds(ts - tDelta + clearingTime),
1.162 + Seconds(2*ts - tDelta + clearingTime));
1.163 + }
1.164 + else
1.165 + {
1.166 + Time start = Seconds(ts + clearingTime - tDelta);
1.167 + Time end = start + Seconds(ts);
1.168 + intPower += intPdp.SumTapsNc(start, end);
1.169 +
1.170 + start = start + Seconds(ts+clearingTime);
1.171 + end = start + Seconds(ts);
1.172 + intPower += intPdp.SumTapsNc(start, end);
1.173 + }
1.174 + intKp += DbToKp(it->GetRxPowerDb()) * intPower;
1.175 + }
1.176 +
1.177 + double totalIntDb = KpToDb(isiKpa + intKp + DbToKp(ambNoiseDb));
1.178 +
1.179 + NS_LOG_DEBUG("Calculating SINR: RxPower = " << rxPowerDb << " dB. Effective Rx power " << effRxPowerDb << " dB. Number of interferers = " << arrivalList.size() << " Interference + noise power = " << totalIntDb << " dB. SINR = " << rxPowerDb - totalIntDb << " dB.");
1.180 + return effRxPowerDb - totalIntDb;
1.181 +}
1.182 +
1.183 +
1.184
1.185 double
1.186 UanPhyCalcSinrDefault::CalcSinrDb(Ptr<Packet> pkt,
1.187 @@ -157,7 +172,7 @@
1.188
1.189 //The default ignores mode data and assumes that all rxpower transmitted is
1.190 //captured by the receiver, and that all signal power associated with
1.191 - //interfering packets acts as additional noise.
1.192 + //interfering packets effects SINR identically to additional ambient noise.
1.193
1.194 double intKp = -DbToKp(rxPowerDb); //This packet is in the arrivalList
1.195 UanTransducer::ArrivalList::const_iterator it = arrivalList.begin();
1.196 @@ -211,6 +226,95 @@
1.197 }
1.198 }
1.199
1.200 +
1.201 +UanPhyPerUmodem::UanPhyPerUmodem()
1.202 +{
1.203 +
1.204 +}
1.205 +UanPhyPerUmodem::~UanPhyPerUmodem()
1.206 +{
1.207 +
1.208 +}
1.209 +
1.210 +TypeId UanPhyPerUmodem::GetTypeId(void)
1.211 +{
1.212 + static TypeId tid =
1.213 + TypeId("ns3::UanPhyPerUmodem")
1.214 + .SetParent<Object> ()
1.215 + .AddConstructor<UanPhyPerUmodem> ()
1.216 + ;
1.217 + return tid;
1.218 +}
1.219 +
1.220 +double
1.221 +UanPhyPerUmodem::nchoosek(uint32_t n, uint32_t k)
1.222 +{
1.223 + double result;
1.224 +
1.225 + result=1.0;
1.226 +
1.227 + for (uint32_t i = std::max(k,n-k) + 1; i <= n; ++i)
1.228 + result *= i;
1.229 +
1.230 + for (uint32_t i = 2; i <= std::min(k,n-k); ++i)
1.231 + result /= i;
1.232 +
1.233 + return result;
1.234 +}
1.235 +
1.236 +double
1.237 +UanPhyPerUmodem::CalcPer(double sinr, UanTxMode mode)
1.238 +{
1.239 + uint32_t d[] =
1.240 + { 12, 14, 16, 18, 20, 22, 24, 26, 28 };
1.241 + double Bd[] =
1.242 + { 33, 281, 2179, 15035LLU, 105166LLU, 692330LLU, 4580007LLU, 29692894LLU,
1.243 + 190453145LLU };
1.244 +
1.245 + //double Rc = 1.0 / 2.0;
1.246 + double ebno = std::pow(10.0, sinr / 10.0);
1.247 + double perror = 1.0 / (2.0 + ebno);
1.248 + double P[9];
1.249 +
1.250 + if (sinr >= 10)
1.251 + return 0;
1.252 + if (sinr <= 6)
1.253 + return 1;
1.254 +
1.255 + for (uint32_t r = 0; r < 9; r++)
1.256 + {
1.257 + double sumd = 0;
1.258 + for (uint32_t k = 0; k < d[r]; k++)
1.259 + {
1.260 + sumd = sumd + nchoosek(d[r] - 1 + k, k) * std::pow(1 - perror, (double) k);
1.261 + }
1.262 + P[r] = std::pow(perror, (double) d[r]) * sumd;
1.263 +
1.264 + }
1.265 +
1.266 + double Pb = 0;
1.267 + for (uint32_t r = 0; r < 8; r++)
1.268 + {
1.269 + Pb = Pb + Bd[r] * P[r];
1.270 + }
1.271 +
1.272 + //cout << "Pb = " << Pb << endl;
1.273 +
1.274 + double Ppacket = 1;
1.275 + double temp = nchoosek(288, 0);
1.276 + temp *= std::pow((1 - Pb), 288.0);
1.277 + Ppacket -= temp;
1.278 + temp = nchoosek(288, 1) * Pb * std::pow((1 - Pb), 287);
1.279 + Ppacket -= temp;
1.280 +
1.281 + //NS_LOG_DEBUG("Pb = " << Pb << " Prob of Packet error = " << Ppacket);
1.282 +
1.283 + if (Ppacket > 1)
1.284 + return 1;
1.285 + else
1.286 + return Ppacket;
1.287 +}
1.288 +
1.289 UanModesList
1.290 UanPhyGen::GetDefaultModes(void)
1.291 {
2.1 --- a/src/devices/uan/uan-phy-gen.h Wed Apr 01 01:35:43 2009 -0700
2.2 +++ b/src/devices/uan/uan-phy-gen.h Wed Apr 01 16:00:30 2009 -0700
2.3 @@ -34,9 +34,8 @@
2.4 /**
2.5 * \class UanPhyPerGenDefault
2.6 * \brief Default Packet Error Rate calculator for UanPhyGen
2.7 - * This class uses basic probability of error equations learned
2.8 - * in any wireless comms course. Not accurate for
2.9 - * underwater.
2.10 + * Considers no error if SINR is > user defined threshold
2.11 + * (configured by an attribute).
2.12 */
2.13 class UanPhyPerGenDefault : public UanPhyPer
2.14 {
2.15 @@ -52,6 +51,24 @@
2.16 };
2.17
2.18 /**
2.19 + * \class UanPhyPerUmodem
2.20 + * \brief Packet error rate calculation assuming WHOI Micromodem like PHY
2.21 + * Calculates PER assuming rate 1/2 convolutional code with constraint length 9
2.22 + * with soft decision viterbi decoding and a CRC capable of correcting 1 bit error
2.23 + */
2.24 +class UanPhyPerUmodem : public UanPhyPer
2.25 +{
2.26 +public:
2.27 + UanPhyPerUmodem();
2.28 + virtual ~UanPhyPerUmodem();
2.29 +
2.30 + static TypeId GetTypeId(void);
2.31 + virtual double CalcPer(double sinrDb, UanTxMode mode);
2.32 +private:
2.33 + double nchoosek(uint32_t n, uint32_t k);
2.34 +
2.35 +};
2.36 +/**
2.37 * \class UanPhyCalcSinrDefault
2.38 * \brief Default SINR calculator for UanPhyGen
2.39 */
2.40 @@ -73,6 +90,34 @@
2.41 };
2.42
2.43 /**
2.44 + * \class UanPhyCalcSinrFhFsk
2.45 + * \brief WHOI Micromodem like FH-FSK model
2.46 + *
2.47 + * Model of interference calculation for FH-FSK wherein all nodes
2.48 + * use an identical hopping pattern. In this case, there is an (M-1)*SymbolTime
2.49 + * clearing time between symbols transmitted on the same frequency.
2.50 + * This clearing time combats ISI from channel delay spread and also has
2.51 + * a byproduct of possibly reducing interference from other transmitted packets.
2.52 + */
2.53 +class UanPhyCalcSinrFhFsk : public UanPhyCalcSinr
2.54 +{
2.55 +
2.56 +public:
2.57 + UanPhyCalcSinrFhFsk();
2.58 + virtual ~UanPhyCalcSinrFhFsk();
2.59 + static TypeId GetTypeId(void);
2.60 + virtual double CalcSinrDb(Ptr<Packet> pkt,
2.61 + Time arrTime,
2.62 + double rxPowerDb,
2.63 + double ambNoiseDb,
2.64 + UanTxMode mode,
2.65 + UanPdp pdp,
2.66 + const UanTransducer::ArrivalList &arrivalList
2.67 + ) const;
2.68 + uint32_t m_hops;
2.69 +};
2.70 +
2.71 +/**
2.72 * \class UanPhyGen
2.73 * \brief Generic PHY model
2.74 */
3.1 --- a/src/devices/uan/uan-tx-mode.h Wed Apr 01 01:35:43 2009 -0700
3.2 +++ b/src/devices/uan/uan-tx-mode.h Wed Apr 01 16:00:30 2009 -0700
3.3 @@ -115,7 +115,10 @@
3.4
3.5 };
3.6
3.7 -
3.8 +/**
3.9 + * \class UanModesList
3.10 + * \brief Container for UanTxModes
3.11 + */
3.12 class UanModesList : public ns3::Object
3.13 {
3.14 public:
3.15 @@ -123,9 +126,23 @@
3.16 virtual ~UanModesList();
3.17 static TypeId GetTypeId(void);
3.18
3.19 + /**
3.20 + * \param mode Add mode to list
3.21 + */
3.22 void AppendMode(UanTxMode mode);
3.23 + /**
3.24 + * \brief delete mode at given index
3.25 + * \param num Index of mode to delete
3.26 + */
3.27 void DeleteMode(uint32_t num);
3.28 + /**
3.29 + * \param index Mode index
3.30 + * \returns mode at given index
3.31 + */
3.32 UanTxMode operator[](uint32_t index) const;
3.33 + /**
3.34 + * \returns Number of modes in list
3.35 + */
3.36 uint32_t GetNModes(void) const;
3.37
3.38