martes, 21 de mayo de 2013

Tarea 7: Simuación de movilidad

Para esta tarea se nos pide realizar un código documentado en donde implementemos una simulación de una MANET que cumpla con las siguientes características.

  • Llegadas y salidas de nodos con una distribución exponencial, procesos poisson.
  • Un modelo de movilidad
  • Nodos con capacidad de batería inicial
  • Envío de mensajes consume batería según el radio de transmisión
  • El radio es ajustable en cada nodo
  • Se utiliza una inundación con un TTL adaptable.

Por lo que realicé un código en python, utilizando pygame, y numeros random con la librería estandar de python y de numpy, para poder realizar esta simulación.

Primero que nada declaro variables generales, de esta manera, podemos tener el largo y ancho de la ventana, esto es importante para obtener los limites de la imagen, los cuales van a estar rebotando durante toda la pantalla, en las muestras de simulación declaro una población de 100 nodos que van entrado por procesos poisson, estoy verificando el tiempo cada corrida y estos en su vez tienen su propio tiempo que si entran dentro de los parámetros aparecen en la simulación.

El campo de visión de cada nodo es parametrizado de manera inicial, este puede ser modificado durante el transcurso de la simulación, al igual que el TTL, el cual crea conexiones con los nodos vecinos que se encuentran a su alrededor,

El TTL se puede cambiar según su propagación hacia atrás, pero esto afecta considerablemente su rendimiento ya que cada nodo tiene una batería y al momento de tener más TTL, estas conexiones pierden la batería y se quedan sin poder propagar la información por inundación.

El movimiento que desarrollé fue el agregar velocidad de manera exponencial y cambiar sus ángulos con un aleatorio con distribución uniforme, y luego de esta manera genera pequeños vectores y de esta manera hace buenos movimientos y creo que es apropiado para este tipo de simulación.

El TTL es una función recursiva que hace la propagación según cada distancia junto con todos los nodos y vamos comparando para obtener las que se encuentran en el rango de recepción, por lo que cambiamos sus estados y estos a su vez, van hacia atrás para obtener un mayor rango de información según su TTL.

En esta simulación podemos suponer que el enemigo es un helicóptero que esta en un campo tratando de mandar bombas en un campo de batalla, entonces, los soldados tienen radios que mandan información cuando uno de estos ve que en su campo de visión se encuentra el helicóptero, se quedan quietos y envían a los demás.

