Categories
Uncategorized

Swarm-Intelligence-Centric Routing Algorithm for WSNs

The blog written below reviews and summaries the novel idea put forward in this paper: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7570729/

The paper, given in the link above, focuses on how swarm intelligence principles can be applied to a wireless sensor network (WSN), and how stable routes and connections are maintained. It describes a novel algorithm that explains how improvements can be made on current techniques to improve performance over different network environments.

What is swarm intelligence(SI)?

SI is generally defined as the collective behaviour of life groups in an environment and the decisions they make. It is a complex system in which individuals interact with each other with minimal communication about aspects. Although SI is defined differently depending on where you look and what you apply it to so for this example, I will be explaining the idea of SI with regards to an ant colony.

The ant colony example

Ants use different types of pheromones depending on the environment and if they have found food or not. Their goal is to find the shortest route to a food source from their habitat. The problem for each ant is given based on factors such as transportation scheduling storage and the best route to the source of food. Each ant attempts to solve this puzzle. With aim to find the best possible version of each of these factors above and depending on the outcome of the ant’s results (of a certain method/ route) it relays that information back to other ants around it.

The pheromones are updated and released to the environment every time an ant does a certain iteration of the problem and that is fed back to the other ants around it until the ants find the best possible route/ method for doing all the tasks, hence they find the optimum path or calculation due to all of them doing iterations of the same problem and feeding the results to each other. Figure 1 shows several iterations of the best route problem completed by several ants (a, b) then in Figure 1 c the optimum route has been solved and collectively the ants are using this route. For an individual ant passing across the path which provides the shortest route to a food source, the ant collects many pheromones.  The large number of pheromones collected causes the ants to recognise it is on the shortest/most optimised path. Consequently, resulting in the ant to move along this subsequent path.

Figure 1. Route solving by ants.

The SICROA (swarm-intelligence-centric routing algorithm) 

Below are listed the three main issues with current WSNs.

  • Nodes in WSN are mobile.
  • Data transmission is limited by the battery power/power supply.
  • Unstable path routing, disconnections over links cause interference.

We can overcome all these issues with the SICROA algorithm which can produce an agile and appropriate response to routing issues. This is done through the idea of collision avoidance using interrupts:

Currently AODV (Ad-hoc On demand distance vectors) systems provide a ‘hello’ message to prevent link disconnection issues and means mobile nodes can exchange information with each other. However, AODV can cause congestion and dropouts to occur. 

To avoid this congestion a method close to that of the ant colony example is used. In biology when a large accumulation or a different type of pheromone is sensed then information is fed back about that route. Using this idea, when a node (or point at which routes cross) becomes overloaded with data passing through them they can ‘interrupt’ one (or x amount) and put a hold signal on that route. This changes the ‘hello’ signal (which checks the connection to the node) to a feedback signal, a battery check signal. This essentially blocks the transmission of the data until the check is completed.

A different sort of check is also used: ‘mobility check’ which causes the overloaded node to move position. The movement can cancel all incoming and outgoing data transmission to allow the new signal to pass through it (if it moves to a location that can transmit the data to the correct place). Path recovery is then performed to return the other nodes to transmitting data successfully. 

The sender node then attempts to resend the signal either by the same route or another route until the data is passed successfully. Once it knows which route is the most successful route it will delete all the other routes and only use this one.

Figure 2. Transmission of data between different nodes

Figure 2 shows an overload of data being passed through node A and hence a ‘battery check’ interrupt signal has been passed to node S2 to prevent it transmitting its data through node A. to solve this an alternative route has been found, by node S2, to get to node D2 that is successful with no overloading or collision occurring. This example relates to our ant example as there is an action occurring when an accumulation of paths goes across the same point. In this case we re-route one of our paths.

The name dubbed for this collision avoidance process is CATI. CATI causes an overall performance increase as link disconnections are predicted and hence prevented.

The algorithm itself:

