for {set count 0} {$count<$num_of_UEs} { incr count } {
puts $count
set tcp$count [new Agent/TCP]
#$tcp$count set fid_ $count
#$tcp$count set prio_ 2
}
My problem is with the line#$tcp$count set fid_ $count
When I try to execute it it says
can't read "tcp": no such variable
while executing
"$tcp$count set fid_ $count"
("for" body line 4)
invoked from within
"for {set count 0} {$count<$num_of_UEs} { incr count } {
puts $count
set tcp$count [new Agent/TCP]
$tcp$count set fid_ $count
$tcp$coun..."
It says Can't read tcp, well it shouldnt read tcp it should read it as tcp0 in the first iteration and tcp1 in the second and so on.
What amI doing wrong?
thanks
EDIT:
I tried using arrays, thanks for the TIP. It worked for most parts but in one specific case
when I did this:
for {set count 0} {$count<$num_of_UEs} { incr count } {
set ftp($count) [new Application/FTP]
$ftp($count) attach-agent $tcp($count)
}
It gives me the following error:
Came here 0
(_o180 cmd line 1)
invoked from within
"_o180 cmd target _o99"
invoked from within
"catch "$self cmd $args" ret"
invoked from within
"if [catch "$self cmd $args" ret] {
set cls [$self info class]
global errorInfo
set savedInfo $errorInfo
error "error when calling class $cls: $args" $..."
(procedure "_o180" line 2)
(SplitObject unknown line 2)
invoked from within
"$agent target [[$self node] entry]"
(procedure "_o98" line 2)
(RtModule attach line 2)
invoked from within
"$m attach $agent $port"
(procedure "_o97" line 4)
(Node add-target line 4)
invoked from within
"$self add-target $agent $port"
(procedure "_o97" line 15)
(Node attach line 15)
invoked from within
"$node attach $agent"
(procedure "_o3" line 2)
(Simulator attach-agent line 2)
invoked from within
"$ns attach-agent $node2 $tcp($count)"
("for" body line 3)
invoked from within
"for {set count 0} {$count<$num_of_UEs} { incr count } {
puts "Came here $count"
$ns attach-agent $node2 $tcp($count)
}"
(file "hsexample.tcl" line 104)
I know its a long one, but I would really appreciate your help
The problem is that the parsing of the variable name after the $ stops at the first non-alphanumeric character (except for cases that I'll mention in a moment). This means that $tcp$count is interpreted as the string that is the concatenation of the contents of the tcp variable and the count variable (only one of which you've defined).
The best way of dealing with this is to use Tcl's associative arrays:
for {set count 0} {$count<$num_of_UEs} { incr count } {
puts $count
set tcp($count) [new Agent/TCP]
$tcp($count) set fid_ $count
$tcp($count) set prio_ 2
}
The ( is a special case in variable access syntax handling; it starts processing an associative array access (which goes on to the matching ), assuming no unquoted spaces).
(The other special case in variable names is ::, which is Tcl's namespace separator.)
I your big error traceback, I see:
if [catch "$self cmd $args" ret] {
Do you really have an instance method named "cmd" (or whatever terminology for the OO system you appear to use)
Do you want:
if {[catch {$self $cmd $args} ret]} { ...
If you do it as you do you are trying to get the contents of the (non existent variable) tcp and the content of the variable count. What you want is to get the content of tcp$count. You can achieve this using the set command. Simply do:
[set tcp$count] set fid_ $count
Related
I try to implement a simple scenario for LEACH protocol but I get this error:
Creating Sensors ...
invalid command name "Agent/LeachAgent"
while executing
"Agent/LeachAgent create _o2340 "
invoked from within
"catch "$className create $o $args" msg"
invoked from within
"if [catch "$className create $o $args" msg] {
if [string match "__FAILED_SHADOW_OBJECT_" $msg] {
delete $o
return ""
}
global errorInfo
error "class $..."
(procedure "new" line 3)
invoked from within
"new Agent/LeachAgent"
("for" body line 3)
invoked from within
"for {set i 1} {$i <= $val(nsn)} {incr i} {
set agent($i) [new Agent/LeachAgent]
$ns attach-agent $node_($i) $agent($i)
$agent($i) set packetSize_..."
(file "newleach3.tcl" line 187)
I use ubuntu 16.04 and ns-allinone-2.35 . when I ran my tcl file for the first time, i did not get this error.
Change your script to use Agent/RCAgent/LeachAgent as class name:
set agent($i) [new Agent/RCAgent/LeachAgent]
From what I can see, there is no Agent/LeachAgent in ns-allinone-2.35.
I was not successful in writing a correct code for attaching Leach protocol in my scenario, but I found that mannasim has a Mannasim Script Generator (MSG). It is a front-end for TCL simulation scripts easy creation.
Hi i'm new to tcl i'm trying to insert element to list in proc from user input and return the list and invoke it in another list
i have tried this and i'm get
puts "Enter list Size"
set size [gets stdin]
set aList [fillTheList $size]
proc fillTheList {arg1 } {
set lList {}
for {set i 0} {$i <= $arg1} {incr i} {
set value [gets stdin]
linsert $lList $i int(value)]
puts "[lindex $lList $i]"
}
return $lList
}
and i'm getting this error in cmd
invalid command name "fillTheList"
while executing
"fillTheList $size"
invoked from within
"set aList [fillTheList $size]"
(file "ascending.tcl" line 5)
Try
proc fillTheList {arg1 } {
set lList {}
for {set i 0} {$i < $arg1} {incr i} {
puts -nonewline "Enter value "
set value [gets stdin]
lappend lList $value
puts [lindex $lList $i]
}
return $lList
}
puts -nonewline "Enter list Size "
set size [gets stdin]
set aList [fillTheList $size]
A couple of notes:
If you set the condition in the for invocation to $i <= $arg1 it will ask for one more list item than you wanted, since i starts from 0.
Instead of lappend, lset lList $i $value could be used. It used to only be able to change elements already in the list, but nowadays it can change the element after the last one in the list, extending the list by one.
lList is a really bad variable name, because it is easy to mix up with names like IList.
Tcl is barely typed at all. You type strings from the keyboard, those strings are entered in the list. If those strings are valid integers they can be used like integers. You don't need, and you can't, convert them.
Documentation:
< (operator),
for,
gets,
incr,
lappend,
lindex,
lset,
proc,
puts,
return,
set
This is the code in TCL that is meant to produce factorial of a number given as parameter by the user.
if {$argc !=1}{
puts stderr "Error! ns called with wrong number of arguments! ($argc)"
exit 1
} else
set f [lindex $argv 0]
proc Factorial {x}{
for {set result 1} {$x>1}{set x [expr $x - 1]}{
set result [expr $result * $x]
}
return $result
}
set res [Factorial $f]
puts "Factorial of $f is $res"
There is a similar SO question, but it does not appear to directly address my problem. I have double-checked the code for syntax errors, but it does not compile successfully in Cygwin via tclsh producing the error:
$ tclsh ext1-1.tcl
extra characters after close-brace
while executing
"if {$argc !=1}{
puts stderr "Error! ns called with wrong number of arguments! ($argc)"
exit 1
} else
set f [lindex $argv 0]
proc Factorial {x}{..."
(file "ext1-1.tcl" line 3)
TCL Code from: NS Simulator for Beginners, Sophia-Antipolis, 2003-2004
Tcl is a little bit more sensitive about whitespace than most languages (though not as much as, say, Python). For instance, you can't add unescaped newlines except between commands as command separators. Another set of rules are that 1) every command must be written in the same manner as a proper list (where the elements are separated by whitespace) and 2) a command invocation must have exactly the number of arguments that the command definition has specified.
Since the invocation must look like a proper list, code like
... {$x>1}{incr x -1} ...
won't work: a list element that starts with an open brace must end with a matching close brace, and there can't be any text immediately following the close brace that matches the initial open brace. (This sounds more complicated than it is, really.)
The number-of-arguments requirement means that
for {set result 1} {$x>1}{incr x -1}{
set result [expr $result * $x]
}
won't work because the for command expects four arguments (start test next body) and it's only getting two, start and a mashup of the rest of other three (and actually not even that, since the mashup is illegal).
To make this work, the arguments need to be separated:
for {set result 1} {$x>1} {incr x -1} {
set result [expr {$result * $x}]
}
Putting in spaces (or tabs, if you want) makes the arguments legal and correct in number.
i am using 20 node in ns2 , i am trying to access the a(0) a(1) a(2) a(3) a(4) variables with for loop how can i do that
here is my code
for {set i 0} {$i < $val(nn)} {incr i} {
set sink($i) [new Agent/LossMonitor]
$ns attach-agent $n($i) $sink($i)
}
but its gives an error
bad variable name "sink(0)": upvar won't create a scalar variable that looks like an array element
i declare the variable in following manner
proc record {} {
global sink(0) sink(1) sink(2) sink(3) sink(4) sink(5)
}
Just use
global sink
(global is just a special upvar case)
variables that end with (...) are (associative) arrays, using numbers as key is not recommended, it is better to use a list instead, e.g.
set mylist {}
# append some elements
lappend mylist "foo" "bar" "baz"
# get the 2nd element
puts [lindex $mylist 1]
# set the 3rd element to "Hello World"
lset mylist 2 "Hello World"
Can anyone tell me how should I fix this problem? I have a problem in attaching more than one applications to one agent. (I am running ns2.35 on Ubuntu12.10)
There are two nodes(Source and Destination) in my environment and here are some features:
I attached a loss-monitor agent on Destination node.
I attached an udp agent on Source node.
I attached 9 applications on the udp agent by following declaration:
set nExpGen 9
for {set i 1} {$i <= $nExpGen} {incr i} {
set eee($i) [new Application/Traffic/Exponential]
$eee($i) attach-agent $udp
$ns connect $eee($i) $lmt
#nExpGen= number of exponential generators
#eee = exponential application
#lmt = loss-monitor agent
I got errors "cant read agent address: no such variable.." when running my tcl file ( see [error message])
Did I use the wrong way to attach these applications to the agent? How can I fix that?
Thank you all in advance.
[error messages]
can't read "agent_addr_": no such variable
while executing
"subst $[subst $var]"
(procedure "_o40" line 5)
(Object next line 5)
invoked from within
"_o40 next agent_addr_"
("eval" body line 1)
invoked from within
"eval $self next $args"
(procedure "_o40" line 11)
(Application/Traffic set line 11)
invoked from within
"$dst set agent_addr_"
(procedure "_o3" line 2)
(Simulator simplex-connect line 2)
invoked from within
"$self simplex-connect $dst $src"
(procedure "_o3" line 10)
(Simulator connect line 10)
invoked from within
"$ns connect $eee($i) $lmt"
("for" body line 4)
invoked from within
"for {set i 1} {$i <= $nExpGen} {incr i} {
set eee($i) [new Application/Traffic/Exponential]
$eee($i) attach-agent $udp
$ns con..."
(file "myTest3.tcl" line 47)
I got the solution:
The following statement build connections between two "Agents" (here $A and $B).
$ns connect $A $B
So, for this question, I shall connect my UDP agent and LossMonitor agent (outside my for loop).
$ns connect $udp $lmt
Connecting an "application" to an "agent" causes compiling error.