Código
import pygame
import random
import math
import numpy
import time
#Simulacion de manet
#Variables generales
(largo, ancho) = (600, 400)
pantalla = pygame.display.set_mode((largo, ancho))
pygame.display.set_caption('Simulacion Redes')
Numero_Nodos = 100
Nodos = []
nivel_ttl = 1
radio_ttl = 100.0
campo_vision = 30.0
#Clase nodo la cual crea los circulos y tiene propiedades individuales
#Cada nodo se posiciona en un x, y, tienen tamanos diferentes, su propio estado, una ID, al igual que un tiempo de vida inicial y final
class Nodo:
#Atributos de objeto
def __init__(self, (x,y), tam, estado, ID, inicio, final):
self.x = x
self.y = y
self.tam = tam
self.estado = estado
self.cont = 5
self.vel = 0
self.ang = 0
self.bateria = 100.0
self.ID = ID
self.mov = "+"
self.inicio = inicio
self.final = final
#Funcion para mostrar dicho objeto en pantalla
def mostrar(self):
pygame.draw.circle(pantalla, self.estado, (int(self.x), int(self.y)), self.tam, self.cont)
#Funcion la cual crea una simulacion de aceleracion y velocidad para mover el nodo
#Crea vectores pequenos para hacer sus movimientos
def mover(self):
while True:
ang = numpy.random.exponential()
if ang <= math.pi:
break
else:
pass
(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
#Crea un espacio limite entre el ancho y largo de la imagen para hacer el estilo de rebote entre los nodos
def limites(self):
if self.x > largo - self.tam:
self.x = 2*(largo - self.tam) - self.x
self.ang = - self.ang
elif self.x < self.tam:
self.x = 2*self.tam - self.x
self.ang = - self.ang
if self.y > ancho - self.tam:
self.y = 2*(ancho - self.tam) - self.y
self.ang = math.pi - self.ang
elif self.y < self.tam:
self.y = 2*self.tam - self.y
self.ang = math.pi - self.ang
#Funcion que crea pequenos vectores segun valores dados
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)
#La funcion TTL se llama de manera recursiva segun el nivel ttl que queramos para hacer una propagacion por inundacion
def TTL(particula, nivel, tiempo):
if nivel == nivel_ttl: return
if particula.inicio <= tiempo <= particula.final:
for particula2 in Nodos:
x1 = particula.x
y1 = particula.y
x2 = particula2.x
y2 = particula2.y
dist = math.hypot(x1-x2, y1-y2)
#checamos la distancia de cada nodo
if dist <= radio_ttl and particula2.ID != "ENEMIGO" and particula.ID != "ENEMIGO" and particula2.inicio <= tiempo <= particula2.final:
cmp = particula2.bateria - dist
if 0.0 <= cmp <= 100.0:
particula2.estado = (0, 0, 255)
particula2.mov = "-"
particula2.bateria = particula2.bateria - dist
pygame.draw.line(pantalla, (255, 255, 255), (x1, y1), (x2, y2))
TTL(particula2, nivel+1, tiempo)
else:
#print "Se acabo la pila "
pass
#Funcion que crea toda la poblacion de la simulacion
def creaPoblacion():
for n in range(Numero_Nodos):
tam = 10
x = random.randint(tam, largo-tam)
y = random.randint(tam, ancho-tam)
estado = (0, 255, 0)
Persona = Nodo((x, y), tam, estado, n, numpy.random.poisson(10), numpy.random.poisson(40))
Persona.vel = numpy.random.poisson(5)*.01
while True:
ang = numpy.random.exponential()
if ang <= math.pi:
Persona.ang = ang
break
else:
pass
Nodos.append(Persona)
Enemigo = Nodo((0, 0), 20, (255,0,0), "ENEMIGO", 0.0, 60.0)
Enemigo.vel = numpy.random.poisson(5)*.01
Enemigo.ang = 0.1
Nodos.append(Enemigo)
return Nodos
#Funcion principal que hace que la simulacion se vea en pygame y carga todos los objetos de crea poblacion.
def main():
inicio = time.time()
Nodos = creaPoblacion()
ventana = True
while ventana:
for evento in pygame.event.get():
if evento.type == pygame.QUIT:
ventana = False
pantalla.fill((0,0,0))
for i, particula in enumerate(Nodos):
final = time.time()
tiempo = final - inicio
if particula.inicio <= tiempo <= particula.final:
if particula.mov != "-":
particula.mover()
particula.limites()
for particula2 in Nodos:
x1 = particula.x
y1 = particula.y
x2 = particula2.x
y2 = particula2.y
dist = math.hypot(x1-x2, y1-y2)
if particula.ID == "ENEMIGO" and dist <= campo_vision and particula2.ID != "ENEMIGO" and particula.inicio <= tiempo <= particula.final: #Vista enemigo
particula2.estado = (0, 0, 255)
particula2.mov = "-"
TTL(particula2, 0, tiempo)
particula.mostrar()
pygame.display.flip()
main()
view raw manet.py hosted with ❤ by GitHub


Video de muestras


Referencias
Peter's Website, Project pygame physics simulation, Peter Colling, extraido de http://www.petercollingridge.co.uk/
Redes ad hoc, Redes de telecomunicaciones, Elisa Schaeffer, extraido de http://elisa.dyndns-web.com/~elisa/

1 comentario: