Social Icons

twitterfacebookgoogle plusemail

lunes, 6 de mayo de 2013

Tarea 6 : Geolocalización usando triangulación

En esta entrada hablaremos sobre geolocalización por medio de triangulación, la triangulación es una técnica utilizada para poder determinar la posición de un nodo, a partir de la fuerza de señal de tres nodos transmisores. A continuación vemos una imagen de como funciona la triangulación.


Se realizó un simulador en la cual crea tres puntos que actúan como transmisores y un cuarto punto que es como el nodo a localizar. Se tienen estos valores de entrada:


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.



El tercero de ellos es colocando un margen de error en los transmisores muy bajo y en el receptor colocando un margen muy alto.



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:
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

1 comentarios:

  1. Interesante combinación de técnicas de visión para evitar resolver ecuaciones :) 10 pts.

    ResponderEliminar