![]() |
User Manual, Developers Guide and API Documentation |
![]() |
00001 /****************************************************************************** 00002 * WiMeMac * 00003 * This file is part of openWNS (open Wireless Network Simulator) 00004 * _____________________________________________________________________________ 00005 * 00006 * Copyright (C) 2004-2011 00007 * Chair of Communication Networks (ComNets) 00008 * Kopernikusstr. 5, 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 <WIMEMAC/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 wimemac::management::protocolCalculatorPlugins; 00038 00039 ErrorProbability::ErrorProbability() 00040 { 00041 00042 } 00043 00044 ErrorStatistic 00045 ErrorProbability::getError(wns::Ratio postSNR, 00046 Bit packetLength, 00047 wimemac::convergence::PhyMode phyMode) const 00048 { 00049 double cyclicPrefixReduction = 0.0; 00050 if(phyMode.getGuardIntervalDuration() == 0.8e-6) 00051 { 00052 cyclicPrefixReduction = 0.8; 00053 } 00054 if(phyMode.getGuardIntervalDuration() == 0.4e-6) 00055 { 00056 cyclicPrefixReduction = 0.9; 00057 } 00058 assure(cyclicPrefixReduction > 0, "Unknown guard interval"); 00059 00060 ErrorStatistic e; 00061 00062 postSNR.set_factor(postSNR.get_factor() * cyclicPrefixReduction); 00063 00064 if(phyMode.getMCS().getModulation() == "BPSK") 00065 { 00066 e.ser = Q(sqrt(2*postSNR.get_factor())); 00067 e.ber = e.ser; 00068 } 00069 if(phyMode.getMCS().getModulation() == "QPSK") 00070 { 00071 e.ser = 2.0 * Q(sqrt(postSNR.get_factor())) * (1.0 - 0.5 * Q(sqrt(postSNR.get_factor()))); 00072 e.ber = 0.5 * e.ser; 00073 } 00074 if(phyMode.getMCS().getModulation() == "QAM16") 00075 { 00076 double P_sqrt16 = 3.0/2.0 * Q(sqrt((3.0/15.0) * postSNR.get_factor())); 00077 e.ser = 1 - pow((1 - P_sqrt16), 2); 00078 e.ber = e.ser / 4.0; 00079 } 00080 if(phyMode.getMCS().getModulation() == "QAM64") 00081 { 00082 double P_sqrt64 = 7.0/4.0 * Q(sqrt((3.0/63.0) * postSNR.get_factor())); 00083 e.ser = 1 - pow((1 - P_sqrt64), 2); 00084 e.ber = e.ser / 6.0; 00085 } 00086 00087 if(phyMode.getMCS().getRate() == "1/2") 00088 { 00089 e.u = std::min(1.0, Pu12(e.ber)); 00090 } 00091 if(phyMode.getMCS().getRate() == "2/3") 00092 { 00093 e.u = std::min(1.0, Pu23(e.ber)); 00094 } 00095 if(phyMode.getMCS().getRate() == "3/4") 00096 { 00097 e.u = std::min(1.0, Pu34(e.ber)); 00098 } 00099 if(phyMode.getMCS().getRate() == "5/6") 00100 { 00101 e.u = std::min(1.0, Pu56(e.ber)); 00102 } 00103 00104 // Packet error probability 00105 e.per = 1.0 - pow(1.0 - e.u, static_cast<double>(packetLength)); 00106 00107 assure(e.valid(), "Calculated error probabilities are not valid"); 00108 00109 return e; 00110 } 00111 00112 double 00113 ErrorProbability::getPER(wns::Ratio postSNR, Bit packetLength, wimemac::convergence::PhyMode phyMode) const 00114 { 00115 ErrorStatistic e = getError(postSNR, packetLength, phyMode); 00116 return(e.per); 00117 } 00118 00119 00120 double 00121 ErrorProbability::Pd(double p, double d) const 00122 { 00123 // Chernoff - Approximation 00124 return (pow(4*p*(1-p), d/2)); 00125 } 00126 00127 double 00128 ErrorProbability::Pu12(double rawBer) const 00129 { 00130 return( 11 * Pd(rawBer,10) + 00131 38 * Pd(rawBer,12) + 00132 193 * Pd(rawBer, 14) + 00133 1331 * Pd(rawBer, 16) + 00134 7275 * Pd(rawBer, 18) + 00135 40406 * Pd(rawBer, 20) + 00136 234969 * Pd(rawBer, 22) ); 00137 } 00138 00139 double 00140 ErrorProbability::Pu23(double rawBer) const 00141 { 00142 return( Pd(rawBer,6) + 00143 16 * Pd(rawBer, 7) + 00144 48 * Pd(rawBer, 8) + 00145 158 * Pd(rawBer, 9) + 00146 642 * Pd(rawBer, 10) + 00147 2435 * Pd(rawBer, 11) + 00148 6174 * Pd(rawBer, 12) + 00149 34705 * Pd(rawBer, 13) + 00150 131585 * Pd(rawBer, 14) + 00151 499608 * Pd(rawBer, 15)); 00152 } 00153 00154 double 00155 ErrorProbability::Pu34(double rawBer) const 00156 { 00157 return( 8 * Pd(rawBer, 5) + 00158 31 * Pd(rawBer, 6) + 00159 160 * Pd(rawBer, 7) + 00160 892 * Pd(rawBer, 8) + 00161 4512 * Pd(rawBer, 9) + 00162 23307 * Pd(rawBer, 10) + 00163 121077 * Pd(rawBer, 11) + 00164 625059 * Pd(rawBer, 12) + 00165 3234886 * Pd(rawBer, 13) + 00166 16753077 * Pd(rawBer, 14)); 00167 } 00168 00169 double 00170 ErrorProbability::Pu56(double rawBer) const 00171 { 00172 return( 14 * Pd(rawBer, 4) + 00173 69 * Pd(rawBer, 5) + 00174 654 * Pd(rawBer, 6) + 00175 4996 * Pd(rawBer, 7) + 00176 39677 * Pd(rawBer, 8) + 00177 314973 * Pd(rawBer, 9) + 00178 2503576 * Pd(rawBer, 10) + 00179 19875546 * Pd(rawBer, 11)); 00180 } 00181 00182 double 00183 ErrorProbability::Q(double x) const 00184 { 00185 return( erfc(x/sqrt(2.0)) / 2.0); 00186 } 00187
1.5.5