我正在建立一个网络环境,其中有DSR协议将n个节点围成一个圆圈。但是,当我修复大多数错误时,标题无法解决的最困惑的错误。如何修复“无法读取“ node_(0)”:无此类变量”错误?我不是已经在第86行的for循环中定义它了吗?
我找不到解决方法,当我改变时
set node_($i) [$ns node]
到
set node_($i) [$ns_ node]
这是完整的代码。
set val(chan) Channel/WirelessChannel
set val(prop) Propagation/TwoRayGround
set val(netif) Phy/WirelessPhy
set val(mac) Mac/802_11
set val(ifq) CMUPriQueue
set val(ll) LL
set val(ant) Antenna/OmniAntenna
set val(ifqlan) 50
set val(nn) 0
set val(rp) DSR
set val(x) 1000
set val(y) 1000
set val(r) 400
proc usage {} \
{
global argv0
puts "\nusage: $argv0 \[-nn node\] \[-r r\] \[-x x\] \[-y y\]\n"
puts "note: \[-nn nodes\] is essential, and the others are optional.\n"
}
proc getval {argc argv} \
{
global val
lappend vallist nn r x y z
for {set i 0} {$i < $argc} {incr i} {
set arg [lindex $argv $i]
if {[string range $arg 0 0] != "-"} continue
set name [string range $arg 1 end]
set val($name) [lindex $argv[expr $i+1]]
}
}
getval $argc $argv
if {$val(nn) == 0} {
usage
exit
}
set ns [new Simulator]
set tracefd [open circle.tr w]
$ns trace-all $tracefd
set namtracefd [open circle.nam w]
$ns namtrace-all-wireless $namtracefd $val(x) $val(y)
proc finish {} \
{
global ns tracefd namtracefd
$ns flush-trace
#close the trace file
close $tracefd
close $namtracefd
#execute nam on the trace file
exec nam circle.nam &
exit 0
}
set topo [new Topography]
$topo load_flatgrid $val(x) $val(y)
create-god $val(nn)
$ns node-config -addressType def\
-adhocRouting $val(rp)\
-llType $val(ll)\
-macType $val(mac)\
-ifqType $val(ifq)\
-ifqLan $val(ifqlan)\
-antType $val(ant)\
-propType $val(prop)\
-phyType $val(netif)\
-channelType $val(chan)\
-topoInstance $topo\
-agenttrace ON\
-routertrace ON\
-mactrace OFF\
-movementtrace OFF
##################################
for {set i 0} {$i < $val(nn)} {incr i} {
set node_($i) [$ns node]
$node_($i) random-motion 0
$node_($i) set X_ [expr $val(r) * cos($i * 2 * 3.14159 / $val(nn))]
$node_($i) set Y_ [expr $val(r) * sin($i * 2 * 3.14159 / $val(nn))]
$node_($i) set Z_ 0
$ns initial_node_pos $node_($i) [expr $val(x) / 10]
}
##################################
set tcp [new Agent/UDP]
$ns attach-agent $node_(0) $tcp
set null [new Agent/Null]
$ns attach-agent $node_([expr $val(nn) / 2]) $null
set cbr [new Application/Traffic/CBR]
$cbr set packetSize_ 5000
$cbr set interval_ 0.05
$cbr attach-agent $tcp
$ns connect $tcp $null
$ns at 0.1 "$cbr start"
$ns at 3.0 "$cbr stop"
$ns at 5.0 "finish"
$ns run
当我输入ns circle.tcl -nn 12
时,我期望输出:
num_node is set 12
warning: Please use -channel as shown in tcl/ex/wireless-mitf.tcl
INITIALIZE THE LIST xListHead
channel.cc:sendUp - Calc highestAntennaZ_and distCST_
SORTING LISTS ...DONE!
请帮助我,我已经被困了很长时间了。
答案 0 :(得分:2)
只要val(nn)
不大于零,就会产生该错误,因为这样会创建节点的循环:
for {set i 0} {$i < $val(nn)} {incr i} {
set node_($i) [$ns node]
$node_($i) random-motion 0
$node_($i) set X_ [expr $val(r) * cos($i * 2 * 3.14159 / $val(nn))]
$node_($i) set Y_ [expr $val(r) * sin($i * 2 * 3.14159 / $val(nn))]
$node_($i) set Z_ 0
$ns initial_node_pos $node_($i) [expr $val(x) / 10]
}
只会简单地决定它无事可做,甚至不会执行一次循环主体。是什么原因造成的?好吧,如果我们看一下参数解析过程:
proc getval {argc argv} \
{
global val
lappend vallist nn r x y z
for {set i 0} {$i < $argc} {incr i} {
set arg [lindex $argv $i]
if {[string range $arg 0 0] != "-"} continue
set name [string range $arg 1 end]
set val($name) [lindex $argv[expr $i+1]]
}
}
我们可以看到许多问题,其中最大的问题是(与set val($name)
相同的行:
lindex $argv[expr $i+1]
这里的问题是$argv
与表达式求值之间缺少空格;在将结果作为单个参数输入lindex
之前将两个字符串连接起来! ({lindex
仅带有一个自变量,只是使用“优雅地执行任何操作”的原则返回该自变量。)这在语法上甚至在所有情况下都不正确,但可能是在您尝试并导致{{1 }}设置为类似于字符串val(nn)
的内容。现在, -nn 101
运算符(在节点生成循环中)每当 端看起来都是非数字时,将使用ASCII排序。字符串中有多余的垃圾,因此绝对是非数字的。噢亲爱的。 ({<
是ASCII字符代码45,而-
是ASCII字符代码48,因此0
在-
之前。)这不是您想要的!
这是参数解析器的固定版本:
0
记住,在Tcl中,空格很重要!
答案 1 :(得分:0)
添加四行,可以运行模拟。
if(require(seqinr)){
mase.res <- read.alignment(file=system.file("sequences/test.mase",package="seqinr"), format = "mase")
mase.res
x <- alignment2genind(mase.res)
x
}
/// GENIND OBJECT /////////
// 6 individuals; 82 loci; 212 alleles; size: 57.2 Kb
// Basic content
@tab: 6 x 212 matrix of allele counts
@loc.n.all: number of alleles per locus (range: 2-5)
@loc.fac: locus factor for the 212 columns of @tab
@all.names: list of allele names for each locus
@ploidy: ploidy of each individual (range: 1-1)
@type: codom
@call: alignment2genind(x = mase.res)
// Optional content
@other: a list containing: com
set val(ifqlen) 50 ;# added (Line 7)
set val(nn) 10 ;# added (Line 10)
.
-movementtrace OFF \
-ifqLen $val(ifqlen) ;# added (Line 85)
.
for {set i 0} {$i < [expr $val(nn)]} {incr i} {
set node_($i) [$ns node] ;# added (Line 89)
的原因:我没有使用[$ argv]。 (set val(nn) 10
或$ ns file.tcl -nn 10
)
链接到已编辑文件:https://www.dropbox.com/s/m7zsnga6wf29r95/2Ezio-Auditore-DSR.tcl?dl=0
https://drive.google.com/drive/folders/0B7S255p3kFXNSmRYb2lGcDRUdWs?usp=sharing之前的所有3500 ns2仿真
EDIT:添加了@Donal Fellows的'argument parser',现在可以与$ ns file.tcl nn 10
一起运行。新示例https://www.dropbox.com/s/br6qaeg5kj73k14/4-circle-Ezio-Auditore.tar.gz?dl=0
ns2分析脚本https://drive.google.com/drive/folders/1rU_MFAEl1GCLMTJPLR3zbxPxkQQHkQ7T?usp=sharing