The SICROA algorithm contains a series of if and else statements which ask question such as is the node in question in the RREQ state (return request), if the node in question is broadcasting an interrupt state battery/mobility, is the destination the node in question. Some of the processes regarding the broadcasted interrupt state involve ignoring the packet, processing the data packet to follow the existing route, send the interrupt state to the source of the data packet transmission. Then once these processes are complete the data packet will follow the original route or solve for a new route.

Overall, the algorithm manages to predict links between individual nodes, sources and destinations.

How does this process look in a WNS?

Firstly, the RREQ packets are broadcasted from source to neighbour nodes, then the packets are received and the route from the source to the intermediate node is stored in a table. If the intermediate nodes are not the destination, then they broadcast packets to other neighbouring nodes. When the destination node is reached, there will be no further broadcast of the packet and the route from source – destination is saved in a routing table before returning any data RREP (route reply packet). If a single intermediate node receives the same packet from different routes, it will disregard one of the packets completely.

Figure 3. Shows what a RREQ message in SICROA might look like

When receiving a RREQ, intermediate nodes also measure the ‘warning_energy’ which is the energy rating to maintain transmission of data in the packet. When two of the same packets meet a node, the node takes the packet with the larger ‘warning_energy’ as this link will be more stable and can be maintained for longer durations.

To Evaluate the Results

The testing of the SICROA algorithm was used on Network Simulator-2 (NS-2) and appropriate evaluations were observed using this. The simulation testing ran on 10-100 individual nodes, each simulation lasted for 90 seconds. This process was iterated 10 times, increasing the number of nodes by 10 each time.

RWP random waypoint was used as a mobility model and which measured performance. The speed of the system was observed to increase from 5m/s to 30m/s. RREQ flooding between nodes was initialised to begin the process of data transmission to test the algorithm. The end-to-end delay between a packet to be sent and then received at its destination, represents the path length used from data transmission. Whereas SICROA represents a smaller delay and hence a smaller path length in comparison to existing techniques used in WNS, AODV and DSR.

Furthermore, it was also witnessed that using the algorithm SICROA the flooding period was dealt with quicker and more efficiently, as at this time the delay compared to the other techniques is smaller. This means paths are updated quicker as well. The points above are shown in Figure 4. Nevertheless, a setback was the delay of the successfully delivered packets was measured and hence some packets may have been lost in the process of this simulation.

Figure 4. Shows the end-to-end delay of SICROA versus other techniques

Another test that ran in parallel to the delay time was the packet delivery ratio, which is the number of packets transmitted from source nodes over the number of packets received at the destination nodes. The figure below (Figure 5) shows that the ratio has increased in comparison to existing methods which allows saying that the efficiency of this algorithm is greater than others in use currently.

Figure 5. Packet delivery ratio graph

 Finally, the last graph (Figure 6) demonstrates the percentage of nodes which did not drop out due to high power consumption levels. This shows, again, the benefits of the SICROA algorithm having a far higher survival rate than the other techniques in question, at 90% compared to 70-75%.

Figure 6. Node survival rate during the simulation period

Therefore, it can be concluded that SICROA clearly outperforms current techniques, AODV and DSR.  Packet delivery rates, node survival and packet delivery ratio are all better for SICROA. The reason behind this stems from the transmitting node always continuing to find new paths until the one of its packets has been delivered. This increases node speed and number of connections which all aid the speeding up for packet delivery, whilst avoiding the disconnection of paths to the destination node.  All this reduces link damage and increases the stability of the system.

Conclusions

To summarise, the proposed SICROA algorithm surpasses both AODV and DSR in general performance in all ways that were tested. Route finding avoiding collision and node drop out was reduced and the quality of node links was ensured and maintained.

The Swarm intelligence inspiration plays a significant part in the route finding, collision avoidance and has aided the success of this algorithm in difficult environments. Moreover, the implementation of a SI inspired (pheromone inspired) interrupt message which can pass link quality and strength information improves the routing performance. Reiterating this process in short, when a packet is passed onto a node with high energy level, the node can deny that signal, or not continue it, as that connection can be considered an unstable link. However, when the energy level is received by the packet is low, the connection is deemed stable. This was inspired from the pheromone in the ant, as when the ant meets a strong pheromone area it knows to follow it. In our example, this would be the interpret feedback signal providing data about a node’s connection and link to the destination. This algorithm goes beyond what AODV and DSR can achieve as packet loss is reduced, route robustness is increased, and the latency of transmission is lower. These factors are all improvements from the existing techniques. SICROA enforces an efficient use of energy by each node, increasing the networks overall lifespan, it also allows adaptation to variations in the network environment.

