Dec 12, 2011

Creating a New Agent in Network Simulator 2

How to create a new agent in NS2. You can use any version of the Simulator. The following codes will make you to understand the writing of a sample agent.

Requirements:

  • NS2 Simulator
  • A tcl file to test the compiled agent

If any two values are supplied from the TCL file, the agent computes the Surface area of the Cylinder which is nothing but (2* PI * r * h).  The supplied values from TCL file are r and h.

How to do that.

1. Copy the newagent.cc (given below ) file in ~ns-allinone-2.34/ns-2.34/newfolder
2. Make an entry in the ~ns-2.34/Makefile.in
    Make an entry in the OBJ_CC =
            newfolder/newagent.o \
3. in the shell prompt, go to ~ns-2.34 and give the command
./configure
make
4. run the file agent_new.tcl (given below)
you can see the output

Here is the C++ code to be written and compiled

//Name of the file is newagent.cc and put it in a folder inside ~ns-2.34/newfolder/
#include <stdio.h>
#include <string.h>
#include "agent.h"
class TSPAgent : public Agent {
public:
        TSPAgent();
protected:
        int command(int argc, const char*const* argv);
private:
        int    tsp_var1;
        double tsp_var2;
        void   TSPPrivFunc(void);
};

static class TSPAgentClass : public TclClass {
public:
       TSPAgentClass() : TclClass("Agent/TSPAgentOtcl") {}
        TclObject* create(int, const char*const*) {
                return(new TSPAgent());
        }
} class_tsp_agent;

TSPAgent::TSPAgent() : Agent(PT_UDP) {
       bind("tsp_var1_otcl", &tsp_var1);
       bind("tsp_var2_otcl", &tsp_var2);
}
int TSPAgent::command(int argc, const char*const* argv) {
      if(argc == 2) {
           if(strcmp(argv[1], "call-tsp-priv-func") == 0) {
                  TSPPrivFunc();
                  return(TCL_OK);
           }
      }
     return(Agent::command(argc, argv));
}

void TSPAgent::TSPPrivFunc(void) {
      Tcl& tcl = Tcl::instance();
      tcl.eval("puts \"Message From TSPPrivFunc\"");
      tcl.evalf("puts \"     Area of the Cylinder is = %f\"", tsp_var1*tsp_var2*2*3.14);
}

TCL Code to Test the above C++ Program (Agent)

# Create MyAgent (This will give two warning messages that
set myagent [new Agent/TSPAgentOtcl]

# Set configurable parameters of MyAgent
$myagent set tsp_var1_otcl 2
$myagent set tsp_var2_otcl 6.5

# Give a command to MyAgent
$myagent call-tsp-priv-func

21 comments:

  1. Sir
    can you please tell me how to implement fuzzy logic rules and membership functions in network simulator2

    ReplyDelete
  2. Sir

    I am working in wireless sensor networks. Can you guide me about scenario generation in ns2.

    ReplyDelete
  3. I did not understand how ı will run the file agent_new.tcl

    ReplyDelete
  4. I created new agent Application i made appropriate changes in Makefile.in but still it is giving me error :

    invalid command name "Application/Test"
    while executing
    "Application/Test create _o59 _o10"
    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 ""

    ReplyDelete
  5. I am having same problem as posted above :( Please help

    ReplyDelete
  6. I am having same problem, i.e., "invalid command name". I am using ns2.35 with ubuntu. can anyone help me please

    ReplyDelete
    Replies
    1. show me the exact output or send me the files that you have used for recompilation

      Delete
    2. This comment has been removed by the author.

      Delete
    3. This comment has been removed by the author.

      Delete
  7. Hello Pradeepkumar!!
    Below is the code and output.
    --------------------------------------------
    My exlinkage.cc file is:

    #include
    #include
    #include "agent.h"

    class MyAgent : public Agent {
    public:
    MyAgent();
    protected:
    int command(int argc, const char*const* argv);
    private:
    int my_var1;
    double my_var2;
    void MyPrivFunc(void);
    };


    static class MyAgentClass : public TclClass {
    public:
    MyAgentClass() : TclClass("Agent/MyAgentOtcl") {}
    TclObject* create(int, const char*const*) {
    return(new MyAgent());
    }
    } class_my_agent;

    MyAgent::MyAgent() : Agent(PT_UDP) {
    bind("my_var1_otcl", &my_var1);
    bind("my_var2_otcl", &my_var2);
    }

    int MyAgent::command(int argc, const char*const* argv) {
    if(argc == 2) {
    if(strcmp(argv[1], "call-my-priv-func") == 0) {
    MyPrivFunc();
    return(TCL_OK);
    }
    }
    return(Agent::command(argc, argv));
    }


    void MyAgent::MyPrivFunc(void) {
    Tcl& tcl = Tcl::instance();
    tcl.eval("puts \"Message From MyPrivFunc\"");
    tcl.evalf("puts \" my_var1 = %d\"", my_var1);
    tcl.evalf("puts \" my_var2 = %f\"", my_var2);
    }
    ----------------------------------------------------------

    The corresponding tcl file is, ex-linkage.tcl:

    set myagent [new ./Agent/MyAgentOtcl]

    # Set configurable parameters of MyAgent

    $myagent set my_var1_otcl 2

    $myagent set my_var2_otcl 3.14

    # Give a command to MyAgent

    $myagent call-my-priv-func
    ----------------------------------------------------------
    And the output after running is:

    ~/ns-allinone-2.35/ns-2.35/common$ ns ex-linkage.tcl
    invalid command name "./Agent/MyAgentOtcl"
    while executing
    "./Agent/MyAgentOtcl create _o3 "
    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/MyAgentOtcl"
    invoked from within
    "set myagent [new ./Agent/MyAgentOtcl]"
    (file "ex-linkage.tcl" line 7)
    --------------------------------------------
    I saved the file in ns2.35/common and made the required changes in makefile.in.

    Thanks in advance
    --
    Bilal

    ReplyDelete
    Replies
    1. hi bilal,
      change the folloiwng line to
      set myagent [new ./Agent/MyAgentOtcl]
      this line
      set myagent [new Agent/MyAgentOtcl]

      Delete
    2. Thanks for your quick reply.
      but it still doesn't work.

      almost the same error

      ~/ns-allinone-2.35/ns-2.35/common$ ns ex-linkage.tcl
      invalid command name "Agent/MyAgentOtcl"
      while executing..

      Delete
    3. but it is executing in my machine. have you recompiled the .cc code. check for the .o file which was created from your .cc file.

      Delete
    4. Yes,I checked the .o in makefile.in, it is correct. I also executed configure and make commands. The problems is still there.
      I also used different directories to test my code. I saved .cc and .tcl files in ns-allinone-2.35/ns-2.35 but failed then i tried saving these files in ns-allinone-2.35/ns-2.35/common yet they didn't work.
      Any other reason for failure, like ubuntu version etc..??

      Delete
    5. Since the error is "failed shadow object" it means the object is not known to the tcl file. in the Makefile.in, in which variable you set the .o. you have to set the .o entry in the OBJ_CC varaible.

      Delete
    6. I put it under OBJ_CC. Here it is:


      OBJ_CC = \
      common/ex-linkage.o \

      Delete
  8. Dear sir,
    i have encountered the following error while trying to run a tcl script for wireless networks...


    num_nodes is set 25
    can't read "node_(0)": no such variable
    while executing
    "$node_($j) set X_ $k"
    ("for" body line 2)
    invoked from within
    "for {set j 0} {$j < 5 } {incr j} {
    $node_($j) set X_ $k
    $node_($j) set Y_ 5.0
    $node_($j) set Z_ 0.0
    incr k 10
    } "
    (file "test.tcl" line 60)


    this is the part of the code that is having the problem

    # Configure node position - assume static node
    set k 5
    for {set j 0} {$j < 5} {incr j} {
    $node_($j) set X_ $k
    $node_($j) set Y_ 5.0
    $node_($j) set Z_ 0.0
    incr k 10
    }
    set l 5
    for {set j 5} {$j < 10} {incr j} {
    $node_($j) set X_ $l
    $node_($j) set Y_ 15.0
    $node_($j) set Z_ 0.0
    incr l 10
    }
    set m 5
    for {set j 10} {$j < 15} {incr j} {
    $node_($j) set X_ $m
    $node_($j) set Y_ 25.0
    $node_($j) set Z_ 0.0
    incr m 10
    }
    set n 5
    for {set j 15} {$j < 20} {incr j} {
    $node_($j) set X_ $n
    $node_($j) set Y_ 35.0
    $node_($j) set Z_ 0.0
    incr n 10
    }
    set o 5
    for {set j 20} {$j < $val(nn)} {incr j} {
    $node_($j) set X_ $o
    $node_($j) set Y_ 45.0
    $node_($j) set Z_ 0.0
    incr o 10
    }
    for {set i 0} {$i < $val(nn) } {incr i} {
    $ns initial_node_pos $node_($i) 3

    }

    Sir, kindly help me rectify the problem...
    thanks for your time..
    thanks for your time

    ReplyDelete
    Replies
    1. this part of the code is correct, send me the code where you have created the node. the issue is there only. if you want to send, send it to tspembedded @ gmail dot com.

      Delete
    2. Sir kindly check your mail..i have sent the file..my email is eliza.maxwell17@gmail.com

      Delete
    3. Hey Liz, check your email for corrected code.

      Delete
  9. Hello everyone,

    Is there any means to access the port number of an agent? if I have an agent creation like the following
    MyAgentClass() : TclClass("Agent/MyAgentOtcl") {}
    TclObject* create(int, const char*const*) {
    return(new MyAgent());
    }
    How can I access the port number of this agent instance in c++?

    ReplyDelete