![]() |
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-2009 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 <WNS/scheduler/grouper/TreeBasedGrouper.hpp> 00029 00030 #include <WNS/pyconfig/View.hpp> 00031 #include <WNS/StaticFactory.hpp> 00032 #include <WNS/scheduler/SchedulerTypes.hpp> 00033 00034 #include <list> 00035 #include <math.h> 00036 #include <algorithm> 00037 00038 using namespace wns::scheduler; 00039 using namespace wns::scheduler::grouper; 00040 00041 TreeBasedGrouper::TreeBasedGrouper(const wns::pyconfig::View& config) 00042 : SpatialGrouper(config) 00043 { 00044 } 00045 00046 00047 std::map<UserID, wns::CandI> 00048 TreeBasedGrouper::getCandIsForGroup(const UserSet group, ModeType mode) 00049 { 00050 std::map<UserID, wns::CandI> candis; 00051 candis.clear(); 00052 00053 switch(mode) { 00054 case tx: 00055 { 00056 if(beamforming){ 00057 00058 std::map<wns::node::Interface*, wns::Power> userNoiseIInterMap; 00059 userNoiseIInterMap.clear(); 00060 00061 for (UserSet::const_iterator iter = group.begin(); 00062 iter != group.end(); ++iter) { 00063 UserID user = *iter; 00064 00065 userNoiseIInterMap[user.getNode()] = 00066 colleagues.registry->estimateTxSINRAt(user).interference; 00067 } 00068 00069 candis = convertMap(friends.ofdmaProvider->calculateCandIsTx(userNoiseIInterMap, x_friendliness, txPower)); 00070 } 00071 else{ 00072 assure(group.size() == 1, "We don't do beamforming, so only one-user groups are supported"); 00073 UserID user = *group.begin(); 00074 wns::scheduler::ChannelQualityOnOneSubChannel cqi = 00075 colleagues.registry->estimateTxSINRAt(user); 00076 candis[user] = wns::CandI(cqi.carrier, cqi.interference); 00077 00078 } 00079 MESSAGE_BEGIN(VERBOSE, logger, m, colleagues.registry->getNameForUser(colleagues.registry->getMyUserID())); 00080 00081 for (std::map<UserID, wns::CandI>::const_iterator iter = candis.begin(); 00082 iter != candis.end(); ++iter) 00083 m << " Selecting TX grouping for " 00084 << colleagues.registry->getNameForUser(iter->first) 00085 << "\nAssumed TxPower: " << txPower 00086 << "\nEstimated Carrier: " << iter->second.C 00087 << "\nEstimated Interference: " << iter->second.I << "\n" 00088 << "\nEstimated SDMA intra-cell interference: " << iter->second.sdma.iIntra << "\n"; 00089 MESSAGE_END(); 00090 break; 00091 } 00092 case rx: 00093 { 00094 if (beamforming){ 00095 std::vector<wns::node::Interface*> combination; 00096 combination.clear(); 00097 wns::Power meanBsInterference = wns::Power::from_mW(0.0); 00098 00099 for (UserSet::const_iterator user = group.begin(); 00100 user != group.end(); ++user) { 00101 combination.push_back(user->getNode()); 00102 meanBsInterference += colleagues.registry->estimateRxSINROf(*user).interference; 00103 } 00104 assure(combination.size() == group.size(), "we estimate SINRs for a different set of users than we were asked to do"); 00105 meanBsInterference /= static_cast<unsigned long int>(combination.size()); 00106 00107 candis = convertMap(friends.ofdmaProvider->calculateCandIsRx(combination, meanBsInterference)); 00108 } 00109 else{ // no beamforming 00110 00111 assure(group.size() == 1, "We don't do beamforming, so only one-user groups are supported"); 00112 UserID user = *group.begin(); 00113 wns::scheduler::ChannelQualityOnOneSubChannel cqi = 00114 colleagues.registry->estimateRxSINROf(user); 00115 candis[user] = wns::CandI(cqi.carrier, cqi.interference); 00116 } 00117 00118 MESSAGE_BEGIN(VERBOSE, logger, m, colleagues.registry->getNameForUser(colleagues.registry->getMyUserID())); 00119 for (std::map<UserID, wns::CandI>::const_iterator iter = candis.begin(); 00120 iter != candis.end(); ++iter) 00121 m << " Selecting RX grouping for " 00122 << colleagues.registry->getNameForUser(iter->first) 00123 << "\nEstimated Carrier: " << iter->second.C 00124 << "\nEstimated Interference: " << iter->second.I << "\n"; 00125 MESSAGE_END(); 00126 00127 break; 00128 } 00129 default: 00130 assure(0, "Wrong mode, can either be RX or TX"); 00131 } 00132 00133 return candis; 00134 } 00135 00136 00137 float 00138 TreeBasedGrouper::getTPfromTreeLevelByMode(const TreeLevel level, ModeType mode) 00139 { 00140 float throughput = 0.0; 00141 00142 // a tree level consists of a number of UserSets 00143 for (TreeLevel::const_iterator iter = level.begin(); 00144 iter != level.end(); ++iter) 00145 { 00146 UserSet group = *iter; 00147 std::map<UserID, wns::CandI> candis = getCandIsForGroup(group, mode); 00148 00149 for (std::map<UserID, wns::CandI>::const_iterator iter2 = candis.begin(); 00150 iter2 != candis.end(); ++iter2) { 00151 wns::Ratio sinr(iter2->second.C / iter2->second.I); 00152 //float dataRate = colleagues.registry->getPhyModeForSIR( iter2->second.C / iter2->second.I ).second; 00153 if (colleagues.phyModeMapper->sinrIsAboveLimit(sinr)) { 00154 double tp = colleagues.phyModeMapper->getBestPhyMode(sinr)->getDataRate(); 00155 throughput += tp; 00156 } else // user without service, we don't allow this 00157 return 0.0; 00158 } 00159 } 00160 00161 return throughput; 00162 } 00163 00164 Grouping 00165 TreeBasedGrouper::convertTreeLevelToGrouping(TreeLevel level, ModeType mode) 00166 { 00167 Grouping grouping; 00168 int groupCount = 0; 00169 00170 00171 // for all user groups in that level 00172 for (TreeLevel::const_iterator iter = level.begin(); 00173 iter != level.end(); ++iter) { 00174 UserSet users = *iter; 00175 groupCount++; 00176 00177 std::vector<wns::node::Interface*> usersInGroup; 00178 usersInGroup.clear(); 00179 00180 // calculate the pattern for every user in the group: 00181 for (UserSet::const_iterator iter2 = users.begin(); 00182 iter2 != users.end(); ++iter2) 00183 usersInGroup.push_back(iter2->getNode()); 00184 00186 // for every user generate a pattern that has the other group members as 00187 // undesired interferers 00188 for (unsigned int d = 0; d < usersInGroup.size(); ++d) { 00189 std::vector<wns::node::Interface*> undesireds; 00190 undesireds.clear(); 00191 for (unsigned int u = 0; u < usersInGroup.size(); ++u) 00192 if (d != u) 00193 undesireds.push_back(usersInGroup[u]); 00194 // calculate users pattern with his co-scheduled users as undesireds 00195 if(mode == tx){ 00196 grouping.patterns[UserID(usersInGroup[d])] = friends.ofdmaProvider-> 00197 calculateAndSetBeam(usersInGroup[d], undesireds, x_friendliness); 00198 } 00199 else{ 00200 // according to the estimation of C and I 00201 // values in getCandIsForGroup, the mean 00202 // interference level of the SSs is taken into 00203 // account 00204 wns::Power meanBsInterference = wns::Power::from_mW(0.0); 00205 for (UserSet::const_iterator user = users.begin(); 00206 user != users.end(); ++user) { 00207 meanBsInterference += colleagues.registry->estimateRxSINROf(*user).interference; 00208 } 00209 meanBsInterference /= static_cast<unsigned long int>(users.size()); 00210 00211 grouping.patterns[UserID(usersInGroup[d])] = friends.ofdmaProvider-> 00212 calculateAndSetBeam(usersInGroup[d], undesireds, meanBsInterference); 00213 // grouping.patterns[usersInGroup[d]] = friends.ofdmaProvider-> 00214 // calculateAndSetBeam(usersInGroup[d], undesireds, 00215 // colleagues.registry->estimateRxSINROf(usersInGroup[d])->interference; 00216 } 00217 00218 assure(grouping.patterns[UserID(usersInGroup[d])] != 00219 wns::service::phy::ofdma::PatternPtr(), "Invalid pattern returned"); 00220 } 00221 // calculate the SINR values for every user in the group 00222 Group newGroup = getCandIsForGroup(users, mode); 00223 // save it in grouping 00224 grouping.groups.push_back(newGroup); 00225 // and update the group look-up-table 00226 for (std::vector<wns::node::Interface*>::const_iterator iter2 = usersInGroup.begin(); 00227 iter2 != usersInGroup.end(); 00228 ++iter2) 00229 grouping.userGroupNumber[UserID(*iter2)] = groupCount; 00230 } // for all user groups in level 00231 return grouping; 00232 } 00233 00234 00235 00236 Grouping 00237 TreeBasedGrouper::getTxGrouping(const UserSet activeUsers, int maxBeams) { 00238 assure(colleagues.registry, "Registry not set"); 00239 assure(friends.ofdmaProvider, "OFDMAprovider not set"); 00240 00241 return treeAlgorithm(activeUsers, maxBeams, tx); 00242 } 00243 00244 Grouping 00245 TreeBasedGrouper:: getRxGrouping(const UserSet activeUsers, int maxBeams) { 00246 assure(colleagues.registry, "Registry not set"); 00247 assure(friends.ofdmaProvider, "OFDMAprovider not set"); 00248 00249 return treeAlgorithm(activeUsers, maxBeams, rx); 00250 } 00251 00252 00253 00254
1.5.5