0

我有两个 tcl 文件。一个是主 tcl 文件(main.tcl),另一个是主 tcl 文件的帮助文件(help.tcl)。我想在执行主文件时从主文件执行该帮助文件。我使用命令“源文件名”为此。但是我遇到了一些错误。在这里我发布了两个 tcl 文件以及执行时发生的错误。请帮我解决这个问题...

Error
num_nodes is set 4
warning: Please use -channel as shown in tcl/ex/wireless-mitf.tcl
INITIALIZE THE LIST xListHead
Enter Source Node (0 to 4)
0
Enter Destination Node (0 to 4)
3
SORTING LISTS ...DONE!
channel.cc:sendUp - Calc highestAntennaZ_ and distCST_
highestAntennaZ_ = 1.5,  distCST_ = 716.1
ns: proc1: can't read "n0": no such variable
    while executing
"attach-CBR-traffic $n0 $sink1 64 0.07"
    invoked from within
"set inf0_1[attach-CBR-traffic $n0 $sink1 64 0.07]"
    (file "final.tcl" line 1)
    invoked from within
"source.orig final.tcl"
    ("uplevel" body line 1)
    invoked from within
"uplevel source.orig [list $fileName]"
    invoked from within
"if [$instance_ is_http_url $fileName] {
set buffer [$instance_ read_url $fileName]
uplevel eval $buffer
} else {
uplevel source.orig [list $fileName]
..."
    (procedure "source" line 8)
    invoked from within
"source final.tcl"
    (procedure "proc1" line 6)
    invoked from within
"proc1"

在文件 Main.tcl 中:

set val(chan)           Channel/WirelessChannel    ;# Channel Type
set val(prop)           Propagation/TwoRayGround   ;# radio-propagation model
set val(netif)          Phy/WirelessPhy            ;# network interface type
set val(mac)            Mac/802_11                 ;# MAC type
set val(ifq)            CMUPriQueue            ;# interface queue type
set val(ll)             LL                         ;# link layer type
set val(ant)            Antenna/OmniAntenna        ;# antenna model
set val(ifqlen)         340                        ;# max packet in ifq
set val(nn)             4                          ;# number of mobilenodes
set val(rp)             DSR                        ;# routing protocol
set val(x)      630            ;# X axis distance   
set val(y)      570            ;# Y axis distance
set opt(energymodel)    EnergyModel                ;# Initial Energy
set opt(initialenergy)  100                        ;# Initial energy in Joules

set ns [new Simulator]

set nam1 [open nam11.nam w]
$ns namtrace-all-wireless $nam1 $val(x) $val(y)

set trace1 [open trace11.tr w]
$ns trace-all $trace1
$ns use-newtrace

set topo [new Topography]
$topo load_flatgrid $val(x) $val(y)

create-god $val(nn)
Phy/WirelessPhy set Pt_ 0.81

$ns node-config -adhocRouting $val(rp) \
        -llType $val(ll) \
        -macType $val(mac) \
        -ifqType $val(ifq) \
        -ifqLen $val(ifqlen) \
        -antType $val(ant) \
        -propType $val(prop) \
        -phyType $val(netif) \
        -topoInstance $topo \
        -agentTrace ON \
        -routerTrace ON \
        -macTrace ON \
        -movementTrace ON \
        -rxPower 0.36 \
        -txPower 0.14 \
            -channelType $val(chan) \
        -initialEnergy $opt(initialenergy) \
        -energyModel $opt(energymodel)  \


for { set i 0 } {$i < $val(nn)} { incr i } {
  set n($i) [$ns node]
  $n($i) random-motion 0
  $n($i) color black
  $ns initial_node_pos $n($i) 30
}

for { set i 0 } { $i < $val(nn)} { incr i } {
  $ns at 0.0 "$n($i) color black"
  $ns at 0.0 "$n($i) label-color maroon"
}

$ns at 0.0 "$n(0) setdest 220.00 210 3000"
$ns at 0.0 "$n(1) setdest 320.00 310 3000"
$ns at 0.0 "$n(2) setdest 420.00 110 3000"
$ns at 0.0 "$n(3) setdest 520.00 210 3000"


for {set i 0} {$i<$val(nn)} {incr i} {
  set sink($i) [new Agent/LossMonitor]
  $ns attach-agent $n($i) $sink($i)
}

proc attach-CBR-traffic { node sink size itval} {
  #Get an instance of the simulator
  set ns_ [Simulator instance]
  set udp [new Agent/UDP]
  $ns_ attach-agent $node $udp
  #Create a CBR  agent and attach it to the node
  set cbr [new Application/Traffic/CBR]
  $cbr attach-agent $udp
  $cbr set packetSize_ $size    ;#sub packet size
  $cbr set interval_ $itval
  #Attach CBR source to sink;
  $ns_ connect $udp $sink
  return $cbr
}
set cbr001 [attach-CBR-traffic $n(0) $sink(1) 256 0.082]
$ns at 1.0 "$cbr001 start"
$ns at 1.001 "$cbr001 stop"

set cbr001 [attach-CBR-traffic $n(1) $sink(3) 256 0.082]
$ns at 1.002 "$cbr001 start"
$ns at 1.003 "$cbr001 stop"

# neighbor node calculation
set nbr [open Neighbor w]
puts $nbr "\t\t\t\t\tNeighbor Detail"
puts $nbr "\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
puts $nbr "\tNode\t\tNb node\t\tNode-Xpos\tNode-Ypos\tNb-Xpos\t\tNb-Ypos\t\tDistance(d)"
puts $nbr "\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
close $nbr


#~~~~~~~~~~~~~~~~ Calculation of neighbor nodes of all node~~~~~~~~~~~~~~~~~~~
proc distance { n1 n2 nd1 nd2} {
  global c n bnd
  set nbr [open Neighbor a]
  set x1 [expr int([$n1 set X_])]
  set y1 [expr int([$n1 set Y_])]
  set x2 [expr int([$n2 set X_])]
  set y2 [expr int([$n2 set Y_])]
  set d [expr int(sqrt(pow(($x2-$x1),2)+pow(($y2-$y1),2)))]
  if {$d<300} {
    if {$nd2!=$nd1} {
      puts $nbr "\t$nd1\t\t$nd2\t\t$x1\t\t$y1\t\t$x2\t\t$y2\t\t$d"
    }
  }
  close $nbr
}


for {set i 0} {$i <$val(nn)} {incr i} {
  for {set j 0} {$j <$val(nn)} {incr j} {
    $ns at 1.002 "distance $n($i) $n($j) $i $j" 
  }
}

# For Input
set f 1
while {$f} {
  puts "Enter Source Node (0 to 4)"
  gets stdin src
  puts "Enter Destination Node (0 to 4)"
  gets stdin dst
  if {$src>=0 && $src<5 && $dst>=0 && $dst<5 && $src!=$dst} {
    set f 0
    set sd [open srcdst w]
    puts $sd "$src $dst"
    close $sd
  } else {
    puts "\n\t---------Enter Proper Input-------\n"
  }
}

#minimum

proc proc1 {} {
  exec awk -f distance.awk srcdst Neighbor &
  exec awk -f mm.awk snd & 
  exec awk -f mnode.awk min snd &
  exec awk -f final.awk srcdst mnode &
  source final.tcl
}

$ns at 1.5 "proc1"

proc proc2 {} {
  global ns trace1 nam1
  $ns flush-trace
  close $trace1
  close $nam1
  exec nam nam11.nam &
  exit 0
}

$ns at 3.0 "proc2"

$ns run

在文件 final.tcl 中:

set inf0_1[attach-CBR-traffic $n0 $sink1 64 0.07]
$ns at2.1 "$inf0_1 start"
$ns at2.3 "$inf0_1 stop"
$ns at2.1 "$n(0) color green4"
$ns at2.4 "$ns trace-annotate\"Node-0 send data to its neighbor1\""
set inf1_3[attach-CBR-traffic $n1 $sink3 64 0.07]
$ns at2.1 "$inf1_3 start"
$ns at2.3 "$inf1_3 stop"
$ns at2.1 "$n(1) color green4"
$ns at2.4 "$ns trace-annotate\"Node-1 send data to its neighbor3\""
4

1 回答 1

2

main.tcl您的文件中似乎没有任何您来源的地方help.tcl。但是,在错误消息中,您声称的文件似乎help.tcl实际上名为final.tcl. 假设这是您的意思,那么我可以诊断错误。

问题是在您的final.tcl文件中,第一行尝试执行此语句:

set inf0_1 [attach-CBR-traffic $n0 $sink1 64 0.07]
#         ^
#         |
# BTW, unrelated to the error, there is also a missing space here which
# is probably not what you intended. 

该语句的问题在于变量n0sink1未定义。

更新的答案

好的,您对Tcl的理解似乎有很多误解。我强烈推荐阅读 Tcl 语言的文档。幸运的是,与 C 或 Perl 或几乎任何其他语言不同,tcl 语法的完整文档只有一个页面:http ://www.tcl.tk/man/tcl/TclCmd/Tcl.htm 。请特别注意第 8 条规则(变量替换)。

首先你需要知道你的脚本有问题的是错误消息告诉你的:你没有n0在程序的任何地方定义变量(也没有定义sink1)。然而,有一个全局变量n恰好是一个数组。从您的评论看来,这就是您尝试访问时的意思n0。如果是这样,则在规则 8 中给出了正确的语法:使用该arrayname(index)语法访问数组。在我们继续之前,我想提醒您,Tcl 所谓的数组在技术上是关联数组(在其他语言中它们有时称为散列或映射),因此索引可以是字符串。现在,话虽如此,访问的正确语法n是:

set inf0_1 [attach-CBR-traffic $n(0) $sink(1) 64 0.07]
#                                 ^        ^

但这仍然行不通。如果你尝试这个,它仍然会抱怨nsink未定义。那是因为 tcl 作用域规则是如何工作的。在函数内部,只有局部变量是可见的。全局变量在函数内部不可用,除非您明确要求 tcl 导入它们。要访问全局变量,您有两种选择:

一、传统方式:使用global命令导入全局变量。您可以在源final.tcl文件的 proc 中执行此操作:

proc proc1 {} {
  global n sink
  # ...
  source final.tcl
}

或者您可以在 final.tcl 文件本身中执行此操作:

global n sink
set inf0_1 [attach-CBR-traffic $n(0) $sink(1) 64 0.07]
# ...

第二种方法是使用全局命名空间访问全局变量::。这样您就不需要使用以下global命令导入变量:

set inf0_1 [attach-CBR-traffic $::n(0) $::sink(1) 64 0.07]

修复我上面强调的所有问题应该可以让你的代码运行(假设我猜对了你的意图)。但是我强烈建议阅读 tcl 手册页并熟悉 tcl 以避免将来出现错误。至少您应该了解语法规则、set 的手册页和 proc 的手册页:

以下页面也是对 tcl 的一个很好的介绍:An Introduction to Tcl Scripting

于 2012-10-29T06:34:43.843 回答