Finally, if SICROA was to be used in communication networks in the real world the simulation would predict a good improvement in performance of these systems. Systems such as small-scale home Wi-Fi networks are a small example of where we could speed up pack transmission, however, the SICROA system will be mostly built for larger more complex networks such as mobile WSNs.

The below video represents a demonstration coded by myself of the SICROA style algorithm.

In this Video each box has a different role and each different role is defined by a colour

  • Red – Source node
  • Pink – Intermediate node
  • Blue – Destination node
  • White – Data packets

To begin, with the source block releases several packets into the environment and they travel with random velocity around the arena, until they hit either the intermediate nodes or the destination node.

When a packet hits an intermediate node it claims the node for its route to the destination. which means if the other packet comes along and hits the node an error message will be sent saying ‘node x overload – sending incoming packet back to source’. This message simulates the algorithm proposed by the paper explained in the blog above, and means nodes wont be overloaded with data. Overall, meaning a smoother running system.

After a packet has collided and claimed a node it then changes velocity randomly until it collides with the destination node. From where it is moved back to the source block and it resent but this time along the route it has found using the intermediate block and the destination block location.

Again this demo shows an implementation of a swarm intelligence feature with regards to the information that is being passed between agents in the swarm.

Obviously, with this video, only 2 packets and 2 intermediate nodes are represented, however, the architecture is sufficient that the code can be added to increase both of these features. Unfortunately, with my current knowledge of programming adding more levels of complexity would be hard without further teaching, which this module did not provide.

The video below was a big inspiration on my demo and taught me the basics of how to use the ‘pygame’ libraries.

References:

Shim, C., Lee, M., 2020. Swarm-Intelligence-Centric Routing Algorithm for Wireless Sensor Networks. PMC. https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7570729/

Clear Code, 2021. Python / Pygame tutorial: Collisions between static and moving objects. [online] Available at: <https://www.youtube.com/watch?v=1_H7InPMjaY> [Accessed 25 March 2021].

Rath, M., Darwish, A., Pati, B., Pattanayak, B.K., Panigrahi, C.R., 2020. Swarm intelligence as a solution for technological problems associated with Internet of Things. ISBN,https://www.sciencedirect.com/science/article/pii/B978012818287100005X

The code for the applet is given as follows:

import pygame, sys
from random import randint

def bouncingObj():

global speedPacket1X, speedPacket1Y, packet1, packet2, node1assignment, node2assignment, packet1destroute, speedPacket2X, speedPacket2Y, packet2destroute

int(node1assignment)
int(node2assignment)
int(packet1destroute)
int(packet2destroute)

packet1.x += speedPacket1X
packet1.y += speedPacket1Y
packet2.x += speedPacket2X
packet2.y += speedPacket2Y

collisionallowance = 10

#border collision
if packet1.right >= screenWidth or packet1.left <= 0:
    speedPacket1X *= -1
if packet1.bottom >= screenHeight or packet1.top <= 0:
    speedPacket1Y *= -1

if packet2.right >= screenWidth or packet2.left <= 0:
    speedPacket2X *= -1
if packet2.bottom >= screenHeight or packet2.top <= 0:
    speedPacket2Y *= -1

