
Figure 1: WSN Localization Simulator
Introduction
Modeling the localization problem is virtually impossible to solve mathematically because many environmental changes can be simulated such as a channel noise and sensor modes (i.e. wakeup and sleep), and the effect of these alterations on the model's behavior can be observed. By changing simulation inputs and observing the resulting outputs, valuable insight may be obtained into which variables are most important and how variables interact.
A simulation is the operation of a system model which can be reconfigured and experimented. This operation is impossible, too expensive or impractical to do in the system it represents. The operation of the model can be studied, and hence, properties concerning the behavior of the actual system or its subsystem can be inferred. In its broadest sense, simulation is a tool to evaluate the performance of a system, existing or proposed, under different configurations of interest and over long periods of real time.
The advantages of simulation are: simulation enables the study of the internal interactions of a complex system, or of a subsystem within a complex system. Simulation can be used to experiment with new designs or policies prior to implementation, so as to prepare for what may happen. Simulation can be used to verify analytic solutions. Simulation animation shows a system in simulated operation so that the plan can be visualized. Time can be compressed or expanded allowing for a speedup or slowdown of the phenomena under investigation. Insight can be obtained about the importance of variables to the performance of the system. A simulation study can help in understanding how the system operates rather than how individuals think the system operates.
The major properties of system simulation are: simulation is used before an existing system is altered or a new system built, to reduce the chances of failure to meet specifications, to eliminate unforeseen bottlenecks, to prevent under or over-utilization of resources, and to optimize system performance. For instance, simulation can be used to answer questions like: What is the best design for a new WSN? What are the associated resource requirements? How will a WSN perform when the traffic load increases by 50%? How will a new routing algorithm affect its performance? Which network protocol optimizes network performance? What will be the impact of a link failure?
Background
WSN localization is the operation of determining the position of sensor nodes; this position is estimated and not accurate. Because GPS have high cost and works outdoors only, there are many localization algorithm that tries to be more accurate in determining the position of sensor nodes (i.e. have low localization error). In order to effectively design and develop new localization algorithms targeted towards WSNs, there is a strong need to use an equally effective and reliable simulation environment. Sensor nodes are, by design, tiny and inexpensive, but due to their need to work in large numbers make full-scale testing a fairly expensive process to be carried out using real hardware. Analytical modeling using tools such as MATLAB help in acquiring a quick insight, but they fail to provide anything close to realistic results that can be acquired through proper implementations and good simulation tools.
The problem and its solution
Wireless sensor networks face many problems that do not arise in other types of networks: Power constraints, limited hardware, decreased reliability, and a typically higher density and number of nodes than those found in conventional networks are few of the problems that have to be considered when developing a simulation tool for use in wireless sensor networks. Hence, most of network simulators fail to support all the following criteria: easy, where the vast amount of variables involved in the definition of a WSN experiment requires the use of specific input scripting languages, with high-level semantics, extendable where simulation is used to test novel techniques in realistic and controlled scenarios (researchers are usually interested in comparing the performance of a new technique against existing proposals) and scalable where increasing number of nodes without degrading the performance of network, so a simulation tool for WSNs localization is required specifically for the analysis of different types of localization schemes.
Design criteria for the proposed simulator
This section describes the development of the proposed simulation tool. The proposed simulation tool has the following advantages:
- Supports completely large scale networks (scalable simulator).
- All simulator classes are packed into a referenced DLL file for better modularity design. For example, various localization algorithms can be implemented by encapsulating each one into a separate DLL file.
- Developers can write their own localization algorithm into a DLL file and reference it to the proposed simulation tool (extendable simulator).
The proposed simulation tool is a discrete event simulator which is written in the C# programming language. This discrete event simulation tool operates on the basis of chronological consecutive events to change a system’s state. These events are processed by the simulation kernel. User-defined localization algorithms are implemented as C# classes and mostly utilize simulation tool concepts. Node composition and network layout along with environmental and setup parameters are set via user interface. The modules are compiled and linked with the simulation kernel, and result in the simulation application.
The simulation tool architecture design is flexible, and modular, allowing for customizations to be made using an object oriented component files. Such an approach allows for users to adapt the simulation tool, or extend it to different localization algorithms
Simulator architecture
The proposed simulation tool is composed of two main software layers, a core simulator layer and a localization layer as shown in Fig. 2. A core simulator layer includes several classes; the network class contains all those classes (e.g. sensor class, anchor class, packet class ...etc.) and the developer interface class which contains all control methods (e.g. run/stop, pause/resume simulator, painting method,… etc.). The second layer of the proposed simulation tool is the localization layer which is written by the developer into a DLL file which will be referenced to the proposed simulation tool, so that the developer has the ability to write his localization algorithm.
A wireless sensor node is typically composed of multiple modules (e.g., CPU, timer, radio, network layers). Internally, every module is based on one or more tasks. The proposed simulation tool defines the classes corresponding to each module, for example application, routing, MAC and physical layer. Every module is implemented as a C# class derived from a core simulator layer class. Also, Tasks are implemented as methods within a module class.
Figure 2: Simulator Architecture
How does this Simulator help developers?
This simulator has the ability to be extended by future researchers. Developers (researchers) can design their localization scheme into DLL class file and reference it to the proposed simulator. This simulator is compatible to different kinds of localization schemes.
Features of this Simulator
- Supports a lot of mobility models such as: Random Waypoint – Modified Random Waypoint - Random Direction – Modified Boundless – Manhattan – Freeway and RPGM.
- Supports two ray ground and shadowing propagation models.
- All events done during simulation time are written into an external trace file as shown in Fig. 3.
- Supports Monte Carlo Localization (MCL) scheme, Improved Monte Carlo Localization (IMCL) scheme and Kalman Filter Localization (KFL) scheme beside mobility prediction localization (MPL) scheme and its secure version using Elliptic Curve Cryptography (ECC).
- Supports Wormhole, Sybil, Spoofing and Replay attacks and their defense algorithms.
- Supports two types of sensor models: MICA2 and TelosB
Allows users to generate different scenarios (file written to scenario folder) and read these scenarios again from the generated files. This helps one researcher to run the same scenarios generated by other researcher.

