Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

energy-model.cc

Go to the documentation of this file.
00001 /* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- 
00002  *
00003  * Copyright (c) 1997, 2000 Regents of the University of California.
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. All advertising materials mentioning features or use of this software
00015  *    must display the following acknowledgement:
00016  *      This product includes software developed by the Computer Systems
00017  *      Engineering Group at Lawrence Berkeley Laboratory.
00018  * 4. Neither the name of the University nor of the Laboratory may be used
00019  *    to endorse or promote products derived from this software without
00020  *    specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00023  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00026  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00027  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00028  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00031  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00032  * SUCH DAMAGE.
00033  *
00034  * $Header: /nfs/jade/vint/CVSROOT/ns-2/mobile/energy-model.cc,v 1.5 2000/08/31 20:11:49 haoboy Exp $
00035  */
00036 
00037 // Contributed by Satish Kumar <kkumar@isi.edu>
00038 
00039 #include <stdarg.h>
00040 #include <float.h>
00041 
00042 #include "random.h"
00043 #include "energy-model.h"
00044 #include "mobilenode.h"
00045 #include "god.h"
00046 
00047 static class EnergyModelClass : public TclClass
00048 {
00049 public:
00050         EnergyModelClass ():TclClass ("EnergyModel") {}
00051         TclObject *create (int argc, const char *const *argv) {
00052                 if (argc == 8) {
00053                         MobileNode *n=(MobileNode*)TclObject::lookup(argv[4]);
00054                         return (new EnergyModel(n, atof(argv[5]), 
00055                                                 atof(argv[6]), atof(argv[7])));
00056                 } else {
00057                         Tcl::instance().add_error("Wrong arguments to ErrorModel");
00058                         return 0;
00059                 }
00060         }
00061 } class_energy_model;
00062 
00063 void EnergyModel::DecrTxEnergy(double txtime, double P_tx) 
00064 {
00065         double dEng = P_tx * txtime;
00066         if (energy_ <= dEng)
00067                 energy_ = 0.0;
00068         else
00069                 energy_ = energy_ - dEng;
00070         if (energy_ <= 0.0)
00071                 God::instance()->ComputeRoute();
00072 }
00073 
00074 
00075 void EnergyModel::DecrRcvEnergy(double rcvtime, double P_rcv) 
00076 {
00077         double dEng = P_rcv * rcvtime;
00078         if (energy_ <= dEng)
00079                 energy_ = 0.0;
00080         else
00081                 energy_ = energy_ - dEng;
00082         if (energy_ <= 0.0)
00083                 God::instance()->ComputeRoute();
00084 }
00085 
00086 void EnergyModel::DecrIdleEnergy(double idletime, double P_idle) 
00087 {
00088         double dEng = P_idle * idletime;
00089         if (energy_ <= dEng)
00090                 energy_ = 0.0;
00091         else
00092                 energy_ = energy_ - dEng;
00093         if (energy_ <= 0.0)
00094                 God::instance()->ComputeRoute();
00095 }
00096 
00097 // XXX Moved from node.cc. These wireless stuff should NOT stay in the 
00098 // base node.
00099 void EnergyModel::start_powersaving()
00100 {
00101         snh_ = new SoftNeighborHandler(this);
00102         snh_->start();
00103         
00104         afe_ = new AdaptiveFidelityEntity(this);
00105         afe_->start();
00106 
00107         state_ = EnergyModel::POWERSAVING;
00108         state_start_time_ = Scheduler::instance().clock();
00109 }
00110 
00111 void EnergyModel::set_node_sleep(int status)
00112 {
00113         Tcl& tcl=Tcl::instance();
00114         //static float last_time_gosleep;
00115         // status = 1 to set node into sleep mode
00116         // status = 0 to put node back to idle mode.
00117         // time in the sleep mode should be used as credit to idle 
00118         // time energy consumption
00119         if (status) {
00120                 last_time_gosleep = Scheduler::instance().clock();
00121                 //printf("id=%d : put node into sleep at %f\n",
00122                 // address_,last_time_gosleep);
00123                 sleep_mode_ = status;
00124                 if (node_->exist_namchan()) 
00125                         tcl.evalf("%s add-mark m1 blue hexagon",node_->name());
00126         } else {
00127                 sleep_mode_ = status;
00128                 if (node_->exist_namchan()) 
00129                         tcl.evalf("%s delete-mark m1", node_->name()); 
00130                 //printf("id= %d last_time_sleep = %f\n",
00131                 // address_, last_time_gosleep);
00132                 if (last_time_gosleep) {
00133                         total_sleeptime_ += Scheduler::instance().clock() -
00134                                 last_time_gosleep;
00135                         last_time_gosleep = 0;
00136                 }
00137         }       
00138 }
00139 
00140 void EnergyModel::set_node_state(int state)
00141 {
00142         switch (state_) { 
00143         case POWERSAVING:
00144         case WAITING:
00145                 state_ = state;
00146                 state_start_time_ = Scheduler::instance().clock();
00147                 break;
00148         case INROUTE:
00149                 if (state == POWERSAVING) {
00150                         state_ = state;
00151                 } else if (state == INROUTE) {
00152                         // a data packet is forwarded, needs to reset 
00153                         // state_start_time_
00154                         state_start_time_= Scheduler::instance().clock();
00155                 }
00156                 break;
00157         default:
00158                 printf("Wrong state, quit...\n");
00159                 abort();
00160         }
00161 }
00162 
00163 void EnergyModel::add_neighbor(u_int32_t nodeid)
00164 {
00165         neighbor_list_item *np;
00166         np = neighbor_list.head;
00167         for (; np; np = np->next) {
00168                 if (np->id == nodeid) {
00169                         np->ttl = maxttl_;
00170                         break;
00171                 }
00172         }
00173         if (!np) {      // insert this new entry
00174                 np = new neighbor_list_item;
00175                 np->id = nodeid;
00176                 np->ttl = maxttl_;
00177                 np->next = neighbor_list.head;
00178                 neighbor_list.head = np;
00179                 neighbor_list.neighbor_cnt_++;
00180         }
00181 }
00182 
00183 void EnergyModel::scan_neighbor()
00184 {
00185         neighbor_list_item *np, *lp;
00186         if (neighbor_list.neighbor_cnt_ > 0) {
00187                 lp = neighbor_list.head;
00188                 np = lp->next;
00189                 for (; np; np = np->next) {
00190                         np->ttl--;
00191                         if (np->ttl <= 0){
00192                                 lp->next = np->next;
00193                                 delete np;
00194                                 np = lp;
00195                                 neighbor_list.neighbor_cnt_--;
00196                         } 
00197                         lp = np;
00198                 }
00199                 // process the first element
00200                 np = neighbor_list.head;
00201                 np->ttl--;
00202                 if (np->ttl <= 0) {
00203                         neighbor_list.head = np->next;
00204                         delete np;
00205                         neighbor_list.neighbor_cnt_--;
00206                 }
00207         }
00208 }
00209 
00210 
00211 void SoftNeighborHandler::start()
00212 {
00213         Scheduler::instance().schedule(this, &intr, CHECKFREQ);
00214 }
00215 
00216 void SoftNeighborHandler::handle(Event *)
00217 {
00218         Scheduler &s = Scheduler::instance();
00219         nid_->scan_neighbor();
00220         s.schedule(this, &intr, CHECKFREQ);
00221 }
00222 
00223 void AdaptiveFidelityEntity::start()
00224 {
00225         sleep_time_ = 2;
00226         sleep_seed_ = 2;
00227         idle_time_ = 10;
00228         nid_->set_node_sleep(0);
00229         Scheduler::instance().schedule(this, &intr, 
00230                                        Random::uniform(0, idle_time_));
00231 }
00232 
00233 void AdaptiveFidelityEntity::handle(Event *)
00234 {
00235         Scheduler &s = Scheduler::instance();
00236         int node_state = nid_->state();
00237         switch (node_state) {
00238         case EnergyModel::POWERSAVING:
00239                 if (nid_->sleep()) {
00240                         // node is in sleep mode, wake it up
00241                         nid_->set_node_sleep(0);
00242                         adapt_it();
00243                         s.schedule(this, &intr, idle_time_);
00244                 } else {
00245                         // node is in idle mode, put it into sleep
00246                         nid_->set_node_sleep(1);
00247                         adapt_it();
00248                         s.schedule(this, &intr, sleep_time_);
00249                 }
00250                 break;
00251         case EnergyModel::INROUTE:
00252                 // 100s is the maximum INROUTE time.
00253                 if (s.clock()-(nid_->state_start_time()) < 
00254                     nid_->max_inroute_time()) {
00255                         s.schedule(this, &intr, idle_time_);
00256                 } else {
00257                         nid_->set_node_state(EnergyModel::POWERSAVING);
00258                         adapt_it();
00259                         nid_->set_node_sleep(1);
00260                         s.schedule(this, &intr, sleep_time_); 
00261                 }
00262                 break;
00263         case EnergyModel::WAITING:
00264                 // 10s is the maximum WAITING time
00265                 if (s.clock()-(nid_->state_start_time()) < MAX_WAITING_TIME) {
00266                         s.schedule(this, &intr, idle_time_);
00267                 } else {
00268                         nid_->set_node_state(EnergyModel::POWERSAVING);
00269                         adapt_it();
00270                         nid_->set_node_sleep(1);
00271                         s.schedule(this, &intr, sleep_time_); 
00272                 }
00273                 break;
00274         default:
00275                 fprintf(stderr, "Illegal Node State!");
00276                 abort();
00277         }
00278 }
00279 
00280 void AdaptiveFidelityEntity::adapt_it()
00281 {
00282         float delay;
00283         // use adaptive fidelity
00284         if (nid_->adaptivefidelity()) {
00285                 int neighbors = nid_->getneighbors();
00286                 if (!neighbors) 
00287                         neighbors = 1;
00288                 delay = sleep_seed_ * Random::uniform(1,neighbors); 
00289                 set_sleeptime(delay);
00290         }
00291 }
00292 

Generated on Tue Apr 20 12:14:16 2004 for NS2.26SourcesOriginal by doxygen 1.3.3