⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ns-leach.tcl

📁 对于LEACH协议阈值修改进行的改进
💻 TCL
📖 第 1 页 / 共 2 页
字号:
############################################################################
#
# This code was developed as part of the MIT uAMPS project. (June, 2000)
#
############################################################################


# Message Constants
set ADV_CH         0
set JOIN_REQ       1
set ADV_SCH        2
set DATA           3
set MAC_BROADCAST  0xffffffff
set LINK_BROADCAST 0xffffffff
set BYTES_ID       2


############################################################################
#
# LEACH Application
#
############################################################################

Class Application/LEACH -superclass Application


Application/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]
          }
        }
      }
    	$self GoToSleep
    } 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_)
    set Etotal 0
    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 aveE [expr $Etotal / $opt(nn)]
    set E [[$self getER] query]
    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 && $E >= $aveE} {
    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_ 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -