NS2之移动节点

  1. #include <math.h>  
  2. #include <stdlib.h>  
  3.   
  4. #include "connector.h"  
  5. #include "delay.h"  
  6. #include "packet.h"  
  7. #include "random.h"  
  8. #include "trace.h"  
  9. #include "address.h"  
  10.   
  11. #include "arp.h"  
  12. #include "topography.h"  
  13. #include "ll.h"  
  14. #include "mac.h"  
  15. #include "propagation.h"  
  16. #include "mobilenode.h"  
  17. #include "phy.h"  
  18. #include "wired-phy.h"  
  19. #include "god.h"  
  20.   
  21. // XXX Must supply the first parameter in the macro otherwise msvc  
  22. // is unhappy.   
  23. static LIST_HEAD(_dummy_MobileNodeList, MobileNode) nodehead = { 0 };  
  24.   
  25. static class MobileNodeClass : public TclClass {  
  26. public:  
  27.         MobileNodeClass() : TclClass("Node/MobileNode") {}  
  28.         TclObject* create(intconst char*const*) {  
  29.                 return (new MobileNode);  
  30.         }  
  31. } class_mobilenode;  
  32.   
  33. /* 
  34.  *  PositionHandler() 
  35.  * 
  36.  *  Updates the position of a mobile node every N seconds, where N is 
  37.  *  based upon the speed of the mobile and the resolution of the topography. 
  38.  * 
  39.  */  
  40. void  
  41. PositionHandler::handle(Event*)  
  42. {  
  43.     Scheduler& s = Scheduler::instance();  
  44.   
  45. #if 0  
  46.     fprintf(stderr, "*** POSITION HANDLER for node %d (time: %f) ***\n",  
  47.         node->address(), s.clock());  
  48. #endif  
  49.     /* 
  50.      * Update current location 
  51.      */  
  52.     node->update_position();  
  53.   
  54.     /* 
  55.      * Choose a new random speed and direction 
  56.      */  
  57. #ifdef DEBUG  
  58.         fprintf(stderr, "%d - %s: calling random_destination()\n",  
  59.                 node->address_, __PRETTY_FUNCTION__);  
  60. #endif  
  61.     node->random_destination();  
  62.   
  63.     s.schedule(&node->pos_handle_, &node->pos_intr_,  
  64.            node->position_update_interval_);  
  65. }  
  66.   
  67.   
  68. /* ====================================================================== 
  69.    Mobile Node 
  70.    ====================================================================== */  
  71.   
  72. MobileNode::MobileNode(void) :   
  73.     pos_handle_(this)  
  74. {  
  75.     X_ = Y_ = Z_ = speed_ = 0.0;  
  76.     dX_ = dY_ = dZ_ = 0.0;  
  77.     destX_ = destY_ = 0.0;  
  78.   
  79.     random_motion_ = 0;  
  80.     base_stn_ = -1;  
  81.     T_ = 0;  
  82.   
  83.     log_target_ = 0;  
  84.     next_ = 0;  
  85.     radius_ = 0;  
  86.   
  87.     position_update_interval_ = POSITION_UPDATE_INTERVAL;  
  88.     position_update_time_ = 0.0;  
  89.       
  90.   
  91.     LIST_INSERT_HEAD(&nodehead, this, link_);   // node list  
  92.     LIST_INIT(&ifhead_);                // interface list  
  93.     bind("X_", &X_);  
  94.     bind("Y_", &Y_);  
  95.     bind("Z_", &Z_);  
  96.     bind("speed_", &speed_);  
  97.       
  98. }  
  99.   
  100. int  
  101. MobileNode::command(int argc, const char*const* argv)  
  102. {  
  103.     Tcl& tcl = Tcl::instance();  
  104.     if(argc == 2) {  
  105.         if(strcmp(argv[1], "start") == 0) {  
  106.                 start();  
  107.             return TCL_OK;  
  108.         } else if(strcmp(argv[1], "log-movement") == 0) {  
  109. #ifdef DEBUG  
  110.                         fprintf(stderr,  
  111.                                 "%d - %s: calling update_position()\n",  
  112.                                 address_, __PRETTY_FUNCTION__);  
  113. #endif  
  114.                 update_position();  
  115.                 log_movement();  
  116.             return TCL_OK;  
  117.         } else if(strcmp(argv[1], "log-energy") == 0) {  
  118.             log_energy(1);  
  119.             return TCL_OK;  
  120.         } else if(strcmp(argv[1], "powersaving") == 0) {  
  121.             energy_model()->powersavingflag() = 1;  
  122.             energy_model()->start_powersaving();  
  123.             return TCL_OK;  
  124.         } else if(strcmp(argv[1], "adaptivefidelity") == 0) {  
  125.             energy_model()->adaptivefidelity() = 1;  
  126.             energy_model()->powersavingflag() = 1;  
  127.             energy_model()->start_powersaving();  
  128.             return TCL_OK;  
  129.         } else if (strcmp(argv[1], "energy") == 0) {  
  130.             Tcl& tcl = Tcl::instance();  
  131.             tcl.resultf("%f", energy_model()->energy());  
  132.             return TCL_OK;  
  133.         } else if (strcmp(argv[1], "adjustenergy") == 0) {  
  134.             // assume every 10 sec schedule and 1.15 W   
  135.             // idle energy consumption. needs to be  
  136.             // parameterized.  
  137.             idle_energy_patch(10, 1.15);  
  138.             energy_model()->total_sndtime() = 0;  
  139.             energy_model()->total_rcvtime() = 0;  
  140.             energy_model()->total_sleeptime() = 0;  
  141.             return TCL_OK;  
  142.         } else if (strcmp(argv[1], "on") == 0) {  
  143.             energy_model()->node_on() = true;  
  144.             tcl.evalf("%s set netif_(0)", name_);  
  145.             const char *str = tcl.result();  
  146.             tcl.evalf("%s NodeOn", str);  
  147.             God::instance()->ComputeRoute();  
  148.             return TCL_OK;  
  149.         } else if (strcmp(argv[1], "off") == 0) {  
  150.             energy_model()->node_on() = false;  
  151.             tcl.evalf("%s set netif_(0)", name_);  
  152.             const char *str = tcl.result();  
  153.             tcl.evalf("%s NodeOff", str);  
  154.             tcl.evalf("%s set ragent_", name_);  
  155.             str = tcl.result();  
  156.             tcl.evalf("%s reset-state", str);  
  157.             God::instance()->ComputeRoute();  
  158.                 return TCL_OK;  
  159.         } else if (strcmp(argv[1], "shutdown") == 0) {  
  160.             // set node state  
  161.             //Phy *p;  
  162.             energy_model()->node_on() = false;  
  163.               
  164.             //p = ifhead().lh_first;  
  165.             //if (p) ((WirelessPhy *)p)->node_off();  
  166.             return TCL_OK;  
  167.         } else if (strcmp(argv[1], "startup") == 0) {  
  168.             energy_model()->node_on() = true;  
  169.             return TCL_OK;  
  170.         }  
  171.       
  172.     } else if(argc == 3) {  
  173.         if(strcmp(argv[1], "addif") == 0) {  
  174.             WiredPhy* phyp = (WiredPhy*)TclObject::lookup(argv[2]);  
  175.             if(phyp == 0)  
  176.                 return TCL_ERROR;  
  177.             phyp->insertnode(&ifhead_);  
  178.             phyp->setnode(this);  
  179.             return TCL_OK;  
  180.         } else if (strcmp(argv[1], "setsleeptime") == 0) {  
  181.             energy_model()->afe()->set_sleeptime(atof(argv[2]));  
  182.             energy_model()->afe()->set_sleepseed(atof(argv[2]));  
  183.             return TCL_OK;  
  184.         } else if (strcmp(argv[1], "setenergy") == 0) {  
  185.             energy_model()->setenergy(atof(argv[2]));  
  186.             return TCL_OK;  
  187.         } else if (strcmp(argv[1], "settalive") == 0) {  
  188.             energy_model()->max_inroute_time() = atof(argv[2]);  
  189.             return TCL_OK;  
  190.         } else if (strcmp(argv[1], "maxttl") == 0) {  
  191.             energy_model()->maxttl() = atoi(argv[2]);  
  192.             return TCL_OK;  
  193.         } else if(strcmp(argv[1], "radius") == 0) {  
  194.                         radius_ = strtod(argv[2],NULL);  
  195.                         return TCL_OK;  
  196.                 } else if(strcmp(argv[1], "random-motion") == 0) {  
  197.             random_motion_ = atoi(argv[2]);  
  198.             return TCL_OK;  
  199.         } else if(strcmp(argv[1], "addif") == 0) {  
  200.             WirelessPhy *n = (WirelessPhy*)  
  201.                 TclObject::lookup(argv[2]);  
  202.             if(n == 0)  
  203.                 return TCL_ERROR;  
  204.             n->insertnode(&ifhead_);  
  205.             n->setnode(this);  
  206.             return TCL_OK;  
  207.         } else if(strcmp(argv[1], "topography") == 0) {  
  208.             T_ = (Topography*) TclObject::lookup(argv[2]);  
  209.             if (T_ == 0)  
  210.                 return TCL_ERROR;  
  211.             return TCL_OK;  
  212.         } else if(strcmp(argv[1], "log-target") == 0) {  
  213.             log_target_ = (Trace*) TclObject::lookup(argv[2]);  
  214.             if (log_target_ == 0)  
  215.                 return TCL_ERROR;  
  216.             return TCL_OK;  
  217.         } else if (strcmp(argv[1],"base-station") == 0) {  
  218.             base_stn_ = atoi(argv[2]);  
  219.             if(base_stn_ == -1)  
  220.                 return TCL_ERROR;  
  221.             return TCL_OK;  
  222.         }   
  223.     } else if (argc == 4) {  
  224.         if (strcmp(argv[1], "idleenergy") == 0) {  
  225.             idle_energy_patch(atof(argv[2]),atof(argv[3]));  
  226.             return TCL_OK;  
  227.         }  
  228.     } else if (argc == 5) {  
  229.         if (strcmp(argv[1], "setdest") == 0) {   
  230.             /* <mobilenode> setdest <X> <Y> <speed> */  
  231. #ifdef DEBUG  
  232.             fprintf(stderr, "%d - %s: calling set_destination()\n",  
  233.                 address_, __FUNCTION__);  
  234. #endif  
  235.     
  236.             if (set_destination(atof(argv[2]), atof(argv[3]),   
  237.                         atof(argv[4])) < 0)  
  238.                 return TCL_ERROR;  
  239.             return TCL_OK;  
  240.         }  
  241.     }  
  242.     return Node::command(argc, argv);  
  243. }  
  244.   
  245.   
  246. /* ====================================================================== 
  247.    Other class functions 
  248.    ====================================================================== */  
  249. void  
  250. MobileNode::dump(void)  
  251. {  
  252.     Phy *n;  
  253.     fprintf(stdout, "Index: %d\n", address_);  
  254.     fprintf(stdout, "Network Interface List\n");  
  255.     for(n = ifhead_.lh_first; n; n = n->nextnode() )  
  256.         n->dump();     
  257.     fprintf(stdout, "--------------------------------------------------\n");  
  258. }  
  259.   
  260. /* ====================================================================== 
  261.    Position Functions 
  262.    ====================================================================== */  
  263. void   
  264. MobileNode::start()  
  265. {  
  266.     Scheduler& s = Scheduler::instance();  
  267.   
  268.     if(random_motion_ == 0) {  
  269.         log_movement();  
  270.         return;  
  271.     }  
  272.   
  273.     assert(initialized());  
  274.   
  275.     random_position();  
  276. #ifdef DEBUG  
  277.         fprintf(stderr, "%d - %s: calling random_destination()\n",  
  278.                 address_, __PRETTY_FUNCTION__);  
  279. #endif  
  280.     random_destination();  
  281.     s.schedule(&pos_handle_, &pos_intr_, position_update_interval_);  
  282. }  
  283.   
  284. void   
  285. MobileNode::log_movement()  
  286. {  
  287.         if (!log_target_)   
  288.         return;  
  289.   
  290.     Scheduler& s = Scheduler::instance();  
  291.     sprintf(log_target_->pt_->buffer(),  
  292.         "M %.5f %d (%.2f, %.2f, %.2f), (%.2f, %.2f), %.2f",  
  293.         s.clock(), address_, X_, Y_, Z_, destX_, destY_, speed_);  
  294.     log_target_->pt_->dump();  
  295. }  
  296.   
  297.   
  298. void  
  299. MobileNode::log_energy(int flag)  
  300. {  
  301.     if (!log_target_)   
  302.         return;  
  303.     Scheduler &s = Scheduler::instance();  
  304.     if (flag) {  
  305.         sprintf(log_target_->pt_->buffer(),"N -t %f -n %d -e %f", s.clock(),  
  306.             address_, energy_model_->energy());   
  307.     } else {  
  308.         sprintf(log_target_->pt_->buffer(),"N -t %f -n %d -e 0 ", s.clock(),  
  309.             address_);   
  310.     }  
  311.     log_target_->pt_->dump();  
  312. }  
  313.   
  314. //void  
  315. //MobileNode::logrttime(double t)  
  316. //{  
  317. //  last_rt_time_ = (int)t;  
  318. //}  
  319.   
  320. void  
  321. MobileNode::bound_position()  
  322. {  
  323.     double minX;  
  324.     double maxX;  
  325.     double minY;  
  326.     double maxY;  
  327.     int recheck = 1;  
  328.   
  329.     assert(T_ != 0);  
  330.   
  331.     minX = T_->lowerX();  
  332.     maxX = T_->upperX();  
  333.     minY = T_->lowerY();  
  334.     maxY = T_->upperY();  
  335.   
  336.     while (recheck) {  
  337.         recheck = 0;  
  338.         if (X_ < minX) {  
  339.             X_ = minX + (minX - X_);  
  340.             recheck = 1;  
  341.         }  
  342.         if (X_ > maxX) {  
  343.             X_ = maxX - (X_ - maxX);  
  344.             recheck = 1;  
  345.         }  
  346.         if (Y_ < minY) {  
  347.             Y_ = minY + (minY - Y_);  
  348.             recheck = 1;  
  349.         }  
  350.         if (Y_ > maxY) {  
  351.             Y_ = maxY- (Y_ - maxY);  
  352.             recheck = 1;  
  353.         }  
  354.         if (recheck) {  
  355.             fprintf(stderr, "Adjust position of node %d\n",address_);  
  356.         }  
  357.     }  
  358. }  
  359.   
  360. int  
  361. MobileNode::set_destination(double x, double y, double s)  
  362. {  
  363.     assert(initialized());  
  364.   
  365.     if(x >= T_->upperX() || x <= T_->lowerX())  
  366.         return -1;  
  367.     if(y >= T_->upperY() || y <= T_->lowerY())  
  368.         return -1;  
  369.       
  370.     update_position();  // figure out where we are now  
  371.       
  372.     destX_ = x;  
  373.     destY_ = y;  
  374.     speed_ = s;  
  375.       
  376.     dX_ = destX_ - X_;  
  377.     dY_ = destY_ - Y_;  
  378.     dZ_ = 0.0;      // this isn't used, since flying isn't allowed  
  379.   
  380.     if (destX_ != X_ || destY_ != Y_) {  
  381.         // normalize dx, dy to unit len  
  382.         double len = sqrt( (dX_ * dX_) + (dY_ * dY_) );  
  383.         dX_ /= len;  
  384.         dY_ /= len;  
  385.     }  
  386.     
  387.     position_update_time_ = Scheduler::instance().clock();  
  388.   
  389. #ifdef DEBUG  
  390.     fprintf(stderr, "%d - %s: calling log_movement()\n",   
  391.         address_, __FUNCTION__);  
  392. #endif  
  393.     log_movement();  
  394.   
  395.     /* update gridkeeper */  
  396.     if (GridKeeper::instance()){  
  397.         GridKeeper* gp =  GridKeeper::instance();  
  398.         gp-> new_moves(this);  
  399.     }                       
  400.   
  401.     if (namChan_ != 0) {  
  402.         sprintf(nwrk_,       
  403.             "n -t %f -s %d -x %f -y %f -U %f -V %f -T %f",  
  404.             Scheduler::instance().clock(),  
  405.             nodeid_,  
  406.             X_, Y_,  
  407.             speed_ * dX_, speed_ * dY_,  
  408.             ((speed_*dX_) != 0) ?   
  409.                 (destX_-X_)/(speed_*dX_) : speed_*dX_  
  410.             );     
  411.         namdump();           
  412.     }  
  413.     return 0;  
  414. }  
  415.   
  416.   
  417.   
  418. void   
  419. MobileNode::update_position()  
  420. {  
  421.     double now = Scheduler::instance().clock();  
  422.     double interval = now - position_update_time_;  
  423.     double oldX = X_, oldY = Y_;  
  424.   
  425.     if ((interval == 0.0)&&(position_update_time_!=0))  
  426.         return;         // ^^^ for list-based imprvmnt   
  427.   
  428.   
  429.     // CHECK, IF THE SPEED IS 0, THEN SKIP, but usually it's not 0  
  430.     X_ += dX_ * (speed_ * interval);  
  431.     Y_ += dY_ * (speed_ * interval);  
  432.   
  433.     if ((dX_ > 0 && X_ > destX_) || (dX_ < 0 && X_ < destX_))  
  434.       X_ = destX_;      // correct overshoot (slow? XXX)  
  435.     if ((dY_ > 0 && Y_ > destY_) || (dY_ < 0 && Y_ < destY_))  
  436.       Y_ = destY_;      // correct overshoot (slow? XXX)  
  437.       
  438.     /* list based improvement */  
  439.     if(oldX != X_)// || oldY != Y_)  
  440.         T_->updateNodesList(this, oldX);//, oldY);  
  441.     // COMMENTED BY -VAL- // bound_position();  
  442.   
  443.     // COMMENTED BY -VAL- // Z_ = T_->height(X_, Y_);  
  444.   
  445. #if 0  
  446.     fprintf(stderr, "Node: %d, X: %6.2f, Y: %6.2f, Z: %6.2f, time: %f\n",  
  447.         address_, X_, Y_, Z_, now);  
  448. #endif  
  449.     position_update_time_ = now;  
  450. }  
  451.   
  452.   
  453. void  
  454. MobileNode::random_position()  
  455. {  
  456.     if (T_ == 0) {  
  457.         fprintf(stderr, "No TOPOLOGY assigned\n");  
  458.         exit(1);  
  459.     }  
  460.   
  461.     X_ = Random::uniform() * T_->upperX();  
  462.     Y_ = Random::uniform() * T_->upperY();  
  463.     Z_ = T_->height(X_, Y_);  
  464.   
  465.     position_update_time_ = 0.0;  
  466. }  
  467.   
  468. void  
  469. MobileNode::random_destination()  
  470. {  
  471.     if (T_ == 0) {  
  472.         fprintf(stderr, "No TOPOLOGY assigned\n");  
  473.         exit(1);  
  474.     }  
  475.   
  476.     random_speed();  
  477. #ifdef DEBUG  
  478.         fprintf(stderr, "%d - %s: calling set_destination()\n",  
  479.                 address_, __FUNCTION__);  
  480. #endif  
  481.     (void) set_destination(Random::uniform() * T_->upperX(),  
  482.                                Random::uniform() * T_->upperY(),  
  483.                                speed_);  
  484. }  
  485.   
  486. void  
  487. MobileNode::random_direction()  
  488. {  
  489.     /* this code isn't used anymore -dam 1/22/98 */  
  490.     double len;  
  491.   
  492.     dX_ = (double) Random::random();  
  493.     dY_ = (double) Random::random();  
  494.   
  495.     len = sqrt( (dX_ * dX_) + (dY_ * dY_) );  
  496.   
  497.     dX_ /= len;  
  498.     dY_ /= len;  
  499.     dZ_ = 0.0;              // we're not flying...  
  500.   
  501.     /* 
  502.      * Determine the sign of each component of the 
  503.      * direction vector. 
  504.      */  
  505.     if (X_ > (T_->upperX() - 2*T_->resol())) {  
  506.         if (dX_ > 0)   
  507.             dX_ = -dX_;  
  508.     } else if (X_ < (T_->lowerX() + 2*T_->resol())) {  
  509.         if (dX_ < 0)   
  510.             dX_ = -dX_;  
  511.     } else if (Random::uniform() <= 0.5) {  
  512.         dX_ = -dX_;  
  513.     }  
  514.   
  515.     if (Y_ > (T_->upperY() - 2*T_->resol())) {  
  516.         if (dY_ > 0)   
  517.             dY_ = -dY_;  
  518.     } else if (Y_ < (T_->lowerY() + 2*T_->resol())) {  
  519.         if (dY_ < 0)   
  520.             dY_ = -dY_;  
  521.     } else if(Random::uniform() <= 0.5) {  
  522.         dY_ = -dY_;  
  523.     }  
  524. #if 0  
  525.     fprintf(stderr, "Location: (%f, %f), Direction: (%f, %f)\n",  
  526.         X_, Y_, dX_, dY_);  
  527. #endif  
  528. }  
  529.   
  530. void  
  531. MobileNode::random_speed()  
  532. {  
  533.     speed_ = Random::uniform() * MAX_SPEED;  
  534. }  
  535.   
  536. double  
  537. MobileNode::distance(MobileNode *m)  
  538. {  
  539.     update_position();      // update my position  
  540.     m->update_position();        // update m's position  
  541.   
  542.         double Xpos = (X_ - m->X_) * (X_ - m->X_);  
  543.         double Ypos = (Y_ - m->Y_) * (Y_ - m->Y_);  
  544.     double Zpos = (Z_ - m->Z_) * (Z_ - m->Z_);  
  545.   
  546.         return sqrt(Xpos + Ypos + Zpos);  
  547. }  
  548.   
  549. double  
  550. MobileNode::propdelay(MobileNode *m)  
  551. {  
  552.     return distance(m) / SPEED_OF_LIGHT;  
  553. }  
  554.   
  555. void   
  556. MobileNode::idle_energy_patch(float /*total*/float /*P_idle*/)  
  557. {  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值