interference_miv.cc

00001 /*
00002  * Copyright (c) 2007 Regents of the SIGNET lab, University of Padova.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the University of Padova (SIGNET lab) nor the 
00014  *    names of its contributors may be used to endorse or promote products 
00015  *    derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
00018  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 
00019  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
00020  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
00021  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00022  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
00023  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
00024  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
00025  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
00026  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
00027  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 #include"interference_miv.h"
00031 
00032 #include<iostream>
00033 #include <iomanip>
00034 
00035 #include"mphy.h"
00036 //#include <values.h>
00037 
00038 
00039 #define POWER_PRECISION_THRESHOLD (- 1e-14)
00040 
00041 
00042 static class MInterferenceMIVClass : public TclClass {
00043 public:
00044   MInterferenceMIVClass() : TclClass("MInterference/MIV") {}
00045   TclObject* create(int, const char*const*) {
00046     return (new MInterferenceMIV);
00047   }
00048 } class_minterference_miv;
00049 
00050 
00051 void EndInterferenceMIVTimer::handle(Event *e)
00052 {
00053   // This does not work, Event is not polymorphic
00054   //  PowerEvent* pe = dynamic_cast<PowerEvent*>(e);
00055   PowerEvent* pe = (PowerEvent*) e;
00056   mimiv->addToInterference( - pe->power, NOW);
00057   delete pe;
00058   if (mimiv->debug_) mimiv->dump("EndInterferenceMIVTimer::handle");
00059 }
00060 
00061 
00062 MInterferenceMIV::MInterferenceMIV()
00063   : endinterftimer(this)
00064 {
00065   bind("maxinterval_", &maxinterval_);
00066   bind("debug_", &debug_);
00067 }
00068 
00069 
00070 MInterferenceMIV::~MInterferenceMIV()
00071 {
00072 
00073 }
00074 
00075 
00076 void MInterferenceMIV::addToInterference(Packet* p)
00077 {
00078   hdr_MPhy *ph = HDR_MPHY(p);
00079   addToInterference(ph->Pr, NOW);
00080   PowerEvent* pe = new PowerEvent(ph->Pr);
00081   Scheduler::instance().schedule(&endinterftimer, pe, ph->duration);
00082   if (debug_) dump("MInterferenceMIV::addToInterference");
00083 }
00084 
00085 
00086 void MInterferenceMIV::addToInterference(double power, double starttime)
00087 {
00088   // Delete too old items
00089   Function::iterator it; 
00090   for (it = pp.begin(); it!=pp.end();  )
00091     {
00092       if (it->time < starttime - maxinterval_)
00093         {          
00094           it = pp.erase(it); // Side effect: it++          
00095         }
00096       else
00097         break;
00098     }
00099 
00100   // Add new item
00101 
00102   if (pp.empty())
00103     {
00104       Point newp(NOW, power);
00105       pp.push_back(newp);      
00106     }
00107   else
00108     {
00109       Point lastp(pp.back());
00110       Point newp(NOW, lastp.value + power);
00111 
00112       // Check for cancellation errors
00113       // which can arise when interference is subtracted
00114       if (newp.value < 0)
00115         {
00116           if (newp.value < POWER_PRECISION_THRESHOLD)
00117             {
00118               if (debug_)
00119                 std::cerr << "WARNING: interf=" << newp.value << " - cancellation error or bug?" << std::endl;
00120             }
00121           newp.value = 0;
00122         }
00123 
00124       pp.push_back(newp);
00125     }
00126 
00127 }
00128 
00129 
00130 
00131 double MInterferenceMIV::getInterferencePower(Packet* p)
00132 {
00133   hdr_MPhy *ph = HDR_MPHY(p);
00134   return (getInterferencePower(ph->Pr, ph->rxtime, ph->duration));  
00135 }
00136       
00137 
00138 
00139 double MInterferenceMIV::getInterferencePower(double power, double starttime, double duration)
00140 {
00141 
00142   Function::reverse_iterator rit; 
00143   
00144   double integral = 0;
00145   double lasttime = NOW;
00146 
00147   assert(starttime<= NOW);
00148   assert(duration > 0);
00149   assert(maxinterval_ > duration);
00150 
00151   for (rit = pp.rbegin(); rit != pp.rend(); ++rit )
00152     {
00153       if (starttime < rit->time)
00154         {
00155           integral += rit->value * (lasttime - rit->time);
00156           lasttime = rit->time;   
00157         }
00158       else
00159         {
00160           integral += rit->value * (lasttime - starttime);
00161           break;
00162         }
00163     }
00164 
00165   double interference = (integral/duration) - power;
00166 
00167   // Check for cancellation errors
00168   // which can arise when interference is subtracted
00169   if (interference < 0)
00170     {
00171       if (interference < POWER_PRECISION_THRESHOLD)
00172         {
00173           // should be a cancellation error, but it exceeds the
00174           // precision threshold, so we print a warning 
00175           if (debug_)
00176             cerr << "MInterferenceMIV::getInterferencePower() WARNING:" 
00177                  << " interference=" << interference 
00178                  << " POWER_PRECISION_THRESHOLD=" <<  POWER_PRECISION_THRESHOLD
00179                  << endl;
00180         }
00181       interference = 0;
00182     }
00183 
00184 
00185   if (debug_) {
00186     dump("MInterferenceMIV::getInterferencePower");
00187     std::cerr << "transmission from " << starttime 
00188               << " to " << starttime + duration 
00189               << " power " << power
00190               << " gets interference " << interference
00191               << std::endl;
00192   }
00193 
00194   return interference;
00195 }
00196 
00197 
00198 
00199 void MInterferenceMIV::dump(string msg)
00200 {
00201   Function::iterator it; 
00202 
00203   std::cerr  << NOW << " "
00204              << msg << std::endl;
00205 
00206   for (it = pp.begin(); it!=pp.end();  ++it)
00207     std::cerr << std::setw(7) << std::setprecision(5) <<it->value << " ";
00208 
00209   std::cerr << std::endl;
00210 
00211   for (it = pp.begin(); it!=pp.end();  ++it)
00212     std::cerr << std::setw(7) << std::setprecision(5) << it->time << " ";
00213 
00214   std::cerr << std::endl; 
00215 }     
00216 
00217 
00218 double MInterferenceMIV::getCurrentTotalPower()
00219 {
00220   if (pp.empty())
00221     return 0.0;
00222   else
00223     return (pp.back().value);
00224 }

Generated on Wed Nov 26 15:47:28 2008 for NS-MIRACLE library by  doxygen 1.5.2