- 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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
Video de muestras
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/