NS2之移动节点

移动节点的定义代码如下:

#include <math.h> #include <stdlib.h> #include "connector.h" #include "delay.h" #include "packet.h" #include "random.h" #include "trace.h" #include "address.h" #include "arp.h" #include "topography.h" #include "ll.h" #include "mac.h" #include "propagation.h" #include "mobilenode.h" #include "phy.h" #include "wired-phy.h" #include "god.h" // XXX Must supply the first parameter in the macro otherwise msvc // is unhappy. static LIST_HEAD(_dummy_MobileNodeList, MobileNode) nodehead = { 0 }; static class MobileNodeClass : public TclClass { public: MobileNodeClass() : TclClass("Node/MobileNode") {} TclObject* create(int, const char*const*) { return (new MobileNode); } } class_mobilenode; /* * PositionHandler() * * Updates the position of a mobile node every N seconds, where N is * based upon the speed of the mobile and the resolution of the topography. * */ void PositionHandler::handle(Event*) { Scheduler& s = Scheduler::instance(); #if 0 fprintf(stderr, "*** POSITION HANDLER for node %d (time: %f) ***\n", node->address(), s.clock()); #endif /* * Update current location */ node->update_position(); /* * Choose a new random speed and direction */ #ifdef DEBUG fprintf(stderr, "%d - %s: calling random_destination()\n", node->address_, __PRETTY_FUNCTION__); #endif node->random_destination(); s.schedule(&node->pos_handle_, &node->pos_intr_, node->position_update_interval_); } /* ====================================================================== Mobile Node ====================================================================== */ MobileNode::MobileNode(void) : pos_handle_(this) { X_ = Y_ = Z_ = speed_ = 0.0; dX_ = dY_ = dZ_ = 0.0; destX_ = destY_ = 0.0; random_motion_ = 0; base_stn_ = -1; T_ = 0; log_target_ = 0; next_ = 0; radius_ = 0; position_update_interval_ = POSITION_UPDATE_INTERVAL; position_update_time_ = 0.0; LIST_INSERT_HEAD(&nodehead, this, link_); // node list LIST_INIT(&ifhead_); // interface list bind("X_", &X_); bind("Y_", &Y_); bind("Z_", &Z_); bind("speed_", &speed_); } int MobileNode::command(int argc, const char*const* argv) { Tcl& tcl = Tcl::instance(); if(argc == 2) { if(strcmp(argv[1], "start") == 0) { start(); return TCL_OK; } else if(strcmp(argv[1], "log-movement") == 0) { #ifdef DEBUG fprintf(stderr, "%d - %s: calling update_position()\n", address_, __PRETTY_FUNCTION__); #endif update_position(); log_movement(); return TCL_OK; } else if(strcmp(argv[1], "log-energy") == 0) { log_energy(1); return TCL_OK; } else if(strcmp(argv[1], "powersaving") == 0) { energy_model()->powersavingflag() = 1; energy_model()->start_powersaving(); return TCL_OK; } else if(strcmp(argv[1], "adaptivefidelity") == 0) { energy_model()->adaptivefidelity() = 1; energy_model()->powersavingflag() = 1; energy_model()->start_powersaving(); return TCL_OK; } else if (strcmp(argv[1], "energy") == 0) { Tcl& tcl = Tcl::instance(); tcl.resultf("%f", energy_model()->energy()); return TCL_OK; } else if (strcmp(argv[1], "adjustenergy") == 0) { // assume every 10 sec schedule and 1.15 W // idle energy consumption. needs to be // parameterized. idle_energy_patch(10, 1.15); energy_model()->total_sndtime() = 0; energy_model()->total_rcvtime() = 0; energy_model()->total_sleeptime() = 0; return TCL_OK; } else if (strcmp(argv[1], "on") == 0) { energy_model()->node_on() = true; tcl.evalf("%s set netif_(0)", name_); const char *str = tcl.result(); tcl.evalf("%s NodeOn", str); God::instance()->ComputeRoute(); return TCL_OK; } else if (strcmp(argv[1], "off") == 0) { energy_model()->node_on() = false; tcl.evalf("%s set netif_(0)", name_); const char *str = tcl.result(); tcl.evalf("%s NodeOff", str); tcl.evalf("%s set ragent_", name_); str = tcl.result(); tcl.evalf("%s reset-state", str); God::instance()->ComputeRoute(); return TCL_OK; } else if (strcmp(argv[1], "shutdown") == 0) { // set node state //Phy *p; energy_model()->node_on() = false; //p = ifhead().lh_first; //if (p) ((WirelessPhy *)p)->node_off(); return TCL_OK; } else if (strcmp(argv[1], "startup") == 0) { energy_model()->node_on() = true; return TCL_OK; } } else if(argc == 3) { if(strcmp(argv[1], "addif") == 0) { WiredPhy* phyp = (WiredPhy*)TclObject::lookup(argv[2]); if(phyp == 0) return TCL_ERROR; phyp->insertnode(&ifhead_); phyp->setnode(this); return TCL_OK; } else if (strcmp(argv[1], "setsleeptime") == 0) { energy_model()->afe()->set_sleeptime(atof(argv[2])); energy_model()->afe()->set_sleepseed(atof(argv[2])); return TCL_OK; } else if (strcmp(argv[1], "setenergy") == 0) { energy_model()->setenergy(atof(argv[2])); return TCL_OK; } else if (strcmp(argv[1], "settalive") == 0) { energy_model()->max_inroute_time() = atof(argv[2]); return TCL_OK; } else if (strcmp(argv[1], "maxttl") == 0) { energy_model()->maxttl() = atoi(argv[2]); return TCL_OK; } else if(strcmp(argv[1], "radius") == 0) { radius_ = strtod(argv[2],NULL); return TCL_OK; } else if(strcmp(argv[1], "random-motion") == 0) { random_motion_ = atoi(argv[2]); return TCL_OK; } else if(strcmp(argv[1], "addif") == 0) { WirelessPhy *n = (WirelessPhy*) TclObject::lookup(argv[2]); if(n == 0) return TCL_ERROR; n->insertnode(&ifhead_); n->setnode(this); return TCL_OK; } else if(strcmp(argv[1], "topography") == 0) { T_ = (Topography*) TclObject::lookup(argv[2]); if (T_ == 0) return TCL_ERROR; return TCL_OK; } else if(strcmp(argv[1], "log-target") == 0) { log_target_ = (Trace*) TclObject::lookup(argv[2]); if (log_target_ == 0) return TCL_ERROR; return TCL_OK; } else if (strcmp(argv[1],"base-station") == 0) { base_stn_ = atoi(argv[2]); if(base_stn_ == -1) return TCL_ERROR; return TCL_OK; } } else if (argc == 4) { if (strcmp(argv[1], "idleenergy") == 0) { idle_energy_patch(atof(argv[2]),atof(argv[3])); return TCL_OK; } } else if (argc == 5) { if (strcmp(argv[1], "setdest") == 0) { /* <mobilenode> setdest <X> <Y> <speed> */ #ifdef DEBUG fprintf(stderr, "%d - %s: calling set_destination()\n", address_, __FUNCTION__); #endif if (set_destination(atof(argv[2]), atof(argv[3]), atof(argv[4])) < 0) return TCL_ERROR; return TCL_OK; } } return Node::command(argc, argv); } /* ====================================================================== Other class functions ====================================================================== */ void MobileNode::dump(void) { Phy *n; fprintf(stdout, "Index: %d\n", address_); fprintf(stdout, "Network Interface List\n"); for(n = ifhead_.lh_first; n; n = n->nextnode() ) n->dump(); fprintf(stdout, "--------------------------------------------------\n"); } /* ====================================================================== Position Functions ====================================================================== */ void MobileNode::start() { Scheduler& s = Scheduler::instance(); if(random_motion_ == 0) { log_movement(); return; } assert(initialized()); random_position(); #ifdef DEBUG fprintf(stderr, "%d - %s: calling random_destination()\n", address_, __PRETTY_FUNCTION__); #endif random_destination(); s.schedule(&pos_handle_, &pos_intr_, position_update_interval_); } void MobileNode::log_movement() { if (!log_target_) return; Scheduler& s = Scheduler::instance(); sprintf(log_target_->pt_->buffer(), "M %.5f %d (%.2f, %.2f, %.2f), (%.2f, %.2f), %.2f", s.clock(), address_, X_, Y_, Z_, destX_, destY_, speed_); log_target_->pt_->dump(); } void MobileNode::log_energy(int flag) { if (!log_target_) return; Scheduler &s = Scheduler::instance(); if (flag) { sprintf(log_target_->pt_->buffer(),"N -t %f -n %d -e %f", s.clock(), address_, energy_model_->energy()); } else { sprintf(log_target_->pt_->buffer(),"N -t %f -n %d -e 0 ", s.clock(), address_); } log_target_->pt_->dump(); } //void //MobileNode::logrttime(double t) //{ // last_rt_time_ = (int)t; //} void MobileNode::bound_position() { double minX; double maxX; double minY; double maxY; int recheck = 1; assert(T_ != 0); minX = T_->lowerX(); maxX = T_->upperX(); minY = T_->lowerY(); maxY = T_->upperY(); while (recheck) { recheck = 0; if (X_ < minX) { X_ = minX + (minX - X_); recheck = 1; } if (X_ > maxX) { X_ = maxX - (X_ - maxX); recheck = 1; } if (Y_ < minY) { Y_ = minY + (minY - Y_); recheck = 1; } if (Y_ > maxY) { Y_ = maxY- (Y_ - maxY); recheck = 1; } if (recheck) { fprintf(stderr, "Adjust position of node %d\n",address_); } } } int MobileNode::set_destination(double x, double y, double s) { assert(initialized()); if(x >= T_->upperX() || x <= T_->lowerX()) return -1; if(y >= T_->upperY() || y <= T_->lowerY()) return -1; update_position(); // figure out where we are now destX_ = x; destY_ = y; speed_ = s; dX_ = destX_ - X_; dY_ = destY_ - Y_; dZ_ = 0.0; // this isn't used, since flying isn't allowed if (destX_ != X_ || destY_ != Y_) { // normalize dx, dy to unit len double len = sqrt( (dX_ * dX_) + (dY_ * dY_) ); dX_ /= len; dY_ /= len; } position_update_time_ = Scheduler::instance().clock(); #ifdef DEBUG fprintf(stderr, "%d - %s: calling log_movement()\n", address_, __FUNCTION__); #endif log_movement(); /* update gridkeeper */ if (GridKeeper::instance()){ GridKeeper* gp = GridKeeper::instance(); gp-> new_moves(this); } if (namChan_ != 0) { sprintf(nwrk_, "n -t %f -s %d -x %f -y %f -U %f -V %f -T %f", Scheduler::instance().clock(), nodeid_, X_, Y_, speed_ * dX_, speed_ * dY_, ((speed_*dX_) != 0) ? (destX_-X_)/(speed_*dX_) : speed_*dX_ ); namdump(); } return 0; } void MobileNode::update_position() { double now = Scheduler::instance().clock(); double interval = now - position_update_time_; double oldX = X_, oldY = Y_; if ((interval == 0.0)&&(position_update_time_!=0)) return; // ^^^ for list-based imprvmnt // CHECK, IF THE SPEED IS 0, THEN SKIP, but usually it's not 0 X_ += dX_ * (speed_ * interval); Y_ += dY_ * (speed_ * interval); if ((dX_ > 0 && X_ > destX_) || (dX_ < 0 && X_ < destX_)) X_ = destX_; // correct overshoot (slow? XXX) if ((dY_ > 0 && Y_ > destY_) || (dY_ < 0 && Y_ < destY_)) Y_ = destY_; // correct overshoot (slow? XXX) /* list based improvement */ if(oldX != X_)// || oldY != Y_) T_->updateNodesList(this, oldX);//, oldY); // COMMENTED BY -VAL- // bound_position(); // COMMENTED BY -VAL- // Z_ = T_->height(X_, Y_); #if 0 fprintf(stderr, "Node: %d, X: %6.2f, Y: %6.2f, Z: %6.2f, time: %f\n", address_, X_, Y_, Z_, now); #endif position_update_time_ = now; } void MobileNode::random_position() { if (T_ == 0) { fprintf(stderr, "No TOPOLOGY assigned\n"); exit(1); } X_ = Random::uniform() * T_->upperX(); Y_ = Random::uniform() * T_->upperY(); Z_ = T_->height(X_, Y_); position_update_time_ = 0.0; } void MobileNode::random_destination() { if (T_ == 0) { fprintf(stderr, "No TOPOLOGY assigned\n"); exit(1); } random_speed(); #ifdef DEBUG fprintf(stderr, "%d - %s: calling set_destination()\n", address_, __FUNCTION__); #endif (void) set_destination(Random::uniform() * T_->upperX(), Random::uniform() * T_->upperY(), speed_); } void MobileNode::random_direction() { /* this code isn't used anymore -dam 1/22/98 */ double len; dX_ = (double) Random::random(); dY_ = (double) Random::random(); len = sqrt( (dX_ * dX_) + (dY_ * dY_) ); dX_ /= len; dY_ /= len; dZ_ = 0.0; // we're not flying... /* * Determine the sign of each component of the * direction vector. */ if (X_ > (T_->upperX() - 2*T_->resol())) { if (dX_ > 0) dX_ = -dX_; } else if (X_ < (T_->lowerX() + 2*T_->resol())) { if (dX_ < 0) dX_ = -dX_; } else if (Random::uniform() <= 0.5) { dX_ = -dX_; } if (Y_ > (T_->upperY() - 2*T_->resol())) { if (dY_ > 0) dY_ = -dY_; } else if (Y_ < (T_->lowerY() + 2*T_->resol())) { if (dY_ < 0) dY_ = -dY_; } else if(Random::uniform() <= 0.5) { dY_ = -dY_; } #if 0 fprintf(stderr, "Location: (%f, %f), Direction: (%f, %f)\n", X_, Y_, dX_, dY_); #endif } void MobileNode::random_speed() { speed_ = Random::uniform() * MAX_SPEED; } double MobileNode::distance(MobileNode *m) { update_position(); // update my position m->update_position(); // update m's position double Xpos = (X_ - m->X_) * (X_ - m->X_); double Ypos = (Y_ - m->Y_) * (Y_ - m->Y_); double Zpos = (Z_ - m->Z_) * (Z_ - m->Z_); return sqrt(Xpos + Ypos + Zpos); } double MobileNode::propdelay(MobileNode *m) { return distance(m) / SPEED_OF_LIGHT; } void MobileNode::idle_energy_patch(float /*total*/, float /*P_idle*/) { }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值