energy-model.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:9k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- 
  2.  *
  3.  * Copyright (c) 1997, 2000 Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. All advertising materials mentioning features or use of this software
  15.  *    must display the following acknowledgement:
  16.  * This product includes software developed by the Computer Systems
  17.  * Engineering Group at Lawrence Berkeley Laboratory.
  18.  * 4. Neither the name of the University nor of the Laboratory may be used
  19.  *    to endorse or promote products derived from this software without
  20.  *    specific prior written permission.
  21.  *
  22.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  23.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  26.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  27.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  28.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  31.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  32.  * SUCH DAMAGE.
  33.  *
  34.  * $Header: /cvsroot/nsnam/ns-2/mobile/energy-model.cc,v 1.6 2005/06/13 17:50:41 haldar Exp $
  35.  */
  36. // Contributed by Satish Kumar <kkumar@isi.edu>
  37. #include <stdarg.h>
  38. #include <float.h>
  39. #include "random.h"
  40. #include "energy-model.h"
  41. #include "mobilenode.h"
  42. #include "god.h"
  43. static class EnergyModelClass : public TclClass
  44. {
  45. public:
  46. EnergyModelClass ():TclClass ("EnergyModel") {}
  47. TclObject *create (int argc, const char *const *argv) {
  48. if (argc == 8) {
  49. MobileNode *n=(MobileNode*)TclObject::lookup(argv[4]);
  50. return (new EnergyModel(n, atof(argv[5]), 
  51. atof(argv[6]), atof(argv[7])));
  52. } else {
  53. Tcl::instance().add_error("Wrong arguments to ErrorModel");
  54. return 0;
  55. }
  56. }
  57. } class_energy_model;
  58. void EnergyModel::DecrTxEnergy(double txtime, double P_tx) 
  59. {
  60. double dEng = P_tx * txtime;
  61. if (energy_ <= dEng)
  62. energy_ = 0.0;
  63. else
  64. energy_ = energy_ - dEng;
  65. if (energy_ <= 0.0)
  66. God::instance()->ComputeRoute();
  67. //
  68. // This variable keeps track of total energy consumption in Transmission..
  69. et_=et_+dEng;
  70. //
  71. }
  72. void EnergyModel::DecrRcvEnergy(double rcvtime, double P_rcv) 
  73. {
  74. double dEng = P_rcv * rcvtime;
  75. if (energy_ <= dEng)
  76. energy_ = 0.0;
  77. else
  78. energy_ = energy_ - dEng;
  79. if (energy_ <= 0.0)
  80. God::instance()->ComputeRoute();
  81. //
  82. // This variable keeps track of total energy consumption in RECV mode..
  83. er_=er_+dEng;
  84. //
  85. }
  86. void EnergyModel::DecrIdleEnergy(double idletime, double P_idle) 
  87. {
  88. double dEng = P_idle * idletime;
  89. if (energy_ <= dEng)
  90. energy_ = 0.0;
  91. else
  92. energy_ = energy_ - dEng;
  93. if (energy_ <= 0.0)
  94. God::instance()->ComputeRoute();
  95. //
  96. // This variable keeps track of total energy consumption in IDLE mode..
  97. ei_=ei_+dEng;
  98. //
  99. }
  100. //
  101. void EnergyModel::DecrSleepEnergy(double sleeptime, double P_sleep) 
  102. {
  103. double dEng = P_sleep * sleeptime;
  104. if (energy_ <= dEng)
  105. energy_ = 0.0;
  106. else
  107. energy_ = energy_ - dEng;
  108. if (energy_ <= 0.0)
  109. God::instance()->ComputeRoute();
  110. // This variable keeps track of total energy consumption in SLEEP mode..
  111. es_=es_+dEng;
  112. }
  113. void EnergyModel::DecrTransitionEnergy(double transitiontime, double P_transition) 
  114. {
  115. double dEng = P_transition * transitiontime;
  116. if (energy_ <= dEng)
  117. energy_ = 0.0;
  118. else
  119. energy_ = energy_ - dEng;
  120. if (energy_ <= 0.0)
  121. God::instance()->ComputeRoute();
  122. }
  123. //
  124. // XXX Moved from node.cc. These wireless stuff should NOT stay in the 
  125. // base node.
  126. void EnergyModel::start_powersaving()
  127. {
  128. snh_ = new SoftNeighborHandler(this);
  129. snh_->start();
  130. afe_ = new AdaptiveFidelityEntity(this);
  131. afe_->start();
  132. state_ = EnergyModel::POWERSAVING;
  133. state_start_time_ = Scheduler::instance().clock();
  134. }
  135. void EnergyModel::set_node_sleep(int status)
  136. {
  137. Tcl& tcl=Tcl::instance();
  138. //static float last_time_gosleep;
  139. // status = 1 to set node into sleep mode
  140. // status = 0 to put node back to idle mode.
  141. // time in the sleep mode should be used as credit to idle 
  142. // time energy consumption
  143. if (status) {
  144. last_time_gosleep = Scheduler::instance().clock();
  145. //printf("id=%d : put node into sleep at %fn",
  146. // address_,last_time_gosleep);
  147. sleep_mode_ = status;
  148. if (node_->exist_namchan()) 
  149. tcl.evalf("%s add-mark m1 blue hexagon",node_->name());
  150. } else {
  151. sleep_mode_ = status;
  152. if (node_->exist_namchan()) 
  153. tcl.evalf("%s delete-mark m1", node_->name()); 
  154. //printf("id= %d last_time_sleep = %fn",
  155. // address_, last_time_gosleep);
  156. if (last_time_gosleep) {
  157. total_sleeptime_ += Scheduler::instance().clock() -
  158. last_time_gosleep;
  159. last_time_gosleep = 0;
  160. }
  161. }
  162. }
  163. void EnergyModel::set_node_state(int state)
  164. {
  165. switch (state_) { 
  166. case POWERSAVING:
  167. case WAITING:
  168. state_ = state;
  169. state_start_time_ = Scheduler::instance().clock();
  170. break;
  171. case INROUTE:
  172. if (state == POWERSAVING) {
  173. state_ = state;
  174. } else if (state == INROUTE) {
  175. // a data packet is forwarded, needs to reset 
  176. // state_start_time_
  177. state_start_time_= Scheduler::instance().clock();
  178. }
  179. break;
  180. default:
  181. printf("Wrong state, quit...n");
  182. abort();
  183. }
  184. }
  185. void EnergyModel::add_neighbor(u_int32_t nodeid)
  186. {
  187. neighbor_list_item *np;
  188. np = neighbor_list.head;
  189. for (; np; np = np->next) {
  190. if (np->id == nodeid) {
  191. np->ttl = maxttl_;
  192. break;
  193. }
  194. }
  195. if (!np) {      // insert this new entry
  196. np = new neighbor_list_item;
  197. np->id = nodeid;
  198. np->ttl = maxttl_;
  199. np->next = neighbor_list.head;
  200. neighbor_list.head = np;
  201. neighbor_list.neighbor_cnt_++;
  202. }
  203. }
  204. void EnergyModel::scan_neighbor()
  205. {
  206. neighbor_list_item *np, *lp;
  207. if (neighbor_list.neighbor_cnt_ > 0) {
  208. lp = neighbor_list.head;
  209. np = lp->next;
  210. for (; np; np = np->next) {
  211. np->ttl--;
  212. if (np->ttl <= 0){
  213. lp->next = np->next;
  214. delete np;
  215. np = lp;
  216. neighbor_list.neighbor_cnt_--;
  217. lp = np;
  218. }
  219. // process the first element
  220. np = neighbor_list.head;
  221. np->ttl--;
  222. if (np->ttl <= 0) {
  223. neighbor_list.head = np->next;
  224. delete np;
  225. neighbor_list.neighbor_cnt_--;
  226. }
  227. }
  228. }
  229. void SoftNeighborHandler::start()
  230. {
  231. Scheduler::instance().schedule(this, &intr, CHECKFREQ);
  232. }
  233. void SoftNeighborHandler::handle(Event *)
  234. {
  235. Scheduler &s = Scheduler::instance();
  236. nid_->scan_neighbor();
  237. s.schedule(this, &intr, CHECKFREQ);
  238. }
  239. void AdaptiveFidelityEntity::start()
  240. {
  241. sleep_time_ = 2;
  242. sleep_seed_ = 2;
  243. idle_time_ = 10;
  244. nid_->set_node_sleep(0);
  245. Scheduler::instance().schedule(this, &intr, 
  246.        Random::uniform(0, idle_time_));
  247. }
  248. void AdaptiveFidelityEntity::handle(Event *)
  249. {
  250. Scheduler &s = Scheduler::instance();
  251. int node_state = nid_->state();
  252. switch (node_state) {
  253. case EnergyModel::POWERSAVING:
  254. if (nid_->sleep()) {
  255. // node is in sleep mode, wake it up
  256. nid_->set_node_sleep(0);
  257. adapt_it();
  258. s.schedule(this, &intr, idle_time_);
  259. } else {
  260. // node is in idle mode, put it into sleep
  261. nid_->set_node_sleep(1);
  262. adapt_it();
  263. s.schedule(this, &intr, sleep_time_);
  264. }
  265. break;
  266. case EnergyModel::INROUTE:
  267. // 100s is the maximum INROUTE time.
  268. if (s.clock()-(nid_->state_start_time()) < 
  269.     nid_->max_inroute_time()) {
  270. s.schedule(this, &intr, idle_time_);
  271. } else {
  272. nid_->set_node_state(EnergyModel::POWERSAVING);
  273. adapt_it();
  274. nid_->set_node_sleep(1);
  275. s.schedule(this, &intr, sleep_time_); 
  276. }
  277. break;
  278. case EnergyModel::WAITING:
  279. // 10s is the maximum WAITING time
  280. if (s.clock()-(nid_->state_start_time()) < MAX_WAITING_TIME) {
  281. s.schedule(this, &intr, idle_time_);
  282. } else {
  283. nid_->set_node_state(EnergyModel::POWERSAVING);
  284. adapt_it();
  285. nid_->set_node_sleep(1);
  286. s.schedule(this, &intr, sleep_time_); 
  287. }
  288. break;
  289. default:
  290. fprintf(stderr, "Illegal Node State!");
  291. abort();
  292. }
  293. }
  294. void AdaptiveFidelityEntity::adapt_it()
  295. {
  296. float delay;
  297. // use adaptive fidelity
  298. if (nid_->adaptivefidelity()) {
  299. int neighbors = nid_->getneighbors();
  300. if (!neighbors) 
  301. neighbors = 1;
  302. delay = sleep_seed_ * Random::uniform(1,neighbors); 
  303.        set_sleeptime(delay);
  304. }
  305. }