User Manual, Developers Guide and API Documentation

PhyModeMapper.cpp

Go to the documentation of this file.
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 

Generated on Fri May 25 03:31:58 2012 for openWNS by  doxygen 1.5.5