#packet 1 collision with node1
if packet1.colliderect(node1):
    if node1assignment != 2:
        node1assignment = 1
    print("node 2 assignemnt = ", node1assignment)
    if packet1destroute == 0:
        if node1assignment == 1:
            print("packet 1 node 1 transmission")
            if abs(node1.top - packet1.bottom) < collisionallowance:
                packet1 = pygame.Rect(100,375,25,25)
                speedPacket1X = randint(-5,4)
                speedPacket1Y = randint(-5,4)
            if abs(node1.bottom - packet1.top) < collisionallowance:
                packet1 = pygame.Rect(100,375,25,25)
                speedPacket1X = randint(-5,4)
                speedPacket1Y = randint(-5,4)
            if abs(node1.right - packet1.left) < collisionallowance:
                packet1 = pygame.Rect(100,375,25,25)
                speedPacket1X = randint(-5,4)
                speedPacket1Y = randint(-5,4)
            if abs(node1.left - packet1.right) < collisionallowance:
                packet1 = pygame.Rect(100,375,25,25)
                speedPacket1X = randint(-5,4)
                speedPacket1Y = randint(-5,4)
        if node1assignment == 2:
            print("node 1 overload - packet 1 Send back interupt message")
            if abs(node1.top - packet1.bottom) < collisionallowance:
                packet1 = pygame.Rect(150,430,25,25)
                speedPacket1X = 2
                speedPacket1Y = 2
            if abs(node1.bottom - packet1.top) < collisionallowance:
                packet1 = pygame.Rect(150,430,25,25)
                speedPacket1X = 2
                speedPacket1Y = 2
            if abs(node1.right - packet1.left) < collisionallowance:
                packet1 = pygame.Rect(150,430,25,25)
                speedPacket1X = 2
                speedPacket1Y = 2
            if abs(node1.left - packet1.right) < collisionallowance:
                packet1 = pygame.Rect(150,430,25,25)
                speedPacket1X = 2
                speedPacket1Y = 2
    if packet1destroute == 1:
        if abs(node1.top - packet1.bottom) < collisionallowance:
            packet1 = pygame.Rect(100,375,25,25)
            speedPacket1X = 2
            speedPacket1Y = -2
        if abs(node1.bottom - packet1.top) < collisionallowance:
            packet1 = pygame.Rect(100,375,25,25)
            speedPacket1X = 2
            speedPacket1Y = -2
        if abs(node1.right - packet1.left) < collisionallowance:
            packet1 = pygame.Rect(100,375,25,25)
            speedPacket1X = 2
            speedPacket1Y = -2
        if abs(node1.left - packet1.right) < collisionallowance:
            packet1 = pygame.Rect(100,375,25,25)
            speedPacket1X = 2
            speedPacket1Y = -2

#packet2 collision with node1
if packet2.colliderect(node1):
    if node1assignment != 1:
        node1assignment = 2
    print("node 1 assignemnt = ", node1assignment)
    if packet2destroute == 0:
        if node1assignment == 2:
            print("packet 2 node 1 transmission")
            if abs(node1.top - packet2.bottom) < collisionallowance:
                packet2 = pygame.Rect(100,375,25,25)
                speedPacket2X = randint(-5,4)
                speedPacket2Y = randint(-5,4)
            if abs(node1.bottom - packet2.top) < collisionallowance:
                packet2 = pygame.Rect(100,375,25,25)
                speedPacket2X = randint(-5,4)
                speedPacket2Y = randint(-5,4)
            if abs(node1.right - packet2.left) < collisionallowance:
                packet2 = pygame.Rect(100,375,25,25)
                speedPacket2X = randint(-5,4)
                speedPacket2Y = randint(-5,4)
            if abs(node1.left - packet2.right) < collisionallowance:
                packet2 = pygame.Rect(100,375,25,25)
                speedPacket2X = randint(-5,4)
                speedPacket2Y = randint(-5,4)
        if node1assignment == 1:
            print("node 1 overload - packet 2 Send back interupt message")
            if abs(node1.top - packet2.bottom) < collisionallowance:
                packet2 = pygame.Rect(150,430,25,25)
                speedPacket2X = 2
                speedPacket2Y = 2
            if abs(node1.bottom - packet2.top) < collisionallowance:
                packet2 = pygame.Rect(150,430,25,25)
                speedPacket2X = 2
                speedPacket2Y = 2
            if abs(node1.right - packet2.left) < collisionallowance:
                packet2 = pygame.Rect(150,430,25,25)
                speedPacket2X = 2
                speedPacket2Y = 2
            if abs(node1.left - packet2.right) < collisionallowance:
                packet2 = pygame.Rect(150,430,25,25)
                speedPacket2X = 2
                speedPacket2Y = 2
    if packet2destroute == 1:
        if abs(node1.top - packet2.bottom) < collisionallowance:
            packet2 = pygame.Rect(100,375,25,25)
            speedPacket2X = 4
            speedPacket2Y = -4
        if abs(node1.bottom - packet2.top) < collisionallowance:
            packet2 = pygame.Rect(100,375,25,25)
            speedPacket2X = 4
            speedPacket2Y = -4
        if abs(node1.right - packet2.left) < collisionallowance:
            packet2 = pygame.Rect(100,375,25,25)
            speedPacket2X = 4
            speedPacket2Y = -4
        if abs(node1.left - packet2.right) < collisionallowance:
            packet2 = pygame.Rect(100,375,25,25)
            speedPacket2X = 4
            speedPacket2Y = -4

