martes, 21 de mayo de 2013

Redes ad hoc

Para mi programa realice lo siguiente:

Se crean nodos con la clase Nodo que tiene los siguientes atributos:
  • posición x
  • posición y
  • batería (parámetro ajustable)
  • estado TTL (parámetro ajustable)
  • color
  • velocidad
  • radio (alcance) (parámetro ajustable)
  • radio (dibujo)
  • nodo_padre (es necesario para poder ir ajustando el TTL)
  • nodo_hijo
Los nodos introduciendo según tiempo generado con la formula poisson  así se tienen llegadas exponenciales.
Después de un tiempo los mensajes se comienzan a transmitir por INUNDACIÓN lo que va pintando cada circulo de color BLANCO, se da un valor a los padres e hijos de los nodos de acuerdo al nodo que pinta a su circunferencia, es decir el nodo que esta en x y y pinta a todos los demás que están en su ZONA de ALCANCE entonces se dice que este es el padre de los que acaba de pintar y a los hijos se va reduciendo el valor para el TTL, así al llegar a 0 deja de transmitir.

El enemigo esta representado con un circulo color rojo y con un radio mayor a los demás, la manera en que los nodos se protegen del enemigo es durmiendo, es decir el nodo se pone en GRIS y disminuye su movimiento.

La manera en que se adapta es contando los nodos que no se han conectado y aumentando el radio de alcance de los que si están comunicados.

En mi ejemplo utilice un TTL de 10 y otro de 3 para que se vea la diferencia, en el de 10 se alcanzan a salvar casi todos los nodos pintandose de gris y protegiendose del enemigo y en el de 3 muchos se quedan activos propensos del enemigo.
Aunque tiene algunas funciones que ayudan a adaptarse aun quedan nodos incomunicados esto debido al bajo valor del TTL.

Los nodos mueren cuando se cumple su ciclo de vida, o cuando se termina su batería la cual se gasta de acuerdo a los mensajes que ya se envió es una función lineal.

