![]() |
User Manual, Developers Guide and API Documentation |
![]() |
00001 /******************************************************************************* 00002 * This file is part of openWNS (open Wireless Network Simulator) 00003 * _____________________________________________________________________________ 00004 * 00005 * Copyright (C) 2004-2007 00006 * Chair of Communication Networks (ComNets) 00007 * Kopernikusstr. 5, D-52074 Aachen, Germany 00008 * phone: ++49-241-80-27910, 00009 * fax: ++49-241-80-22242 00010 * email: info@openwns.org 00011 * www: http://www.openwns.org 00012 * _____________________________________________________________________________ 00013 * 00014 * openWNS is free software; you can redistribute it and/or modify it under the 00015 * terms of the GNU Lesser General Public License version 2 as published by the 00016 * Free Software Foundation; 00017 * 00018 * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY 00019 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00020 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00021 * details. 00022 * 00023 * You should have received a copy of the GNU Lesser General Public License 00024 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00025 * 00026 ******************************************************************************/ 00027 00028 #include <WNS/Assure.hpp> 00029 #include <WNS/StaticFactory.hpp> 00030 #include <WNS/StaticFactoryBroker.hpp> 00031 #include <WNS/PyConfigViewCreator.hpp> 00032 #include <WNS/service/phy/phymode/PhyModeInterface.hpp> 00033 #include <WNS/service/phy/phymode/PhyModeMapperInterface.hpp> 00034 #include <RISE/plmapping/PhyModeMapper.hpp> 00035 00036 using namespace rise::plmapping; 00037 00038 // Situation: There are (too) many PhyModeMapper objects instanciated, 00039 // although they are all contain the same data. 00040 // TODO: is this the way to make a singleton? 00041 STATIC_FACTORY_BROKER_REGISTER(rise::plmapping::PhyModeMapper, 00042 wns::service::phy::phymode::PhyModeMapperInterface, 00043 "rise.plmapping.PhyModeMapper"); 00044 00045 /* 00046 STATIC_FACTORY_REGISTER_WITH_CREATOR(rise::plmapping::PhyModeMapper, 00047 wns::service::phy::phymode::PhyModeMapperInterface, 00048 "rise.plmapping.PhyModeMapper", 00049 wns::PyConfigViewCreator); 00050 */ 00051 00052 PhyModeMapper::PhyModeMapper(const wns::pyconfig::View& config) 00053 : subCarriersPerSubChannel(config.get<unsigned int>("subCarriersPerSubChannel")), 00054 symbolDuration(config.get<simTimeType>("symbolDuration")), 00055 phyModeCount(config.len("mapEntries")), 00056 minimumSINR(config.get<double>("minimumSINR")), 00057 mi2perMapper(wns::service::phy::phymode::CoderFullMappingInterface::getCoderFullMapping(config.get("mi2perMapper"))), 00058 SNR2MImapper(wns::service::phy::phymode::SNR2MIInterface::getSNR2MImapper(config.get("snr2miMapper"))), 00059 logger(std::string("RISE"), std::string("PhyModeMapper")) 00060 //logger(config.get("logger")) // TODO 00061 { 00062 MESSAGE_SINGLE(NORMAL, logger, "PhyModeMapper::Constructor: I am object "<<this); 00063 // phyModeRangeMap is empty here 00064 // iterate through the SINR-2-PhyMode table 00065 for (unsigned int phymodeIndex=0; phymodeIndex < phyModeCount; ++phymodeIndex) { 00066 //MESSAGE_SINGLE(NORMAL, logger, "PhyModeMapper::Constructor: phymodeIndex="<<phymodeIndex); 00067 wns::pyconfig::View mapEntry = config.getView("mapEntries",phymodeIndex); 00068 // mapEntry contains "phyMode" and "sinrInterval" 00069 00070 //wns::SmartPtr<rise::plmapping::PhyMode> aPhyMode = 00071 // wns::SmartPtr<rise::plmapping::PhyMode> 00072 wns::service::phy::phymode::PhyModeInterface* phyModeInterfacePtr = wns::service::phy::phymode::createPhyModeNonConst(mapEntry.get<wns::pyconfig::View>("phyMode")); 00073 00074 PhyModePtr aPhyMode = 00075 PhyModePtr(dynamic_cast<rise::plmapping::PhyMode*>(phyModeInterfacePtr)); 00076 MESSAGE_SINGLE(NORMAL, logger, "PhyModeMapper::Constructor: aPhyMode["<<phymodeIndex<<"]="<<*aPhyMode); 00077 00078 aPhyMode->setSubCarriersPerSubChannel(subCarriersPerSubChannel); 00079 aPhyMode->setSymbolDuration(symbolDuration); 00080 assure(aPhyMode->dataRateIsValid(),"unknown dataRate for PhyMode "<< *aPhyMode); 00081 phyModeVector.push_back(aPhyMode); 00082 wns::service::phy::phymode::SINRRange sinrRange = 00083 wns::service::phy::phymode::SINRRange::CreateFrom(mapEntry.get<wns::pyconfig::View>("sinrInterval")); 00084 phyModeRangeMap.insert( sinrRange, phymodeIndex ); 00085 phyModeSINRRangeRegistry.insert( *aPhyMode,sinrRange ); 00086 } 00087 } 00088 00089 wns::service::phy::phymode::PhyModeInterfacePtr 00090 PhyModeMapper::getBestPhyMode(const wns::Ratio& sinr) const 00091 { 00092 return getBestPhyMode(sinr.get_dB()); 00093 } 00094 00095 wns::service::phy::phymode::PhyModeInterfacePtr 00096 PhyModeMapper::getBestPhyMode(double sinr /* dB */) const 00097 { 00098 unsigned int phymodeIndex; 00099 try { 00100 phymodeIndex=phyModeRangeMap.get(sinr); 00101 MESSAGE_SINGLE(NORMAL, logger,"phymodeIndex: "<<phymodeIndex); 00102 00103 } catch ( ... ) { // out of range 00104 if (sinr<0) { return getLowestPhyMode(); } 00105 else { return getHighestPhyMode(); } 00106 } 00107 return phyModeVector[phymodeIndex]; 00108 } 00109 00110 int 00111 PhyModeMapper::getBestPhyModeIndex(double sinr /* dB */) const 00112 { 00113 return phyModeRangeMap.get(sinr); 00114 } 00115 00116 wns::Ratio 00117 PhyModeMapper::getMinSINRRatio(const wns::service::phy::phymode::PhyModeInterfacePtr phyMode) const 00118 { 00119 assure(phyMode != wns::service::phy::phymode::PhyModeInterfacePtr(),"invalid phyModePtr"); 00120 wns::Ratio ratio; 00121 ratio.set_dB(getMinSINR(phyMode)); // double dB 00122 return ratio; 00123 } 00124 00126 double 00127 PhyModeMapper::getMinSINR(const wns::service::phy::phymode::PhyModeInterfacePtr phyMode) const 00128 { 00129 assure(phyMode != wns::service::phy::phymode::PhyModeInterfacePtr(),"invalid phyModePtr"); 00130 const rise::plmapping::PhyMode& aPhyMode = static_cast<const rise::plmapping::PhyMode&>(*phyMode); 00131 double minSINR = phyModeSINRRangeRegistry.find(aPhyMode).min(); 00132 if (minSINR<minimumSINR) { minSINR=minimumSINR; } 00133 return minSINR; 00134 } 00135 00137 wns::service::phy::phymode::SINRRange 00138 PhyModeMapper::getSINRRange(const wns::service::phy::phymode::PhyModeInterfacePtr phyMode) const 00139 { 00140 assure(phyMode != wns::service::phy::phymode::PhyModeInterfacePtr(),"invalid phyModePtr"); 00141 const rise::plmapping::PhyMode& aPhyMode = static_cast<const rise::plmapping::PhyMode&>(*phyMode); 00142 return phyModeSINRRangeRegistry.find(aPhyMode); 00143 } 00144 00145 const wns::service::phy::phymode::PhyModeInterfacePtr 00146 PhyModeMapper::getHighestPhyMode() const 00147 { 00148 return phyModeVector.back(); 00149 } 00150 00151 const wns::service::phy::phymode::PhyModeInterfacePtr 00152 PhyModeMapper::getLowestPhyMode() const 00153 { 00154 return phyModeVector.front(); 00155 } 00156 00157 int 00158 PhyModeMapper::getPhyModeCount() const 00159 { 00160 return (int)phyModeCount; 00161 } 00162 00163 PhyModeMapper::PhyModeVector 00164 PhyModeMapper::getListOfPhyModes() const 00165 { 00166 return phyModeVector; 00167 } 00168 00169 const std::vector< wns::service::phy::phymode::PhyModeInterfacePtr > 00170 PhyModeMapper::getListOfPhyModePtr() const 00171 { 00172 std::vector< wns::service::phy::phymode::PhyModeInterfacePtr > phyModePtrVector(phyModeCount); 00173 for(unsigned int i=0; i<phyModeCount; i++) { 00174 phyModePtrVector[i] = phyModeVector[i]; 00175 } 00176 return phyModePtrVector; 00177 } 00178 00179 wns::service::phy::phymode::PhyModeInterfacePtr 00180 PhyModeMapper::getPhyModeForIndex(int index) const 00181 { 00182 assure(index>=0,"invalid index="<<index); 00183 return phyModeVector[index]; 00184 } 00185 00186 int 00187 PhyModeMapper::getIndexForPhyMode(const wns::service::phy::phymode::PhyModeInterface& phyMode) const 00188 { 00189 for (unsigned int phymodeIndex=0; phymodeIndex < phyModeCount; ++phymodeIndex) { 00190 if (*(phyModeVector[phymodeIndex]) == phyMode) return phymodeIndex; 00191 } 00192 // this helps debugging, in case the phyMode is not found: 00193 /* 00194 MESSAGE_SINGLE(NORMAL, logger, "getIndexForPhyMode(PhyMode="<<phyMode<<" @ "<<&phyMode<<"): not found"); 00195 for (unsigned int phymodeIndex=0; phymodeIndex < phyModeCount; ++phymodeIndex) { 00196 MESSAGE_SINGLE(NORMAL, logger, "getIndexForPhyMode(PhyMode="<<phyMode<<" @ "<<&phyMode<<"): compared to phyModeVector["<<phymodeIndex<<"]="<<*(phyModeVector[phymodeIndex])<<" @ "<<(phyModeVector[phymodeIndex])); 00197 } 00198 */ 00199 assure(-1,"getIndexForPhyMode("<<phyMode<<"): not found"); 00200 return wns::service::phy::phymode::UNDEFINED_PHYMODEINDEX; // (-1) = not found 00201 } 00202 00203 void 00204 PhyModeMapper::calculateSINRRanges(double targetPER, unsigned int bl) 00205 { 00206 //std::cout<<"calculateSINRRanges(targetPER="<<targetPER<<", bl="<<bl<<"):"<<std::endl; 00207 // ::From(from).To(to); 00208 // ::FromIncluding(from).ToExcluding(to); 00209 // ::FromExcluding(from).ToIncluding(to); 00210 phyModeRangeMap = PhyModeRangeMap(); // empty phyModeRangeMap 00211 phyModeSINRRangeRegistry = PhyModeSINRRangeRegistry(); // empty phyModeSINRRangeRegistry 00212 double from = -200.0; 00213 double to; 00214 // This method can only collaborate with a rise::plmapping::SNR2MImapper 00215 rise::plmapping::SNR2MI* snr2miMapper = dynamic_cast<rise::plmapping::SNR2MI*>(SNR2MImapper); 00216 assure(snr2miMapper, "SNR2MI Mapper is not of type rise::plmapping::SNR2MI*"); 00217 rise::plmapping::CoderFullMapping* coderMapper = dynamic_cast<rise::plmapping::CoderFullMapping*>(mi2perMapper); 00218 assure(coderMapper, "mi2perMapper is not of type rise::plmapping::CoderFullMapping*"); 00219 00220 PhyMode previousPhyMode = *(phyModeVector[0]); // worst PhyMode (BPSK*) 00221 { 00222 double mib = coderMapper->PER2MIB(targetPER, bl, previousPhyMode.getCoding()); // inversion 00223 minimumSINR = snr2miMapper->convertMIB2SNR(mib,previousPhyMode.getModulation()).get_dB(); 00224 //std::cout<<" minimumSINR("<<previousPhyMode<<") = "<<minimumSINR<<std::endl; 00225 } 00226 for(unsigned int phymodeIndex=1; phymodeIndex<phyModeCount; phymodeIndex++) { // start with 2nd 00227 wns::SmartPtr<PhyMode> phyModePtr = phyModeVector[phymodeIndex]; 00228 double mib = coderMapper->PER2MIB(targetPER, bl, phyModePtr->getCoding()); // inversion 00229 to = snr2miMapper->convertMIB2SNR(mib,phyModePtr->getModulation()).get_dB(); 00230 // sinr range for previous PhyMode 00231 wns::service::phy::phymode::SINRRange sinrRange = 00232 wns::service::phy::phymode::SINRRange::FromExcluding(from).ToIncluding(to); 00233 phyModeRangeMap.insert( sinrRange, phymodeIndex-1 ); 00234 phyModeSINRRangeRegistry.insert( previousPhyMode,sinrRange ); 00235 MESSAGE_SINGLE(NORMAL, logger, " SINRRange("<<previousPhyMode<<") = "<<from<<"..."<<to); 00236 from = to; 00237 previousPhyMode = *phyModePtr; // copy 00238 } 00239 to = 200.0; 00240 wns::service::phy::phymode::SINRRange sinrRange = 00241 wns::service::phy::phymode::SINRRange::FromExcluding(from).ToIncluding(to); 00242 phyModeRangeMap.insert( sinrRange, phyModeCount-1 ); 00243 phyModeSINRRangeRegistry.insert( previousPhyMode,sinrRange ); 00244 //std::cout<<" SINRRange("<<previousPhyMode<<") = "<<from<<"..."<<to<<std::endl; 00245 } 00246 00247 std::string 00248 PhyModeMapper::printSwitchingPoints() const 00249 { 00250 std::stringstream line; 00251 // don't start with index 0; get lowest switching point from getMinimumSINR() 00252 line << "[ "<<getMinimumSINR()<<" "; 00253 for(unsigned int phymodeIndex=1; phymodeIndex<phyModeCount; phymodeIndex++) { 00254 wns::service::phy::phymode::PhyModeInterfacePtr phyModePtr = getPhyModeForIndex(phymodeIndex); 00255 double min = getSINRRange(phyModePtr).min(); 00256 line <<min<<" "; 00257 } 00258 line<<"]"; 00259 return line.str(); 00260 } 00261 00262 std::string 00263 PhyModeMapper::printPhyModeNames() const 00264 { 00265 std::stringstream line; 00266 line << "char( "; 00267 for(unsigned int phymodeIndex=0; phymodeIndex<phyModeCount; phymodeIndex++) { 00268 wns::service::phy::phymode::PhyModeInterfacePtr phyModePtr = getPhyModeForIndex(phymodeIndex); 00269 line <<"'"<< phyModePtr->getString() <<"', "; 00270 } 00271 line<<"'invalid' )"; 00272 return line.str(); 00273 } 00274 00275
1.5.5