#packet 1 collision with node2
if packet1.colliderect(node2):
    if node2assignment != 2:
        node2assignment = 1
    print("node 2 assignemnt = ", node2assignment)
    if packet1destroute == 0:
        if node2assignment == 1:
            print("packet 1 node 2 transmission")
            if abs(node2.top - packet1.bottom) < collisionallowance:
                packet1 = pygame.Rect(700,375,25,25)
                speedPacket1X = randint(-5,4)
                speedPacket1Y = randint(-5,4)
            if abs(node2.bottom - packet1.top) < collisionallowance:
                packet1 = pygame.Rect(700,375,25,25)
                speedPacket1X = randint(-5,4)
                speedPacket1Y = randint(-5,4)
            if abs(node2.right - packet1.left) < collisionallowance:
                packet1 = pygame.Rect(700,375,25,25)
                speedPacket1X = randint(-5,4)
                speedPacket1Y = randint(-5,4)
            if abs(node2.left - packet1.right) < collisionallowance:
                packet1 = pygame.Rect(700,375,25,25)
                speedPacket1X = randint(-5,4)
                speedPacket1Y = randint(-5,4)
        if node2assignment == 2:
            print("node 2 overload - packet 1 Send back interupt message")
            if abs(node2.top - packet1.bottom) < collisionallowance:
                packet1 = pygame.Rect(650,430,25,25)
                speedPacket1X = -2
                speedPacket1Y = 2
            if abs(node2.bottom - packet1.top) < collisionallowance:
                packet1 = pygame.Rect(650,430,25,25)
                speedPacket1X = -2
                speedPacket1Y = 2
            if abs(node2.right - packet1.left) < collisionallowance:
                packet1 = pygame.Rect(650,430,25,25)
                speedPacket1X = -2
                speedPacket1Y = 2
            if abs(node2.left - packet1.right) < collisionallowance:
                packet1 = pygame.Rect(650,430,25,25)
                speedPacket1X = -2
                speedPacket1Y = 2
    if packet1destroute == 1:
        if abs(node2.top - packet1.bottom) < collisionallowance:
            packet1 = pygame.Rect(700,375,25,25)
            speedPacket1X = -2
            speedPacket1Y = -2
        if abs(node2.bottom - packet1.top) < collisionallowance:
            packet1 = pygame.Rect(700,375,25,25)
            speedPacket1X = -2
            speedPacket1Y = -2
        if abs(node2.right - packet1.left) < collisionallowance:
            packet1 = pygame.Rect(700,375,25,25)
            speedPacket1X = -2
            speedPacket1Y = -2
        if abs(node2.left - packet1.right) < collisionallowance:
            packet1 = pygame.Rect(700,375,25,25)
            speedPacket1X = -2
            speedPacket1Y = -2

