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