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 <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 

Generated on Sun May 27 03:32:18 2012 for openWNS by  doxygen 1.5.5