Processing math: 100%

martes, 5 de marzo de 2013

Laboratorio 5. Simulación con NS-2

Para esta semana de clase, se nos pidió correr una simulación en Network Simulator ya sea en la versión 2 o 3, en mi caso utilicé la 2.

Para escribir estas simulaciones se utiliza la extensió "tcl".

La programación NS-2 basicamente tiene el siguiente procedimiento.
  1. Crear el planificador de eventos
  2. Encender el rastreo
  3. Crear red
    - Configuración de enrutamiento - rtproto
    - Crear conexión (capa de transporte) - agentes
    - Crear trafico - aplicaciones
  4. Monitoreo
    - Visualización usando nam

 Comunicación UDP


Los datos son los flujos del agente UDP al agente Nulo.
        
  #Crear un agente UDP y ponerselo al nodo 0
  set udp0 [new Agent/UDP]
  $ns attach-agent $n0 $udp0

  # Crear un agente Nulo que actue como recolector de tráfico y se lo adjunte al
  # nodo 1
  set null0 [new Agent/Null]
  $ns attach-agent $n1 $null0

  # Conectar dos agentes
  $ns connect $udp0 $null0

Comunicación TCP

Los datos son flujos del agente TCP al agente recolector TCP

# Crear agente TCP y adjuntarselo al nodo n0
set tcp0 [new Agent/TCP]
$ns attach-agent $n0 $tcp0

# Crear un agente tcpsink que actue como recolector de tráfico y se lo adjunte al  
# nodo 1
set tcpsink0 [new Agent/TCPSink]
$ns attach-agent $n1 $tcpsink0

# Conecta dos agentes
$ns connect $tcp0 $tcpsink0

Generador de tráfico


Se necesita generadores de tráfico para los datos actuales, estos simulan alguna aplicación de tráfico

Ejemplo simple utilizando CBR

# Crear agente CBR
set cbr0 [new Application/Traffic/CBR]

# Adjuntar el agente CBR a algun agente UDP/TCP
$cbr0 attach-agent $udp0

Planificar los eventos


"At" juega el rol más importante

$ns at 1.0 “$cbr0 start”
$ns at 5.0 “finish"

cbr0 empezará al tiempo de 1.0 ms y todo el proceso se parara a los 5.0 ms, también se puede parar cada generador de tráfico.

$ns at 4.0 ”$cbr0 stop”

El generador de tráfico cbr0 se parará a los 4.0 ms


A continuación pongo unas simulaciones que corrí, agregue algunos comentarios a los códigos según lo que entendí que hacia cada simulación.

Simulación 1.


Código
set ns [new Simulator]
$ns color 0 blue
$ns color 1 red
# Abrir trace files
set f [open out.tr w]
$ns trace-all $f
set nf [open out.nam w]
$ns namtrace-all $nf
# Crear topologia, tres nodos en linea
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
$ns duplex-link $n0 $n2 2Mb 5ms DropTail
$ns duplex-link $n2 $n1 1.5Mb 10ms DropTail
$ns duplex-link-op $n0 $n2 orient right
$ns duplex-link-op $n2 $n1 orient right
# Creación de agentes UDP
set udp0 [new Agent/UDP]
$ns attach-agent $n0 $udp0
set udp1 [new Agent/UDP]
$ns attach-agent $n1 $udp1
$ns connect $udp0 $udp1
# La instancia "process_data" es la que va a procesar los datos recibidos
# en caso de que ninguna aplicacion estuviera adjuntada al agente
# en este caso se responde a mensajes de la forma "ping(####")
Agent/UDP instproc process_data {size data} {
global ns
$self instvar node_
$ns trace-annotate "[$node_ node-addr] received {$data}"
# Si el mensaje fue en forma "ping(####)" entonces se manda una respuesta de la forma "pong(####)"
if {[regexp {ping *([09]+)} $data entirematch number]} {
$self send 100 "pong($number)"
} elseif {[regexp {countdown *([09]+)} $data entirematch number]
&& $number > 0 } {
incr number -1
$self send 100 "countdown($number)"
}
}
# Crear clases nos permite poner colores en NAM
$udp0 set class_ 0
$udp1 set class_ 1
# Se programan algunos mensajes para ser enviados, usando el procedimientoUDP "enviar"
# El primer argumento es la longitud de los datos y el segundo son los datos
# Se puede fingir con la longitud, esto permite que se envien paquetes de cualquier
# tamaño que se necesite en la simulación sin necesidad de generar una cadena con
# la longitud de los datos, la longitud que se especifica no debe ser mas grande que
# el maximo tamaño del paquete UDP (el default es 1000 bytes)
$ns at 0.1 "$udp0 send 724 ping(42)"
$ns at 0.2 "$udp1 send 100 countdown(5)"
$ns at 0.3 "$udp0 send 500 {ignore this message please}"
$ns at 0.4 "$udp1 send 828 {ping (12345678)}"
$ns at 1.0 "finish"
proc finish {} {
global ns f nf
$ns flush-trace
close $f
close $nf
puts "running nam..."
exec nam out.nam &
exit 0
}
$ns run
view raw simu2.tcl hosted with ❤ by GitHub
Este programa simple que muestra como se envían datos en datagramas UDP.




