User Manual, Developers Guide and API Documentation

receiver.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 <sstream>
00029 #include <cassert>
00030 
00031 #include <RISE/transceiver/receiver.hpp>
00032 #include <RISE/transceiver/transmitter.hpp>
00033 #include <RISE/antenna/Antenna.hpp>
00034 #include <RISE/manager/systemmanager.hpp>
00035 #include <RISE/scenario/Scenario.hpp>
00036 #include <RISE/medium/PhysicalResource.hpp>
00037 #include <WNS/PowerRatio.hpp>
00038 #include <RISE/transmissionobjects/transmissionobject.hpp>
00039 #include <RISE/stations/station.hpp>
00040 #include <RISE/medium/Medium.hpp>
00041 #include <WNS/TimeWeightedAverage.hpp>
00042 #include <RISE/transceiver/cache/hashcache.hpp>
00043 #include <RISE/transceiver/cache/idvectorcache.hpp>
00044 #include <RISE/transceiver/cache/vectorcache.hpp>
00045 #include <RISE/transceiver/cache/nocache.hpp>
00046 #include <RISE/transceiver/cache/h2cache.hpp>
00047 #include <RISE/RISE.hpp>
00048 
00049 using namespace std;
00050 using namespace rise;
00051 
00052 ReceiverBase::ReceiverBase(Station* s,
00053                            Demodulator *demodulator,
00054                            Decoder *decoder,
00055                            wns::Ratio rnf) :
00056     receiverId(nextid++),
00057     demodulator(demodulator),
00058     decoder(decoder),
00059     totalRxPower(),
00060     propCache(0),
00061     receiverNoiseFigure(rnf),
00062     active(false),
00063     midFrequency(0),
00064     log("ReceiverBase")
00065     //log(config.getView("logger")) // no wns::pyconfig::View here !
00066 {
00067     assure(s, "No valid station provided");
00068     totalRxPower.setDirty();
00069     configureLogger(); // name="ReceiverBase(receiverId)"
00070     this->startObserving(s);
00071     initiatePropCache();
00072 }
00073 
00074 ReceiverBase::~ReceiverBase()
00075 {
00076     MESSAGE_BEGIN(NORMAL, log, m, "Shutting down ...");
00077     MESSAGE_END();
00078     delete propCache;
00079 }
00080 
00081 void ReceiverBase::initiatePropCache()
00082 {
00083     MESSAGE_BEGIN(NORMAL, log, m, "Created ...");
00084     MESSAGE_END();
00085     wns::pyconfig::View pyConfigView = RISE::getPyConfigView();
00086     std::string cache = pyConfigView.get<std::string>("propagationCache.cache");
00087     if(cache==std::string("hash"))
00088         propCache = new HashCache(this);
00089     else if(cache==std::string("H2"))
00090         propCache = new H2Cache(this);
00091     else if(cache==std::string("idVector"))
00092         propCache = new IdVectorCache(this);
00093     else if(cache==std::string("vector"))
00094         propCache = new VectorCache(this);
00095     else if(cache==std::string("no"))
00096         propCache = new NoCache(this);
00097     else {
00098         throw(wns::Exception(std::string("No such cache strategy available: ")+cache));
00099     }
00100 }
00101 
00102 
00103 void ReceiverBase::configureLogger() {
00104     stringstream location;
00105     location << "ReceiverBase(" << receiverId << ")";
00106     log = RISELogger(location.str());
00107 
00108     if(RISE::getPyConfigView().get<bool>("debug.receiver"))
00109     {
00110         log.switchOn();
00111         pd_debugFlag = true;
00112         MESSAGE_SINGLE(NORMAL, log, "configureLogger(): switchOn. receiverId="<<receiverId);
00113     } else {
00114         log.switchOff();
00115         pd_debugFlag = false;
00116     };
00117 }
00118 
00119 void ReceiverBase::startReceiving()
00120 {
00121     MESSAGE_BEGIN(NORMAL, log, m, "Started receiving ...");
00122     MESSAGE_END();
00123     //std::cout << "rise::ReceiverBase::startReceiving" << std::endl;
00124     assure(!active, "Receiver already active!");
00125     long int nSB = prc.size();
00126     for(long int i=0; i < nSB; ++i) 
00127     {
00128         assert(prc.at(i));
00129         prc.at(i)->attach(this);
00130     }
00131     active = true;
00132 }
00133 
00134 void ReceiverBase::stopReceiving()
00135 {
00136     MESSAGE_BEGIN(NORMAL, log, m, "Stop receiving.");
00137     MESSAGE_END();
00138     //std::cout << "rise::ReceiverBase::stopReceiving" << std::endl;
00139     assure(active, "Receiver is not active!");
00140     long int nSC = prc.size();
00141     for(long int i = 0; i < nSC; ++i)
00142     {
00143         assert(prc.at(i));
00144         prc.at(i)->detach(this);
00145     }
00146     active = false;
00147     // remove all transmission objects and their according averaging objects
00148     transmissionObjects.clear();
00149     removeAll();
00150 }
00151 
00152 wns::Power ReceiverBase::getTotalRxPower()
00153 {
00154     assure(active, "Receiver is not active! Should we return 0 W here?");
00155     totalRxPower = getNoise();
00156     PhysicalResourceIterator itr,itrEND;
00157     itrEND = prc.end();
00158     itr = prc.begin();
00159     while(itr != itrEND)
00160     {
00161         medium::PhysicalResource::TransmissionObjectIterator TOI,TOI_END;
00162         TOI_END = (*itr)->getTOEnd();
00163         for(TOI = (*itr)->getTOBegin(); TOI != TOI_END; ++TOI) {
00164             totalRxPower += getRxPower(*TOI);
00165         }
00166         ++itr;
00167     }
00168     return totalRxPower;
00169 }
00170 
00171 wns::Power ReceiverBase::getInterference(const TransmissionObjectPtr& t)
00172 {
00173     wns::Power rxPower = getRxPower(t);
00174     assert(this->contains(t));
00175     wns::Power Interference = getTotalRxPower() - rxPower;
00176     assert(Interference>=getNoise()*.99); // should at least contain Noise
00177     return Interference; // I+N
00178 }
00179 
00180 wns::Power ReceiverBase::getRxPower(const TransmissionObjectPtr& t)
00181 {
00182     wns::Power rxPower = t->getTxPower();
00183     PhysicalResourceIterator itr,itrEND;
00184     itr = prc.begin();
00185     itrEND = prc.end();
00186     while((!(*itr)->contains(t)) && itr != itrEND)
00187     {
00188         ++itr;
00189     }
00190     assert(itr!=itrEND);
00191     double freq = (*itr)->getFrequency();
00192     rxPower -= propCache->getLoss(t->getTransmitter(),freq);
00193     return rxPower;
00194 }
00195 
00196 
00197 wns::Power ReceiverBase::getNoise()
00198 {
00199     double receiver_band = 0;
00200     PhysicalResourceIterator itr,itrEND;
00201     itrEND = prc.end();
00202     for(itr = prc.begin(); itr != itrEND; ++itr) {
00203         receiver_band += (*itr)->getBandwidth();
00204     }
00205     wns::Power bg = wns::Power::from_dBm(-174);
00206     bg += receiverNoiseFigure;
00207     bg += wns::Ratio::from_factor(receiver_band*1E6);
00208     return bg;
00209 }
00210 
00211 void ReceiverBase::writeCacheEntry(PropCacheEntry& cacheEntry,
00212                                    Transmitter* t,
00213                                    double freq)
00214 {
00215     wns::Ratio pl = getPathloss(*t, freq);
00216     wns::Ratio sh = getShadowing(*t);
00217 
00218     antenna::Antenna* txA = t->getAntenna();
00219     Station* RxStation = getAntenna()->getStation();
00220     Station* TxStation = txA->getStation();
00221 
00222     MESSAGE_BEGIN(NORMAL, log, m, "");
00223     m  << TxStation->getStationId() << TxStation->getPosition()
00224        << " -> "
00225        << RxStation->getStationId() << RxStation->getPosition()
00226        << " pathloss: " << pl;
00227     MESSAGE_END();
00228     cacheEntry.setPathloss(pl);
00229     cacheEntry.setShadowing(sh);
00230     // receive antenna gain  at transmitter's position
00231     // which beam does receiver use to listen to the transmitter
00232     wns::Ratio r1 = getAntenna()->getGain(txA->getPosition(),
00233                                      rise::antenna::PatternPtr());
00234     // transmit antenna gain at receiver's position
00235     // which beam does transmitter use to send to this receiver
00236     wns::Ratio r2 = txA->getGain(getAntenna()->getPosition(),
00237                                  rise::antenna::PatternPtr());
00238     cacheEntry.setAntennaGain(r1 + r2);
00239     cacheEntry.setValid(true);
00240 }
00241 
00242 void ReceiverBase::tune(double f,double b,long int numberOfSubCarriers)
00243 {
00244     assure(!active, "Tuning not possible.Transceiver is active!");
00245     assure(f>0, "No negative frequencies allowed.");
00246     assure(b>0, "No negative bandwidth allowed.");
00247     assure(numberOfSubCarriers>0, "No negative number of sub-carriers allowed.");
00248 
00249     MESSAGE_SINGLE(NORMAL, log, "rise::ReceiverBase::tune(f="<<f<<",b="<<b<<",#SC="<<numberOfSubCarriers<<")");
00250 
00251     midFrequency = f;
00252     double subCarrierBandwidth = b/numberOfSubCarriers;
00253     double lowerFrequency = f - b/2;
00254     for(long int i = 0; i < numberOfSubCarriers; ++i) {
00255         double subCarrierCenterFrequency = lowerFrequency + (2*i + 1) * subCarrierBandwidth/2;
00256         prc.push_back(medium::Medium::getInstance()->getPhysicalResource(subCarrierCenterFrequency, subCarrierBandwidth));
00257         // TODO [rs]: way to give the subChannel number into the PhysicalResource
00258     }
00259 }
00260 
00261 void ReceiverBase::positionChanged()
00262 {
00263     propCache->invalidatePropagationEntries();
00264 }
00265 
00266 void ReceiverBase::positionWillChange()
00267 {
00268     /* do nothing */
00269 }
00270 
00271 void ReceiverBase::mobilityUpdate(Transmitter* transmitter)
00272 {
00273     propCache->invalidatePropagationEntries(transmitter);
00274     totalRxPower.setDirty();
00275     signalLevelsChange();
00276 }
00277 
00278 bool ReceiverBase::contains(TransmissionObjectPtr t)
00279 {
00280     return find(transmissionObjects.begin(), transmissionObjects.end(), t) != transmissionObjects.end();
00281 }
00282 
00283 unsigned long int ReceiverBase::nextid = 0;
00284 
00285 Receiver::Receiver(Station* s,
00286                    antenna::Antenna* a,
00287                    Demodulator *demodulator,
00288                    Decoder *decoder,
00289                    wns::Ratio rnf)
00290     :ReceiverBase(s, demodulator, decoder, rnf),
00291      antenna(a)
00292 {}
00293 Receiver::~Receiver()
00294 {
00295     antenna = 0;
00296 }
00298 wns::Ratio Receiver::getLoss(Transmitter* t)
00299 {
00300     double freq = 0;
00301     long int nSB = prc.size();
00302     for(long int i = 0; i < nSB; ++i)
00303         freq += prc[i]->getFrequency();
00304     return propCache->getLoss(t, freq);
00305 }
00306 
00307 
00308 
00309 

Generated on Sun May 27 03:31:58 2012 for openWNS by  doxygen 1.5.5