Figure 3: Sample Trace File
The Development of the Proposed Simulation Tool
As shown in Fig. 4, the architecture of the proposed simulation tool can be divided into two layers: the first layer contains the classes related to the core simulator. The second layer contains the classes and functions related to the localization layer.
Figure 4: Simulator Class Diagram
The first layer (Core Simulator) is divided into two derived classes. The first one is Network class which contains several classes and methods related to the wireless sensor network (e.g. sensor nodes, anchor nodes, packets…etc). The second class is Developer Interface class which contains the functions and parameters that control the behavior of the simulation tool such as (run, stop, pause, resume, deploy, painting, changing number of sensors and number of anchors…etc). In what follows, all classes in the simulation tool that implement the basic components mentioned previously are described.
Network Class
The Network
class represents all simulator kernel classes such as: Energy_Model
class represents level of energy in a mobile node and track the energy consumption of each node. The energy model in a node has an initial value which is the level of energy the node has at the beginning of the simulation; it inherits mobile node class. The Battery
class represents sensor nodes power supply; it can be used to implement all different kinds of existing battery models. The class contains methods to turn sensor node on and off, put it into sleep and wake it up. Also contains methods to decrease energy when a sensing, processing or disseminating job is performed by the sensor node; it inherits energy model class.
The Propagation_Model
class used to predict the received signal power of each packet. At the physical layer of each wireless sensor node, there is a receiving threshold. When a packet is received, if its signal power is below the receiving threshold, it is marked as error and dropped by the MAC layer. Delay
class computes the time required for a packet to traverse a link. Also it gets the time required for sending/receiving packets. The Adversary
class that controls the behavior of the adversary nodes and its threats to a WSN; this class inherits the mobile node class. The Anchor
class contains all the arguments need for deploying, constructing, changing radio range….etc of the anchor nodes; this class inherits the mobile node class. The BaseStation
class plays the role of a gateway for the wired and wireless domains. It is responsible for delivering packets into and out of the wireless domain. It controls the behavior of a base station e.g. changing its radio range and its position; this class inherits the node class. The Packet
class contains different fields of the packets transmitted between different nodes in a WSN. It defines the structure of a packet and provides member functions to handle a free list for objects of this type. The Encrypted_Packet
class is responsible for maintaining the cipher text and its corresponding encryption algorithm; it inherits packet class. The Routing
class performs a routing algorithm which exchanges routing packet with neighbors.
The TemperatureDataGenerator
class which simulates temperature generation task which is based on Gaussian distribution so average and standard deviations are fields of this class. The Sensed_Data
class is responsible for sensor node application such as (sensing temperature, tracking movable objects,…etc). It represents sensed data after processing. Data contained in the Sensed_Data
class is ready for dissemination so the class provides networking information such as source node identification, message type, message priority among others (e.g. sending alarm message to base station when temperature exceeds a predefined maximum temperature). The WirelessSensor
class contains all the arguments needed for constructing, deploying, changing radio range…etc of sensor nodes; it inherits the mobile node class by adding specific sensor nodes characteristics as power consumption for sensing and processing activities, instructions executed per seconds by its microcontroller, states of sensor parts (processor, sensing devices). The WirelessChannel
class simulates the shared medium and supports the medium access mechanisms of the MAC objects on the sending side of the transmission. It allows the MAC to carry out TDMA which distribute different slot for each node so as to avoid collisions.
The Event
class provides basic functionality for all events. It contains the time at which an event should work, and provides methods for constructing different types of events. The Scheduler
class is responsible of selecting the next earliest event, executing it to completion, and returning to execute the next event. Unit of time used by scheduler is seconds. The Error_Model
class introduces packet losses into a simulation. It simulates packet, byte or bit corruption by marking the packet’s error flags. The RNG
class contains an implementation of combined multiple recursive random number generators such as normal, log normal, exponential and uniform distributions. In the following the attributes and methods of each class will be described.
Using the code
1. Energy_Model Class
Attributes
energy
: private double energy
This variable represents the amount of current energy.
initialenergy
: private double initialenergy
This is a private variable indicating the initial energy (full energy) of this node.
last_time_gosleep
: private float last_time_gosleep
This variable represents the time when radio is turned off.
max_inroute_time
: private float max_inroute_time
This variable represents the maximum time that a node can remaining active.
node_on
: private bool node_on
This is Boolean variable represents on-off status of this node.
sleep_mode
: private int
sleep_mode
This variable indicates that radio is turned off when its value =1.
total_rcvtime
: private float total_rcvtime
This variable represents the total time in receiving data.
total_sleeptime
: private float total_sleeptime
This variable represents the total time of radio in off mode.
total_sndtime
: private float total_sndtime
This variable indicates the total time in sending data.
Methods
Decrease_Mobility_Energy
: public void Decrease_Mobility_Energy(double distance, double P_mob,double slot_time)
This method is responsible for decreasing sensors (or anchors) residual energy due to mobility.
Decrease_Rcv_Energy: public void Decrease_Rcv_Energy(double rcvtime, double P_rcv)
This method is responsible for decreasing receive energy of mobile node.
Decrease_Sleep_Energy: public void Decrease_sleep_Energy(double idletime, double P_idle)
This method is responsible for decreasing receive energy of mobile node.
Decrease_Tx_Energy: public void Decrease_Tx_Energy(double txtime, double P_tx)
This method decreases transmit energy.
getenergy: public double getenergy()
This method returns the current energy.
max_inroute_time: public float max_inroute_time()
This method returns the maximum time that a node can remaining active.
Max_Rcv_time: public double Max_Rcv_time(double P_rcv) {return(energy_/P_rcv)
This method returns the maximum receive time.
Max_Tx_time: public double Max_Tx_time(double P_tx)
This method returns the maximum transmit time.
MaxIdletime: public double MaxIdletime(double P_idle)
This method returns the maximum sleep time.
node_on: public bool node_on()
This method returns the status of this node.
setenergy: public void setenergy(double e)
This method sets the current energy of this node.
total_rcvtime: public float total_rcvtime()
This method returns the total receiving time.
total_sleeptime: public float total_sleeptime()
This method returns the total sleep time.
total_sndtime: public float total_sndtime()
This method returns the total sending time.
2. Battery Class
According to battery model, it is responsible for modeling the different aspects of sensor energy. The battery class consists of attributes and methods applied to this class.
Attributes
energy: public double energy
This field is responsible for storing the amount of energy resides in the sensor node. At the deployment, all sensor nodes initially charged with full energy which also represented by this attribute. As time goes the energy will be decreased.
node_on: public bool node_on
This Boolean variable represents the status of sensor node.
sensing_power: public double sensing_power
This variable represents the amount of sensing power.
sensing_time: public double sensing_time
This variable indicates the amount of sensing time.
Methods
DecrProcessingEnergy: public void DecrProcessingEnergy(int number_instructions, double instructions_per_second, double processing_power)
This method computes the energy spent by a processing task and reduce energy stock by this amount.
DecrSensingEnergy: public void DecrSensingEnergy(double sensing_time, double sensing_power)
This method computes the energy spent by a sensing task and reduces energy stock by this amount.
SetNodeOff: public void setNodeOff()
This method turns sensor node off.
SetNodeOn: public void setNodeOn()
This method turns sensor node on.
Sleep: public void sleep()
This method puts node battery in sleep mode.
WakeUp: public void wakeUp()
This method wakes up the sleepy node battery.
3. Propagation_Model class
Attributes
Gr: public double Gr
This variable represents omni-directional antenna gain for receiving.
Gt: public double Gt
This variable represents omni-directional antenna gain for sending.
hr: public double hr
This variable represents antenna height for transmitter.
ht: public double hr
This variable represents antenna height for receiver.
L: public double L
This variable represents system loss.
Lambda: public double lambda
This variable represents wave length.
Methods
Cross_Distance: public double Crossover_Distance(double Frequency)
This method is responsible for calculation crossover distance.
Friis: public double Friis(double Pt, double Frequency, double d)
This method simulates free space model.
inv_erfc: public double inv_erfc(double y)
This method gets the inverse of complementary error function.
inv_Q: public double inv_Q(double y)
This method gets the inverse of Q function.
RXThresh_Shadowing: public double RXThresh_Shadowing(double prob, double pathlossExp, double std_db, double Pt, double Frequency, double dist)
This method calculates the received signal threshold for shadowing model.
Shadowing: public double Shadowing(double Pt, double Frequency, double dist, double pathlossExp, double std_db)
This method returns the received signal power for shadowing model at distance dist.
Two_Ray_Ground: public double Two_Ray_Ground(double Pt, double Frequency, double d)
This method simulates two_ray ground model. It is used when distance (d) between transmitter and receiver > cross over distance (dc).
4. Delay Class
Attributes
Link_Length: public double Link_length
This variable represents the distance between transmitter and receiver.
pkt_size: public double pkt_size
This variable represents the packet size.
sensor_data_rate: public double sensor_data_rate
This variable represents data rate of sensor node.
Methods
propagation_delay: public double propagation_delay(double distance)
This method calculates link propagation delay.
rcvtime: public double rcvtime(double pkt_size, double rate)
This method calculates delay time required for receiving a packet.
RTT: public double RTT(double distance)
This method calculates the round trip time.
total_txtime: public double total_txtime(double pkt_size, double rate, double distance)
This method calculates total transmission time.
txtime: public double txtime(double pkt_size, double rate)
This method calculates the transmission time for a packet.
5. Routing Class
Attributes
connectionCurrent: public bool connectionCurrent
This is a public Boolean variable indicating whether there a connection or not.
iReceiveCost: public float iReceiveCost
This variable is responsible for storing the value of energy consumed by receiving packet(s).
iResidualEnergy: public int iResidualEnergy
This integer is responsible for storing the amount of residual energy of sensor nodes.
iTransmitCost: public float iTransmitCost
This variable is responsible for storing the value of energy consumed by sending packet(s).
Methods
Routing: public Routing(float iReceiveCost, float iTransmitCost, int iResidualCost, bool connectionCurrent)
This is a constructor for the Routing class.
SetRoutingInformation: public void SetRoutingInformation()
This method contains the representation of routing protocol.
send: public void send(Packet p)
This method is responsible for sending packets.
receive: public Packet receive()
This method is responsible for receiving packets.
6. TemperatureDataGenerator Class
Attributes
avg_temp: public double avg_temp
This variable represents the average temperature sensed.
initialenergy: public double initialenergy
This variable represents sensor node energy.
sensing_power: public double sensing_power
This variable represents the amount of energy required for sensing task.
sensing_time: public double sensing_time
This variable represents the amount of time required for sensing task.
temp: public double temp
This variable represents the amount of temperature generated.
Methods
generate_temp: public void generate_temp(ArrayList asensor,double now)
This method is used to generate random temperature using Gaussian distribution.
sense_temperture: public void sense_temperature(ArrayList asensors)
This method is used to simulate the sensing operation of sensor nodes.
TemperatureDataGenerator: public TemperatureDataGenerator(ArrayList asensor, double avg_temp, double max_temp, double std_dev)
This is the constructor of TemperatureDataGenerator
class.
7. WirelessChannel Class
Attributes
M_node_list: public ArrayList M_node_list
This variable represents a list of communicating nodes.
Num_nodes: public int Num_nodes
This variable indicates number of mobile nodes added to the channel.
pdelay: public double pdelay
This variable represents the propagation delay which determines exactly when the receiver's interface detects the first bit received packet.
Receiver: public Mobile_Node Receiver
This mobile node is considered the destination node.
Sender: public Mobile_Node Sender
This mobile node is considered the source node.
Methods
addNodetoList: public void addNodeToList(Mobile_Node mn)
This method creates a list of mobile nodes for this channel.
get_pdelay: public double get_pdelay(Mobile_Node tnode, Mobile_Node rnode)
This method returns the propagation delay between two nodes.
recv: public void recv(Packet pkt)
This method receives packets from the channel checks if the packet has been received correctly.
sendUp: public void sendUp(Packet pkt)
This method check if the packet has been sent correctly and to decrement the energy consumed in the packet reception.
WirelessChannel: public WirelessChannel(Mobile_Node sSender, Mobile_Node sReceiver)
This is the class constructor.
8. Adversary Class
Attributes
AdvRadius: public int AdvRadius
This field is responsible for changing adversary radio range.
AdvRepConnection: public System.Collections.ArrayList AdevRepConnection
This array list is responsible for storing all valid connection made by adversary using reply attack.
AdvSpoofConnection: public System.Collections.ArrayList AdevSpoofConnection
This array list is responsible for storing all valid connection made by adversary under spoofing attack.
AdvSybilConnection: public System.Collections.ArrayList AdevSybilConnection
This array list is responsible for storing all valid connection made by adversary under Sybil attack.
AdvWormConnection: public System.Collections.ArrayList AdevWormConnection
This array list is responsible for storing all valid connection made by adversary under Wormhole attack.
id: public int id
This variable is responsible for storing the identity of the adversary node deployed.
Methods
Adversary: public Adversary(int id, int AdvRadius)
This is the constructor of the adversary nodes which initialize it to its identity id and its communication range AdvRadius.
9. Anchor Class
Attributes
Anchor_Connections: public ArrayList Anchor_Connections
This array list stores all valid connections done through anchor nodes.
AnchorRadius: public int AnchorRadius
This variable is responsible for storing the value of anchor radio range.
direction: public double direction
This variable is responsible for storing the moving direction of anchor node.
distance: public int distance
This variable is responsible for storing the distance moved by anchor node.
id: public int id
This variable is responsible for storing the identity of the anchor nodes deployed.
sangle: public int sangle
This variable is responsible for storing the direction of the anchor’s beam when directed antenna is employed.
Methods
Anchor
(+3 overloads): public Anchor(int id, int x, int y, int AnchorRadius, int sangle)
public Anchor(int x, int y, int dx, int dy)
public Anchor(int x, int y, double dx, double dy, double direction)
public Anchor(int x, int y, double dx, double dy, double direction, int distance, double speed)
The previous overloaded constructors are used to construct the anchor node according to its required parameters as shown above.
10. Base_Station Class
Attributes
BSSRadius: public int BSSRadius
This public variable is responsible for assigning the value of base station communication range.
id: public int id
This public variable assigns the identity for each base station.
x: public int x
This public variable is responsible for assigning the value of x-coordinated for base station.
y: public int y
This public variable is responsible for assigning the value of y-coordinated for base station.
Methods
Base_Station: public Base_Station(int id, int x, int y, int BSSRadius)
This is a constructor for the base station that responsible for constructing it in the deployment field.
11.Packet Class
Attributes
bits: public int bits
This field contains the address of the first byte of where packet header fields are stored.
data: private ArrayList data
This field represents a variable size buffer for data.
datalen: private int datalen
This field indicates the length of variable size buffer holding data.
hdrlen: public static int hdrlen
This field indicates the size of a packet's header.
next: public Packet next
This field points to next packet in free list.
PktList: private ArrayList PktList
This field represents a free list for packets.
sangle: public int sangle
This field represents the rotation angle of directed antenna.
Methods
accessdata: public ArrayList accessdata()
This method returns data field of the packet.
alloc: public Packet alloc(int n)
This field allocates a packet with an n byte data buffer.
allocdata: public void allocdata(int n)
This field allocates an n byte data buffer to an existing packet.
free: public Packet free(Packet p)
This field frees a packet by returning it to the free list.
get_bits: public int get_bits()
This field returns the header offset in packet.
12.Encrypted_Packet Class
Attributes
anchor_public_key: public ECDiffieHellmanPublicKey anchor_public_key
This variable is used to store the public key of anchor node.
Encrypted: public byte[] Encrypted
This is the cipher text represented as a byte array.
sensor_private_key: public ECDiffieHellmanCng sensor_private_key
This variable is responsible for storing the private key of sensor node.
Methods
Encrypted_Packet: public Encrypted_Packet(byte[] enc, ECDiffieHellmanPublicKey anchor_public_key, ECDiffieHellmanCng sensor_private_key)
This is the constructor of Encrypted_Packet class which constructs the encrypted packet composed of three fields: cipher text, anchor’s public key and sensor’s private key respectively.
13.WirelessSensor Class
Attributes
AppList: public ArrayList AppList
This field represents the list of WSN applications which the sensor node is associated to.
Connection: public ArrayList Connections
This attribute contains valid connections.
direction: public double direction
This variable represents the moving direction of sensor node.
distance: public int distance
This variable represents the moved distance of sensor node.
ID: public int ID
This variable represents unique identity of sensor node.
instructionsPerSecond: public int instructionsPerSecond
This attribute indicates the number of instructions the nodes processor can execute in a second.
processingPower: public double processingPower
This variable represents the energy consumption of the sensor node in processing activities. This attribute has its value expressed in watts (joules/second).
ProessorUseState: public int processorUseState
This attribute represents the processor state. Indicates whether the node’s processing activity is in use or not.
sensingPower: public double sensingPower
This variable indicates the energy consumption of the sensor node in sensing activities. This attribute has its value expressed in watts (joules/second).
sensorUseState: public int sensorUseState
This variable represents the sensor state. Indicates whether the node’s sensing activity is in use or not.
transceptorUseState: public int transceptorUseState
This attribute represents the transceiver state. Indicates whether the node’s dissemination activity is in use or not.
Methods
instructionsPerSecond: public double instructionsPerSecond()
This method gets sensor node instructions per second executed by its processor.
processingPower: public double processingPower()
This method gets sensor node processing energy consumption.
sensingPower: public double sensingPower()
This method gets sensor node sensing energy consumption.
sleep: public void sleep()
This method turns the sensor node off when necessary. Stop all of its applications.
wakeUp: public void wakeUp()
This method wakes the sensor node up after a sleepy period. Start all of its applications.
WirelessSensor: public WirelessSensor
(+3 overloads) This method represents the class constructor containing three overloaded constructors.
14.Sensed_Data Class
Attributes
AppDataListinfo: public ArrayList AppDataList
This attribute represents sensed data buffer. Storages all data processed by the sensor node.
eventType: public int eventType
This variable indicates type of the event that caused sensed data processing.
msgType: public int msgType
This integer represents type of the message to be disseminated to the network.
node_id: public int node_id
This variable represents source node identification for sensed data dissemination purposes.
Priority: public int priority
This variable represents the priority of sensed data message.
timestamp: public double timestamp
This variable represents sensed data timestamp.
Methods
copy: public Sensed_Data copy()
This method creates a copy of the sensed data object.
existisData: public bool existsData()
This method informs if there is processed data stored in data buffer.
get_data: public ArrayList get_data()
This method returns processed data stored in data buffer.
get_eventType():public int get_eventType()
This method returns an event type.
get_msgType: public int get_msgType()
This method returns a reference to sensed data message type.
get_node_id: public int get_node_id()
This method returns a reference to source node identification.
get_priority: public int get_priority()
This method returns sensed data priority. This is useful during disseminating tasks.
get_timestatmp: public double get_timeStamp()
This method returns a reference to sensed data timestamp.
insert_new_data: public void insert_new_data(ArrayList data)
This method inserts new processed data into data buffer.
Sensed_Data: public Sensed_Data(Sensed_Data data)
This is copy constructor, creates a new Sensed Data object equals to data parameter.
set_priority: public void set_priority(int p)
This method adjusts sensed data priority.
15.Event Class
Attributes
next: public ArrayList next
This attribute represents the list of next events.
prev: public ArrayList prev
This attribute represents the list of previous events.
scheduler_id: public int scheduler_id
This variable represents unique identity for the scheduler.
time: public double time
This variable indicates the time at which event is ready.
Methods
16. Scheduler Class
Attributes
clock: public double clock
This variable represents simulator time.
queue: private Event queue
This variable represents an event to be dequeued
Sched_Start: public double Sched_Start
This attribute indicates start time (secs).
Methods
dequeue: public Event dequeue()
This method de-queues next event.
dispatch: public void dispatch
(+1 overload) This method is responsible for executing an event.
head: public Event head()
This method sets next head event.
insert: public void insert(Event e)
This method inserts an event into scheduler list.
lookup: public Event lookup(int sched_id)
This method looks up for an event into scheduler list.
run: public double run()
This method represents the starting time of an event.
schedule: public void schedule(Event e, double delay)
This method schedules later event.
Scheduler: public Scheduler()
This method represents Scheduler class constructor.
17.Error_Model Class
Attributes
drop: public bool drop
This Boolean variable represents drop status of the packet.
errLength: public double errLength
This variable represents time to the next error, from the last time an error occurred on the channel. It is dependent on the random variable being used internally.
Methods
corrupt: public int corrupt(Packet p)
This method returns the status of packet corruption.
CorruptBit: public int CorruptBit(Packet p)
This method pre-computes the probabilities for each bit-error.
CorruptByte: public int CorruptByte(Packet p)
This method computes packet error rate, assume uniformly distributed byte error.
CorruptPkt: public int CorruptPkt(Packet p)
This method is responsible for packet corruption.
CorruptTime: public int CorruptTime(Packet p)
This method decides whether or not to corrupt this packet, for a continuous time-based error model.
recv: public void recv(Packet p)
This method Determine the error by calling corrupt(p), Set the packet's error flag if it is corrupted.
18.RNG Class
Attributes
rand: public double rand
This attribute represents the random number generated.
seed_val: public long seed_val
This variable represents seed value of random number generator.
Methods
exponential: public double exponential()
This method returns a number sampled from an exponential distribution with mean 1.0. The other overloaded method is:
exponential: public double exponential(double k)
This method returns a number sampled from an exponential distribution with mean k.
lognormal: public double lognormal(double avg, double std)
This method returns a number sampled from a lognormal distribution with the given average and standard deviation.
next: public long next()
This method returns the next random number as an integer.
next_double: public double next_double()
This method returns the next random number on [0, 1].
normal: public double normal(double avg, double std)
This method returns a number sampled from a normal distribution with the given average and standard deviation.
seed: public long seed()
This method returns the current seed.
set_seed: public void set_seed (long seed)
This method sets the seed of the RNG, if seed = 0, the seed is set according to the current time and a counter.
uniform: public double uniform(double a, double b)
This method returns a number sampled from a uniform distribution on [a, b].
Here is sample code of Monte Carlo localization (MCL) scheme:
using System;
using System.IO;
using System.Text;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using networkdll;
using Mapack;
namespace MCL
{
public class MCL
{
public int counter, slot_duration, delimiter = 0;
public DateTime timeStart;
public String path, path1;
public float locatorRadius = 0, sensorRadius = 0;
public MCL(ArrayList asensor, ArrayList alocator, int counter, int slot_duration,
String path, String path1, float locatorRadius, float sensorRadius,
int delimiter, int SensorModel, double initialenergy)
{
set_parameters(locatorRadius, sensorRadius, counter, slot_duration);
localize(asensor, alocator, locatorRadius, path,
path1, delimiter, SensorModel, initialenergy);
}
public void set_parameters(float locatorRadius,
float sensorRadius, int counter, int slot_duration)
{
this.locatorRadius = locatorRadius;
this.sensorRadius = sensorRadius;
this.slot_duration = slot_duration;
this.counter = counter;
}
public void localize(ArrayList asensor, ArrayList alocator,
float locatorRadius, String path, String path1,
int delimiter, int SensorModel, double initialenergy)
{
networkdll.Class1.Trace trace = new Class1.Trace();
networkdll.Class1.Battery battery = new Class1.Battery();
String time = "";
long start, end, executiontime;
start = System.DateTime.Now.Ticks;
int s = 0, count = 0;
int ersum, avger = 0;
int comm_cost = 0;
float coverage = 0;
int no_samples = 0, avg_samples = 0;
String ext = "", del = "";
String result = "";
String result1 = "";
if (delimiter == 0)
{
del = ","; ext = "xls";
result = "Node" + del + "EstX" + del + "EstY" + del +
"ActualX" + del + "ActualY" + del + "Error" + del +
"1hAnchor" + del + "2hAnchor" + del + "Neighbors" +
del + "No.samples" + del + "Constraint\n";
}
else if (delimiter == 1)
{
del = "\t"; ext = "doc";
result = "Node" + del + "EstX" + del + "EstY" + del +
"ActualX" + del + "ActualY" + del + "Error" + del +
"1hAnchor" + del + "2hAnchor" + del + "Neighbors" +
del + "No.samples" + del + "Constraint\n";
result += "========================================================================\n";
}
float ax = 0, ay = 0;
double processing_time;
double ProcessingPower = 0.029;
if (SensorModel == 0)
ProcessingPower = 0.029;
else if (SensorModel == 1)
ProcessingPower = 0.038;
if (counter % slot_duration == 0)
{
ersum = 0; avger = 0;
foreach (networkdll.Class1.WirelessSensor sensor in asensor)
{
if (sensor.ResidualEnergy > 0)
{
if (counter == 0)
{
String location = "", write_location = "",
samples = "",sample = "",sample1 = "", pos = "";
location = path + "\\sensor" + s + "." + ext;
write_location = path + "\\slot_" + ((counter) / slot_duration) +
"_sensor" + s + "." + ext;
int xg = 0, yg = 0, score, score1, ns = 0, ns1 = 0;
float sx = 0, sy = 0, sxs = 0, sys = 0, sx1 = 0, sy1 = 0;
ax = 0; ay = 0;
for (int i = 0; i < 50; i++)
{
Random rs = new Random(i + 1000 * sensor.ID);
xg = rs.Next(0, 550);
yg = rs.Next(0, 550);
sxs += xg;
sys += yg;
samples += xg + del + yg + "\n";
}
if (sensor.apkts.Count == 0)
{
float erx, ery;
ax = (sxs / 50);
ay = (sys / 50);
pos = ax + del + ay;
erx = Math.Abs(ax - sensor.x);
ery = Math.Abs(ay - sensor.y);
no_samples += 50;
result += s + del + ax + del + ay + del + sensor.x + del + sensor.y + del +
(int)Math.Sqrt(erx * erx + ery * ery) + del + sensor.apkts.Count + del +
sensor.two_hop_apkts.Count + del + "--" +
del + 50 + del + "No anchors heard" +"\n";;
ersum += (int)Math.Sqrt(erx * erx + ery * ery);
count++;
using (FileStream fs = new FileStream(write_location, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(samples);
}
}
using (FileStream fs = new FileStream(location, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(pos);
}
}
}
else
{
int j = 0; samples = "";
while (sensor.two_hop_apkts.Count > 0 ? ns1 < 50 : ns < 50)
{
int i = 0;
foreach (networkdll.Class1.pkt packet in sensor.apkts)
{
Random rs = new Random(i + j + 1000 * sensor.ID);
xg = rs.Next((int)(packet.x - locatorRadius),
(int)(packet.x + locatorRadius));
yg = rs.Next((int)(packet.y - locatorRadius),
(int)(packet.y + locatorRadius));
if (xg < 20)
xg = 20;
if (yg < 20)
yg = 20;
samples += xg + del + yg + "\n";
score = 0; score1 = 0;
foreach (networkdll.Class1.pkt packet1 in sensor.apkts)
{
float as1Radius = (float)Math.Sqrt(
Math.Pow(packet1.x - xg, 2) + Math.Pow(packet1.y - yg, 2));
if (as1Radius <= locatorRadius)
score++;
}
foreach (networkdll.Class1.two_hop_apkts packet2 in sensor.two_hop_apkts)
{
float as2Radius = (float)Math.Sqrt(Math.Pow(
packet2.x - xg, 2) + Math.Pow(packet2.y - yg, 2));
if (as2Radius >= locatorRadius &&
as2Radius <= 2 * locatorRadius)
score1++; only
}
if (score1 == sensor.two_hop_apkts.Count && score == sensor.apkts.Count
&& score != 0 && score1 != 0)
{
sx1 += xg;
sy1 += yg;
ns1++;
sample1 += xg + del + yg + "\n";
}
else if (score == sensor.apkts.Count && score != 0 && score1 == 0)
{
sx += xg;
sy += yg;
ns++;
sample += xg + del + yg + "\n";
}
i++;
}
j++;
if (j > 50) break;
}
using (FileStream fs = new FileStream(path +
"\\samples_of_sensor_" + s + "." +ext, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(samples);
}
}
if (ns1 != 0)
{
float erx, ery;
ax = (sx1 / ns1);
ay = (sy1 / ns1);
pos = ax + del + ay;
erx = Math.Abs(ax - sensor.x);
ery = Math.Abs(ay - sensor.y);
comm_cost += sensor.apkts.Count + sensor.two_hop_apkts.Count;
no_samples += ns1;
result += s + del + ax + del + ay + del + sensor.x + del +
sensor.y + del + (int)Math.Sqrt(erx * erx + ery * ery) +
del + sensor.apkts.Count + del + sensor.two_hop_apkts.Count + del +
"--" + del + ns1 + del +
"2-hop anchor" + "\n";
ersum += (int)Math.Sqrt(erx * erx + ery * ery);
count++;
using (FileStream fs = new FileStream(write_location, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(sample1);
}
}
using (FileStream fs = new FileStream(location, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(pos);
}
}
}
else if (ns != 0)
{
float erx, ery;
ax = (sx / ns);
ay = (sy / ns);
pos = ax + del + ay;
erx = Math.Abs(ax - sensor.x);
ery = Math.Abs(ay - sensor.y);
comm_cost += sensor.apkts.Count;
no_samples += ns;
result += s + del + ax + del + ay + del + sensor.x + del +
sensor.y + del + (int)Math.Sqrt(erx * erx + ery * ery) + del +
sensor.apkts.Count + del + sensor.two_hop_apkts.Count + del +
"--" + del + ns + del + "1-hop anchor" + "\n";
ersum += (int)Math.Sqrt(erx * erx + ery * ery);
count++;
using (FileStream fs = new FileStream(write_location, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(sample);
}
}
using (FileStream fs = new FileStream(location, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(pos);
}
}
}
}
if (sensor.apkts.Count > 0)
processing_time = 0.1;
else
processing_time = 0.0;
battery.DecrProcessingEnergy(sensor, processing_time, ProcessingPower);
trace.Localize_Trace(path1, "L", counter + 3.0 * sensor.rcvtime,
"S" + sensor.ID, sensor.x, sensor.y,
(int)ax, (int)ay, sensor.ResidualEnergy);
}
else
{
String location = "", read_location =
"", write_location = "",
samples = "", sample = "",
sample1 = "", pos = "";
ax = 0; ay = 0;
location = path + "\\sensor" + s + "." + ext;
read_location = path + "\\slot_" + (((counter) /
slot_duration)-1) + "_sensor" + s +
"." + ext;
write_location = path + "\\slot_" + ((counter) /
slot_duration) + "_sensor" + s + "." + ext;
int score1 = 0, score2 = 0, ns1 = 0, ns2 = 0;
float sxx = 0, syy = 0, sx = 0, sy = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0;
try
{
Matrix samples_matrix = new Matrix(50, 2);
using (StreamReader re = new StreamReader(read_location))
{
for (int row = 0; row < samples_matrix.Rows; row++)
{
string line = re.ReadLine();
string[] values;
if (del == ",")
values = line.Split(',');
else
values = line.Split('\t');
for (int col = 0; col < 2; col++)
{
samples_matrix[row, col] = double.Parse(values[col]);
}
if (re.EndOfStream) break;
}
int k = 0;
if (sensor.apkts.Count > 0)
{
hile (sensor.two_hop_apkts.Count > 0 ? ns2 < 50 : ns1 < 50)
{
for (int i = 0; i < 50; i++)
{
sxx = (float)samples_matrix[i, 0];
syy = (float)samples_matrix[i, 1];
Random rs = new Random(i + k + 1000 * sensor.ID);
sx = rs.Next((int)Math.Abs(sxx - sensorRadius),
(int)(sxx + sensorRadius));
sy = rs.Next((int)Math.Abs(syy - sensorRadius),
(int)(syy + sensorRadius));
if (sx < 20)
sx = 20;
if (sy < 20)
sy = 20;
samples += sx + del + sy + "\n";
score1 = 0; score2 = 0;
foreach (networkdll.Class1.pkt packet1 in sensor.apkts)
{
float as1Radius = (float)Math.Sqrt(
Math.Pow(packet1.x - sx, 2) + Math.Pow(packet1.y - sy, 2));
if (as1Radius <= locatorRadius)
score1++;
}
foreach (networkdll.Class1.two_hop_apkts packet2
in sensor.two_hop_apkts)
{
float as2Radius = (float)Math.Sqrt(
Math.Pow(packet2.x - sx, 2) + Math.Pow(packet2.y - sy, 2));
if (as2Radius >= locatorRadius &&
as2Radius <= 2 * locatorRadius)
score2++; }
if (score2 == sensor.two_hop_apkts.Count &&
score1 == sensor.apkts.Count &&
score1 != 0 && score2 != 0)
{
x2 += sx;
y2 += sy;
ns2++;
sample1 += sx + del + sy + "\n";
}
else if (score1 == sensor.apkts.Count &&
score1 != 0 && score2 == 0
{
x1 += sx;
y1 += sy;
ns1++;
sample += sx + del + sy + "\n";
}
if (sensor.two_hop_apkts.Count > 0)
{
if (ns2 == 50)
goto aa;
}
else
if (ns1 == 50)
goto aa;
}
k++;
if (k > 50)
goto aa;
}
}
aa:
using (FileStream fs = new FileStream(path +
"\\samples_of_sensor_" + s +
"." + ext, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(samples);
}
}
if (ns2 != 0)
{
float erx, ery;
ax = (x2 / ns2);
ay = (y2 / ns2);
pos = ax + del + ay;
erx = Math.Abs(ax - sensor.x);
ery = Math.Abs(ay - sensor.y);
comm_cost += sensor.apkts.Count + sensor.two_hop_apkts.Count;
no_samples += ns2;
result += s + del + ax + del + ay + del + sensor.x + del + sensor.y + del +
(int)Math.Sqrt(erx * erx + ery * ery) + del + sensor.apkts.Count + del +
sensor.two_hop_apkts.Count + del + del + ns2 + del +
"1-hop and 2-hop anchors" + del + "\n";
ersum += (int)Math.Sqrt(erx * erx + ery * ery);
count++;
using (FileStream fs = new FileStream(write_location, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(sample1);
}
}
using (FileStream fs = new FileStream(location, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(pos);
}
}
}
else if (ns1 != 0)
{
float erx, ery;
ax = (x1 / ns1);
ay = (y1 / ns1);
pos = ax + del + ay;
erx = Math.Abs(ax - sensor.x);
ery = Math.Abs(ay - sensor.y);
comm_cost += sensor.apkts.Count;
no_samples += ns1;
result += s + del + ax + del + ay + del + sensor.x + del + sensor.y + del +
(int)Math.Sqrt(erx * erx + ery * ery) + del + sensor.apkts.Count + del +
sensor.two_hop_apkts.Count + del + del + ns1 + del +
"1-hop anchors" + del + "\n";
ersum += (int)Math.Sqrt(erx * erx + ery * ery);
count++;
using (FileStream fs = new FileStream(write_location, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(sample);
}
}
using (FileStream fs = new FileStream(location, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(pos);
}
}
}
else if (ns1 == 0 && ns2 == 0)
{
Matrix sample_matrix = new Matrix(1, 2);
using (StreamReader re = new StreamReader(location))
{
for (int row = 0; row < 1; row++)
{
string line = re.ReadLine();
string[] values;
if (del == ",")
values = line.Split(',');
else
values = line.Split('\t');
for (int col = 0; col < 2; col++)
{
sample_matrix[row, col] = double.Parse(values[col]);
}
}
}
float erx, ery;
ax = (float)sample_matrix[0, 0];
ay = (float)sample_matrix[0, 1];
pos = ax + del + ay;
erx = Math.Abs(ax - sensor.x);
ery = Math.Abs(ay - sensor.y);
no_samples += 50;
result += s + del + ax + del + ay + del + sensor.x + del + sensor.y + del +
(int)Math.Sqrt(erx * erx + ery * ery) + del + sensor.apkts.Count + del +
sensor.two_hop_apkts.Count + del + "--" +
del + 0 + del + "No anchors heard\n"
ersum += (int)Math.Sqrt(erx * erx + ery * ery);
count++;
}
}
catch
{
if (sensor.apkts.Count == 0)
{
Matrix samples_matrix = new Matrix(1, 2);
using (StreamReader re = new StreamReader(location))
{
for (int row = 0; row < 1; row++)
{
string line = re.ReadLine();
string[] values;
if (del == ",")
values = line.Split(',');
else
values = line.Split('\t');
for (int col = 0; col < 2; col++)
{
samples_matrix[row, col] = double.Parse(values[col]);
}
}
}
float erx, ery;
ax = (float)samples_matrix[0, 0];
ay = (float)samples_matrix[0, 1];
pos = ax + del + ay;
erx = Math.Abs(ax - sensor.x);
ery = Math.Abs(ay - sensor.y);
no_samples += 50;
result += s + del + ax + del + ay + del + sensor.x +
del + sensor.y + del + (int)Math.Sqrt(erx *
erx + ery * ery) + del + sensor.apkts.Count +
del + sensor.two_hop_apkts.Count + del +
"--" + del + 0 + del +
"No anchors heard \n";
ersum += (int)Math.Sqrt(erx * erx + ery * ery);
count++;
}
else
{
int j = 0;
while (sensor.two_hop_apkts.Count > 0 ? ns2 < 50 : ns1 < 50)
{
int i = 0;
foreach (networkdll.Class1.pkt packet in sensor.apkts)
{
Random rs = new Random(i + j + 1000 * sensor.ID);
sx = rs.Next((int)(packet.x - locatorRadius), (int)(packet.x + locatorRadius));
sy = rs.Next((int)(packet.y - locatorRadius), (int)(packet.y + locatorRadius));
if (sx < 20)
sx = 20;
if (sy < 20)
sy = 20;
samples += sx + del + sy + "\n";
score1 = 0; score2 = 0;
foreach (networkdll.Class1.pkt packet1 in sensor.apkts)
{
float as1Radius = (float)Math.Sqrt(
Math.Pow(packet1.x - sx, 2) + Math.Pow(packet1.y - sy, 2));
if (as1Radius <= locatorRadius)
score1++;
}
foreach (networkdll.Class1.two_hop_apkts packet2 in sensor.two_hop_apkts)
{
float as2Radius = (float)Math.Sqrt(Math.Pow(
packet2.x - sx, 2) + Math.Pow(packet2.y - sy, 2));
if (as2Radius >= locatorRadius &&
as2Radius <= 2 * locatorRadius)
score2++;
}
if (score2 == sensor.two_hop_apkts.Count &&
score1 == sensor.apkts.Count &&
score1 != 0 && score2 != 0)
{
x2 += sx;
y2 += sy;
ns2++;
sample1 += sx + del + sy + "\n";
}
else if (score1 == sensor.apkts.Count &&
score1 != 0 && score2 == 0)
{
x1 += sx;
y1 += sy;
ns1++;
sample += sx + del + sy + "\n";
}
i++;
}
j++;
if (j > 50)
break;
}
using (FileStream fs = new FileStream(path +
"\\samples_of_sensor_" + s + "." +
ext, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(samples);
}
}
if (ns2 != 0)
{
float erx, ery;
ax = (x2 / ns2);
ay = (y2 / ns2);
pos = ax + del + ay;
erx = Math.Abs(ax - sensor.x);
ery = Math.Abs(ay - sensor.y);
comm_cost += sensor.apkts.Count + sensor.two_hop_apkts.Count;
no_samples += ns2;
result += s + del + ax + del + ay + del + sensor.x + del +
sensor.y + del + (int)Math.Sqrt(erx * erx +
ery * ery) + del + sensor.apkts.Count + del +
sensor.two_hop_apkts.Count + del + del +
ns2 + del + "1-hop and 2-hop anchors" +
del + "\n";
ersum += (int)Math.Sqrt(erx * erx + ery * ery);
count++;
using (FileStream fs = new FileStream(write_location, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(sample1);
}
}
using (FileStream fs = new FileStream(location, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(pos);
}
}
}
else if (ns1 != 0)
{
float erx, ery;
ax = (x1 / ns1);
ay = (y1 / ns1);
pos = ax + del + ay;
erx = Math.Abs(ax - sensor.x);
ery = Math.Abs(ay - sensor.y);
comm_cost += sensor.apkts.Count;
no_samples += ns1;
result += s + del + ax + del + ay + del + sensor.x + del +
sensor.y + del + (int)Math.Sqrt(erx * erx + ery * ery) + del +
sensor.apkts.Count + del + sensor.two_hop_apkts.Count + del +
del + ns1 + del + "1-hop anchors" + del + "\n";
ersum += (int)Math.Sqrt(erx * erx + ery * ery);
count++;
using (FileStream fs = new FileStream(write_location, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(sample);
}
}
using (FileStream fs = new FileStream(location, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(pos);
}
}
}
}
}
if (sensor.apkts.Count > 0)
processing_time = 0.1;
else
processing_time = 0.0;
battery.DecrProcessingEnergy(sensor, processing_time, ProcessingPower);
trace.Localize_Trace(path1, "L", counter + 3.0 * sensor.rcvtime,
"S" + sensor.ID, sensor.x, sensor.y,
(int)ax, (int)ay, sensor.ResidualEnergy);
}
sensor.estx = (int)ax;
sensor.esty = (int)ay;
}
s++;
}
end = System.DateTime.Now.Ticks;
executiontime = end - start;
time = " " + (double)(executiontime / 10000);
trace.Percent_Residual_Energy(path1, asensor, counter / slot_duration, initialenergy);
if (count != 0) { avger = ersum / count; avg_samples = no_samples / count; }
if (s != 0 && count != 0) coverage = (float)((float)count / (float)s) * 100;
using (FileStream fs = new FileStream(path + "\\MCL_of_slot" +
((counter) / slot_duration) + "." + ext, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(result + "\n\n" + "\nAverage" +
del + "error = " + del + avger + del + "m" +
"\nPercent" + del + " error = " + del +
(avger / sensorRadius) + del + "R" + "\nCommunication" + del +
"cost = " + del + comm_cost + del + "packet\n" +
"Avg.Number of" + del +
"samples = " + del + avg_samples + del + "sample\n");
w.Dispose();
}
}
if (delimiter == 1)
result1 += (((counter)) / slot_duration) + del + (avger / sensorRadius) + del +
del + del + comm_cost + del + del + del + avg_samples ;
else
result1 += (((counter)) / slot_duration) + del + (avger / sensorRadius) +
del + comm_cost + del + avg_samples;
if (counter == 0)
using (FileStream fs = new FileStream(path +
"\\MCL_total_results." + ext, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
if (delimiter == 1)
w.WriteLine("Slot" + del + "Localization" +
del + "Communication" + del +
"Number of" +
del + "\nNo." +
del + "Error \"R\"" + del + del +
"Cost \"packet\"" + del +
"samples \"sample\"" +
del +
"\n===========
========================================================\n" + result1);
else
w.WriteLine("Slot" + del +
"Localization" + del + "Communication" +
del + "Number of" +
del + "\nNo." +
del + "Error \"R\"" + del +
"Cost \"packet\"" + del +
"samples \"sample\"" +
del + "\n" + result1);
w.Dispose();
}
}
else
using (FileStream fs = new FileStream(path +
"\\MCL_total_results." + ext, FileMode.Append))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(result1);w.Dispose();
}
}
}
}
}
}
How to simulate a localization algorithm? (e.g. MCL)
In order to simulate MCL follow the following steps:
- Set number of anchor nodes
- Set number of mobile sensors
- Set sensors radio button to mobile
- Select sensors’ mobility model (e.g. modified random waypoint)
- Set anchors radio button to mobile
- Select anchors’ mobility model (e.g. modified random waypoint)
- Set Deploy Base Stations check box
- Select Localization algorithm (e.g. MCL)
Figure 5: Mobility Setting and Network Parameters
From Sensor Settings tab:
- Select sensor model (e.g. Mica2)
- Select propagation model

Figure 6: Sensor Settings Tab
From Scenario Settings tab:
- Set Simulation time (e.g. 150 sec.)
- Verify that the folder of Trace & Energy files is created.
- Verify that the folder of Scenario files is created.
- Verify that the folder of localization algorithm Results (e.g. MCL) is created.
- Select type of Results files from output file list box (e.g. xls for Excel files or doc for word files)

Figure 7: Scenario Settings Tab
From Simulation Control Group Box:
- Press Deploy WSN button.
- Press Start Simulation button.
- Wait until progress bar completes 100%.
- Open Results file (MCL_total_results.xls) found in MCL folder.
- Residual energy and trace files are found in Trace folder (shown in Fig. 10 and Fig. 11)

Figure 8: Deploy WSN and Run Simulation
Output files

Figure 9: Output File (Results of MCL)
Figure 10: Residual Energy File
Figure 11: Trace File
Note
In order to simulate already existing scenario do all previous steps but you have to select Read scenario radio button instead of Generate scenario radio button from scenario settings.
Conclusion
The design of the proposed simulation tool is focusing on object oriented architecture which allows users to adapt the simulation tool, or extend it to different localization algorithms. This simulator has been developed in such a way so that it can support or work with different kinds of localization algorithms. The proposed simulator has the ability to generate different scenarios written into external files so as to allow users to use the same scenarios when comparing different localization algorithms.
History
This is a Wireless Sensor Network Localization Simulator v2.1 it is an extension for the previous version v1.1. Written by Abdelhady Mohammad Naguib in Jun 2013. Thank you for using the WSN Localization Simulator.