User Manual, Developers Guide and API Documentation

Scanner.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 <OFDMAPHY/Sender.hpp>
00029 #include <OFDMAPHY/Scanner.hpp>
00030 
00031 #include <RISE/transmissionobjects/broadcasttransmissionobject.hpp>
00032 #include <RISE/manager/metasystemmanager.hpp>
00033 
00034 #include <WNS/PowerRatio.hpp>
00035 #include <WNS/node/component/Component.hpp>
00036 #include <WNS/probe/bus/ContextProvider.hpp>
00037 #include <WNS/probe/bus/ContextProviderCollection.hpp>
00038 #include <WNS/distribution/DiscreteUniform.hpp>
00039 
00040 #include <boost/bind.hpp>
00041 
00042 using namespace ofdmaphy;
00043 
00044 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00045     Scanner,
00046     wns::node::component::Interface,
00047     "ofdmaphy.Scanner",
00048     wns::node::component::ConfigCreator
00049     );
00050 
00051 Scanner::Receiver::Receiver(const wns::pyconfig::View& config, Scanner* s) :
00052     ofdmaphy::receiver::Receiver(config, s),
00053     scanner(s),
00054     bsID(0),
00055     margin(wns::Ratio::from_dB(-250.0))
00056 {
00057 }
00058 
00059 Scanner::Receiver::~Receiver()
00060 {
00061 }
00062 
00063 void
00064 Scanner::Receiver::notify(rise::TransmissionObjectPtr to)
00065 {
00066     add(to);
00067     transmissions.push_back(to);
00068     MESSAGE_SINGLE(NORMAL, logger, "ofdmaphy::Receiver::notify(): startOfTransmission");
00069 }
00070 
00071 void
00072 Scanner::Receiver::positionChanged()
00073 {
00074     ofdmaphy::receiver::Receiver::positionChanged();
00075 
00076     if(transmissions.empty())
00077         return;
00078 
00079     wns::Position currentPosition = getStation()->getAntenna()->getPosition();
00080 
00081     assure(margin >= wns::Ratio::from_dB(0.0), "Margin must be >= 0 dB");
00082 
00083     wns::Ratio nullMargin = wns::Ratio::from_dB(0);
00084     wns::Ratio maxSINR = wns::Ratio::from_dB(-250);
00085     wns::Power maxRxPwr = wns::Power::from_dBm(-250);
00086     wns::Ratio minPathloss = wns::Ratio::from_dB(300);
00087     double assocdistance = 0.0;
00088 
00089     std::multimap<wns::Ratio, rise::TransmissionObjectPtr> sinrSortedTransmissions;                                    
00090 
00091     for (TOList::const_iterator itr = transmissions.begin();
00092          itr != transmissions.end();
00093          ++itr)
00094     {
00095         Transmitter<Sender>* transmitter = 
00096             dynamic_cast<Transmitter<Sender>*>((*itr)->getTransmitter());
00097 
00098         wns::Position bsPosition = transmitter->getAntenna()->getPosition();
00099         double distance = (bsPosition - currentPosition).abs();
00100         wns::Power txp    = (*itr)->getTxPower();
00101         wns::Power rxp    = this->getRxPower(*itr);
00102         wns::Power interf = this->getInterference(*itr);
00103         wns::Ratio sinr   = rxp / interf;
00104         wns::Ratio pathloss = this->getQuasiStaticPathLoss((*itr), wns::service::phy::ofdma::PatternPtr());
00105         pathloss += wns::Ratio::from_dB(2.0);
00106 
00107         if(margin > nullMargin)
00108             sinrSortedTransmissions.insert(std::pair<wns::Ratio, rise::TransmissionObjectPtr>(sinr, *itr));
00109 
00110         maxSINR = std::max(maxSINR, sinr);
00111         maxRxPwr = std::max(maxRxPwr, rxp);
00112         if (pathloss < minPathloss)
00113         {
00114             minPathloss = pathloss;
00115             assocdistance = distance;
00116         }
00117 
00118         bsID = transmitter->getStation()->getStationId();
00119 
00120         MESSAGE_BEGIN(NORMAL, logger, m, "Measured ");
00121 
00122         std::string msName = scanner->getMyNode()->getName();
00123         std::string bsName = transmitter->getStation()->getMyNode()->getName();
00124 
00125         m << bsName << "(bsId=" << bsID << ") by " << msName << "(msId=" << scanner->getStationId() << "):\n"
00126           << "TxPower: " << txp.get_dBm() << "\n"
00127           << "RxPower: " << rxp.get_dBm() << "\n"
00128           << "Interference+Noise: " << interf.get_dBm() << "\n"
00129           << "SINR:" << sinr.get_dB() << "\n";
00130         MESSAGE_END();
00131 
00132         rxpContextCollector->put(rxp.get_dBm());
00133         sinrContextCollector->put(sinr.get_dB());
00134         pathlossContextCollector->put(-1 * pathloss.get_dB());
00135     }
00136 
00137     if(margin > nullMargin)
00138     {
00139         wns::Ratio marginSINR = maxSINR - margin;
00140 
00141         std::multimap<wns::Ratio, rise::TransmissionObjectPtr>::iterator it_bound;
00142 
00143         it_bound = sinrSortedTransmissions.lower_bound(marginSINR);
00144         assure(it_bound != sinrSortedTransmissions.end(), "Maximum SINR not in sorted SINR container");
00145         
00146         std::vector<rise::TransmissionObjectPtr> candidates;
00147         
00148         std::multimap<wns::Ratio, rise::TransmissionObjectPtr>::iterator it;
00149         for(it = it_bound; it != sinrSortedTransmissions.end(); it++)
00150             candidates.push_back(it->second);
00151 
00152         wns::distribution::DiscreteUniform rng(0, candidates.size() - 1);
00153         rise::TransmissionObjectPtr serving =  candidates[rng()];
00154 
00155         wns::Power rxp    = this->getRxPower(serving);
00156         wns::Power interf = this->getInterference(serving);
00157         wns::Ratio sinr   = rxp / interf;
00158 
00159         maxRxpContextCollector->put(rxp.get_dBm());
00160         maxSINRContextCollector->put(sinr.get_dB());
00161         minPathlossContextCollector->put(-1 * this->getQuasiStaticPathLoss((serving), 
00162             wns::service::phy::ofdma::PatternPtr()).get_dB());
00163 
00164         Transmitter<Sender>* transmitter = 
00165             dynamic_cast<Transmitter<Sender>*>((serving)->getTransmitter());
00166         wns::Position bsPosition = transmitter->getAntenna()->getPosition();
00167         distanceContextCollector->put((bsPosition - currentPosition).abs());
00168 
00169         MESSAGE_BEGIN(NORMAL, logger, m, "Selected " << transmitter->getStation()->getMyNode()->getName());
00170         m << "Number of candidates: " << candidates.size() << "\n"
00171           << "SINR:" << sinr.get_dB() << "\n";
00172         MESSAGE_END();
00173     }
00174     else
00175     {
00176         maxRxpContextCollector->put(maxRxPwr.get_dBm());
00177         maxSINRContextCollector->put(maxSINR.get_dB());
00178         minPathlossContextCollector->put(-1 * minPathloss.get_dB());
00179         distanceContextCollector->put(assocdistance);
00180     }
00181 }
00182 
00183 wns::Power
00184 Scanner::Receiver::getRxPower(const rise::TransmissionObjectPtr& to)
00185 {
00186     return ofdmaphy::receiver::Receiver::getRxPower(to, wns::service::phy::ofdma::PatternPtr());
00187 }
00188 
00189 wns::service::phy::ofdma::PatternPtr
00190 Scanner::Receiver::getCurrentReceivePattern(const rise::TransmissionObjectPtr& /*t*/)
00191 {
00192     return  wns::service::phy::ofdma::PatternPtr();
00193 }
00194 
00195 void
00196 Scanner::Receiver::initProbes(const wns::pyconfig::View& config)
00197 {
00198     MESSAGE_SINGLE(NORMAL, logger, "ofdmaphy::Scanner::Receiver initializing PutDecorators");
00199 
00200     wns::probe::bus::ContextProviderCollection localcpc(&scanner->getMyNode()->getContextProviderCollection());
00201     
00202     localcpc.addProvider(wns::probe::bus::contextprovider::Constant("MSID", scanner->getStationId()));
00203 
00204     localcpc.addProvider(wns::probe::bus::contextprovider::Callback("BSID", boost::bind(&Scanner::Receiver::Receiver::getBSID, this)));
00205 
00206     rxpContextCollector = wns::probe::bus::ContextCollectorPtr(
00207         new wns::probe::bus::ContextCollector(localcpc,
00208                                               config.get<std::string>("rxpProbeName")));
00209 
00210     sinrContextCollector = wns::probe::bus::ContextCollectorPtr(
00211         new wns::probe::bus::ContextCollector(localcpc,
00212                                               config.get<std::string>("sinrProbeName")));
00213 
00214     pathlossContextCollector = wns::probe::bus::ContextCollectorPtr(
00215         new wns::probe::bus::ContextCollector(localcpc,
00216                                               config.get<std::string>("pathlossProbeName")));
00217     
00218     maxRxpContextCollector = wns::probe::bus::ContextCollectorPtr(
00219         new wns::probe::bus::ContextCollector(localcpc,
00220                                               config.get<std::string>("maxRxpProbeName")));
00221 
00222     maxSINRContextCollector = wns::probe::bus::ContextCollectorPtr(
00223         new wns::probe::bus::ContextCollector(localcpc,
00224                                               config.get<std::string>("maxSINRProbeName")));
00225 
00226     minPathlossContextCollector = wns::probe::bus::ContextCollectorPtr(
00227         new wns::probe::bus::ContextCollector(localcpc,
00228                                               config.get<std::string>("minPathlossProbeName")));
00229 
00230     distanceContextCollector = wns::probe::bus::ContextCollectorPtr(
00231         new wns::probe::bus::ContextCollector(localcpc,
00232                                               config.get<std::string>("distanceProbeName")));
00233 }
00234 
00235 void Scanner::Receiver::setMargin(wns::Ratio m)
00236 {
00237     margin = m;
00238     assure(margin >= wns::Ratio::from_dB(0.0), "Margin must be >= 0 dB");
00239 }
00240 
00241 int
00242 Scanner::Receiver::getBSID()
00243 {
00244     return bsID;
00245 }
00246 
00247 
00248 Scanner::Scanner(wns::node::Interface* _node, const wns::pyconfig::View& pyConfigView) :
00249     rise::Station(pyConfigView),
00250     wns::node::component::Component(_node, pyConfigView),
00251     logger(pyConfigView.get("logger")),
00252     systemManager(rise::MetaSystemManager::getInstance()->getSystemManagerBySystemName(pyConfigView.get<std::string>("systemManagerName"))),
00253     receiver(NULL)
00254 {
00255     assure(systemManager, "Was not able to acquire SystemManager");
00256 }
00257 
00258 void
00259 Scanner::doStartup()
00260 {
00261     wns::pyconfig::View pyConfigView = this->getConfig();
00262     MESSAGE_SINGLE(NORMAL, logger, "ofdmaphy::Scanner construction");
00263     systemManager->addStation(this);
00264     this->receiver = new Receiver(pyConfigView.getView("receiver", 0), this);
00265     this->receiver->initProbes(pyConfigView);
00266     this->receiver->setMargin(pyConfigView.get<wns::Ratio>("margin"));
00267 
00268     double rxFrequency = pyConfigView.get<double>("rxFrequency");
00269     double bandwidth = pyConfigView.get<double>("bandwidth");
00270     int numberOfSubCarrier = pyConfigView.get<int>("numberOfSubCarrier");
00271 
00272     receiver->tune(rxFrequency,
00273                    bandwidth,
00274                    numberOfSubCarrier);
00275 
00276     MESSAGE_BEGIN(NORMAL, logger, m, "ofdmaphy::Scanner constructed: ");
00277     m << "#SC="<<numberOfSubCarrier<<", fRx="<<rxFrequency<<",  b="<<bandwidth;
00278     MESSAGE_END();
00279 }
00280 
00281 Scanner::~Scanner()
00282 {
00283     delete receiver;
00284 }
00285 
00286 void
00287 Scanner::onNodeCreated()
00288 {
00289     this->setMobility( getService<rise::scenario::mobility::MobilityInterface*>("mobility"));
00290 }
00291 
00292 void
00293 Scanner::onWorldCreated()
00294 {
00295 }
00296 
00297 
00298 void
00299 Scanner::onShutdown()
00300 {
00301 }
00302 
00303 rise::SystemManager*
00304 Scanner::getSystemManager() const
00305 {
00306     return systemManager;
00307 }
00308 
00309 wns::node::Interface*
00310 Scanner::getMyNode() const
00311 {
00312     return this->getNode();
00313 }
00314 
00315 
00316 

Generated on Fri May 25 03:32:20 2012 for openWNS by  doxygen 1.5.5