#!/usr/bin/python
#Autor
#Sandra Cecilia Urbina Coronado
#----------------------------------------------------------
import pygame
from pygame.locals import *
import random, math, sys
import time
import random
import numpy
import threading
# ==================================================
# -------- CONSTANTES ---------
PARTICULAS_DEFAULT = 100
PROPORCION_DEFAULT = 20
NODOS = list()
BLANCOS = list()
# --------- PANTALLA ----------
PANTALLA = {
'ANCHO': 800,
'ALTO': 600,
'RESOLUCION': (800, 600),
'FPS': 30
}
# --------- COLORES ----------
COLORES = {
'NEGRO': (0,0,0),
'BLANCO': (255,255,255)
}
# --------- PYGAME ----------
pygame.init()
fpsClock = pygame.time.Clock()
VENTANA = pygame.display.set_mode(PANTALLA['RESOLUCION'])
pygame.display.set_caption('simulacion')
# ==================================================
def creaVector((ang1, len1), (ang2, len2)):
x = math.sin(ang1) * len1 + math.sin(ang2) * len2
y = math.cos(ang1) * len1 + math.cos(ang2) * len2
len = math.hypot(x, y)
ang = 0.5 * math.pi - math.atan2(y, x)
return (ang, len)
def exp(lamb):
return (-1*math.log(random.random( ))/lamb)
class Nodo:
def __init__(self, ID, radio, color):
self.id = ID
self.x = random.randint(10,PANTALLA['ANCHO'])
self.y = random.randint(10,PANTALLA['ALTO'])
self.radio = radio
self.color = color
self.ang = 0
self.vel = 0
self.bateria = 120
self.ttl = 3
self.visitado = False
self.papa = None
self.hijo = None
self.tiempo = time.time()
self.mueves = True
def mueve(self):
"""obtiene las nuevas posiciones
"""
global NODOS
(self.ang, self.vel) = creaVector((self.ang, self.vel), (random.uniform(0,math.pi*2), numpy.random.poisson(4)*.01))
self.x += math.sin(self.ang) * self.vel
self.y -= math.cos(self.ang) * self.vel
self.bounce()
self.dibuja()
def dibuja(self):
"""actualiza el canvas
"""
global VENTANA, COLORES
pygame.draw.circle(VENTANA, self.color, (int(self.x), int(PANTALLA['ALTO'] - self.y)), int(round(self.radio)))
def bounce(self):
"""para que no se salgan de la pantalla
"""
largo = 800
ancho = 600
if self.x > largo - self.radio:
self.x = 2*(largo - self.radio) - self.x
self.ang = - self.ang
elif self.x < self.radio:
self.x = 2*self.radio - self.x
self.ang = - self.ang
if self.y > ancho - self.radio:
self.y = 2*(ancho - self.radio) - self.y
self.ang = math.pi - self.ang
elif self.y < self.radio:
self.y = 2*self.radio - self.y
self.ang = math.pi - self.ang
def getInput():
"""para terminar la animacion adecuadamente
"""
presiona = pygame.key.get_pressed()
for event in pygame.event.get():
if event.type == QUIT or presiona[K_ESCAPE]:
pygame.quit()
sys.exit()
class agrega(threading.Thread):
"""agrega el numero de nodos indicado
"""
def __init__(self):
threading.Thread.__init__(self)
self.id = 0
def run(self):
while True:
global NODOS
if self.id > PARTICULAS_DEFAULT:
color = (255, 0, 0)
radio = 30
nodo = Nodo(self.id, radio,color)
NODOS.append(nodo)
print 'enemigo %d' %nodo.id
break
color = (random.randint(100,200), random.randint(100,200), random.randint(100,200))
radio = 20
nodo = Nodo(self.id, radio,color)
NODOS.append(nodo)
print 'Se creo el nodo %d' %nodo.id
time.sleep(exp(5))
self.id += 1
class mueve(threading.Thread):
"""mueve todos los nodos que estan en la pantalla
"""
def __init__(self):
threading.Thread.__init__(self)
def run(self):
global VENTANA
global NODOS
while True:
VENTANA.fill(COLORES['NEGRO'])
for p in NODOS:
getInput()
if p.mueves:
p.mueve()
pygame.display.update()
class elimina(threading.Thread):
"""elimina los nodos
ya sea por bateria o por tiempo cumplido
"""
def __init__(self):
threading.Thread.__init__(self)
def run(self):
global PARTICULAS_DEFAULT, NODOS
while True:
for i in NODOS:
if (time.time() - i.tiempo)>30:
i.mueves = False
print "Nodo %s muere" %i.id
class avisa(threading.Thread):
"""manda mensajes a sus nodos dentro
del rando de su senal
"""
def __init__(self, elegido):
threading.Thread.__init__(self)
self.ele = elegido
def run(self):
global NODOS, BLANCOS
print self.ele.id
lock = threading.Lock()
global VENTANA
v = True
while True:
for i in range(len(NODOS)):
if (NODOS[i].id in BLANCOS) == False:
x = self.ele.x
y = self.ele.y
x2 = NODOS[i].x
y2 = NODOS[i].y
dist = math.hypot(x-x2, y-y2)
if dist <= self.ele.radio+100 and NODOS[i].radio != 30:
BLANCOS.append(NODOS[i].id)
pygame.draw.line(VENTANA, (255, 255, 255), (x, y), (x2, y2))
NODOS[i].ttl = self.ele.ttl - 1
NODOS[i].bateria -= NODOS[i].bateria - 40
if NODOS[i].bateria >= 0:
"El nodo %s tiene una bateria de %s" %(NODOS[i].id, NODOS[i].bateria)
if NODOS[i].ttl == 0:
print "El nodo %s ya deja de transmitir" %NODOS[i].id
break
NODOS[i].color =(255,255,255)
NODOS[i].papa = self.ele
self.ele.hijo = NODOS[i]
j = avisa(NODOS[i])
j.start()
elif NODOS[i].radio == 30:
if v:
print "Ya se vio al ENEMIGO!!"
v = False
for s in NODOS:
if s.id in BLANCOS:
s.color = (100,100,100)
if len(BLANCOS) == len(NODOS):
for n in NODOS:
n.mueves = False
else:
pass
def main():
cantidadNodos = PARTICULAS_DEFAULT
proporcion = PROPORCION_DEFAULT
print 'Se dibujaran [%d] nodos' % cantidadNodos
t = agrega()
t.start()
x = mueve()
x.start()
time.sleep(5)
pos = random.randint(0, len(NODOS)-1)
NODOS[pos].color = (255,255,255)
s = avisa(NODOS[pos])
s.start()
e = elimina()
e.start()
if __name__ == '__main__':
main()
view raw gistfile1.py hosted with ❤ by GitHub



VIDEOS:

TTL 10



TTL 3



En el de 10 se alcanzan a salvar casi todos los nodos pintandose de gris y protegiendose del enemigo y en el de 3 muchos se quedan activos propensos del enemigo, también se observa en el terminal cuando los nodos van muriendo ya sea por batería o por tiempo de vida

Por último esta es una gráfica donde se muestra los diferentes ttl con los mensajes enviados, y se comprueba lo visto en la simulación que con mayor ttl mas mensajes se envían.




Referencias

N/A

1 comentario: