HLAExample

From Nsnam
Jump to: navigation, search

Before Getting Started

The tutorial will talk about using hla model for ns-3 to make ns-3 participate in distributed simulation with other federates through a Run Time infrastructure. The code for the tutorial can be found in .cc and .fed files. We will be referring to the ns-3 hla model Wiki, it has mostly model related explanation, only few sub-sections are required for the tutorial. Information about HLA and RTI. on Wikipedia.

If you want to know more about the source code of the hla model, please read the design and see the diagram here and here. Also reading this would be useful. The code can be found here.

The tutorial will assume that you have a working copy on ns-3 with hla which can be obtained here and familiarity with writing and running ns-3 scripts. Please download and install the required packages listed here as set the mentioned environment variables.

Description

The objective here is to make a simple ns-3 script that publishes and subscribes to an object PingPong with attributes Msg and MsgType. Before we could start with this we need to send an initialisation message. Let us first look as what variable we have at our disposal, let's look at the initialisation variables and common terms:

  • Seconds : Number of Times time advance request is expected.
  • SyncPhase : The string that is used by federates for synchronisation in RTI.
  • Fomfile : Name of the file that has the object model
  • FederationName : Name of the federation (Should be same in all federates)
  • FederateName : Name of the federate (ns3)
  • RtiTimeResolution : What time steps are required by the model (Default is 1.0)
  • Object Name : Name of the Object you are sharing
  • Object Attributes : A property of the shared object
  • Object Handle : Unique federate wide identifier for an object
  • Attribute Handle : Unique federate wide identifier for the attribute
  • Attribute Value : Value the attributes presently (RTI Time) posses

Initilisation

The above variables are used for initialisation. Ns-3 will create a federation <FederationName> or join the same if already created by other federates. It will register in the federation as federate <FederateName> and with a synchronisation phrase <SyncPhrase> and RTI will use the object model in <FomFileName>. The simulation will run for <Seconds>*<RtiTimeResolution> seconds and will advance in <RtiTimeResolutionSteps>. Hla model will take care of these events.

Objects

Now lets look at how the objects are created and published. After defining the object model in .fed file you have to create an object and attributes. You can create any number of objects (the helper uses a dynamic memory allocation) and add any number of attributes (again dynamic). You have to specify the name of the object and the number of attributes it will have. Once you create an object you are object handle is issued. This can used in future for listing all attributes of the object and accessing object name. Similarly, attributes can be added to object by specifying Attribute Name and Object Handle and it will return a similar Attribute Handle. All Objects are to be published and subscribed with the RTI. All events are taken care by the hla model

Synchronisation and Update

Whenever a time advance is required the hla model is designed to send it to the RTI and whenever the Time Advance Grant is approved it is handled by the hla model. For this functionality you have use a RTI simulator implementation. Whenever a value is changed in the RTI the hla model automatically updates the value in ns3, so the value of the shared object's attribute attribute value you are using is the one which is known to all federates and is in the federation. Again handled by the hla model.

More low-level implementation details of the hla model can be found here

ns-3 script

The source code of the script can be found here. Functions from the src/hla/helper will be used here. It is good to have this file open along side in another tab. It has doxygen and thus you can easily figure out the API calls, we will be referring to it.

Using the hla API is quite intuitive and if you understand the concept it is quit straightforward. To begin with, you create an object of hla helper in your script:

HlaHelper hla;

Now set the initial values of the hla parameters as discussed above. Function in line number 74 sets the DefaultParameters similar to the example shipped with the code. You MUST set the values according to your requirements, your federation requirements and external federation requirements.For setting various values, just set them using various setter functions like on line 83,192,202,212,222,232. These are for initialization and there meanings are explained in the above section. For example:

hla.SetFomFile("SimpleSharedObjectExample.fed");
hla.SetSyncPhrase("ReadyToRun");
hla.FederationName("ExampleFederation");
hla.FederateName("ns3");
hla.SetRtiTimeResolution("1.0");
hla.SetSeconds("10");

or 

hla.DefaultParameters();

Once you are done setting you default values, you need to create an object that you can share, it can be easily done using function on line 95 :

int ObjectHandle;
ObjectHandle = hla.CreateSharedObject("PingPong","2");

The above command creates a shared object "PingPong" and the object has two characteristics. It also returns an Object Handle (ObjectHandle) of int type used to identify the object. Next we need to set these characteristics or attributes, we can use function on line number 107 to so this:

int AttributeHandle1, AttributeHandle2; 
AttributeHandle1 = hla.AddAttributeOfSharedObject("Msg",ObjectHandle);
AttributeHandle2 = hla.AddAttributeOfSharedObject("MsgType",ObjectHandle);

This will add two values "Msg" and "MsgType" to the Object "PingPong". Now we are done with the object and it's attribute. Let's publish it and create an ns3 Federate.

hla.Start();

This will do the required, but before this we must change simulator implementation to RTI Simulator. This can be done using:

GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RtiSimulatorImpl"));

So, now we are done with creating a federation, once the simulation start you can access values of the published object and other details related to the federation using the API functions at line 173,161,149,137,125 and 116. The values and time advance requests are handles by callbacks and simulator, so user does not have to specify anything for it. ns-3 will synchronise with the RTI and all values will be updated if anything changes in other federates.

Object Model file

The SimpleSharedObjectExample.fed was used for this tutorial. Please make sure you list all objects that you are using and their attributes in the .fed file in similar order. It is used by the RTI. Please note that you have to include these three lines at the beginning. This is because the Portico FED parser want it to be like this.

(FED
(Federation Portico-Test)
(FEDversion v1.3)
...
...
)

List all your objects under the ObjectRoot class, this is done basically to encapsulate all shared Object (classes) created by ns-3 into ObjectRoot class and add attributes as follows. The basic structure of the file should be like this:

(objects 
  (class ObjectRoot 
    (class ...
      (attribute ...)
      (attribute ...)
    (class ...
      (attribute ...)
      (attribute ...)
    .....
    .....
     )
  )
)

Please refer to portico documentation for more details on the .fed files.

Running

Once you have created your .cc and .fed file you can easily run the simulation according to instructions here. So, as it is clear from the section, we will look deeper into the three commands:

$ ./hla.sh --clean
$ Cleaning log files and jar 

It will clear all your files that are generated using your java code. This will include .class files and .jar files. It will also clear all log files. These log files are created by the Run Time Interface, in this case portico. The files can be found in $build/src/hla/model/ns3Federate. It will log the following message

Next is,

$ ./hla.sh --build
$ Building HLA interfaces

It will compile hla module code written in java and will save it in $build/src/hla/model/ns3Federate. Make sure you build ns-3 first by using ./waf, before building hla. To run a specific simulation you can use.

$ ./hla.sh --run scratch/SimpleSharedObjectExample

Make sure you copied your .fed to $ns/scratch and also you are using the .fed file name in the --run command. Also please follow the sequence in which you start the two shells as given in the Wiki Instructions

Testing

The first way to test the code is run two shells one with simple-shared-object-example.cc (in shell 1, say CppShell) and SimpleSharedObjectExample.fed( in shell 2, say JavaShell) as mentioned above. The following will be observed:

in Cpp Shell, if sockets are initialised properly you will get:

***** Ready To Connect To RTI and launch/join Federation

Connecting ...

now start the JavaShell and now run the code using ./hla.sh (as mentioned in the above section)in the other shell, If your fed file is in the right place and the sockets are initialised properly you will get:

Connected ...
Receiving Initialization Message ..
Setting Initial Values ...

ns3  :  >>>>>>>>>> Press Enter to Connect To RTI <<<<<<<<<<

It also confirms that your values were received through the socket and received by the Java Program (Initial Values). This is a good time(***) to launch other federates

and the CppShell will show:

Connected

Sending intialization message

Waiting for Start Signal..

when you press enter### once in JavaShell it will:

ns3  : Connecting ...
ns3  : Connected
ns3  : Created Federation
ns3  : Joined Federation as ns3
ns3  :  >>>>>>>>>> Press Enter to Continue <<<<<<<<<<

connect to the RTI and when you press enter again it will send a start signal to CppShell. It checks if ns3 Federate is able to create and join a federation or not. It will start the simulation and if the RTI time>ns3Time it will process all events

Start Signal Received

Present Time (in ns):
0
Event Time Missed, Ns3 Time More Than RTI Time
Processing Event ...

and the output of the event is displayed. If RTI Time<ns3Time it will ask the event to wait and send a time advance request.

Present Time (in ns):
1000000000
Event in Future, Ns3 Time Less Than RTI Time
Wait For a Time Advance Signal from RTI ...

Sending Time Advance Request to RTI ...

Time Advance Request Sent

Time Advance Granted

Once the request is grated it will execute the event and the event specific log will be displayed. If there is a change in the object values, a callback will log the following:

Value of Shared Object (any attribute) changed ...
Updating ...
Updated

At time (***) is the best time to start an external federate. There is an external federate along with the code in test/SystemIntegration, although there is an issue which might pop up at present (related to RTI) but if no it can be started at time (***) in another shell, lets call it external

external$ cd $ns3/src/hla/test/SystemIntegration/dummy
external$ ./linux.sh execute 

It should start the federate. After a bit of logging it will ask you to press

dummy  :  >>>>>>>>>> Press Enter to Connect To RTI <<<<<<<<<<

when you press enter it will wait for other federates (like ns3) and when we press enter in step (###), we will force ns3 to join the federation

Registered Sync Point, waiting for federation ... 

and in the $JavaShell

ns3  : Connecting ...
ns3  : Connected
ns3  : Cannot create federation, federation already exists 
ns3  : Joining Federation as ns3

Now the ns3 and dummy federates will be synchronised. Dummy will change the value of PinPong every second and will be reflected on $CppShell and $JavaShell