![]() |
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 <OFDMAPHY/receiver/Receiver.hpp> 00029 00030 #include <OFDMAPHY/Station.hpp> 00031 #include <OFDMAPHY/Sender.hpp> 00032 #include <OFDMAPHY/OFDMAMeasurement.hpp> 00033 00034 #include <RISE/medium/PhysicalResource.hpp> 00035 #include <RISE/scenario/Scenario.hpp> 00036 #include <RISE/transceiver/transmitter.hpp> 00037 #include <RISE/transceiver/cache/idvectorcache.hpp> 00038 #include <RISE/receiver/PowerMeasurement.hpp> 00039 00040 #include <valarray> 00041 00042 using namespace ofdmaphy::receiver; 00043 00044 Receiver::Receiver(const wns::pyconfig::View& config, rise::Station* s) : 00045 ReceiverBase(config), 00046 OFDMAAspect(config.get<wns::Ratio>("receiverNoiseFigure")), 00047 FTFadingAspect(config), 00048 MeasurementAspect(config), 00049 LossCalculation(config), 00050 station(s), 00051 propagationCache(new rise::IdVectorCache(this)), 00052 activeTransmissions(), 00053 wraparoundShiftVectors(NULL), 00054 nSectors(config.get<int>("nSectors")) 00055 { 00056 activeTransmissions.clear(); 00057 this->startObserving(s); 00058 00059 if (measurementUpdatesAreOn()) 00060 { 00061 // can also be done if ftfading == NULL 00062 if ((getMeasurementUpdateInterval()==0.0) && (ftfading)) 00063 { 00064 setMeasurementUpdateInterval(ftfading->getSamplingTime()); 00065 } 00066 else if (FTFadingIsActive()) 00067 { 00068 assure(getMeasurementUpdateInterval() == ftfading->getSamplingTime(), 00069 "measurementUpdateInterval="<<getMeasurementUpdateInterval()<<" != ftfading::samplingTime="<<ftfading->getSamplingTime()); 00070 } 00071 else 00072 { 00073 00074 } 00075 00076 assure(getMeasurementUpdateInterval()>0.0, 00077 "doMeasurementUpdates=True but measurementUpdateInterval=0"); 00078 00079 MESSAGE_SINGLE(NORMAL, logger, "doMeasurementUpdates in intervals of "<<getMeasurementUpdateInterval()<<"s, offset="<<getMeasurementUpdateOffset()); 00080 startRegularMeasurementUpdates(); 00081 } 00082 00083 // handle wraparaoundShifts: 00084 wraparoundShiftVectors = s->getSystemManager()->getWraparoundShiftVectors(); 00085 00086 // Is wraparound switched on? Answer is: doWraparound = (wraparoundShiftVectors->size()>0) ? true:false; 00087 MESSAGE_SINGLE(NORMAL, logger, "wraparound: using "<<wraparoundShiftVectors->size()<<" ShiftVectors"); 00088 00089 // use the wraparoundShiftVectors like this: 00090 int shiftListLength = wraparoundShiftVectors->size(); 00091 for(int i=0; i<shiftListLength; i++) 00092 { 00093 wns::geometry::Vector v = (*wraparoundShiftVectors)[i]; 00094 const std::valarray<double> va = v.get(); 00095 MESSAGE_SINGLE(NORMAL, logger, "wraparoundShiftVectors["<<i<<"]=("<<va[0]<<","<<va[1]<<")"); 00096 } 00097 00098 mimoProcessing = mimo::CalculationStrategyFactory::creator( 00099 config.get<std::string>("mimoProcessing.__plugin__"))->create(config.getView("mimoProcessing"), 00100 this, 00101 &logger); 00102 } 00103 00104 Receiver::~Receiver() 00105 { 00106 delete propagationCache; 00107 activeTransmissions.clear(); 00108 // cleanup FTfading object: 00109 if (ftfading) 00110 { 00111 delete ftfading; 00112 ftfading=NULL; 00113 } 00114 } 00115 00116 // this overloads a method from rise::Receiver 00117 wns::Power 00118 Receiver::getRxPower(const rise::TransmissionObjectPtr& t) 00119 { 00120 wns::Power rxPower = getRxPower(t, getCurrentReceivePattern(t)); 00121 MESSAGE_BEGIN(VERBOSE, logger, m , "getRxPower"); 00122 m << "(from: " << dynamic_cast<Station*>(t->getTransmitter()->getStation())->getNode()->getName() << ") = "<< rxPower; 00123 MESSAGE_END(); 00124 return rxPower; 00125 } 00126 00127 wns::Ratio 00128 Receiver::getQuasiStaticPathLoss(const rise::TransmissionObjectPtr& t, wns::service::phy::ofdma::PatternPtr pattern) 00129 { 00130 double frequency = t->getPhysicalResource()->getFrequency(); 00131 rise::Transmitter* transmitter = t->getTransmitter(); 00132 assure(transmitter!=NULL,"transmitter==NULL"); 00133 00134 wns::Ratio transmittersAntennaGain = t->getTransmittersAntennaGain(getStation()->getAntenna()->getPosition()); 00135 // Idea: wns::Ratio transmittersAntennaGain = t->getTransmittersAntennaGain(getStation()->getPosition()->shift(x,y)); 00136 // Idea: wns::Ratio transmittersAntennaGain = t->getTransmittersAntennaGain(getStation()->getPosition()+wns::PositionOffset(x,y,0)); 00137 // Idea: instead of (x,y) we could use wns::PositionOffset() 00138 MESSAGE_SINGLE(VERBOSE,logger, " TransmittersAntennaGain: " << transmittersAntennaGain); 00139 00140 // pure static path loss (from propagationCache): 00141 wns::Ratio purePathLoss = getLoss(transmitter, frequency); 00142 MESSAGE_SINGLE(VERBOSE,logger, " PurePathLoss: " << purePathLoss); 00143 00144 wns::Ratio receiverAntennaGain; 00145 if (pattern == wns::service::phy::ofdma::PatternPtr()) 00146 { 00147 // no pattern = no beamforming 00148 // static antenna 00149 receiverAntennaGain = getStation()->getAntenna()->getGain(transmitter->getAntenna()->getPosition(), wns::service::phy::ofdma::PatternPtr()); 00150 MESSAGE_SINGLE(VERBOSE,logger, " ReceiverAntennaGain of Static Pattern: " << receiverAntennaGain); 00151 } 00152 else 00153 { 00154 // beamforming on 00155 Station* receiverOFDMAStation = dynamic_cast<Station*>(getStation()); 00156 assure(receiverOFDMAStation!=NULL, "station is not an OFDMA station (and may have no beamforming antenna)"); 00157 receiverAntennaGain = receiverOFDMAStation->getBFAntenna()->getGain(transmitter->getAntenna()->getPosition(), pattern); 00158 MESSAGE_SINGLE(VERBOSE,logger, " ReceiverAntennaGain of Beamformed Pattern: " << receiverAntennaGain); 00159 } 00160 // TODO: receiverOFDMAStation->getBFAntenna()->getGain() should deliver the same as 00161 // getStation()->getAntenna()->getGain() 00162 wns::Ratio pathLoss = purePathLoss - transmittersAntennaGain - receiverAntennaGain; 00163 00164 // todo: store it in a cache? 00165 MESSAGE_SINGLE(VERBOSE,logger, " getQuasiStaticPathLoss() = " << pathLoss); 00166 00167 return pathLoss; 00168 } 00169 00170 wns::Ratio 00171 Receiver::getFullPathLoss(const rise::TransmissionObjectPtr& t, wns::service::phy::ofdma::PatternPtr pattern) 00172 { 00173 wns::Ratio pathLoss = getQuasiStaticPathLoss(t,pattern); 00174 00175 MESSAGE_SINGLE(VERBOSE,logger, " getFullPathLoss() = " << pathLoss); 00176 return pathLoss; 00177 } 00178 00179 wns::Power 00180 Receiver::getRxPower(const rise::TransmissionObjectPtr& t, wns::service::phy::ofdma::PatternPtr pattern) 00181 { 00182 assure(t, "no existing transmission object"); 00183 00184 MESSAGE_BEGIN(VERBOSE, logger, m, "Receiver::getRxPower(User "); 00185 std::string userName; // only needed if VERBOSE 00186 Station* OFDMAStation = dynamic_cast<Station*>(t->getTransmitter()->getStation()); 00187 if (OFDMAStation == NULL) 00188 userName = "Unknown"; 00189 else 00190 userName = OFDMAStation->getNode()->getName(); 00191 m << userName <<"): "; 00192 MESSAGE_END(); 00193 00194 wns::Power rxPower = t->getTxPower(); 00195 MESSAGE_SINGLE(NORMAL, logger, "TxPower: " << rxPower); 00196 00197 wns::Ratio fullPathLoss = getFullPathLoss(t,pattern); 00198 MESSAGE_SINGLE(NORMAL, logger, "PathLoss Full (inside getRxPower) " << fullPathLoss ); 00199 00200 rxPower -= fullPathLoss; 00201 MESSAGE_SINGLE(NORMAL, logger, "RxPower: " << rxPower); 00202 return rxPower; 00203 } 00204 00205 wns::Power 00206 Receiver::getUnfilteredRxPower(const rise::TransmissionObjectPtr& t) 00207 { 00208 assure(t, "no existing transmission object"); 00209 00210 wns::Power rxPower = t->getTxPower(); 00211 00212 rxPower -= getLoss(t->getTransmitter(), t->getPhysicalResource()->getFrequency()); 00213 rxPower += t->getTransmittersAntennaGain(getStation()->getAntenna()->getPosition()); 00214 00215 if (ftfading) 00216 { 00217 int subBandIndex = getSubCarrierIndex(t->getPhysicalResource()->getFrequency()); 00218 rxPower += getFTFading(subBandIndex); // TODO: adapt 00219 } 00220 00221 MESSAGE_BEGIN(VERBOSE, logger, m , "Unfiltered RxPower: "); 00222 m << rxPower << " (i.e. without receiver Antenna Gain)"; 00223 MESSAGE_END(); 00224 00225 return rxPower; 00226 } 00227 00228 wns::Power 00229 Receiver::getAllRxPower(const int subCarrier) 00230 { 00231 wns::Power rxPower; 00232 assure(subCarrier >= 0, "Cannot measure RxPower of a subCarrier < 0\n"); 00233 assure(subCarrier <= getCurrentNumberOfSubCarriers(), "subCarrier is too large\n"); 00234 00235 // Add noise 00236 rxPower += getNoise(subCarrier); 00237 00238 // Add all current transmissions 00239 rise::medium::PhysicalResource::TransmissionObjectIterator itr; 00240 for (itr=physicalResources[subCarrier]->getTOBegin(); 00241 itr!=physicalResources[subCarrier]->getTOEnd(); 00242 ++itr) 00243 { 00244 rxPower += getRxPower(*itr); 00245 } 00246 00247 return rxPower; 00248 } 00249 00250 00251 wns::Power 00252 Receiver::getAllRxPower() 00253 { 00254 wns::Power rxPower; 00255 assure(getCurrentNumberOfSubCarriers() > 0, "Cannot measure RxPower without any subCarrier.\n"); 00256 00257 // foreach subcarrier... 00258 for(int SubCarrierIndex=0; SubCarrierIndex<getCurrentNumberOfSubCarriers(); ++SubCarrierIndex) 00259 { 00260 // ...add noise and transmissions 00261 rxPower += getAllRxPower(SubCarrierIndex); 00262 } 00263 return rxPower; 00264 } 00265 00266 00267 wns::Power Receiver::getInterference(const rise::TransmissionObjectPtr& t) 00268 { 00269 // Init with thermal noise plus receiver noise figure 00270 MESSAGE_SINGLE(NORMAL, logger, "---------------- Starting Interference Calculation -----------------"); 00271 wns::Power interference = getNoisePerSubChannel(); 00272 MESSAGE_SINGLE(NORMAL, logger, "Noise: " << interference ); 00273 MESSAGE_SINGLE(NORMAL, logger, "nSectors: " << nSectors ); 00274 00275 rise::medium::PhysicalResource::TransmissionObjectIterator itr; 00276 wns::service::phy::ofdma::PatternPtr currentPattern = getCurrentReceivePattern(t); 00277 00278 // Sum up the power of all active Transmissions itr on this PhysicalResource 00279 for(itr=t->getPhysicalResource()->getTOBegin(); 00280 itr!=t->getPhysicalResource()->getTOEnd(); 00281 ++itr) 00282 { 00283 if (*itr == t) 00284 { 00285 // Do not include power of this transmission 00286 } 00287 else 00288 { 00289 if (nSectors == 1) 00290 { 00291 interference += getRxPower(*itr, currentPattern); 00292 } 00293 else if (nSectors == 3) 00294 { 00295 wns::Position interfering = (*itr)->getTransmitter()->getAntenna()->getPosition(); 00296 Station* ofdmaStation = getOFDMAStation(); 00297 00298 MESSAGE_SINGLE(NORMAL, logger, ofdmaStation->getNode()->getName()); 00299 00300 if( (ofdmaStation->getNode()->getName().at(0)) == 'A' ) 00301 { 00302 MESSAGE_SINGLE(NORMAL, logger, "AP is the receiver" ); 00303 wns::Position BSpos = ofdmaStation->getBFAntenna()->getPosition(); 00304 00305 double phi = ((interfering - BSpos).getAzimuth()*180)/M_PI; 00306 00307 MESSAGE_BEGIN(NORMAL, logger, m, "Angle between "); 00308 m << (*itr)->getTransmitter()->getStation()->getStationId() + 1; 00309 m << " and " << ofdmaStation->getNode()->getNodeID() - 1; 00310 m << " is: " << phi; 00311 MESSAGE_END(); 00312 00313 if(phi <= 90 && phi >= -30) //for three sectors 00314 { 00315 MESSAGE_BEGIN(NORMAL, logger, m, "Interference due to "); 00316 m << (*itr)->getTransmitter()->getStation()->getStationId() + 1; 00317 m << " in the signal of station "; 00318 m << t->getTransmitter()->getStation()->getStationId() + 1; 00319 m << " at the receiver station "<< ofdmaStation->getNode()->getNodeID() - 1; 00320 m <<" : "<< getRxPower(*itr, currentPattern); 00321 MESSAGE_END(); 00322 00323 interference += getRxPower(*itr, currentPattern); 00324 } 00325 } 00326 else 00327 { 00328 MESSAGE_SINGLE(NORMAL, logger, "UT is the receiver" ); 00329 wns::Position SSpos = ofdmaStation->getBFAntenna()->getPosition(); 00330 00331 double phi = ((SSpos-interfering).getAzimuth()*180)/M_PI; 00332 00333 MESSAGE_BEGIN(NORMAL, logger, m, "Angle between "); 00334 m << ofdmaStation->getNode()->getNodeID() - 1; 00335 m << " and " << (*itr)->getTransmitter()->getStation()->getStationId() + 1; 00336 m << " is: " << phi; 00337 MESSAGE_END(); 00338 00339 if(phi <= 90 && phi >= -30)//for three sectors 00340 { 00341 interference += getRxPower(*itr, currentPattern); 00342 00343 MESSAGE_BEGIN(NORMAL, logger, m, "Interference due to "); 00344 m << (*itr)->getTransmitter()->getStation()->getStationId() + 1; 00345 m << " inside the signal of station "; 00346 m << t->getTransmitter()->getStation()->getStationId() + 1; 00347 m << " at the receiver station "; 00348 m << ofdmaStation->getNode()->getNodeID() -1; 00349 m <<" : "<< getRxPower(*itr, currentPattern); 00350 MESSAGE_END(); 00351 } 00352 } 00353 } // for 3 sectors 00354 else 00355 { 00356 interference += getRxPower(*itr, currentPattern); 00357 } 00358 MESSAGE_BEGIN(VERBOSE, logger, m, ""); 00359 m << "RxPower from StationId "; 00360 m << (*itr)->getTransmitter()->getStation()->getStationId(); 00361 m << " = " << getRxPower(*itr, currentPattern); 00362 MESSAGE_END(); 00363 } 00364 } 00365 00366 MESSAGE_SINGLE(VERBOSE, logger, "------- Finished Interference Calculation, Result: " << interference << " -----------------"); 00367 return interference; 00368 } 00369 00370 void 00371 Receiver::insertReceivePattern(wns::node::Interface* node, wns::service::phy::ofdma::PatternPtr pattern) 00372 { 00373 currentReceivePatterns[node] = pattern; 00374 } 00375 00376 void 00377 Receiver::removeReceivePattern(wns::node::Interface* node) 00378 { 00379 currentReceivePatterns.erase(node); 00380 } 00381 00382 void 00383 Receiver::setCurrentReceivePatterns(std::map<wns::node::Interface*, wns::service::phy::ofdma::PatternPtr> _currentReceivePatterns) 00384 { 00385 // old patterns are no longer valid 00386 currentReceivePatterns = _currentReceivePatterns; 00387 } 00388 00389 wns::service::phy::ofdma::PatternPtr 00390 Receiver::getCurrentReceivePattern(const rise::TransmissionObjectPtr& t) const 00391 { 00392 // station must not be an ofdmaphy station, but it must be a node provider 00393 Station* tmpStation = dynamic_cast<ofdmaphy::Station*>(t->getTransmitter()->getStation()); 00394 if (tmpStation) 00395 { 00396 return getCurrentReceivePattern(tmpStation->getNode()); 00397 } 00398 00399 Sender* tmpSender = dynamic_cast<ofdmaphy::Sender*>(t->getTransmitter()->getStation()); 00400 if (tmpSender) 00401 { 00402 return getCurrentReceivePattern(tmpSender->getMyNode()); 00403 } 00404 00405 throw wns::Exception("Unable to determine station type of sender"); 00406 } 00407 00408 wns::service::phy::ofdma::PatternPtr 00409 Receiver::getCurrentReceivePattern(wns::node::Interface* pStack) const 00410 { 00411 MESSAGE_SINGLE(VERBOSE, logger, "Searching ReceivePattern for node: " << pStack->getName()); 00412 std::map<wns::node::Interface*, wns::service::phy::ofdma::PatternPtr>::const_iterator itr; 00413 itr = currentReceivePatterns.find(pStack); 00414 00415 if( itr == currentReceivePatterns.end()) 00416 { 00417 // omni-directional reception performed with static antenna 00418 return wns::service::phy::ofdma::PatternPtr(); 00419 } 00420 else 00421 { 00422 // pattern pointed to the transmitter 00423 MESSAGE_SINGLE(VERBOSE, logger, "Found ReceivePattern for node: " << pStack->getName()); 00424 return itr->second; 00425 } 00426 } 00427 00428 void Receiver::writeCacheEntry(rise::PropCacheEntry& cacheEntry, rise::Transmitter* t, double freq) 00429 { 00430 cacheEntry.setPathloss(getPathloss(*t, freq)); 00431 cacheEntry.setShadowing(getShadowing(*t)); 00432 cacheEntry.setAntennaGain(wns::Ratio::from_dB(0)); 00433 cacheEntry.setValid(true); 00434 } 00435 00436 wns::Ratio Receiver::getLoss(rise::Transmitter* t, double f) 00437 { 00438 MESSAGE_BEGIN(VERBOSE, logger, m , " PathLossFromPropagationCache: "); 00439 m << propagationCache->getLoss(t, f); 00440 MESSAGE_END(); 00441 00442 return propagationCache->getLoss(t, f); 00443 } 00444 00445 void Receiver::positionChanged() 00446 { 00447 propagationCache->invalidatePropagationEntries(); 00448 } 00449 00450 void Receiver::positionWillChange() 00451 { 00452 signalLevelsChange(); 00453 } 00454 00455 // triggered by PhysicalResourceObserver::notify in RISE/PhysicalResource.cpp 00456 void Receiver::notify(rise::TransmissionObjectPtr t) 00457 { 00458 // Only if we were set to receive mode we listen to notifications 00459 if (! (getOFDMAStation()->isReceptionEnabled())) 00460 { 00461 return; 00462 } 00463 // Do not receive from myself 00464 if(t->getTransmitter()->getStation()->getStationId() == getStation()->getStationId()) 00465 { 00466 // For each started and stopped transmission, the Received Signal Strenght 00467 // (RSS) at the receiver changes. Upper FUs can observe the RSS to detect a 00468 // busy channel. 00469 // The signalling is made only if observers are present, as the operation 00470 // (adding dBm values) is costly and must be done for every packet at every receiver. 00471 if (this->wns::Subject<RSSInterface>::hasObservers()) 00472 { 00473 // For getAllRxPower, the notify() comes always too early (see 00474 // rise::medium::PhysicalResource): first the receiver is notified, then 00475 // the transmission is added or removed. Hence, we have to add/substract the 00476 // new/old transmission. The mobility is not effected, as both 00477 // getAllRxPower() and getRxPower() return a 'snapshot' of now 00478 if (t->getIsStart()) 00479 return; 00480 wns::Power newReceivedSignalStrength = getAllRxPower(); 00481 assure(newReceivedSignalStrength > getRxPower(t), "receivedSignalStrength is too low for current ongoing transmission\n"); 00482 newReceivedSignalStrength -= getRxPower(t); 00483 if (newReceivedSignalStrength != receivedSignalStrength) 00484 { 00485 // the new signal strength is propagated with a delay 00486 receivedSignalStrength = newReceivedSignalStrength; 00487 this->signalNewReceivedSignalStrength(); 00488 } 00489 } 00490 return; 00491 } 00492 00493 if (transmissionForMe(t)) 00494 { 00495 wns::node::Interface* sourceNode = registerSource(t); // for OFDMA 00496 // measurements 00497 00498 if (t->getIsStart()) 00499 { 00500 // start of transmission 00501 MESSAGE_BEGIN(NORMAL, logger, m, "ofdmaphy::Receiver::notify(): startOfTransmission"); 00502 if (Station* ofdmaStation = dynamic_cast<Station*>(t->getTransmitter()->getStation())) 00503 { 00504 m << " from " << ofdmaStation->getNode()->getName(); 00505 } 00506 MESSAGE_END(); 00507 00508 add(t); 00509 activeTransmissions.push_back(t); 00510 } 00511 else 00512 { 00513 // end of transmission 00514 if (find(activeTransmissions.begin(), activeTransmissions.end(), t) != activeTransmissions.end()) 00515 { 00516 MESSAGE_BEGIN(NORMAL, logger, m, "ofdmaphy::Receiver::notify(): endOfTransmission"); 00517 if (Station* ofdmaStation = dynamic_cast<Station*>(t->getTransmitter()->getStation())) 00518 { 00519 m << " from " << ofdmaStation->getNode()->getName(); 00520 } 00521 MESSAGE_END(); 00522 00523 endOfTransmission(t); 00524 // ^ inherited from TimeWeightedTransmissionAveraging::endOfTransmission 00525 // inherited from rise::Receiver, from rise::ReceiverInterface::TransmissionAveragingStrategy 00526 00527 wns::Ratio omniAttenuation = wns::Ratio::from_dB(0); 00528 wns::service::phy::ofdma::PatternPtr pattern = getCurrentReceivePattern(t); 00529 if (pattern != wns::service::phy::ofdma::PatternPtr()) 00530 { 00531 // not an empty pattern 00532 omniAttenuation = pattern->getOmniAttenuation(); 00533 } 00534 00535 Station* ofdmaStation = getOFDMAStation(); 00536 00537 if (doMeasurementUpdates) 00538 { 00539 // the periodic "big" ones 00540 wns::Ratio pathLoss = getQuasiStaticPathLoss(t, getCurrentReceivePattern(t)); // determine (again) 00541 saveMeasuredFlatPathloss(sourceNode,pathLoss); 00542 } 00543 00544 std::vector<wns::Ratio> postProcessingSINRFactor(1, wns::Ratio::from_factor(1.0)); 00545 // minimize calculation if MIMO is not used at all 00546 if(ofdmaStation->getNumAntennas() > 1 or t->getNumberOfSpatialStreams() > 1) 00547 { 00548 postProcessingSINRFactor = mimoProcessing->getPostProcessingSINRFactor(t); 00549 } 00550 // Get Interference + Noise 00551 wns::Power ipn = getAveragedInterference(t); 00552 wns::Power noise = getNoisePerSubChannel(); 00553 wns::Ratio iot = ipn / noise; 00554 00555 wns::Ratio ftFadingGain; 00556 if(FTFadingIsActive()) // MUE: We should have a NoFTFading by default returnin 0 dB 00557 { 00558 int subChannelIndex = getSubCarrierIndex(t->getPhysicalResource()->getFrequency()); 00559 ftFadingGain = getFTFading(sourceNode,subChannelIndex); 00560 } 00561 else 00562 { 00563 ftFadingGain = wns::Ratio::from_dB(0.0); 00564 } 00565 00566 wns::geometry::Point him = t->getTransmitter()->getStation()->getAntenna()->getPosition(); 00567 wns::geometry::Point me = getStation()->getAntenna()->getPosition(); 00568 double distance = (him - me).getR(); 00569 00570 wns::service::phy::power::PowerMeasurementPtr rxPowerMeasurementPtr = 00571 wns::SmartPtr<rise::receiver::PowerMeasurement> 00572 (new rise::receiver::PowerMeasurement(t, 00573 sourceNode, 00574 getAveragedRxPower(t) * ftFadingGain, 00575 ipn, 00576 iot, 00577 ftFadingGain, 00578 omniAttenuation, 00579 distance, 00580 postProcessingSINRFactor)); 00581 MESSAGE_SINGLE(NORMAL, logger, "PowerMeasurement="<<*rxPowerMeasurementPtr); 00582 00583 // pass received payload upwards in the stack: 00584 ofdmaStation->receiveData(t->getPayload(), 00585 rxPowerMeasurementPtr); 00586 00587 // update list of receive power of stations in the BFAntenna 00588 // periodically. Note that we have to store unfiltered Rx Power, 00589 // i.e. not taking into account any antenna gains at this receiver 00590 if (ofdmaStation->beamformingEnabled()) 00591 { 00592 Station* transmitterStation = static_cast<Station*>(t->getTransmitter()->getStation()); 00593 ofdmaStation->getBFAntenna() 00594 ->setPowerReceivedForStation(transmitterStation, getUnfilteredRxPower(t)); 00595 ofdmaStation->getBFAntenna() 00596 ->setTxPowerForStation(transmitterStation, t->getTxPower()); 00597 } 00598 00599 remove(t); 00600 assure(find(activeTransmissions.begin(), activeTransmissions.end(),t) != activeTransmissions.end(), 00601 "Mismatch in Transmission Notifications!"); 00602 activeTransmissions.remove(t); 00603 } 00604 else 00605 { 00606 // Do nothing, we haven't heard the beginning of the 00607 // transmission. This can happen if we tune to a new frequency 00608 // and bandwidth. Then transmissions are already active on a 00609 // PhyiscalResource. We will be notified about their end of 00610 // transmission but haven't heard the start ... 00611 } 00612 } 00613 } // transmission was for me 00614 else 00615 { 00616 signalLevelsChange(); 00617 } // transmission was not for me 00618 00619 // For each started and stopped transmission, the Received Signal Strenght 00620 // (RSS) at the receiver changes. Upper FUs can observe the RSS to detect a 00621 // busy channel. 00622 // The signalling is made only if observers are present, as the operation 00623 // (adding dBm values) is costly and must be done for every packet at every receiver. 00624 if (this->wns::Subject<RSSInterface>::hasObservers()) 00625 { 00626 // For getAllRxPower, the notify() comes always too early (see 00627 // rise::medium::PhysicalResource): first the receiver is notified, then 00628 // the transmission is added or removed. Hence, we have to add/substract the 00629 // new/old transmission. The mobility is not effected, as both 00630 // getAllRxPower() and getRxPower() return a 'snapshot' of now 00631 wns::Power newReceivedSignalStrength = getAllRxPower(); 00632 if (t->getIsStart()) 00633 { 00634 newReceivedSignalStrength += getRxPower(t); 00635 } 00636 else 00637 { 00638 assure(newReceivedSignalStrength > getRxPower(t), "receivedSignalStrength is too low for current ongoing transmission\n"); 00639 newReceivedSignalStrength -= getRxPower(t); 00640 } 00641 00642 if (newReceivedSignalStrength != receivedSignalStrength) 00643 { 00644 // the new signal strength is propagated with a delay 00645 receivedSignalStrength = newReceivedSignalStrength; 00646 this->signalNewReceivedSignalStrength(); 00647 } 00648 } 00649 } // Receiver::notify() 00650 00651 void 00652 Receiver::signalNewReceivedSignalStrength() 00653 { 00654 MESSAGE_SINGLE(NORMAL, logger, "notify: New carrier-sense of " << receivedSignalStrength); 00655 this->wns::Subject<RSSInterface>::forEachObserver(OnNewRSS(receivedSignalStrength)); 00656 } 00657 00658 void 00659 Receiver::updateRequest() 00660 { 00661 receivedSignalStrength = getAllRxPower(); 00662 this->wns::Subject<RSSInterface>::forEachObserver(OnNewRSS(receivedSignalStrength)); 00663 } 00664 00665 void 00666 Receiver::doMeasurementsNow() 00667 { 00668 int numberOfSubChannels=getCurrentNumberOfSubCarriers(); 00669 MESSAGE_SINGLE(NORMAL,logger, "doMeasurementsNow(): "<<perSourceMap.size()<<" sources, "<<numberOfSubChannels<<" subChannels:"); 00670 00671 Station* ofdmaStation = getOFDMAStation(); 00672 wns::Power interferenceTemplate = getNoisePerSubChannel(); // only Noise 00673 // algorithm: iterate over all (relevant) sources (all at BS, 1 at UT) 00674 00675 for (PerSourceMap::iterator perSourceIterator = perSourceMap.begin(); 00676 perSourceIterator != perSourceMap.end(); 00677 ++perSourceIterator) 00678 { 00679 wns::node::Interface *source = perSourceIterator->first; 00680 assure(source!=NULL,"source==NULL"); 00681 00682 PerSourceContainer& perSourceContainer = perSourceIterator->second; 00683 wns::Ratio quasiStaticPathLoss = perSourceContainer.quasiStaticPathLoss; 00684 rise::scenario::ftfading::FTFading* ftfading = perSourceContainer.ftfading; 00685 00686 assure((int)perSourceContainer.interferenceVector.size()==numberOfSubChannels, 00687 "wrong interferenceVector.size="<<perSourceContainer.interferenceVector.size()); 00688 00689 MESSAGE_SINGLE(NORMAL, logger, " source="<<source->getName()<<": PL="<<quasiStaticPathLoss<<", c="<<perSourceContainer.packetCount); 00690 wns::service::phy::power::OFDMAMeasurementPtr ofdmaMeasurementPtr = 00691 ofdmaphy::OFDMAPHYMeasurementPtr 00692 (new ofdmaphy::OFDMAMeasurement(source, 00693 numberOfSubChannels, 00694 measurementUpdateInterval, 00695 quasiStaticPathLoss, 00696 ftfading, 00697 perSourceContainer.interferenceVector, // big copy 00698 logger)); 00699 00700 00701 // send measurements 00702 ofdmaStation->measurementUpdate(source,ofdmaMeasurementPtr); 00703 00704 // new vector object 00705 perSourceContainer.interferenceVector = 00706 std::vector<wns::Power>(numberOfSubChannels,interferenceTemplate); 00707 } // forall sources 00708 } 00709 00710 bool 00711 Receiver::isReceiving() const 00712 { 00713 return (!activeTransmissions.empty()); 00714 } 00715 00716 // very useful for debugging: 00717 std::string 00718 Receiver::printActiveTransmissions() const 00719 { 00720 assure(this!=NULL,"Houston, we have a problem"); 00721 std::stringstream s; 00722 s << "activeTransmissions =" << std::endl; 00723 //TransmissionObjectPtrList activeTransmissions; 00724 for ( TransmissionObjectPtrList::const_iterator iter = activeTransmissions.begin(); 00725 iter != activeTransmissions.end(); ++iter) 00726 { 00727 rise::TransmissionObjectPtr transmissionObject = *iter; // SmartPtr 00728 s << transmissionObject->toString() << std::endl; 00729 00730 } 00731 return s.str(); 00732 } 00733 00734 void Receiver::mobilityUpdate(rise::Transmitter* t) 00735 { 00736 signalLevelsChange(); 00737 propagationCache->invalidatePropagationEntries(t); 00738 } 00739 00740 void Receiver::tune(double f, double b, int numberOfSubCarriers) 00741 { 00742 activeTransmissions.clear(); 00743 this->removeAll(); 00744 00745 MESSAGE_SINGLE(NORMAL, logger, "ofdmaphy::Receiver::tune(f="<<f<<",b="<<b<<",#SC="<<numberOfSubCarriers<<")"); 00746 00747 OFDMAAspect::tune(f, b, numberOfSubCarriers); // inherited 00748 00749 // Change of frequency means new received signal strength 00750 if (this->wns::Subject<RSSInterface>::hasObservers()) 00751 { 00752 wns::Power newReceivedSignalStrength = getAllRxPower(); 00753 if (newReceivedSignalStrength != receivedSignalStrength) 00754 { 00755 receivedSignalStrength = newReceivedSignalStrength; 00756 MESSAGE_SINGLE(NORMAL, logger, "tune: New carrier-sense of " << receivedSignalStrength); 00757 this->wns::Subject<RSSInterface>::forEachObserver(OnNewRSS(receivedSignalStrength)); 00758 } 00759 } 00760 } 00761 00762 00763
1.5.5