#packet 2 collision with node2
if packet2.colliderect(node2):
    if node2assignment != 1:
        node2assignment = 2
    print("node 2 assignemnt = ", node2assignment)
    if packet1destroute == 0:
        if node2assignment == 2:
            print(" packet 2 - node 2 transmission")
            if abs(node2.top - packet2.bottom) < collisionallowance:
                packet2 = pygame.Rect(700,375,25,25)
                speedPacket2X = randint(-5,4)
                speedPacket2Y = randint(-5,4)
            if abs(node2.bottom - packet2.top) < collisionallowance:
                packet2 = pygame.Rect(700,375,25,25)
                speedPacket2X = randint(-5,4)
                speedPacket2Y = randint(-5,4)
            if abs(node2.right - packet2.left) < collisionallowance:
                packet2 = pygame.Rect(700,375,25,25)
                speedPacket2X = randint(-5,4)
                speedPacket2Y = randint(-5,4)
            if abs(node2.left - packet2.right) < collisionallowance:
                packet2 = pygame.Rect(700,375,25,25)
                speedPacket2X = randint(-5,4)
                speedPacket2Y = randint(-5,4)
        if node2assignment == 1:
            print("node 2 overload - packect 2 Send back interupt message")
            if abs(node2.top - packet2.bottom) < collisionallowance:
                packet2 = pygame.Rect(650,430,25,25)
                speedPacket2X = -2
                speedPacket2Y = 2
            if abs(node2.bottom - packet2.top) < collisionallowance:
                packet1 = pygame.Rect(650,430,25,25)
                speedPacket2X = -2
                speedPacket2Y = 2
            if abs(node2.right - packet2.left) < collisionallowance:
                packet2 = pygame.Rect(650,430,25,25)
                speedPacket2X = -2
                speedPacket2Y = 2
            if abs(node2.left - packet2.right) < collisionallowance:
                packet2 = pygame.Rect(650,430,25,25)
                speedPacket2X = -2
                speedPacket2Y = 2
    if packet2destroute == 1:
        if abs(node2.top - packet2.bottom) < collisionallowance:
            packet2 = pygame.Rect(700,375,25,25)
            speedPacket2X = -2
            speedPacket2Y = -2
        if abs(node2.bottom - packet2.top) < collisionallowance:
            packet2 = pygame.Rect(700,375,25,25)
            speedPacket2X = -2
            speedPacket2Y = -2
        if abs(node2.right - packet2.left) < collisionallowance:
            packet2 = pygame.Rect(700,375,25,25)
            speedPacket2X = -2
            speedPacket2Y = -2
        if abs(node2.left - packet2.right) < collisionallowance:
            packet2 = pygame.Rect(700,375,25,25)
            speedPacket2X = -2
            speedPacket2Y = -2


#packet 1 collision with Destination block
if packet1.colliderect(destNode):
    print("packet 1 transfer complete")
    if abs(destNode.top - packet1.bottom) < collisionallowance:
        packet1 = pygame.Rect(400,700,25,25)
        if node1assignment == 1:
            packet1destroute = 1
            speedPacket1X = -4
            speedPacket1Y = -4
        elif node2assignment == 1:
            packet1destroute = 1
            speedPacket1X = 4
            speedPacket1Y = -4
        else:
            speedPacket1X = randint(-5,4)
            speedPacket1Y = randint(-5,4)

    if abs(destNode.bottom - packet1.top) < collisionallowance:
        packet1 = pygame.Rect(400,700,25,25)
        if node1assignment == 1:
            packet1destroute = 1
            speedPacket1X = -4
            speedPacket1Y = -4           
        elif node2assignment == 1:
            packet1destroute = 1
            speedPacket1X = 4
            speedPacket1Y = -4
        else:
            speedPacket1X = randint(-5,4)
            speedPacket1Y = randint(-5,4)

    if abs(destNode.right - packet1.left) < collisionallowance:
        packet1 = pygame.Rect(400,700,25,25)
        if node1assignment == 1:
            packet1destroute = 1
            speedPacket1X = -4
            speedPacket1Y = -4
        elif node2assignment == 2:
            packet1destroute = 1
            speedPacket1X = 4
            speedPacket1Y = -4
        else:
            speedPacket1X = randint(-5,4)
            speedPacket1Y = randint(-5,4)

    if abs(destNode.left - packet1.right) < collisionallowance:
        packet1 = pygame.Rect(400,700,25,25)
        if node1assignment == 1:
            packet1destroute = 1
            speedPacket1X = -4
            speedPacket1Y = -4
        elif node2assignment == 2:
            packet1destroute = 1
            speedPacket1X = 4
            speedPacket1Y = -4
        else:
            speedPacket1X = randint(-5,4)
            speedPacket1Y = randint(-5,4)

