Wireless Sensor Network Localization Simulator v2.1






4.93/5 (19 votes)
This is a WSN localization simulator. It is easy, scalable, and extendable which allows researchers to extend it to many/different localization schemes.
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.
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.
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.
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
initialenergy
:private double initialenergy
last_time_gosleep
:private float last_time_gosleep
max_inroute_time
:private float max_inroute_time
node_on
:private bool node_on
sleep_mode
:private int
sleep_mode
total_rcvtime
:private float total_rcvtime
total_sleeptime
:private float total_sleeptime
total_sndtime
:private float total_sndtime
This variable represents the amount of current energy.
This is a private variable indicating the initial energy (full energy) of this node.
This variable represents the time when radio is turned off.
This variable represents the maximum time that a node can remaining active.
This is Boolean variable represents on-off status of this node.
This variable indicates that radio is turned off when its value =1.
This variable represents the total time in receiving data.
This variable represents the total time of radio in off mode.
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)
Decrease_Rcv_Energy: public void Decrease_Rcv_Energy(double rcvtime, double P_rcv)
Decrease_Sleep_Energy: public void Decrease_sleep_Energy(double idletime, double P_idle)
Decrease_Tx_Energy: public void Decrease_Tx_Energy(double txtime, double P_tx)
getenergy: public double getenergy()
max_inroute_time: public float max_inroute_time()
Max_Rcv_time: public double Max_Rcv_time(double P_rcv) {return(energy_/P_rcv)
Max_Tx_time: public double Max_Tx_time(double P_tx)
MaxIdletime: public double MaxIdletime(double P_idle)
node_on: public bool node_on()
setenergy: public void setenergy(double e)
total_rcvtime: public float total_rcvtime()
total_sleeptime: public float total_sleeptime()
total_sndtime: public float total_sndtime()
This method is responsible for decreasing sensors (or anchors) residual energy due to mobility.
This method is responsible for decreasing receive energy of mobile node.
This method is responsible for decreasing receive energy of mobile node.
This method decreases transmit energy.
This method returns the current energy.
This method returns the maximum time that a node can remaining active.
This method returns the maximum receive time.
This method returns the maximum transmit time.
This method returns the maximum sleep time.
This method returns the status of this node.
This method sets the current energy of this node.
This method returns the total receiving time.
This method returns the total sleep time.
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
node_on: public bool node_on
sensing_power: public double sensing_power
sensing_time: public double sensing_time
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.
This Boolean variable represents the status of sensor node.
This variable represents the amount of sensing power.
This variable indicates the amount of sensing time.
Methods
DecrProcessingEnergy: public void DecrProcessingEnergy(int number_instructions, double instructions_per_second, double processing_power)
DecrSensingEnergy: public void DecrSensingEnergy(double sensing_time, double sensing_power)
SetNodeOff: public void setNodeOff()
SetNodeOn: public void setNodeOn()
Sleep: public void sleep()
WakeUp: public void wakeUp()
This method computes the energy spent by a processing task and reduce energy stock by this amount.
This method computes the energy spent by a sensing task and reduces energy stock by this amount.
This method turns sensor node off.
This method turns sensor node on.
This method puts node battery in sleep mode.
This method wakes up the sleepy node battery.
3. Propagation_Model class
Attributes
Gr: public double Gr
Gt: public double Gt
hr: public double hr
ht: public double hr
L: public double L
Lambda: public double lambda
This variable represents omni-directional antenna gain for receiving.
This variable represents omni-directional antenna gain for sending.
This variable represents antenna height for transmitter.
This variable represents antenna height for receiver.
This variable represents system loss.
This variable represents wave length.
Methods
Cross_Distance: public double Crossover_Distance(double Frequency)
Friis: public double Friis(double Pt, double Frequency, double d)
inv_erfc: public double inv_erfc(double y)
inv_Q: public double inv_Q(double y)
RXThresh_Shadowing: public double RXThresh_Shadowing(double prob, double pathlossExp, double std_db, double Pt, double Frequency, double dist)
Shadowing: public double Shadowing(double Pt, double Frequency, double dist, double pathlossExp, double std_db)
Two_Ray_Ground: public double Two_Ray_Ground(double Pt, double Frequency, double d)
This method is responsible for calculation crossover distance.
This method simulates free space model.
This method gets the inverse of complementary error function.
This method gets the inverse of Q function.
This method calculates the received signal threshold for shadowing model.
This method returns the received signal power for shadowing model at distance dist.
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
pkt_size: public double pkt_size
sensor_data_rate: public double sensor_data_rate
This variable represents the distance between transmitter and receiver.
This variable represents the packet size.
This variable represents data rate of sensor node.
Methods
propagation_delay: public double propagation_delay(double distance)
rcvtime: public double rcvtime(double pkt_size, double rate)
RTT: public double RTT(double distance)
total_txtime: public double total_txtime(double pkt_size, double rate, double distance)
txtime: public double txtime(double pkt_size, double rate)
This method calculates link propagation delay.
This method calculates delay time required for receiving a packet.
This method calculates the round trip time.
This method calculates total transmission time.
This method calculates the transmission time for a packet.
5. Routing Class
Attributes
connectionCurrent: public bool connectionCurrent
iReceiveCost: public float iReceiveCost
iResidualEnergy: public int iResidualEnergy
iTransmitCost: public float iTransmitCost
This is a public Boolean variable indicating whether there a connection or not.
This variable is responsible for storing the value of energy consumed by receiving packet(s).
This integer is responsible for storing the amount of residual energy of sensor nodes.
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)
SetRoutingInformation: public void SetRoutingInformation()
send: public void send(Packet p)
receive: public Packet receive()
This is a constructor for the Routing class.
This method contains the representation of routing protocol.
This method is responsible for sending packets.
This method is responsible for receiving packets.
6. TemperatureDataGenerator Class
Attributes
avg_temp: public double avg_temp
initialenergy: public double initialenergy
sensing_power: public double sensing_power
sensing_time: public double sensing_time
temp: public double temp
This variable represents the average temperature sensed.
This variable represents sensor node energy.
This variable represents the amount of energy required for sensing task.
This variable represents the amount of time required for sensing task.
This variable represents the amount of temperature generated.
Methods
generate_temp: public void generate_temp(ArrayList asensor,double now)
sense_temperture: public void sense_temperature(ArrayList asensors)
TemperatureDataGenerator: public TemperatureDataGenerator(ArrayList asensor, double avg_temp, double max_temp, double std_dev)
This method is used to generate random temperature using Gaussian distribution.
This method is used to simulate the sensing operation of sensor nodes.
This is the constructor of TemperatureDataGenerator
class.
7. WirelessChannel Class
Attributes
M_node_list: public ArrayList M_node_list
Num_nodes: public int Num_nodes
pdelay: public double pdelay
Receiver: public Mobile_Node Receiver
Sender: public Mobile_Node Sender
This variable represents a list of communicating nodes.
This variable indicates number of mobile nodes added to the channel.
This variable represents the propagation delay which determines exactly when the receiver's interface detects the first bit received packet.
This mobile node is considered the destination node.
This mobile node is considered the source node.
Methods
addNodetoList: public void addNodeToList(Mobile_Node mn)
get_pdelay: public double get_pdelay(Mobile_Node tnode, Mobile_Node rnode)
recv: public void recv(Packet pkt)
sendUp: public void sendUp(Packet pkt)
WirelessChannel: public WirelessChannel(Mobile_Node sSender, Mobile_Node sReceiver)
This method creates a list of mobile nodes for this channel.
This method returns the propagation delay between two nodes.
This method receives packets from the channel checks if the packet has been received correctly.
This method check if the packet has been sent correctly and to decrement the energy consumed in the packet reception.
This is the class constructor.
8. Adversary Class
Attributes
AdvRadius: public int AdvRadius
AdvRepConnection: public System.Collections.ArrayList AdevRepConnection
AdvSpoofConnection: public System.Collections.ArrayList AdevSpoofConnection
AdvSybilConnection: public System.Collections.ArrayList AdevSybilConnection
AdvWormConnection: public System.Collections.ArrayList AdevWormConnection
id: public int id
This field is responsible for changing adversary radio range.
This array list is responsible for storing all valid connection made by adversary using reply attack.
This array list is responsible for storing all valid connection made by adversary under spoofing attack.
This array list is responsible for storing all valid connection made by adversary under Sybil attack.
This array list is responsible for storing all valid connection made by adversary under Wormhole attack.
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
AnchorRadius: public int AnchorRadius
direction: public double direction
distance: public int distance
id: public int id
sangle: public int sangle
This array list stores all valid connections done through anchor nodes.
This variable is responsible for storing the value of anchor radio range.
This variable is responsible for storing the moving direction of anchor node.
This variable is responsible for storing the distance moved by anchor node.
This variable is responsible for storing the identity of the anchor nodes deployed.
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
id: public int id
x: public int x
y: public int y
This public variable is responsible for assigning the value of base station communication range.
This public variable assigns the identity for each base station.
This public variable is responsible for assigning the value of x-coordinated for base station.
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
data: private ArrayList data
datalen: private int datalen
hdrlen: public static int hdrlen
next: public Packet next
PktList: private ArrayList PktList
sangle: public int sangle
This field contains the address of the first byte of where packet header fields are stored.
This field represents a variable size buffer for data.
This field indicates the length of variable size buffer holding data.
This field indicates the size of a packet's header.
This field points to next packet in free list.
This field represents a free list for packets.
This field represents the rotation angle of directed antenna.
Methods
accessdata: public ArrayList accessdata()
alloc: public Packet alloc(int n)
allocdata: public void allocdata(int n)
free: public Packet free(Packet p)
get_bits: public int get_bits()
This method returns data field of the packet.
This field allocates a packet with an n byte data buffer.
This field allocates an n byte data buffer to an existing packet.
This field frees a packet by returning it to the free list.
This field returns the header offset in packet.
12.Encrypted_Packet Class
Attributes
anchor_public_key: public ECDiffieHellmanPublicKey anchor_public_key
Encrypted: public byte[] Encrypted
sensor_private_key: public ECDiffieHellmanCng sensor_private_key
This variable is used to store the public key of anchor node.
This is the cipher text represented as a byte array.
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
Connection: public ArrayList Connections
direction: public double direction
distance: public int distance
ID: public int ID
instructionsPerSecond: public int instructionsPerSecond
processingPower: public double processingPower
ProessorUseState: public int processorUseState
sensingPower: public double sensingPower
sensorUseState: public int sensorUseState
transceptorUseState: public int transceptorUseState
This field represents the list of WSN applications which the sensor node is associated to.
This attribute contains valid connections.
This variable represents the moving direction of sensor node.
This variable represents the moved distance of sensor node.
This variable represents unique identity of sensor node.
This attribute indicates the number of instructions the nodes processor can execute in a second.
This variable represents the energy consumption of the sensor node in processing activities. This attribute has its value expressed in watts (joules/second).
This attribute represents the processor state. Indicates whether the node’s processing activity is in use or not.
This variable indicates the energy consumption of the sensor node in sensing activities. This attribute has its value expressed in watts (joules/second).
This variable represents the sensor state. Indicates whether the node’s sensing activity is in use or not.
This attribute represents the transceiver state. Indicates whether the node’s dissemination activity is in use or not.
Methods
instructionsPerSecond: public double instructionsPerSecond()
processingPower: public double processingPower()
sensingPower: public double sensingPower()
sleep: public void sleep()
wakeUp: public void wakeUp()
WirelessSensor: public WirelessSensor
(+3 overloads)
This method gets sensor node instructions per second executed by its processor.
This method gets sensor node processing energy consumption.
This method gets sensor node sensing energy consumption.
This method turns the sensor node off when necessary. Stop all of its applications.
This method wakes the sensor node up after a sleepy period. Start all of its applications.
This method represents the class constructor containing three overloaded constructors.
14.Sensed_Data Class
Attributes
AppDataListinfo: public ArrayList AppDataList
eventType: public int eventType
msgType: public int msgType
node_id: public int node_id
Priority: public int priority
timestamp: public double timestamp
This attribute represents sensed data buffer. Storages all data processed by the sensor node.
This variable indicates type of the event that caused sensed data processing.
This integer represents type of the message to be disseminated to the network.
This variable represents source node identification for sensed data dissemination purposes.
This variable represents the priority of sensed data message.
This variable represents sensed data timestamp.
Methods
copy: public Sensed_Data copy()
existisData: public bool existsData()
get_data: public ArrayList get_data()
get_eventType():public int get_eventType()
get_msgType: public int get_msgType()
get_node_id: public int get_node_id()
get_priority: public int get_priority()
get_timestatmp: public double get_timeStamp()
insert_new_data: public void insert_new_data(ArrayList data)
Sensed_Data: public Sensed_Data(Sensed_Data data)
set_priority: public void set_priority(int p)
This method creates a copy of the sensed data object.
This method informs if there is processed data stored in data buffer.
This method returns processed data stored in data buffer.
This method returns an event type.
This method returns a reference to sensed data message type.
This method returns a reference to source node identification.
This method returns sensed data priority. This is useful during disseminating tasks.
This method returns a reference to sensed data timestamp.
This method inserts new processed data into data buffer.
This is copy constructor, creates a new Sensed Data object equals to data parameter.
This method adjusts sensed data priority.
15.Event Class
Attributes
next: public ArrayList next
prev: public ArrayList prev
scheduler_id: public int scheduler_id
time: public double time
This attribute represents the list of next events.
This attribute represents the list of previous events.
This variable represents unique identity for the scheduler.
This variable indicates the time at which event is ready.
Methods
event: public Event(double time, Scheduler id)
This method represents event constructor.
16. Scheduler Class
Attributes
clock: public double clock
queue: private Event queue
Sched_Start: public double Sched_Start
This variable represents simulator time.
This variable represents an event to be dequeued
This attribute indicates start time (secs).
Methods
dequeue: public Event dequeue()
dispatch: public void dispatch
(+1 overload)head: public Event head()
insert: public void insert(Event e)
lookup: public Event lookup(int sched_id)
run: public double run()
schedule: public void schedule(Event e, double delay)
Scheduler: public Scheduler()
This method de-queues next event.
This method is responsible for executing an event.
This method sets next head event.
This method inserts an event into scheduler list.
This method looks up for an event into scheduler list.
This method represents the starting time of an event.
This method schedules later event.
This method represents Scheduler class constructor.
17.Error_Model Class
Attributes
drop: public bool drop
errLength: public double errLength
This Boolean variable represents drop status of the packet.
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)
CorruptBit: public int CorruptBit(Packet p)
CorruptByte: public int CorruptByte(Packet p)
CorruptPkt: public int CorruptPkt(Packet p)
CorruptTime: public int CorruptTime(Packet p)
recv: public void recv(Packet p)
This method returns the status of packet corruption.
This method pre-computes the probabilities for each bit-error.
This method computes packet error rate, assume uniformly distributed byte error.
This method is responsible for packet corruption.
This method decides whether or not to corrupt this packet, for a continuous time-based error model.
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
seed_val: public long seed_val
This attribute represents the random number generated.
This variable represents seed value of random number generator.
Methods
exponential: public double exponential()
exponential: public double exponential(double k)
lognormal: public double lognormal(double avg, double std)
next: public long next()
next_double: public double next_double()
normal: public double normal(double avg, double std)
seed: public long seed()
set_seed: public void set_seed (long seed)
uniform: public double uniform(double a, double b)
This method returns a number sampled from an exponential distribution with mean 1.0. The other overloaded method is:
This method returns a number sampled from an exponential distribution with mean k.
This method returns a number sampled from a lognormal distribution with the given average and standard deviation.
This method returns the next random number as an integer.
This method returns the next random number on [0, 1].
This method returns a number sampled from a normal distribution with the given average and standard deviation.
This method returns the current seed.
This method sets the seed of the RNG, if seed = 0, the seed is set according to the current time and a counter.
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; //sensor index,count for average error
int ersum, avger = 0;//error summation
int comm_cost = 0;//communication cost = no. of packets generated
float coverage = 0; //no. of localized sensor nodes
int no_samples = 0, avg_samples = 0;
//String result = "Node,EstX,EstY,ActualX,ActualY,Error,
// 1hAnchor,2hAnchor,Neighbors,No.samples,Constraint\n";
//String result1 = "";//cumulate all results for all slot
String ext = "", del = "";
//file extension and column delimiter type "comma or tab"
String result = "";
String result1 = "";//cumulate all results for all slot
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;//float estx = 0, esty = 0;
double processing_time;
//Calculate processing power
double ProcessingPower = 0.029;
if (SensorModel == 0)//Mica2
ProcessingPower = 0.029;//watt
else if (SensorModel == 1)//TelosB
ProcessingPower = 0.038;//watt
if (counter % slot_duration == 0)//anchor path
{
ersum = 0; avger = 0;
////////////////////////////Slot 0////////////////////////
foreach (networkdll.Class1.WirelessSensor sensor in asensor)
{
if (sensor.ResidualEnergy > 0)
{
///////Localization using Monte Carlo//////////////
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++)
//generate random samples in the deployment field
{
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)
//No anchors heard ==> No filtering ==> high localization error
{
float erx, ery;//error (x,y)
ax = (sxs / 50);//number of samples = 50
ay = (sys / 50);
pos = ax + del + ay;
erx = Math.Abs(ax - sensor.x);
ery = Math.Abs(ay - sensor.y);
no_samples += 50;//cumulative number of samples
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++;
//file to store filtered samples for each slot
using (FileStream fs = new FileStream(write_location, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(samples);
}
}
//file to store estimated position for current slot only
using (FileStream fs = new FileStream(location, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(pos);
}
}
}
else//anchors heard ==> filtering is done
{
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)
//1-hop anchor packet
{
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)
//filtering by 1-hop and 2-hop anchors
{
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;
}
//file to store random samples generated
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)//2-hop filtering
{
float erx, ery;//error (x,y)
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;
//communication cost
no_samples += ns1;//cumulative number of samples
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";// del +
ersum += (int)Math.Sqrt(erx * erx + ery * ery);
count++;
//file to store filtered samples for each slot
using (FileStream fs = new FileStream(write_location, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(sample1);
}
}
//file to store estimated position for current slot only
using (FileStream fs = new FileStream(location, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(pos);
}
}
}
else if (ns != 0)//1-hop filtering
{
float erx, ery;//error (x,y)
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;//communication cost
no_samples += ns;//cumulative number of samples
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++;
//file to store filtered samples for each slot
using (FileStream fs = new FileStream(write_location, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(sample);
}
}
//file to store estimated position for current slot only
using (FileStream fs = new FileStream(location, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(pos);
}
}
}
}
//processing time for MCL = 100 msec per node
if (sensor.apkts.Count > 0)
processing_time = 0.1;//0.1 sec = 100 msec
else
processing_time = 0.0;
//Compute residual energy for sensor node after processing task (localization)
battery.DecrProcessingEnergy(sensor, processing_time, ProcessingPower);
//writing localize event to trace file
trace.Localize_Trace(path1, "L", counter + 3.0 * sensor.rcvtime,
"S" + sensor.ID, sensor.x, sensor.y,
(int)ax, (int)ay, sensor.ResidualEnergy);
}
///////Slot1,2,3..n/////////////
else
{
String location = "", read_location =
"", write_location = "",
samples = "", sample = "",
sample1 = "", pos = "";
ax = 0; ay = 0;
location = path + "\\sensor" + s + "." + ext;
//file to store sample points coordinated of current slot
read_location = path + "\\slot_" + (((counter) /
slot_duration)-1) + "_sensor" + s +
"." + ext;//to read from previous slot
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;
//sxx.syy:estimated samplex,sx,sy:samplex
// after increment(decrement),x1,x2,y1,y2:cumulative fired samples
try
{
Matrix samples_matrix = new Matrix(50, 2);
//file to read random samples of sensor in prevoius slot
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]);
}
// row++;
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;
////////////////1-hop anchor constraint/////////////////
foreach (networkdll.Class1.pkt packet1 in sensor.apkts)
//1-hop anchor packet
{
float as1Radius = (float)Math.Sqrt(
Math.Pow(packet1.x - sx, 2) + Math.Pow(packet1.y - sy, 2));
if (as1Radius <= locatorRadius)
score1++; //counter for number of 1-hop anchors only
}
////////////2-hop anchor constraint//////////////////
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)//2-hop
{
if (ns2 == 50)
goto aa;
}
else//1-hop
if (ns1 == 50)
goto aa;
}
k++;
if (k > 50)
goto aa;
}
}
aa: //file to store random samples generated
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)//1-hop and 2-hop filtering
{
float erx, ery;//error (x,y)
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;
//communication cost
no_samples += ns2;//cumulative number of samples
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++;
//file to store filtered samples for each slot
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)//1-hop filtering
{
float erx, ery;//error (x,y)
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;//communication cost
no_samples += ns1;//cumulative number of samples
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++;
//file to store filtered samples for each slot
using (FileStream fs = new FileStream(write_location, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(sample);
}
}
//file to store estimated position for current slot only
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);
//file to read last stored estimated position
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;//error (x,y)
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;//cumulative number of samples
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);
//file to read last stored estimated position
using (StreamReader re = new StreamReader(location))
{
//int row = 0;
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;//error (x,y)
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;//cumulative number of samples
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//anchors heard ==> filtering is done
{
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++; //counter for number of 2-hop anchors only
}
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)//1-hop and 2-hop filtering
{
float erx, ery;//error (x,y)
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;//communication cost
no_samples += ns2;//cumulative number of samples
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)//1-hop filtering
{
float erx, ery;//error (x,y)
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;//communication cost
no_samples += ns1;//cumulative number of samples
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;//0.1 sec = 100 msec
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" +
/*"Computation" + del + "cost =" + del + time + del +
"ms\n"*/"Avg.Number of" + del +
"samples = " + del + avg_samples + del + "sample\n"/* +
"Localized" + del + "sensors =" + del +
coverage + del + "%"*/);
w.Dispose();
}
}
if (delimiter == 1)
result1 += (((counter)) / slot_duration) + del + (avger / sensorRadius) + del +
del + del + comm_cost + del + del + del + /*time*/avg_samples /*+ del + del + coverage*/;
else
result1 += (((counter)) / slot_duration) + del + (avger / sensorRadius) +
del + comm_cost + del + /*time*/avg_samples/* + del + coverage*/;
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 +
/*"Computation"*/"Number of" +
del + /*"Localized*/"\nNo." +
del + "Error \"R\"" + del + del +
"Cost \"packet\"" + del +
/*"Cost \"ms\""*/"samples \"sample\"" +
del +
/*"Sensors \"%\*/"\n===========
========================================================\n" + result1);
else
w.WriteLine("Slot" + del +
"Localization" + del + "Communication" +
del + /*"Computation"*/"Number of" +
del + /*"Localized*/"\nNo." +
del + "Error \"R\"" + del +
"Cost \"packet\"" + del +
/*"Cost \"ms\""*/"samples \"sample\"" +
del + /*"Sensors \"%\*/"\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)
- Select sensor model (e.g. Mica2)
- Select propagation model
- 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)
- 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)
From Sensor Settings tab:
From Scenario Settings tab:
From Simulation Control Group Box:
Output files
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.