- #include <stdarg.h>
- #include <float.h>
- #include "random.h"
- #include "energy-model.h"
- #include "mobilenode.h"
- #include "god.h"
- static class EnergyModelClass : public TclClass
- {
- public:
- EnergyModelClass ():TclClass ("EnergyModel") {}
- TclObject *create (int argc, const char *const *argv) {
- if (argc == 8) {
- MobileNode *n=(MobileNode*)TclObject::lookup(argv[4]);
- return (new EnergyModel(n, atof(argv[5]),
- atof(argv[6]), atof(argv[7])));
- } else {
- Tcl::instance().add_error("Wrong arguments to ErrorModel");
- return 0;
- }
- }
- } class_energy_model;
- void EnergyModel::DecrTxEnergy(double txtime, double P_tx)
- {
- double dEng = P_tx * txtime;
- if (energy_ <= dEng)
- energy_ = 0.0;
- else
- energy_ = energy_ - dEng;
- if (energy_ <= 0.0)
- God::instance()->ComputeRoute();
- }
- void EnergyModel::DecrRcvEnergy(double rcvtime, double P_rcv)
- {
- double dEng = P_rcv * rcvtime;
- if (energy_ <= dEng)
- energy_ = 0.0;
- else
- energy_ = energy_ - dEng;
- if (energy_ <= 0.0)
- God::instance()->ComputeRoute();
- }
- void EnergyModel::DecrIdleEnergy(double idletime, double P_idle)
- {
- double dEng = P_idle * idletime;
- if (energy_ <= dEng)
- energy_ = 0.0;
- else
- energy_ = energy_ - dEng;
- if (energy_ <= 0.0)
- God::instance()->ComputeRoute();
- }
- // XXX Moved from node.cc. These wireless stuff should NOT stay in the
- // base node.
- void EnergyModel::start_powersaving()
- {
- snh_ = new SoftNeighborHandler(this);
- snh_->start();
- afe_ = new AdaptiveFidelityEntity(this);
- afe_->start();
- state_ = EnergyModel::POWERSAVING;
- state_start_time_ = Scheduler::instance().clock();
- }
- void EnergyModel::set_node_sleep(int status)
- {
- Tcl& tcl=Tcl::instance();
- //static float last_time_gosleep;
- // status = 1 to set node into sleep mode
- // status = 0 to put node back to idle mode.
- // time in the sleep mode should be used as credit to idle
- // time energy consumption
- if (status) {
- last_time_gosleep = Scheduler::instance().clock();
- //printf("id=%d : put node into sleep at %f\n",
- // address_,last_time_gosleep);
- sleep_mode_ = status;
- if (node_->exist_namchan())
- tcl.evalf("%s add-mark m1 blue hexagon",node_->name());
- } else {
- sleep_mode_ = status;
- if (node_->exist_namchan())
- tcl.evalf("%s delete-mark m1", node_->name());
- //printf("id= %d last_time_sleep = %f\n",
- // address_, last_time_gosleep);
- if (last_time_gosleep) {
- total_sleeptime_ += Scheduler::instance().clock() -
- last_time_gosleep;
- last_time_gosleep = 0;
- }
- }
- }
- void EnergyModel::set_node_state(int state)
- {
- switch (state_) {
- case POWERSAVING:
- case WAITING:
- state_ = state;
- state_start_time_ = Scheduler::instance().clock();
- break;
- case INROUTE:
- if (state == POWERSAVING) {
- state_ = state;
- } else if (state == INROUTE) {
- // a data packet is forwarded, needs to reset
- // state_start_time_
- state_start_time_= Scheduler::instance().clock();
- }
- break;
- default:
- printf("Wrong state, quit...\n");
- abort();
- }
- }
- void EnergyModel::add_neighbor(u_int32_t nodeid)
- {
- neighbor_list_item *np;
- np = neighbor_list.head;
- for (; np; np = np->next) {
- if (np->id == nodeid) {
- np->ttl = maxttl_;
- break;
- }
- }
- if (!np) { // insert this new entry
- np = new neighbor_list_item;
- np->id = nodeid;
- np->ttl = maxttl_;
- np->next = neighbor_list.head;
- neighbor_list.head = np;
- neighbor_list.neighbor_cnt_++;
- }
- }
- void EnergyModel::scan_neighbor()
- {
- neighbor_list_item *np, *lp;
- if (neighbor_list.neighbor_cnt_ > 0) {
- lp = neighbor_list.head;
- np = lp->next;
- for (; np; np = np->next) {
- np->ttl--;
- if (np->ttl <= 0){
- lp->next = np->next;
- delete np;
- np = lp;
- neighbor_list.neighbor_cnt_--;
- }
- lp = np;
- }
- // process the first element
- np = neighbor_list.head;
- np->ttl--;
- if (np->ttl <= 0) {
- neighbor_list.head = np->next;
- delete np;
- neighbor_list.neighbor_cnt_--;
- }
- }
- }
- void SoftNeighborHandler::start()
- {
- Scheduler::instance().schedule(this, &intr, CHECKFREQ);
- }
- void SoftNeighborHandler::handle(Event *)
- {
- Scheduler &s = Scheduler::instance();
- nid_->scan_neighbor();
- s.schedule(this, &intr, CHECKFREQ);
- }
- void AdaptiveFidelityEntity::start()
- {
- sleep_time_ = 2;
- sleep_seed_ = 2;
- idle_time_ = 10;
- nid_->set_node_sleep(0);
- Scheduler::instance().schedule(this, &intr,
- Random::uniform(0, idle_time_));
- }
- void AdaptiveFidelityEntity::handle(Event *)
- {
- Scheduler &s = Scheduler::instance();
- int node_state = nid_->state();
- switch (node_state) {
- case EnergyModel::POWERSAVING:
- if (nid_->sleep()) {
- // node is in sleep mode, wake it up
- nid_->set_node_sleep(0);
- adapt_it();
- s.schedule(this, &intr, idle_time_);
- } else {
- // node is in idle mode, put it into sleep
- nid_->set_node_sleep(1);
- adapt_it();
- s.schedule(this, &intr, sleep_time_);
- }
- break;
- case EnergyModel::INROUTE:
- // 100s is the maximum INROUTE time.
- if (s.clock()-(nid_->state_start_time()) <
- nid_->max_inroute_time()) {
- s.schedule(this, &intr, idle_time_);
- } else {
- nid_->set_node_state(EnergyModel::POWERSAVING);
- adapt_it();
- nid_->set_node_sleep(1);
- s.schedule(this, &intr, sleep_time_);
- }
- break;
- case EnergyModel::WAITING:
- // 10s is the maximum WAITING time
- if (s.clock()-(nid_->state_start_time()) < MAX_WAITING_TIME) {
- s.schedule(this, &intr, idle_time_);
- } else {
- nid_->set_node_state(EnergyModel::POWERSAVING);
- adapt_it();
- nid_->set_node_sleep(1);
- s.schedule(this, &intr, sleep_time_);
- }
- break;
- default:
- fprintf(stderr, "Illegal Node State!");
- abort();
- }
- }
- void AdaptiveFidelityEntity::adapt_it()
- {
- float delay;
- // use adaptive fidelity
- if (nid_->adaptivefidelity()) {
- int neighbors = nid_->getneighbors();
- if (!neighbors)
- neighbors = 1;
- delay = sleep_seed_ * Random::uniform(1,neighbors);
- set_sleeptime(delay);
- }
- }
NS2之移动节点能量模型
最新推荐文章于 2020-09-26 19:01:21 发布