#packet 2 collision with Destination block
if packet2.colliderect(destNode):
    print("packet 2 transfer complete")
    if abs(destNode.top - packet2.bottom) < collisionallowance:
        packet2 = pygame.Rect(400,700,25,25)
        if node1assignment == 2:
            packet2destroute = 1
            speedPacket2X = -4
            speedPacket2Y = -4
        elif node2assignment == 2:
            packet2destroute = 1
            speedPacket2X = 4
            speedPacket2Y = -4
        else:
            speedPacket2X = randint(-5,4)
            speedPacket2Y = randint(-5,4)

    if abs(destNode.bottom - packet2.top) < collisionallowance:
        packet2 = pygame.Rect(400,700,25,25)
        if node1assignment == 2:
            packet2destroute = 1
            speedPacket2X = -4
            speedPacket2Y = -4           
        elif node2assignment == 2:
            packet2destroute = 1
            speedPacket2X = 4
            speedPacket2Y = -4
        else:
            speedPacket2X = randint(-5,4)
            speedPacket2Y = randint(-5,4)

    if abs(destNode.right - packet2.left) < collisionallowance:
        packet2 = pygame.Rect(400,700,25,25)
        if node1assignment == 2:
            packet2destroute = 1
            speedPacket2X = -4
            speedPacket2Y = -4
        elif node2assignment == 2:
            packet2destroute = 1
            speedPacket2X = 4
            speedPacket2Y = -4
        else:
            speedPacket2X = randint(-5,4)
            speedPacket2Y = randint(-5,4)

    if abs(destNode.left - packet2.right) < collisionallowance:
        packet2 = pygame.Rect(400,700,25,25)
        if node1assignment == 2:
            packet2destroute = 1
            speedPacket2X = -4
            speedPacket2Y = -4
        elif node2assignment == 2:
            packet2destroute = 1
            speedPacket2X = 4
            speedPacket2Y = -4
        else:
            speedPacket2X = randint(-5,4)
            speedPacket2Y = randint(-5,4)


pygame.draw.rect(screen, (255,255,255),packet1)
pygame.draw.rect(screen, (255,255,255),packet2)
pygame.draw.rect(screen, (255,0,0),sourceNode)
pygame.draw.rect(screen, (0,0,255),destNode)
pygame.draw.rect(screen, (255,0,255),node1)
pygame.draw.rect(screen, (255,0,255),node2)

pygame.init()

clock = pygame.time.Clock()

screenWidth = 800
screenHeight = 800

screen = pygame.display.set_mode((screenWidth, screenHeight))

packet1 = pygame.Rect(400,700,25,25)
speedPacket1X = randint(-5,4)
speedPacket1Y = randint(-5,4)

sourceNode = pygame.Rect(400,700,50,50)
destNode = pygame.Rect(400,50,50,50)
node1 = pygame.Rect(100,400,50,50)
node2 = pygame.Rect(700,400,50,50)

node1assignment = 0
node2assignment = 0
packet1destroute = 0
packet2destroute = 0

packet2 = pygame.Rect(400,700,25,25)
speedPacket2X = randint(-5,4)
speedPacket2Y = randint(-5,4)

while True:
for event in pygame.event.get():
if event.type ==pygame.QUIT:
pygame.quit()
sys.exit()

screen.fill((30,30,30))
bouncingObj()
pygame.display.flip()
clock.tick(60)
if (speedPacket1X == 0):
    speedPacket1X += 1
if (speedPacket1Y == 0):
    speedPacket1Y += 1
if (speedPacket2X == 0):
    speedPacket2X += 1
if (speedPacket2Y == 0):
    speedPacket2Y += 1