![]() |
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 <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
1.5.5