📄 leachapp.cc
字号:
#include "leachApp.h"#include <random.h>#include <mannasim/battery.h>#include <mannasim/leach/rca/rcagent.h>/** TCL **************************************/static class LeachAppClass : public TclClass{ public: LeachAppClass() : TclClass("Application/SensorBaseApp/CommonNodeApp/LeachApp") {} // Create a TCL Object (parameters starts in 4) TclObject * create(int argc, const char * const * argv) { if (argc != 7) { fprintf(stderr, "Incorrect sintax:\n" " new LeachApp <nNodes> <nClusters> <maxDist>"); } return new LeachApp( atoi(argv[4]), atoi(argv[5]), atof(argv[6])); }} leach_app_object; /*********************************************/LeachApp::LeachApp(int nNodes, int nClusters, double maxDist) : CommonNodeApp() // : SensorBaseApp(){ mac_ = NULL; agent_ = NULL; isCH_ = 0; hasBeenCH_ = false; nextChangeTime_ = 0; round_ = 0; dist_ = 0; code_ = 0; now_ = 0; endFrmTime_ = 0; beginIdle_ = 0; beginSleep_ = 0; /* Although constructing here, can't determine * sensedData's nodeid, because while constructing * the sensed_node_ is not yet defined. */ sensedData_ = new SensedData(); eventHandler_ = new LeachEventHandler(this); config_.numberNodes_ = nNodes; config_.desiredClusters_ = nClusters; config_.maxDist_ = bsDist_ = maxDist; initializeConfig(); frameTime_ = config_.ssSlotTime_ * config_.numberNodes_; lstRndDelay_ = 0; listenADV_ = true; listenJOINREQ_ = false;}/* Initialize LEACH's configuration. */void LeachApp::initializeConfig(){ #define HDR_SIZE 25 // Originalmente era 25 config_.changeTimeIncrement_ = 10 * INITIAL_ENERGY; config_.rndAdvDelay_ = TxTime(HDR_SIZE + 4); config_.ra_advTotal_ = 1 + config_.rndAdvDelay_ * (config_.desiredClusters_ * 4 + 1); config_.ra_join_ = 0.01 * config_.numberNodes_; config_.ra_delay_ = TxTime(HDR_SIZE + 4); config_.spreading_ = config_.desiredClusters_ + 1; config_.sigSize_ = 500; config_.ssSlotTime_ = TxTime(config_.sigSize_ + HDR_SIZE) * config_.spreading_; config_.bsCode_ = 0; #undef HDR_SIZE}LeachApp::~LeachApp(){ if (sensedData_ != NULL) delete sensedData_; delete eventHandler_;}void LeachApp::start(){ if (agent_ == NULL) { char agentName[32]; printf("Warning! LeachApp::start() => agent_ of %d is null! Creating a RCAgent!\n", sensor_node_->nodeid()); sprintf(agentName, "__rcagent%d", sensor_node_->nodeid()); agent_ = new RCAgent(); agent_->name(agentName); Tcl::instance().enter(agent_); printf("%s attach %s", name(), agent_->name()); Tcl::instance().evalf("%s attach %s", name(), agent_->name()); } sensedData_->node_id() == sensor_node_->nodeid(); mac_ = (MacSensor *) ((RCAgent *) agent_)->getMAC(); mac_->node_num() = sensor_node_->nodeid(); decideClusterHead(); CommonNodeApp::start();}void LeachApp::goToSleep(){ ((Battery *) sensor_node_->energy_model())->sleep();}void LeachApp::wakeUp(){ ((Battery *) sensor_node_->energy_model())->wakeUp();}void LeachApp::setCode(int code){ printf("%d is setting code to %d\n", sensor_node_->nodeid(), code); code_ = code; mac_->code() = code;}void LeachApp::setClusterHead(){ isCH_ = true; hasBeenCH_ = true; /* "... when a node decides to become a cluster-head, * it chooses randomly from a list of spreading codes." */}void LeachApp::unsetClusterHead(){ isCH_ = false;}/*** Distributed cluster set-up functions *****************/void LeachApp::decideClusterHead(){ int totRounds; setCode(0); wakeUp(); CHHeard_ = false; // CheckIsAlive??? totRounds = config_.numberNodes_ / config_.desiredClusters_; if (round_ >= totRounds) round_ = 0; if (round_ == 0) setHasNotBeenClusterHead(); if (Random::uniform(0, 1) < calculatePi()) { printf("Node %d is a cluster head at time %lf\n", sensor_node_->nodeid(), Scheduler::instance().clock()); setClusterHead(); Scheduler::instance().schedule( eventHandler_, new LeachEvent(&LeachApp::advertiseClusterHead), config_.rndAdvDelay_); } else { unsetClusterHead(); listenADV_ = true; clearClusterChoices(); } round_++; nextChangeTime_ = Scheduler::instance().clock() + config_.changeTimeIncrement_; Scheduler::instance().schedule( eventHandler_, new LeachEvent(&LeachApp::decideClusterHead),// nextChangeTime_); config_.changeTimeIncrement_); Scheduler::instance().schedule( eventHandler_, new LeachEvent(&LeachApp::findBestCluster), config_.ra_advTotal_);}double LeachApp::calculatePi(){ /* * Pi(t) = k / (N - k mod(r,N/k)) * where k is the expected number of clusters per round * N is the total number of sensor nodes in the network * and r is the number of rounds that have already passed. */ register int n = config_.numberNodes_; register int k = config_.desiredClusters_; double thresh; if (hasBeenClusterHead()) thresh = 0; else if (n - k * round_ < 1) thresh = 1; else thresh = (double) k / (n - k * round_); return thresh;}void LeachApp::advertiseClusterHead(){ int clusterCode; int numCodesAvail; numCodesAvail = 2 * config_.spreading_ - 1; currentCH_ = sensor_node_->nodeid(); currentCHMAC_ = MAC_BROADCAST; clusterCode = (mac_->myADVnum() % numCodesAvail) + 1; setCode(clusterCode); wakeUp(); send( MAC_BROADCAST, LINK_BROADCAST, LEACH_ADV_CH,// (char *) (¤tCH_), (char *) (&code_),// (char *) (&mac_->myADVnum()), sizeof(currentCH_), BYTES_ID, config_.maxDist_, 0); listenJOINREQ_ = true; clusterNodes_.clear();}void LeachApp::findBestCluster(){// int numCodesAvail, clusterCode;// numCodesAvail = 2 * config_.spreading_ - 1; if (isClusterHead()) { // If node is CH, determine code and create a TDMA schedule. dist_ = config_.maxDist_; currentCH_ = sensor_node_->nodeid(); currentCHMAC_ = MAC_BROADCAST;// myADVnum_ = mac_->myADVnum(); /* There are opt(spreading) - 1 codes available b/c need 1 code * for communication with the base station. */// clusterCode = (myADVnum_ % numCodesAvail) + 1; Scheduler::instance().schedule( eventHandler_, new LeachEvent(&LeachApp::createSchedule), config_.ra_advTotal_ + config_.ra_join_); } else { int clusterCode; /* If node is not a CH, find the CH which allows minimum transmit * power for communication. Set the code and "distance" parameters * accordingly. */ if (clusterChoices_.empty()) { printf("Warning! No Cluster Head ADVs were heard by %d\n", sensor_node_->nodeid()); currentCH_ = -1; // VER ISSO ***** currentCHMAC_ = MAC_BROADCAST; sendMyDataToBS(); return; } double min_dist = config_.maxDist_ + 1; int ind = 0; for (CHs::iterator it = clusterChoices_.begin(); it != clusterChoices_.end(); it++, ind++) { chadv element = (chadv) *it; if (element.distance < min_dist) { min_dist = element.distance; currentCH_ = element.nodeid; currentCHMAC_ = element.mac;// clusterCode = (ind % numCodesAvail) + 1; clusterCode = element.code; } } dist_ = min_dist; printf("%d has choosen %d as cluster head (mac = %d)\n", sensor_node_->nodeid(), currentCH_, currentCHMAC_); Scheduler::instance().schedule( eventHandler_, new LeachEvent(&LeachApp::informClusterHead), config_.ra_advTotal_ + Random::uniform(0, config_.ra_join_ - config_.ra_delay_));; goToSleep(); setCode(clusterCode); printf("Current cluster-head of %d is %d, which code is %d, at distance is %lf\n", sensor_node_->nodeid(), currentCH_, clusterCode, dist_); } listenADV_ = false; clearClusterChoices();}void LeachApp::informClusterHead(){ int dataSize; int nodeId; printf("%d sending JOIN_REQ to %d, distance = %lf , at time %lf\n", sensor_node_->nodeid(), currentCH_, dist_, Scheduler::instance().clock()); dataSize = config_.spreading_ * BYTES_ID; nodeId = sensor_node_->nodeid(); send(// MAC_BROADCAST, currentCHMAC_, currentCH_, LEACH_JOIN_REQ, (char *) (&nodeId), sizeof(int), dataSize, config_.maxDist_, // Using maxDist_, the CH can discover node's distance// dist_, code_);}void LeachApp::createSchedule(){ if (clusterNodes_.empty()) { printf("Warning! There are no nodes in cluster %d\n", sensor_node_->nodeid()); sendMyDataToBS(); } else { int * msg; int i = 0; int dataSize; msg = new int[clusterNodes_.size()]; printf("%d sending TDMA schedule (ADV_SCH): ", sensor_node_->nodeid()); for (CNs::iterator it = clusterNodes_.begin(); it != clusterNodes_.end(); it++) { msg[i++] = (int) *it; printf("%d ", (int) *it); } printf("at time %lf\n", Scheduler::instance().clock()); dataSize = config_.spreading_ * sizeof(int) * clusterNodes_.size();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -