0

2 つの tcl ファイルがあります。1 つはメイン tcl ファイル (main.tcl) で、もう 1 つはメイン 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が未定義であるということです。

更新された回答

OK、Tclの理解には多くの誤解があるようです。Tcl言語のドキュメントを読むことを強くお勧めします。幸いなことに、CやPerl、または他のほとんどの言語とは異なり、tcl構文の完全なドキュメントは1ページだけです: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にインポートを要求しない限り、関数内では使用できません。グローバル変数にアクセスするには、次の2つのオプションがあります。

まず、従来の方法:globalコマンドを使用してグローバル変数をインポートします。ファイルをソースするprocでそれを行うことができfinal.tclます:

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]
# ...

2番目の方法は、グローバル名前空間を使用してグローバル変数にアクセスすることです::globalこのように、次のコマンドを使用して変数をインポートする必要はありません。

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

上で強調したすべての問題を修正すると、コードが実行されるはずです(私があなたの意図を正しく推測したと仮定します)。ただし、将来のバグを回避するために、tclのマニュアルページを読み、tclに精通することを強くお勧めします。少なくとも、構文規則、setのmanページ、およびprocのmanページを理解する必要があります。

次のページもtclの良い紹介です:Tclスクリプティングの紹介

于 2012-10-29T06:34:43.843 に答える