viernes, 24 de mayo de 2013

Redes sensoras

Las redes sensoras son computadores muy pequeños que colaboran entre ellos y están equipados con sensores para colaborar con una tarea en común.

Yo elegí simular el control de incendios en un área montañosa, la idea funciona de la siguiente manera: Supongamos que tenemos un área muy grande de bosque en dónde es difícil acceder a ella y darse cuenta que hay algún incendio, y cuando ya nos podemos dar cuenta de ello el incendio ya esta muy avanzado y hay graves daños al ecosistema.
Lo que se busca es con ayuda de la nueva tecnología poder controlar este tipo de situaciones, para esto diseñé una pequeña simulación buscando encontrar la solución en el uso de una red sensora.

Fractal

Lo primero que se realizó es la elaboración del terreno con la ayuda de un fractal, el código es el siguiente:

class Fractal:
"""
"""
def __init__(self):
self.w = 150
self.h = 150
self.image = Image.new("L", (self.w,self.h))
self.roughness = random.randint(2,3)
def adjust(self, xa, ya, x, y, xb, yb):
if(self.image.getpixel((x,y)) == 0):
d=math.fabs(xa-xb) + math.fabs(ya-yb)
v=(self.image.getpixel((xa,ya)) + self.image.getpixel((xb,yb)))/2.0 + (random.random()-0.5) * d * self.roughness
c=int(math.fabs(v) % 256)
self.image.putpixel((x,y), c)
def subdivide(self, x1,y1,x2,y2):
if(not((x2-x1 < 2.0) and (y2-y1 < 2.0))):
x=int((x1 + x2)/2.0)
y=int((y1 + y2)/2.0)
self.adjust(x1,y1,x,y1,x2,y1)
self.adjust(x2,y1,x2,y,x2,y2)
self.adjust(x1,y2,x,y2,x2,y2)
self.adjust(x1,y1,x1,y,x1,y2)
if(self.image.getpixel((x,y)) == 0):
v=int((self.image.getpixel((x1,y1)) + self.image.getpixel((x2,y1)) + self.image.getpixel((x2,y2)) + self.image.getpixel((x1,y2)))/4.0)
self.image.putpixel((x,y),v)
self.subdivide(x1,y1,x,y)
self.subdivide(x,y1,x2,y)
self.subdivide(x,y,x2,y2)
self.subdivide(x1,y,x,y2)
view raw gistfile1.py hosted with ❤ by GitHub


Y el resultado es la siguiente imagen:



Teniendo esto podemos graficarlo en 3D con la ayuda de matplotlib y queda de la siguiente manera:
Simulación de montañas con un fractal

Redes sensoras

Se distribuyeron sensores por todo el terreno de manera aleatoria, también se decidió tener una base elegida también de manera aleatoria que es a la que deben de llegar los mensajes de incendio para poder avisar a las partes correspondientes.
El punto rojo inicial indica que hay algún incendio en alguna parte y rápidamente el sensor que este mas cercano y siempre y cuando tenga el alcance necesario empieza a distribuir todo el mensaje hasta llegar a la base.
Para esta parte se tomaron en cuenta los mismos aspectos de la entrada pasada solo que ahora se agrego la parte adaptativa, es decir si el mensaje no llega a la estación entonces se manda un mensaje para aumentar el TTL y aumentar las posibilidades de llegar a la base.
El triangulo naranja es la base.
Los nodos amarillos son los que pasan el mensaje.
Se tomó en cuenta para que se mueran los nodos la Batería, el ciclo de vida , TTL, Intensidad de señal.
Los nodos grises son los sensores muertos.
Este ejemplo tiene TTL = 10


TTL=2
Los nodos grises significan que los sensores ya no funcionan

No se llegó a la base
TTL = 5


La base es el triángulo naranja 


Código