Simulación 2.


Código
#Creación de nodos
set ns [new Simulator]
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
set f [open out.tr w]
#Simulacion para ver los resultados
$ns trace-all $f
set nf [open out.nam w]
$ns namtrace-all $nf
set trace_flow 1
$ns color 0 red
$ns color 1 blue
#Se crean los enlaces entre los nodos
$ns duplex-link $n2 $n1 0.2Mbps 100ms DropTail
$ns duplex-link $n0 $n1 0.2Mbps 100ms DropTail
$ns duplex-link-op $n2 $n1 orient right-down
$ns duplex-link-op $n0 $n1 orient right-up
set exp1 [new Application/Traffic/Exponential]
$exp1 set packetSize_ 128
$exp1 set burst_time_ [expr 20.0/64]
$exp1 set idle_time_ 325ms
$exp1 set rate_ 65.536k
set a [new Agent/UDP]
$a set fid_ 0
$a set rate_ 32.768k
$a set bucket_ 1024
$exp1 attach-agent $a
set tbf [new TBF]
$tbf set bucket_ [$a set bucket_]
$tbf set rate_ [$a set rate_]
$tbf set qlen_ 100
$ns attach-tbf-agent $n0 $a $tbf
set rcvr [new Agent/SAack]
$ns attach-agent $n1 $rcvr
$ns connect $a $rcvr
set exp2 [new Application/Traffic/Exponential]
$exp2 set packetSize_ 128
$exp2 set burst_time_ [expr 20.0/64]
$exp2 set idle_time_ 325ms
$exp2 set rate_ 65.536k
set a2 [new Agent/UDP]
$a2 set fid_ 1
$exp2 attach-agent $a2
$ns attach-agent $n2 $a2
$ns connect $a2 $rcvr
$ns at 0.0 "$exp1 start;$exp2 start"
$ns at 20.0 "$exp1 stop;$exp2 stop;close $f;close $nf;exec nam out.nam &;exit 0"
$ns run
view raw simu.tcl hosted with ❤ by GitHub
Este programa muestra como utilizar el filtro del algoritmo Token Bucket (algoritmo utilizado para controlar la cantidad de datos inyectados a la red, permitiendo el envío de ráfagas de éstos) para cosas como:
  • Catalogación de paquete. Cuando hay dos modelos del mismo origen conectados a un Receptor común, una de las fuentes está conectada a través de un filtro Token Bucket mientras el otro está conectado directamente.Los parámetros TBF dan forma a la exponencial (on/off) para parecer una codificación bitrate constante.

Simulación 3. 


En la última simulación podemos ver una simulación TCP, en la cual se reenvía una ACK para confirmar que el paquete fue enviado.




Referencias:

Laboratorio 5. Catálogos y Proveedores

Nuestro proyecto consiste en un garage inteligente, vamos a abrir la puerta de este a través el dispositivo móvil.

Para realizar nuestro proyecto se requiere el hardware y software que mencionaré a continuación:

HARDWARE


Smartphone

Para nuestro proyecto utilizaremos un Smartphone con sistema operativo Android.


Este dispositivo será utilizado como lector QR y también para recibir las notificaciones de cuando alguien se encuentre estacionado fuera de tu casa y no seas tu. 

Cámara web

Esta la utilizaremos para detectar las imágenes que se encuentran enfrente del garage, esto con el fin de saber cuando alguien va a entrar o cuando alguien se estaciona frente al garage, estas imagenes se mandan a la computadora para procesarlas.



Precio: $260
Tienda: Steren
Link: http://www.steren.com.mx/catalogo/prod.asp?f=&sf=53&c=569&p=4030&desc=webcam-con-microfono-e-iluminacion-multicolor

Arduino UNO

El Arduino lo utilizaremos para controlar la puerta del garage, este recibirá las señales para saber si abrir o cerrar el garage. 
Precio: $365
Tienda: Electrónica 5hz
Link: http://www.5hz-electronica.com/arduino_uno-3-1.aspx

Módulo Bluetooth

