📄 ns-leach.tcl
字号:
############################################################################## This code was developed as part of the MIT uAMPS project. (June, 2000)############################################################################## Message Constantsset ADV_CH 0set JOIN_REQ 1set ADV_SCH 2set DATA 3set MAC_BROADCAST 0xffffffffset LINK_BROADCAST 0xffffffffset BYTES_ID 2############################################################################## LEACH Application#############################################################################Class Application/LEACH -superclass ApplicationApplication/LEACH instproc init args { global opt $self instvar rng_ isch_ hasbeench_ next_change_time_ round_ $self instvar clusterChoices_ clusterDist_ clusterNodes_ currentCH_ $self instvar xmitTime_ TDMAschedule_ dist_ code_ $self instvar now_ alive_ frame_time_ end_frm_time_ $self instvar begin_idle_ begin_sleep_ $self instvar myADVnum_ receivedFrom_ dataReceived_ set rng_ [new RNG] $rng_ seed 0 set isch_ 0 set hasbeench_ 0 set next_change_time_ 0 set round_ 0 set clusterChoices_ "" set clusterDist_ "" set clusterNodes_ "" set currentCH_ "" set xmitTime_ "" set TDMAschedule_ "" set dist_ 0 set code_ 0 set now_ 0 set alive_ 1 set frame_time_ $opt(frame_time) set end_frm_time_ 0 set begin_idle_ 0 set begin_sleep_ 0 set myADVnum_ 0 set receivedFrom_ "" set dataReceived_ "" $self next $args}Application/LEACH instproc start {} { [$self mac] set node_num_ [$self nodeID] $self decideClusterHead $self checkAlive }############################################################################## Helper Functions#############################################################################Application/LEACH instproc getRandomNumber {llim ulim} { $self instvar rng_ return [$rng_ uniform $llim $ulim]}Application/LEACH instproc node {} { return [[$self agent] set node_]}Application/LEACH instproc nodeID {} { return [[$self node] id]}Application/LEACH instproc mac {} { return [[$self node] set mac_(0)]}Application/LEACH instproc getX {} { return [[$self node] set X_]}Application/LEACH instproc getY {} { return [[$self node] set Y_]}Application/LEACH instproc getER {} { set er [[$self node] getER] return $er}Application/LEACH instproc GoToSleep {} { global opt ns_ $self instvar begin_idle_ begin_sleep_ [[$self node] set netif_(0)] set sleep_ 1 # If node has been awake, remove idle energy (e.g., the amount of energy # dissipated while the node is in the idle state). Otherwise, the node # has been asleep and must remove sleep energy (e.g., the amount of # energy dissipated while the node is in the sleep state). if {$begin_idle_ > $begin_sleep_} { set idle_energy [expr $opt(Pidle) * [expr [$ns_ now] - $begin_idle_]] [$self getER] remove $idle_energy } else { set sleep_energy [expr $opt(Psleep) * [expr [$ns_ now] - $begin_sleep_]] [$self getER] remove $sleep_energy } set begin_sleep_ [$ns_ now] set begin_idle_ 0}Application/LEACH instproc WakeUp {} { global opt ns_ $self instvar begin_idle_ begin_sleep_ [[$self node] set netif_(0)] set sleep_ 0 # If node has been asleep, remove sleep energy (e.g., the amount of energy # dissipated while the node is in the sleep state). Otherwise, the node # has been idling and must remove idle energy (e.g., the amount of # energy dissipated while the node is in the idle state). if {$begin_sleep_ > $begin_idle_} { set sleep_energy [expr $opt(Psleep) * [expr [$ns_ now] - $begin_sleep_]] [$self getER] remove $sleep_energy } else { set idle_energy [expr $opt(Pidle) * [expr [$ns_ now] - $begin_idle_]] [$self getER] remove $idle_energy } set begin_idle_ [$ns_ now] set begin_sleep_ 0}Application/LEACH instproc setCode code { $self instvar code_ set code_ $code [$self mac] set code_ $code}Application/LEACH instproc checkAlive {} { global ns_ chan opt node_ $self instvar alive_ TDMAschedule_ $self instvar begin_idle_ begin_sleep_ # Check the alive status of the node. If the node has run out of # energy, it no longer functions in the network. set ISalive [[[$self node] set netif_(0)] set alive_] if {$alive_ == 1} { if {$ISalive == 0} { puts "Node [$self nodeID] is DEAD!!!!" $chan removeif [[$self node] set netif_(0)] set alive_ 0 set opt(nn_) [expr $opt(nn_) - 1] if {$opt(rcapp) == "LEACH-C/StatClustering" && \ [$self isClusterHead?]} { foreach element $TDMAschedule_ { if {$element != [$self nodeID]} { puts "Node $element is effectively DEAD!!!!" $chan removeif [$node_($element) set netif_(0)] [$node_($element) set netif_(0)] set alive_ 0 [$node_($element) set rca_app_] set alive_ 0 set opt(nn_) [expr $opt(nn_) - 1] } } } } else { $ns_ at [expr [$ns_ now] + 0.1] "$self checkAlive" if {$begin_idle_ >= $begin_sleep_} { set idle_energy [expr $opt(Pidle) * [expr [$ns_ now] - $begin_idle_]] [$self getER] remove $idle_energy set begin_idle_ [$ns_ now] } else { set sleep_energy [expr $opt(Psleep) * [expr [$ns_ now] - $begin_sleep_]] [$self getER] remove $sleep_energy set begin_sleep_ [$ns_ now] } } } if {$opt(nn_) < $opt(num_clusters)} "sens_finish"}############################################################################## Cluster Head Functions#############################################################################Application/LEACH instproc isClusterHead? {} { $self instvar isch_ return $isch_}Application/LEACH instproc hasbeenClusterHead? {} { $self instvar hasbeench_ return $hasbeench_}Application/LEACH instproc hasnotbeenClusterHead {} { $self instvar hasbeench_ set hasbeench_ 0}Application/LEACH instproc setClusterHead {} { $self instvar isch_ hasbeench_ set isch_ 1 set hasbeench_ 1 return }Application/LEACH instproc unsetClusterHead {} { $self instvar isch_ set isch_ 0 return }############################################################################## Distributed Cluster Set-up Functions#############################################################################Application/LEACH instproc decideClusterHead {} { global chan ns_ opt node_ $self instvar next_change_time_ round_ clusterNodes_ $self instvar now_ TDMAschedule_ beginningE_ alive_ $self instvar myADVnum_ CHheard_ set CHheard_ 0 [$self mac] set CHheard_ $CHheard_ set myADVnum_ 0 [$self mac] set myADVnum_ $myADVnum_ # Check the alive status of the node. If the node has run out of # energy, it no longer functions in the network. set ISalive [[[$self node] set netif_(0)] set alive_] if {$alive_ == 1 && $ISalive == 0} { puts "Node [$self nodeID] is DEAD!!!! Energy = [[$self getER] query]" $chan removeif [[$self node] set netif_(0)] set alive_ 0 set opt(nn_) [expr $opt(nn_) - 1] } if {$alive_ == 0} {return} set now_ [$ns_ now] set nodeID [$self nodeID] set beginningE_ [[$self getER] query] $self setCode 0 $self WakeUp set tot_rounds [expr int([expr $opt(nn_) / $opt(num_clusters)])] if {$round_ >= $tot_rounds} { set round_ 0 } if {$opt(eq_energy) == 1} { # # 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. # set nn $opt(nn_) if {[expr $nn - $opt(num_clusters) * $round_] < 1} { set thresh 1 } else { set thresh [expr double($opt(num_clusters)) / \ [expr $nn - $opt(num_clusters) * $round_]] # Whenever round_ is 0, all nodes are eligible to be cluster-head. if {$round_ == 0} { $self hasnotbeenClusterHead } } # If node has been cluster-head in this group of rounds, it will not # act as a cluster-head for this round. if {[$self hasbeenClusterHead?]} { set thresh 0 } } else { # # Pi(t) = Ei(t) / Etotal(t) * k # where k is the expected number of clusters per round, # Ei(t) is the node's current energy, and Etotal(t) is the total # energy from all nodes in the network. # set Etotal 0 # Note! In a real network, would need a routing protocol to get this # information. Alternatively, each node could estimate Etotal(t) from # the energy of nodes in its cluster. for {set id 0} {$id < [expr $opt(nn)-1]} {incr id} { set app [$node_($id) set rca_app_] set E [[$app getER] query] set Etotal [expr $Etotal + $E] } set E [[$self getER] query] set thresh [expr double([expr $E * $opt(num_clusters)]) / $Etotal] } puts "THRESH = $thresh" set clusterNodes_ "" set TDMAschedule_ "" if {[$self getRandomNumber 0 1] < $thresh} { puts "$nodeID: *******************************************" puts "$nodeID: Is a cluster head at time [$ns_ now]" $self setClusterHead set random_access [$self getRandomNumber 0 $opt(ra_adv)] $ns_ at [expr $now_ + $random_access] "$self advertiseClusterHead" } else { puts "$nodeID: *******************************************" $self unsetClusterHead } incr round_ set next_change_time_ [expr $now_ + $opt(ch_change)] $ns_ at $next_change_time_ "$self decideClusterHead" $ns_ at [expr $now_ + $opt(ra_adv_total)] "$self findBestCluster"}Application/LEACH instproc advertiseClusterHead {} { global ns_ opt ADV_CH MAC_BROADCAST LINK_BROADCAST BYTES_ID $self instvar currentCH_ code_ set chID [$self nodeID] set currentCH_ $chID pp "Cluster Head $currentCH_ broadcasting ADV at time [$ns_ now]"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -