User Manual, Developers Guide and API Documentation

BestCapacity.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-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/strategy/dsastrategy/BestCapacity.hpp>
00029 #include <WNS/scheduler/strategy/dsastrategy/DSAStrategyInterface.hpp>
00030 #include <WNS/scheduler/SchedulerTypes.hpp>
00031 #include <vector>
00032 #include <iostream>
00033 #include <algorithm>
00034 
00035 using namespace wns::scheduler;
00036 using namespace wns::scheduler::strategy;
00037 using namespace wns::scheduler::strategy::dsastrategy;
00038 
00039 STATIC_FACTORY_REGISTER_WITH_CREATOR(BestCapacity,
00040                                      DSAStrategyInterface,
00041                                      "BestCapacity",
00042                                      wns::PyConfigViewCreator);
00043 
00044 BestCapacity::BestCapacity(const wns::pyconfig::View& config)
00045     : DSAStrategy(config)
00046 {
00047     //useRandomChannelAtBeginning =
00048     //config.get<bool>("useRandomChannelAtBeginning");
00049 }
00050 
00051 BestCapacity::~BestCapacity()
00052 {
00053 }
00054 
00055 // call this before each timeSlot/frame
00056 void
00057 BestCapacity::initialize(SchedulerStatePtr schedulerState,
00058                          SchedulingMapPtr schedulingMap)
00059 {
00060     DSAStrategy::initialize(schedulerState,schedulingMap); // must always initialize base class too
00061     if (!userInfoMap.empty())
00062     {
00063         userInfoMap.clear();
00064     }
00065     // just a SmartPtr:
00066     //ChannelQualitiesOfAllUsersPtr
00067     assure(schedulerState->currentState!=RevolvingStatePtr(),"currentState must be valid");
00068     // set member:
00069     channelQualitiesOfAllUsers =
00070         schedulerState->currentState->channelQualitiesOfAllUsers;
00071 }
00072 
00073 DSAResult
00074 BestCapacity::getSubChannelWithDSA(RequestForResource& request,
00075                                    SchedulerStatePtr schedulerState,
00076                                    SchedulingMapPtr schedulingMap)
00077 {
00078     DSAResult dsaResult;
00079     UserID user = request.user;
00080     if (userInfoMap.find(user) == userInfoMap.end()) {
00081         userInfoMap.insert(UserInfoMap::value_type(user, UserInfo(schedulerState->currentState->strategyInput->fChannels)));
00082     }
00083     UserInfo& userInfo = userInfoMap.find(user)->second;
00084 
00085     int lastUsedSubChannel = userInfo.lastUsedSubChannel;
00086     int subChannel = lastUsedSubChannel;
00087     int maxSubChannel = schedulingMap->subChannels.size();
00088     int maxTimeSlots = schedulerState->currentState->strategyInput->getNumberOfTimeSlots();
00089     int lastUsedTimeSlot = userInfo.lastUsedTimeSlot;
00090     int timeSlot = lastUsedTimeSlot;
00091 
00092     assure(maxSubChannel==schedulerState->currentState->strategyInput->fChannels,"maxSubChannel="<<maxSubChannel<<"!=fChannels");
00093     ChannelQualitiesOnAllSubBandsPtr channelQualitiesOnAllSubBands = userInfo.channelQualitiesOnAllSubBands;
00094     if (channelQualitiesOnAllSubBands==ChannelQualitiesOnAllSubBandsPtr()) { // empty
00095         assure(channelQualitiesOfAllUsers->knowsUser(user),"channelQualitiesOfAllUsers["<<user.getName()<<"] invalid");
00096         // ^ or should we ask the registryProxy for CQI here?
00097         channelQualitiesOnAllSubBands = channelQualitiesOfAllUsers->find(user)->second;
00098         userInfo.channelQualitiesOnAllSubBands = channelQualitiesOnAllSubBands;
00099     }
00100     MESSAGE_SINGLE(NORMAL, logger, "getSubChannelWithDSA("<<request.toString()<<"): lastSC="<<lastUsedSubChannel);
00101 
00102     int spatialLayer=0;
00103     bool found  = false;
00104     bool giveUp = false;
00105     if (!schedulerState->isTx
00106         && adjacentSubchannelsOnUplink
00107         && (lastUsedSubChannel!=DSAsubChannelNotFound) // already used subChannel
00108         )
00109     { // UL SC-FDMA
00110         // adjacentSubchannelsOnUplink
00111         while(!found && !giveUp)
00112         {
00113             // try same old subChannel again:
00114             subChannel = lastUsedSubChannel;
00115             if (!userInfo.usedSubChannels[subChannel]
00116                 && channelIsUsable(subChannel, timeSlot, request, schedulerState, schedulingMap))
00117             { // PDU fits in
00118                 found=true; break;
00119             } else { // mark unusable
00120                 userInfo.usedSubChannels[subChannel] = true;
00121             }
00122             // TODO: consider timeSlots !!!
00123 
00124             // try +/-1 +/-2 and so on
00125             for (int tryThisSubChannelOffset=0; tryThisSubChannelOffset<maxSubChannel/2; tryThisSubChannelOffset++)
00126             {
00127                 subChannel = (lastUsedSubChannel + tryThisSubChannelOffset*userInfo.toggleOffset);
00128                 if ((subChannel>=0) && !userInfo.usedSubChannels[subChannel]
00129                     && (subChannel<maxSubChannel)
00130                     && channelIsUsable(subChannel, timeSlot, request, schedulerState, schedulingMap))
00131                 { // PDU fits in
00132                     found=true; break;
00133                 } else { // mark unusable
00134                     userInfo.usedSubChannels[subChannel] = true;
00135                 }
00136                 subChannel = (lastUsedSubChannel - tryThisSubChannelOffset*userInfo.toggleOffset);
00137                 if ((subChannel>=0) && !userInfo.usedSubChannels[subChannel]
00138                     && (subChannel<maxSubChannel)
00139                     && channelIsUsable(subChannel, timeSlot, request, schedulerState, schedulingMap))
00140                 { // PDU fits in
00141                     found=true; break;
00142                 } else { // mark unusable
00143                     userInfo.usedSubChannels[subChannel] = true;
00144                 }
00145             } // for offset +/-
00146             // the resulting DSA may not be contiguous in the case of another small-band user nearby
00147         } // while
00148         userInfo.toggleOffset *= -1;
00149     } else { // free search
00150         BetterChannelCapacity comparator; // from SchedulerTypes.hpp
00151         wns::service::phy::phymode::PhyModeMapperInterface* phyModeMapper = colleagues.registry->getPhyModeMapper();
00152         double channelCapacity = 0.0;
00153         double remainingTimeOnthisChannel = 0.0;
00154         wns::Power nominalPower;
00155         // to get tx power, default or nominal
00156         // the same power will be used on all subchannels for comparing, so that
00157         // the best capacity depend only on the free time and datarate
00158         if (schedulerState->defaultTxPower!=wns::Power())
00159         { // predefined, e.g. in slave mode
00160             nominalPower = schedulerState->defaultTxPower;
00161         } else {
00162             wns::scheduler::PowerCapabilities powerCapabilities =
00163                 schedulerState->strategy->getPowerCapabilities(request.user);
00164             nominalPower = powerCapabilities.nominalPerSubband;
00165         }
00166 
00167         // O(N^2) operations:
00168         while(!found && !giveUp)
00169         {
00170             subChannel = DSAsubChannelNotFound;
00171             double bestChannelCapacity = 0.0;
00172             // find channel with best capacity of the remaining subChannels:
00173             for (int tryThisSubChannel=0; tryThisSubChannel<maxSubChannel; tryThisSubChannel++)
00174             {
00175                 for (int tryThisTimeSlot=0; tryThisTimeSlot<maxTimeSlots; tryThisTimeSlot++)
00176                 {
00177                     // TODO: userInfo.usedSubChannels[tryThisSubChannel][tryThisTimeSlot]
00178                     if (!userInfo.usedSubChannels[tryThisSubChannel]) { // could be free (at least not checked before)
00179                         ChannelQualityOnOneSubChannel channelQuality
00180                             = (*channelQualitiesOnAllSubBands)[tryThisSubChannel];
00181                         if (channelIsUsable(tryThisSubChannel, tryThisTimeSlot, request, schedulerState, schedulingMap))
00182                         {
00183                             spatialLayer = getSpatialLayerForSubChannel(tryThisSubChannel, tryThisTimeSlot, request, schedulerState, schedulingMap);
00184                         }
00185                         else
00186                         {
00187                             continue;
00188                         }
00189 
00190                         remainingTimeOnthisChannel = schedulingMap->subChannels[tryThisSubChannel].temporalResources[tryThisTimeSlot]->physicalResources[spatialLayer].getFreeTime();
00191                         wns::Ratio sinr = nominalPower/(channelQuality.interference * channelQuality.pathloss.get_factor());
00192                         wns::SmartPtr<const wns::service::phy::phymode::PhyModeInterface> bestPhyMode = phyModeMapper->getBestPhyMode(sinr);
00193                         channelCapacity = bestPhyMode->getDataRate() * remainingTimeOnthisChannel;
00194 
00195                         if (comparator(channelCapacity, bestChannelCapacity)) {
00196                             bestChannelCapacity = channelCapacity;
00197                             subChannel = tryThisSubChannel;
00198                             timeSlot = tryThisTimeSlot;
00199                         }
00200                     } // if unused
00201                 } // forall tryThisTimeSlot
00202             } // forall tryThisSubChannel
00203 
00204             if (subChannel==DSAsubChannelNotFound)
00205             { // one complete round already done
00206                 giveUp=true; break;
00207             }
00208             // best subChannel and spatialLayer found; now check if usable:
00209             if (channelIsUsable(subChannel, timeSlot, spatialLayer, request, schedulerState, schedulingMap))
00210             { // PDU fits in
00211                 found=true; break;
00212             } else { // mark unusable
00213                 // TODO: userInfo.usedSubChannels[tryThisSubChannel][tryThisTimeSlot]
00214                 userInfo.usedSubChannels[subChannel] = true;
00215             }
00216         } // while
00217     } // if free search or linear (SC-FDMA)
00218 
00219     if (giveUp) {
00220         MESSAGE_SINGLE(NORMAL, logger, "getSubChannelWithDSA(): no free subchannel");
00221         return dsaResult; // empty with subChannel=DSAsubChannelNotFound
00222     } else {
00223         MESSAGE_SINGLE(NORMAL, logger, "getSubChannelWithDSA(): subChannel="<<subChannel);
00224         userInfo.lastUsedSubChannel = subChannel;
00225         dsaResult.subChannel = subChannel;
00226         dsaResult.spatialLayer = spatialLayer;
00227         return dsaResult;
00228     }
00229     return dsaResult; // empty with subChannel=DSAsubChannelNotFound
00230 }
00231 

Generated on Mon May 21 03:31:56 2012 for openWNS by  doxygen 1.5.5