El módulo bluetooth será utilizado en conjunto con el Arduino UNO para establecer una comunicación inalámbrica entre el dispositivo móvil y el garage, mediante una aplicación que tendra el dispositivo Android para abrir y cerrar el garage.
Precio: $580
Tienda: Electrónica 5hz
Link: http://www.5hz-electronica.com/modembluetooth-silver.aspx

Servo

Como realizaremos un prototipo a escala, vamos a necesitar motores para darle movimiento a la puerta del garage, para esto se puede utilizar un servo 360 de rotación, lo cual significa gira 360 grados continuamente, esto suponiendo que una cadena estuviera girando para abrir el garage.
Precio: $220
Tienda: Electrónica 5hz

Computadora

Necesitamos una computadora que se encuentre conectada al Arduino para leer el web service. Estábamos pensando en utilizar una Raspberry PI para realizar esto.


SOFTWARE


Para nuestro proyecto utilizaremos diferentes lenguajes de programación:

  • Python. Escribir código para establecer comunicaciones.
  • Processing. Lenguaje de programación de Arduino.
  • Java. Para la aplicación móvil que realizaremos para abrir o cerrar el garage.
  • PHP. Para el web service.
También son necesarias las librerías de Android SDK y el software de Arduino para programar en Processing y escribir código en el Arduino.


Link de Android SDK: http://developer.android.com/sdk/index.html#download
Link del software de Arduino: http://arduino.cc/en/main/software

Tarea 4. Detección de Circulos

Para esta semana, se nos pidió detectar círculos en una imagen, estos círculos tienen un radio conocido y todos los los mismos tienen el mismo radio.

Para esta tarea utilicé algunas de las fórmulas utilizadas para la detección de líneas, los círculos los dibuje en GIMP con radio de 100.

Para este algoritmo como ya lo mencioné se utilizó el código de detección de líneas, en este nuevo código se utilizaron los gradientes para calcular el ángulo y utilizar este punto para el círculo y se obtiene el centro del círculo.

Fórmula para calcular el gradiente:

Con el gradiente se calcula:

Teniendo esto calculamos obtenemos lo siguiente para calcular los centros:


Tuve algunos problemas con el programa, pero para la tarea de lab pienso solucionarlo.




Resultados:







Código:



def circulo(img_gx, img_gy, imagen, radio):
dim = 400
centros = []
votos = list()
#w, h = imagen.size
pixeles = imagen.load()
for a in range(dim):
votos.append([0] * dim)
for ym in range(dim):
y = dim/2-ym
for xm in range(dim):
x = xm - dim/2
gx = img_gx.getpixel((ym,xm))[0]
gy = img_gy.getpixel((ym,xm))[0]
grad = math.sqrt(math.pow(gx,2) + math.pow(gy,2))
if fabs(grad)>0:
cos_ang = gx/grad
sen_ang = gy/grad
xc = int(round(x-radio*cos_ang))
yx = int(round(y-radio*sen_ang))
xcm = xc + dim/2
ycm = yx + dim/2
if ycm >= 0 and xcm < dim and ycm < dim and xcm >= 0:
votos[ycm][xcm] += 1
for r in xrange(1, int(round(dim * 0.1))):
agrega = True
while agrega:
agrega = False
for y in range(dim):
for x in range(dim):
v = votos[y][x]
if v > 0:
for dx in range(-r,r):
for dy in range(-r,r):
if not (dx == 0 and dy == 0):
try:
w = votos[y+dy][x+dx]
except:
pass
if w>0:
if v -r >= w:
votos[y][x]= v+w
votos[y+dy][x+dx]=0
agrega = True
maxi = 0
suma = 0.0
for x in xrange(dim):
for y in xrange(dim):
v = votos[y][x]
suma += v
if v > maxi:
maxi = v
prom = suma / (dim * dim)
umbral = (maxi + prom) / 2.0
for x in xrange(dim):
for y in xrange(dim):
v = votos[y][x]
if v > umbral:
print 'Posible centro detectado en (%d, %d). ' % (y, x)
centros.append((y,x))
pixeles[y,x]=(0,255,0)
return centros
def pintar_circulos(im, centros, radio):
pix = im.load()
draw = ImageDraw.Draw(im)
for x, y in centros:
pix[y, x] = (0, 255, 0)
am = random.randint(120, 255)
draw.ellipse((y-radio, x-radio, y+radio, x+radio), outline = (am, am, 0))
im.save('output.png')
view raw circulos.py hosted with ❤ by GitHub


Referencias:
http://elisa.dyndns-web.com/~elisa/teaching/comp/vision/circulos.pdf