Referencia:https://confluence.slac.stanford.edu/display/IEPM/TULIP+Algorithm+Alternative+Trilateration+Method
En donde los primeros dos parámetros dados son las propiedades del primer nodo ( 20 20 ) que esta tomado como porcentaje del canvas, luego pasamos a los siguientes dos que es la propiedad del segundo nodo ( 30 70 ) y esto sucede de la misma forma con el tercer nodo ( 40 90 ). El penúltimo parámetro es el margen de error que tienen los transmisores ( 8 ) con el fin de obtener una simulación más realista y el último parámetro es para determinar el margen de error del receptor ( 4 ).
A continuación veremos 3 casos que se ven en la simulación.
El primero de es colocando un margen de error en los transmisores bajo, al igual que en el receptor, como podemos ver el nodo puede ser estimado con un margen de error muy pequeño. Hay que aclarar que el margen de error del transmisor es representado por el ancho del perímetro en el que intercepta el transmisor al nodo, mientras que el margen de error del receptor es el area de color blanco en el que el receptor es estimado.
El segundo de ellos es colocando mucho margen de error en los transmisores mientras que en el receptor se coloco un margen de error muy bajo.
Viendo los 3 casos se hizo notar que es preferible tener un estimado con errores a no tener ningún estimado del receptor.
Ahora veamos el código:
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
from math import fabs | |
from PIL import ImageDraw | |
from sys import argv | |
import numpy as np | |
from Tkinter import * | |
import Image | |
import ImageTk | |
from random import randint | |
#Se obtiene la distancia euclidiana de dos puntos | |
def distancia(x1, y1, x2, y2): | |
return ((x1 - x2)**2.0 + (y1 - y2)**2.0)**0.5 | |
#Se crea red | |
def createNetwork(pos): | |
#Se crea una imagen en rgb con 500 de ancho y 500 de altura | |
image = Image.new(mode='RGB', size=(500, 500)) | |
#Se obtienen las medidas de la imagen | |
width, height = image.size | |
#El metodo load() nos permite modificar los pixeles de la imagen | |
img = image.load() | |
#X de la primera torre como porcentaje del ancho | |
rx = width * int(pos.pop(0)) / 100 | |
#Y de la primera torre como porcentaje de la altura | |
ry = height * int(pos.pop(0)) / 100 | |
#X de la segunda torre como porcentaje del ancho | |
gx = width * int(pos.pop(0)) / 100 | |
#Y de la segunda torre como porcentaje de la altura | |
gy = height * int(pos.pop(0)) / 100 | |
#X de la tercera torre como porcentaje del ancho | |
bx = width * int(pos.pop(0)) / 100 | |
#Y de la tercera torre como porcentaje de la altura | |
by = height * int(pos.pop(0)) / 100 | |
#Para efectos visuales, este valor nos permite evitar el borde de la ventana | |
evitarBorde = 20 | |
#Se genera la posicion del receptor de manera pseudoaleatorio evitando el borde | |
xp = randint(evitarBorde, width - evitarBorde) | |
yp = randint(evitarBorde, height - evitarBorde) | |
#Debug | |
print 'Generados', xp, yp | |
#Esta es la magnitud de error al estimar las distancias, para obtener una simulacion mas realista | |
maxerror = int(pos.pop(0)) | |
#En las distancias euclidianas se agrega un error aleatorio | |
rr = distancia(xp, yp, rx, ry) + randint(-maxerror, maxerror) | |
gr = distancia(xp, yp, gx, gy) + randint(-maxerror, maxerror) | |
br = distancia(xp, yp, bx, by) + randint(-maxerror, maxerror) | |
#Se medira la region blanca en la cual todos los torres estan a su distancia deseada | |
minx = width | |
maxx = 0 | |
miny = height | |
maxy = 0 | |
#Con estas dimensiones se estima la posicion | |
#Se cuentan los pixeles que pertenecen a la region blanca | |
blancos = 0 | |
#Se toma el error que el receptor espera tener en su medicion | |
margen = int(pos.pop(0)) | |
#Se calcula para cada pixel de la zona | |
for x in xrange(width): | |
for y in xrange(height): | |
(r, g, b) = (0, 0, 0) | |
#Las distancias entre las torres y ese pixel | |
dr = distancia(x, y, rx, ry) | |
dg = distancia(x, y, gx, gy) | |
db = distancia(x, y, bx, by) | |
#Para dibujar las torres se necesita saber si estamos cerca de ellas | |
cr = distancia(x, y, rx, ry) | |
cg = distancia(x, y, gx, gy) | |
cb = distancia(x, y, bx, by) | |
#Pintar con el color del torre pixeles que o estan a la distancia adecuada o muy cerca de la torre | |
if fabs(dr - rr) < margen or cr < margen: | |
r = 255 | |
if fabs(dg - gr) < margen or cg < margen: | |
g = 255 | |
if fabs(db - br) < margen or cb < margen: | |
b = 255 | |
if r == 255 and g == 255 and b == 255: | |
#Se aumenta el contador de pixeles blancos | |
blancos += 1 | |
#Se actualizan las medidas | |
if x < minx: | |
minx = x | |
if x > maxx: | |
maxx = x | |
if y < miny: | |
miny = y | |
if y > maxy: | |
maxy = y | |
#Se pinta el pixel para la visualizacion | |
img[y, x] = r, g, b | |
if blancos > 0: | |
#Si hubo por lo menos un pixel blanco, se puede estimar | |
xe = (maxx + minx) / 2 | |
ye = (maxy + miny) / 2 | |
print 'Estimados', xe, ye | |
#Se reporta la distancia entre el punto generado y el punto estimado | |
print 'Error', distancia(xp, yp, xe, ye) | |
else: | |
#Hubo mas error en las distancias medidas que pudo manejar el receptor | |
print 'No se pudo estimar' | |
#Mostrar el resultado | |
return Image.fromarray(np.array(image)) | |
def tk(imagen): | |
root = Tk() | |
width, height = imagen.size | |
canvas = Canvas(root, width=width, height=height) | |
canvas.pack(expand=YES, fill=BOTH) | |
imagen_canvas = ImageTk.PhotoImage(imagen) | |
imagen_canvas_setting = canvas.create_image((2, 2), image=imagen_canvas, anchor=NW) | |
root.mainloop() | |
return | |
def main(): | |
pos = list() | |
for a in argv: | |
pos.append(a) | |
pos.pop(0) | |
image = createNetwork(pos) | |
return tk(image) | |
main() |
Referencias:
TULIP Algorithm Alternative Trilateration Method
https://confluence.slac.stanford.edu/display/IEPM/TULIP+Algorithm+Alternative+Trilateration+Method
Interesante combinación de técnicas de visión para evitar resolver ecuaciones :) 10 pts.
ResponderEliminar