#!/usr/bin/python
from PIL import Image
import math
import random
#from mpl_toolkits.mplot3d import axes3d
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import matplotlib.pyplot as plt
import numpy as np
import itertools
import time
import matplotlib.lines as mlines
import pylab
###################################
#Se genera el fractal creando una
#imagen con PIL
###################################
class Fractal:
"""
"""
def __init__(self):
self.w = 150
self.h = 150
self.image = Image.new("L", (self.w,self.h))
self.roughness = random.randint(2,3)
def adjust(self, xa, ya, x, y, xb, yb):
if(self.image.getpixel((x,y)) == 0):
d=math.fabs(xa-xb) + math.fabs(ya-yb)
v=(self.image.getpixel((xa,ya)) + self.image.getpixel((xb,yb)))/2.0 + (random.random()-0.5) * d * self.roughness
c=int(math.fabs(v) % 256)
self.image.putpixel((x,y), c)
def subdivide(self, x1,y1,x2,y2):
if(not((x2-x1 < 2.0) and (y2-y1 < 2.0))):
x=int((x1 + x2)/2.0)
y=int((y1 + y2)/2.0)
self.adjust(x1,y1,x,y1,x2,y1)
self.adjust(x2,y1,x2,y,x2,y2)
self.adjust(x1,y2,x,y2,x2,y2)
self.adjust(x1,y1,x1,y,x1,y2)
if(self.image.getpixel((x,y)) == 0):
v=int((self.image.getpixel((x1,y1)) + self.image.getpixel((x2,y1)) + self.image.getpixel((x2,y2)) + self.image.getpixel((x1,y2)))/4.0)
self.image.putpixel((x,y),v)
self.subdivide(x1,y1,x,y)
self.subdivide(x,y1,x2,y)
self.subdivide(x,y,x2,y2)
self.subdivide(x1,y,x,y2)
def hip(x1,x2,y1,y2,z1,z2,alcance):
"""saber si el mensaje se puede pasar
"""
d = (abs(x1-x2)**2 + abs(y1-y2)**2 + abs(z1-z2)**2)**0.5
if d < alcance:
return True
else:
return False
class Nodo():
def __init__(self):
self.x = 0
self.y = 0
self.z = 0
self.padre = None
self.hijo = None
self.ttl = 3
self.vivo = True
self.tiempo = time.time()
self.alcance = 80
self.sabe = False
self.base = False
def pasar_mensaje(self, destino):
enterado = hip(self.x,destino.x,self.y,destino.y,self.z,destino.z,self.alcance)
if enterado and destino.vivo:
destino.padre = self
self.hijo = destino
destino.ttl = self.ttl - 1
if destino.ttl > 0:
destino.vivo = True
self.sabe = True
#Nodo aun vivo y alcanzado por el mensaje"
return 1
else:
#Ya no puede enviar
return 2
else:
"Nodo no alcanzado"
return 3
def grafica(imagen):
x = []
y = []
z = []
pixeles = imagen.load()
xx, yy = imagen.size
for a in range(xx):
for b in range(yy):
x.append(a)
y.append(b)
z.append(pixeles[a,b])
colo = np.arange(len(z))
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x,y,z, s=35,c = z, cmap=cm.winter, marker='_', alpha=0.5)
plt.savefig(str(time.time())+".png")
return x, y, z, ax,fig
def sensores(x,y,z,ax):
num = 20
sensors = []
for i in range(num):
#se crea el sensor
sensor = Nodo()
sel = random.randint(0,len(x)-1)
sensor.x, sensor.y, sensor.z = x[sel],y[sel],z[sel]+20
ax.scatter(x[sel],y[sel],z[sel]+20, marker='o',c='black',s=100)
sensors.append(sensor)
sel = random.randint(0,len(x)-1)
ax.scatter(x[sel],y[sel],z[sel]+20, marker='o',c='red',s=100)
#se crea un activador
evento = Nodo()
evento.x, evento.y, evento.z = x[sel],y[sel],z[sel]+20
plt.savefig('1.png')
return sensors, evento
def main():
"""
"""
fractal = Fractal()
fractal.image.putpixel((0,0),random.randint(0, 255))
fractal.image.putpixel((fractal.w-1,0),random.randint(0, 255))
fractal.image.putpixel((fractal.w-1,fractal.h-1),random.randint(0, 255))
fractal.image.putpixel((0,fractal.h-1),random.randint(0, 255))
fractal.subdivide(0,0,fractal.w-1,fractal.h-1)
fractal.image.save("plasma.png", "PNG")
x,y,z,ax,fig = grafica(fractal.image)
sensors, evento = sensores(x,y,z,ax)
sel = random.randint(0,len(x)-1)
ax.scatter(x[sel],y[sel],z[sel]+20, marker='^',c='orange',s=300)
#se crea base
base = Nodo()
base.x, base.y, base.z = x[sel],y[sel],z[sel]+20
eventos = []
base.base = True
sensors.append(base)
eventos.append(evento)
while len(eventos)>0:
evento = eventos.pop()
for sensor in sensors:
if sensor.sabe:
continue
eleccion = evento.pasar_mensaje(sensor)
if eleccion == 1 and not sensor.sabe:
if sensor.base:
print "Mensaje llego a la base en (%s, %s, %s)" %(sensor.x, sensor.y, sensor.z)
ax.scatter(sensor.x,sensor.y-1,sensor.z, marker='^',c='orange',s=400)
plt.savefig(str(time.time())+".png")
ax.scatter(sensor.x,sensor.y-1,sensor.z, marker='^',c='orange',s=500)
plt.savefig(str(time.time())+".png")
ax.scatter(sensor.x,sensor.y-1,sensor.z, marker='^',c='orange',s=600)
plt.savefig(str(time.time())+".png")
ax.scatter(sensor.x,sensor.y-1,sensor.z, marker='^',c='orange',s=700)
plt.savefig(str(time.time())+".png")
return
else:
print "Mensaje recibido por sensor ubicado en (%s, %s, %s)" %(sensor.x, sensor.y, sensor.z)
ax.scatter(sensor.x,sensor.y-1,sensor.z, marker='o',c='yellow',s=200)
plt.savefig(str(time.time())+".png")
eventos.append(sensor)
elif eleccion == 2:
print "El nodo ubicado en (%s, %s, %s) ya no puede enviar mensajes \n no tiene bateria o su ttl = 0" %(sensor.x, sensor.y, sensor.z)
ax.scatter(sensor.x,sensor.y-1,sensor.z, marker='o',c='gray',s=200)
plt.savefig(str(time.time())+".png")
sensors.remove(sensor)
else:
pass
print "Con ttl de %s no fue posible llegar a la base" %base.ttl
plt.show()
main()
view raw gistfile1.py hosted with ❤ by GitHub


Conclusiones

Podemos ver que entre más alcance tengan los sensores es más rápido la detección del incendio, también que es conveniente que se adapte para saber cuando el TTL no llega pues ajustarlo para que sea posible llegar siempre a la base.

Referencias

Elisa Schaeffer - Redes sensoras

2 comentarios:

  1. Me hubiera gustado ver una visualización en video. 15 pts.

    ResponderEliminar
  2. Great information. This works great for me. Thanks for sharing this :)

    ResponderEliminar