![]() |
User Manual, Developers Guide and API Documentation |
![]() |
00001 /****************************************************************************** 00002 * WiFiMac * 00003 * This file is part of openWNS (open Wireless Network Simulator) 00004 * _____________________________________________________________________________ 00005 * 00006 * Copyright (C) 2004-2007 00007 * Chair of Communication Networks (ComNets) 00008 * Kopernikusstr. 16, D-52074 Aachen, Germany 00009 * phone: ++49-241-80-27910, 00010 * fax: ++49-241-80-22242 00011 * email: info@openwns.org 00012 * www: http://www.openwns.org 00013 * _____________________________________________________________________________ 00014 * 00015 * openWNS is free software; you can redistribute it and/or modify it under the 00016 * terms of the GNU Lesser General Public License version 2 as published by the 00017 * Free Software Foundation; 00018 * 00019 * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY 00020 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00021 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00022 * details. 00023 * 00024 * You should have received a copy of the GNU Lesser General Public License 00025 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00026 * 00027 ******************************************************************************/ 00028 00029 #include <WIFIMAC/management/protocolCalculatorPlugins/ErrorProbability.hpp> 00030 00031 #include <WNS/Ttos.hpp> 00032 #include <WNS/simulator/Time.hpp> 00033 00034 #include <cmath> 00035 #include <algorithm> 00036 00037 using namespace wifimac::management::protocolCalculatorPlugins; 00038 00039 ErrorProbability::ErrorProbability() 00040 { 00041 00042 } 00043 00044 double 00045 ErrorProbability::getPER(std::vector<wns::Ratio> snr, 00046 Bit packetLength, 00047 wifimac::convergence::PhyMode phyMode) const 00048 { 00049 // if the packet length is unknown, one symbol is assumed 00050 if(packetLength == 0) 00051 { 00052 packetLength = phyMode.getDataBitsPerSymbol(); 00053 } 00054 00055 double cyclicPrefixReduction = 0.0; 00056 if(phyMode.getGuardIntervalDuration() == 0.8e-6) 00057 { 00058 cyclicPrefixReduction = 0.8; 00059 } 00060 if(phyMode.getGuardIntervalDuration() == 0.4e-6) 00061 { 00062 cyclicPrefixReduction = 0.9; 00063 } 00064 assure(cyclicPrefixReduction > 0, "Unknown guard interval"); 00065 00066 double bitSuccessRate = 1.0; 00067 00068 std::vector<wifimac::convergence::MCS> v = phyMode.getSpatialStreams(); 00069 assure(v.size() > 0, "Must have at least one spatial stream"); 00070 assure(v.size() == snr.size(), "Number of spatial streams and SNRs must match"); 00071 00072 std::vector<wns::Ratio>::const_iterator itSNR = snr.begin(); 00073 std::vector<wifimac::convergence::MCS>::const_iterator itV = v.begin(); 00074 00075 for(; 00076 itSNR != snr.end(), itV != v.end(); 00077 ++itSNR, ++itV) 00078 { 00079 double snr = itSNR->get_factor() * cyclicPrefixReduction; 00080 00081 double ser = 0.0; 00082 double ber = 0.0; 00083 00084 if(itV->getModulation() == "BPSK") 00085 { 00086 ser = Q(sqrt(2*snr)); 00087 ber = ser; 00088 } 00089 else if(itV->getModulation() == "QPSK") 00090 { 00091 ser = 2.0 * Q(sqrt(snr)) * (1.0 - 0.5 * Q(sqrt(snr))); 00092 ber = 0.5 * ser; 00093 } 00094 else if(itV->getModulation() == "QAM16") 00095 { 00096 double P_sqrt16 = 3.0/2.0 * Q(sqrt((3.0/15.0) * snr)); 00097 ser = 1 - pow((1 - P_sqrt16), 2); 00098 ber = ser / 4.0; 00099 } 00100 else if(itV->getModulation() == "QAM64") 00101 { 00102 double P_sqrt64 = 7.0/4.0 * Q(sqrt((3.0/63.0) * snr)); 00103 ser = 1 - pow((1 - P_sqrt64), 2); 00104 ber = ser / 6.0; 00105 } 00106 00107 bitSuccessRate *= (1.0 - ber); 00108 00109 assure((bitSuccessRate >= 0.0 and bitSuccessRate <= 1.0) and 00110 (ber >= 0.0 and ber <= 1.0) and 00111 (ser >= 0.0 and ser <= 1.0), 00112 "Calculated error probabilities are not valid"); 00113 } 00114 00115 double ber = (1.0 - bitSuccessRate); 00116 double u = 0.0; 00117 00118 // only the first coding rate is taken 00119 if(phyMode.getSpatialStreams()[0].getRate() == "1/2") 00120 { 00121 u = std::min(1.0, Pu12(ber)); 00122 } 00123 else if(phyMode.getSpatialStreams()[0].getRate() == "2/3") 00124 { 00125 u = std::min(1.0, Pu23(ber)); 00126 } 00127 else if(phyMode.getSpatialStreams()[0].getRate() == "3/4") 00128 { 00129 u = std::min(1.0, Pu34(ber)); 00130 } 00131 else if(phyMode.getSpatialStreams()[0].getRate() == "5/6") 00132 { 00133 u = std::min(1.0, Pu56(ber)); 00134 } 00135 00136 double per = 1.0 - pow(1.0 - u, static_cast<double>(packetLength)); 00137 00138 assure((per >= 0.0 and per <= 1.0) and 00139 (u >= 0.0 and u <= 1.0), 00140 "Calculated error probabilities are not valid"); 00141 00142 return per; 00143 } 00144 00145 double 00146 ErrorProbability::getPER(wns::Ratio postSNR, 00147 Bit packetLength, 00148 wifimac::convergence::PhyMode phyMode) const 00149 { 00150 std::vector<wns::Ratio> snr(phyMode.getNumberOfSpatialStreams(), postSNR); 00151 return(this->getPER(snr, packetLength, phyMode)); 00152 } 00153 00154 double 00155 ErrorProbability::Pd(double p, double d) const 00156 { 00157 // Chernoff - Approximation 00158 return (pow(4*p*(1-p), d/2)); 00159 } 00160 00161 double 00162 ErrorProbability::Pu12(double rawBer) const 00163 { 00164 return( 11 * Pd(rawBer,10) + 00165 38 * Pd(rawBer,12) + 00166 193 * Pd(rawBer, 14) + 00167 1331 * Pd(rawBer, 16) + 00168 7275 * Pd(rawBer, 18) + 00169 40406 * Pd(rawBer, 20) + 00170 234969 * Pd(rawBer, 22) ); 00171 } 00172 00173 double 00174 ErrorProbability::Pu23(double rawBer) const 00175 { 00176 return( Pd(rawBer,6) + 00177 16 * Pd(rawBer, 7) + 00178 48 * Pd(rawBer, 8) + 00179 158 * Pd(rawBer, 9) + 00180 642 * Pd(rawBer, 10) + 00181 2435 * Pd(rawBer, 11) + 00182 6174 * Pd(rawBer, 12) + 00183 34705 * Pd(rawBer, 13) + 00184 131585 * Pd(rawBer, 14) + 00185 499608 * Pd(rawBer, 15)); 00186 } 00187 00188 double 00189 ErrorProbability::Pu34(double rawBer) const 00190 { 00191 return( 8 * Pd(rawBer, 5) + 00192 31 * Pd(rawBer, 6) + 00193 160 * Pd(rawBer, 7) + 00194 892 * Pd(rawBer, 8) + 00195 4512 * Pd(rawBer, 9) + 00196 23307 * Pd(rawBer, 10) + 00197 121077 * Pd(rawBer, 11) + 00198 625059 * Pd(rawBer, 12) + 00199 3234886 * Pd(rawBer, 13) + 00200 16753077 * Pd(rawBer, 14)); 00201 } 00202 00203 double 00204 ErrorProbability::Pu56(double rawBer) const 00205 { 00206 return( 14 * Pd(rawBer, 4) + 00207 69 * Pd(rawBer, 5) + 00208 654 * Pd(rawBer, 6) + 00209 4996 * Pd(rawBer, 7) + 00210 39677 * Pd(rawBer, 8) + 00211 314973 * Pd(rawBer, 9) + 00212 2503576 * Pd(rawBer, 10) + 00213 19875546 * Pd(rawBer, 11)); 00214 } 00215 00216 double 00217 ErrorProbability::Q(double x) const 00218 { 00219 return( erfc(x/sqrt(2.0)) / 2.0); 00220 } 00221
1.5.5