Problem:
The sample leach script is actually defunct when it comes to being able to switch between mte, dsdv, dsr, leach-c, etc. Trying to get leach to work again, but I get this:
96: Current cluster-head is 66, code is 1, dist is 22
97: Current cluster-head is 66, code is 1, dist is 13
98: Current cluster-head is 66, code is 1, dist is 25
ns: _o217 send_now 0xffffffff 1 8 16 139.0 1: wrong # args: should be "_o217 self class proc mac_dst link_dst type msg data_size dist code"
(Application/LEACH send_now line 1)
invoked from within
"_o217 send_now 0xffffffff 1 8 16 139.0 1"
It looks like some interface is different. I didn't get this error before, and I don't know where it's coming from.
Wading:
Apparently, the offending piece of code is only at once place:
Application/LEACH instproc send_now {mac_dst link_dst type msg data_size dist code} {
called by:
$ns_ at [$ns_ now] "$self send_now $mac_dst $link_dst $type $msg $data_size $dist $code"
After running the code with it printing out the parameters it was passing, in one instance, $link_dst became null for some reason, and that's why tcl thought there was an invalid number of arguments.
Solution:
8: Current cluster-head is 8, code is 1, dist is 139.0
9: Current cluster-head is , code is 1, dist is 0
10: Current cluster-head is 50, code is 2, dist is 29
Looking at node #9 in the snippet above, it ends up that the clusterheads weren't sending the ADV_CH (advertise clusterhead) message loud enough so that some nodes weren't able to hear it. Thus, they did not select a clusterhead and thus, there was no link destination for the messages they were sending.
Either the density of the nodes is too low, or that the power is too low.
printing out the clusterhead choices, it seems like there are some that are missing:
node 7 CH = 48
node 7 choice = 52 37 97 70 77 92 67 2
node 7 CH = 77
node 7 choice = 52 37 97 70 77 92 67 2
7: Current cluster-head is 77, code is 5, dist is 10
node 8 CH = 48
node 8 choice = {} 52 37 97 70 77 92 67 2
node 8 CH =
node 8 choice = {} 52 37 97 70 77 92 67 2
8: Current cluster-head is , code is 1, dist is 0
node 9 CH = 36
node 9 choice = {} {} {} {} {} 52 37 97 70 77 92 67 2
node 9 CH =
node 9 choice = {} {} {} {} {} 52 37 97 70 77 92 67 2
9: Current cluster-head is , code is 1, dist is 0
CH 53 received data (8 , 28.98289012430514) from 8 at 29.015228248610278
9 rcvd ADV_CH from at 29.031284241486009
9 clusterchoice: {}
CH 75 received data (25 , 29.013674076469229) from 25 at 29.046012152938452
It ends up that these nodes are somehow getting phantom blank messages during data transfer phase from node zero when node zero never sent them in the first place. I guess I can assume that it's somewhere in the code, but when I grep for the command, I can only find one stance calling send.
chungw1@CHUNGW1-WD1 ~/ns-allinone-2.27/ns-2.27
$ grep 'send .* .* $ADV_CH' *
mit/uAMPS/ns-leach.tcl: $self send $mac_dst $link_dst $ADV_CH $msg $datasize $opt(max_dist) $code_
mit/uAMPS/ns-leach.tcl~: $self send $mac_dst $link_dst $ADV_CH $msg $datasize $opt(max_dist) $code_
Fix:
I'll assume it's some weird glitch in ns that sends phantom messages, and will just proceed to make the receive function a bit smarter and just ignore all blank and anonymous messages.
I changed
puts "$nodeID rcvd ADV_CH from $chID at [$ns_ now]"
set clusterChoices_ [lappend clusterChoices_ $msg]
set clusterDist_ [lappend clusterDist_ [[$self agent] set distEst_]]
to
# if statement is a patch to deal with phantom ADV_CH messages
if {$msg != ""} {
puts "$nodeID rcvd ADV_CH from $chID at [$ns_ now]"
set clusterChoices_ [lappend clusterChoices_ $msg]
set clusterDist_ [lappend clusterDist_ [[$self agent] set distEst_]]
} else {
puts "$nodeID rcvd PHANTOM ADV_CH <$chID, $msg> at [$ns_ now]"
}
A weakness in the current clusterhead based algorithm is that it depends on a somewhat uniform sensor field to create the network topology.