Max Hernandez

Laberinto - Ejemplo de Canvas en HTML5

jueves, 22 de noviembre de 2012

Laboratorio Automatización entrega 7

Para esta semana en el laboratorio de esta clase nos toco realizar otro problema del libro del cual se muestra su referencia en la parte inferior de este post, y este fue el problema que elegí:

PM9.8.  Considérese el sistema representado en variables de estado de la forma:

$\dot{x} =
\begin{bmatrix}
0 & 1 \\
-1 & -10
\end{bmatrix}
x+
\begin{bmatrix}
0\\
22
\end{bmatrix}
u$

$y = \begin{bmatrix} 10 & 0 \end{bmatrix} x+ \begin{bmatrix} 0 \end{bmatrix}u$

Obtener el diagrama polar utilizando la función niquist.

Solución:  

 La solución fue obtenida utilizando octave utilizando el paquete de control, este es el código:

El resultado fue obtenido utilizando la función niquist del paquete ya mencionado que se encarga de realizar un diagrama niquist los cuales son utilizados para verificar la estabilidad de un sistema. Estos muestran tanto amplitud como angulo de fase y se crean tomando la frecuencia como parámetro.

Primero que nada el sistema se encuentra en su representación de estado de espacios para lo cual, necesitamos pasarla a un sistema que pueda recibir como parámetro la función "nyquist", para lo cual lo utilizamos la función ss() que a grandes rasgos nos ayuda a convertirlo en un sistema de ecuaciones que podemos usar para graficar.

El código construido es el siguiente:
lb7.m


function null =  lb7()
  A = [ 0 1; -1 -10];
  B = [0;22];
  C = [10 0];
  D = [0];

  sys = ss(A,B,C,D);

nyquist(sys)

endfunction


Con lo cual se obtiene la siguiente gráfica:



Referencias:

El problema fue sacado del libro:
Sistemas de control moderno, 10a edición, Richard C. Dorf, Robert H. Bishop, PEARSON.

martes, 20 de noviembre de 2012

Presentación de proyecto aplicado grupal

Reporte de proyecto aplicado grupal

Integrantes:
  • Maximiliano Hernandez Casitllo
  • Isaias Garza Berumen
  • Gerardo Saúl Gausin Valle
El link al reporte es el siguiente:
https://docs.google.com/document/pub?id=1gwlg1K_ADA_i28X2TlDsl-WqtTFnruVZrqPbYFCbBrY




Videos del sistema funcionando






Todo el código se encuentra para descargar en Gist:
https://gist.github.com/4115449

El código

Reporte entrega final de redes neuronales

Esta publicación esta dedicada a ser un reporte para la entrega final de la clase de redes neuronales con una explicación de mi aportación al proyecto de la red neuronal para controlar el brazo robótico.

Nuestro proyecto

Componentes
1.- El brazo robótico es el siguiente (Link) esta la compramos en Steren, este tiene cinco motores de directa, para utilizarlo desarmamos el dispositivo y controlamos utilizando un Arduino cada motor por separado para mapear cada uno con una salida de nuestra red neuronal.


[Imagen obtenida de: http://www.steren.com.mx/_imgs/prod/grande/k-682.jpg]

2.-  Electroencefalograma del juguete The Star Wars Force Trainer el cual es un sensor que mide la actividad electrica del cerebro.


[Image obtenida de: http://cdn2-b.examiner.com/sites/default/files/styles/image_content_width/hash/e2/93/e293a53f702510273b7481b9ce4d9462.jpg]



3.- Dos Arduinos , la idea es utilizarlo como interfaz de las señales recibidas del sensor y también para las señales mandadas al brazo robótico controlando cada motor del brazo mecánico.

[Imagen obtenida de:http://arduino.cc/en/uploads/Main/arduino_uno_test.jpg]


Funcionamiento
La idea es que utilizando el electroencefalograma como entrada  ala red, esta sea capaz de mapear pensamientos específicos como arriba, abajo izquierda y derecha a movimientos del brazo robótico directamente relacionados como moverse a esas direcciones.

Mi aportación

Algoritmo heurístico para configurar la red neuronal
Una vez teniendo una red capaz de entrenarse para el proyecto nos dimos cuenta que escoger una configuración de conexiones para la red neuronal era algo complicado y que necesitábamos un análisis minucioso sobre los valores de entrada  ala red para poder elegir una configuración correcta, pero dado que tardamos mucho tiempo en elegir un aparato que nos diera señales de entrada decidimos implementar un algoritmo heurístico que buscara la configuración con el menor error posible para no tener que preocuparnos por la configuración de la misma.

Algoritmo voraz 

El algoritmo voraz fue el seleccionado para configurar la red debido a su simplesa, el algoritmo genera grafos aleatorios y utiliza el error del entrenamiento de una red como función objetivo, es decir entrena n cantidad de veces la red neuronal y el error en n cantidad de entrenamientos finales es el valor de salida en la función objetivo.

Una vez teniendo definido esto solo se crean diferentes redes aleatorias y se modifican seleccionando siempre la que reduzca mas el error.

Esta es una gráfica del programa minimizando el error de una red neuronal

Aquí se muestra una red óptima generada por el programa:



Una nueva red mas flexible

Para que el programa heurístico pudiera minimizar el error de entrenamiento necesitábamos una  red neuronal mas flexible que fuera capaz de evaluar y entrenar una red neuronal con las características ya mencionadas por lo cual tuvimos que implementar una nueva red neuronas, utilizando Backpropagation otra vez como algoritmo de entrenamiento de entrenamiento.

El algoritmo funciona como una búsqueda de profundidad BFS, para evaluar empieza con las neuronas de la capa de entrada, después busca las neuronas con las que tiene conexión y visita las mismas, evalúa las salidas para las mismas y pasa  alas siguientes mas cercanas cuidando no volver a visitar neuronas que ya han sido visitadas antes.

Para el backpropagation utiliza la misma lógica pero esta vez empieza a visitar a las neuronas desde la capa de salida.

Exor
Como prueba para el algoritmo empezamos creando una red para un exór y entrenándola para lo cual esta fue el resultado: 
 
Salidas

[0, 0] (0.08847382273808657, [-0.42065145367176987])
[0, 1] (0.003901019389583797, [0.9116708497767153])
[1, 0] (0.0031196995578053406, [0.9210101328295162])
[1, 1] (0.039653499234460134, [-0.2816149826783374])
Error:  0.346610025801

Entrenando la red con entradas del EGG
Una vez teniendo la red, empezamos a entrenar la red con valores que habiamos tomado del egg con anterioridad, los valores fueron tomados.
Para mandar los valores a la red se creo un parser muy sencillo y se metieron todas las entradas en un vector junto con su salida esperada y se dieron com entrada a la red.

def cargar_archivos(archivos):
    muestras = list()

    for i in range(len(archivos)):
        fl = open(archivos[0])
        for j in fl:
            temp = j.split(",")
            for h in range(len(temp)):
  temp[h] = int(temp[h])
            muestras.append([temp, [i]])
        fl.close()

    random.shuffle(muestras)

    return muestras

El resultado de la red fue el siguiente:

Debido a un problema con la red neuronal, las entradas no siempre se entrenan de forma correcta y eso provoca que el algoritmo heuristico funcione mal y lanze males valores.

La gráfica del entrenamiento es la siguiente:

La red optima que me lanzo es la siguiente:


Programa
El programa se encuentra para descargar en Github desde el siguiente enlace:

https://github.com/SaulG/redesNeuronales

Con las versiones mas estables del programa.

Pero para modificar directamente y mantener una copia automática en tiempo real de lo que modificaba utilice mi cuenta de Dropbox para la cual por cuestiones de seguridad solo daré permiso de acceder a la doctora que imparte la clase.

Esta es la dirección del Dropbox
https://www.dropbox.com/sh/nsn458htcnvcoqo/ydTh4nYjc0

En esta página se puede ver el registro de actividades
https://www.dropbox.com/events?ns=160486657&n=1&d

jueves, 15 de noviembre de 2012

Laboratorio Automatización entrega 6

Para esta semana en el laboratorio de esta clase nos toco realizar otro problema del libro del cual se muestra su referencia en la parte inferior de este post, y este fue el problema que elegí:



Solución:

$A = \begin{bmatrix} 0 & 1 & 0 \\ 0 & 0 & 1 \\ 0 & -5 & -6 \end{bmatrix} \\
B = \begin{bmatrix} 0 \\ 0 \\ 1 \end{bmatrix} \\
C = \begin{bmatrix} 1 & 0 & 0 \end{bmatrix} \\
D = 0$

$s = -2+j4, s = s-j4, s=-10$

La ganancia de retroalimentación debe cumplir con la siguiente regla:

$det(sI-A+BK) = (s+2-j4)(s+2+j4)(s+10) \\
= [s^{2} + (2+j4)s + (2-j4)s +20](s+10) \\
= [s^{2} + 4s +20](s+10) \\
= s^{3} + 4s^{2} + 20s + 10s^{2} + 40s + 200 \\
= s^{3}+14s^{2}+60s+200$


Ahora usaremos la misma regla para las matrices:
$det(sI-A+BK) =
s \begin{bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{bmatrix}
- \begin{bmatrix} 0 & 1 & 0 \\ 0 & 0 & 1 \\ 0 & -5 & -6 \end{bmatrix}
+\begin{bmatrix} 0 \\ 0 \\ 1 \end{bmatrix}
\begin{bmatrix} k1 & k2 & k3 \end{bmatrix}$

$
det(sI-A+BK) =
\begin{bmatrix} s & 0 & 0 \\ 0 & s & 0 \\ 0 & 0 & s \end{bmatrix}
- \begin{bmatrix} 0 & 1 & 0 \\ 0 & 0 & 1 \\ 0 & -5 & -6 \end{bmatrix}
+ \begin{bmatrix} 0 & 0 & 0 \\ 0 & 0 & 0 \\ k1 & k2 & k3 \end{bmatrix}$

$
det(sI-A+BK) = \begin{bmatrix} s & -1 & 0 \\ 0 & s & -1 \\ k1 & k2+5 & s+k3+6 \end{bmatrix}$

Podemos obtener los valores de k igualando las ecuaciones y sustituyendo valores en $s$ y evaluando:
$= s^{3} + (k3+6)s^{2} + (k2+5)s + k1 = s^{3}+14s^{2}+60s+200 \\
$para$ s = 0 \\
(0)^{3} + (k3+6)(0)^{2} + (k2+5)(0) + k1 = (0)^{3}+14(0)^{2}+60(0)+200 \\
k1 = 200 \\$


para $s = 1 \\
(1)^{3} + (k3+6)(1)^{2} + (k2+5)(1) + k1 = (1)^{3}+14(1)^{2}+60(1)+200 \\
= 1 + k3 + 6 + k2 + 5 + 200 = 1 + 14 + 60 + 200 \\
= k3 + k2 = 63 \\$


para $s = 2 \\
(2)^{3} + (k3+6)(2)^{2} + (k2+5)(2) + k1 = (2)^{3}+14(2)^{2}+60(2)+200 \\
= 8 + 4k3 + 24 + 2k2 + 10 + 200 = 8 + 28 + 120 + 200 \\
= 4k3 + 2k2 = 114 \\
= 2k3 + k2 = 57 \\$

$
k3 + k2 = 63 \\
-2k3 + -k2 = -57 \\
\overline{-k3 = -57}$

$k3 = 57$

$
k2 + 57 = 63 \\
k2 = 63-57 = 6$

Entonces los valores de $K$ son los siguientes:
$
k1 = 200 \\
k2 = 6\\
k3 = 57$

Respuesta a impulso unitario
Código:
function null =  lb6()
  A = [ 0 1 0; 0 0 1;-200 -6 -57];
  B = [0;0;1];
  C = [1 0 200];
  D = [0];
step(ss(A,B,C,D));
title('Respuesta impulso unitario');
endfunction



Referencias:

El problema fue sacado del libro:
Ogata, Katsuhiko. Modern Control Engineering / Katsuiko Ogata.
Tehran: A'eizh, 1381 = 2002.
964.: ill
Reprint of 4th ed. 2002, Prentice Hall, New Jersey.

 La solución la realice bazandome en la solución el problema 18.1 de los expuestos en esta página:
http://csd.newcastle.edu.au/solved_probs/wp18.pdf

martes, 13 de noviembre de 2012

Caso de uso redes neuronales [Puntos extra]

Para puntos extra esta semana se nos dio la oportunidad de buscar alguna aplicación de lo aprendido en redes neuronales aplicado por profesionales y publicado internacionalmente.

Para esta tarea la investigación que elegí fue la siguiente:

A neural network application for bankruptcy prediction
Autores: Wullianallur Raghupathi, Lawrence L. Schkade, Bapi S. Raju
En la universidad de Arlington, Texas

Este es el enlace al paper:
http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=184054



Mi resumen sobre el artículo
Específicamente su objetivo es la aplicación de una red neuronal con backpropagation con una o dos capaz escondidas y variando nodos para hacer una predicción de la quiebra bancaria. Además de que la red neuronal puede producir una medida de que tan certero es su funcionamiento.

Su motivación parece ser lo incierto que es hacer una predicción a futuro de una compañía, por lo poco claro que es trabajar con estados financieros, leyes y directrices. La razón por la cual eligieron una red neuronal como algoritmo para este problema, es que los algoritmos estadísticos que existen son muy especifico y exigen modelar funciones que podrían o no funcionar y que quizas no podrían dar la generalización que requiere el problema.


[Imagen obtenida de: https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2YvRacTlpRT6S-HY1ZF-2ArF1EpyS-29o1CJk8ol8yRcEu60GwSG7b_OkpPDHV9kGZ98XwkHKAwHrpdLvZYZhLkzMDBv04FOwmUcXugyGXi7jCmF0Z4vR_hji-gqJ8wUabe34OhgoCIA/s1600/bankruptcy.jpg]

Como manejan el problema


Para poder interpretar el problema con una red neuronal ellos manejan el problema como uno de clasificación puesto que esto es muy común para este tipo de problema. En su clasificación existen dos grupos, los que van a quedar en banca rota y los que no, utilizando la red neuronal producen estas dos salidas.

Su red neuronal
La red neuronal que utilizan es una común donde cada capa esta completamente conectada con la siguiente.


[imagen obtenida de:"http://galaxy.agh.edu.pl/~vlsi/AI/backp_t_en/backprop_files/img19.gif"]

La función kernel que utilizan para transformar las neuronas es la de Sigmoid y la regla delta del error es utilizada para calcular pues el error.


[Imagen obtenida de:"http://reed.cs.depaul.edu/peterh/class/csc578/lectures/bookpng/ann-sigmoid.png"]

Sus entradas para la red
Para seleccionar sus variables de entrada a la red neuronal, ellos hicieron una extensa investigación sobre personas que hayan tratado de resolver el mismo problema y seleccionaron las variables más utilizadas para predecir bancarrota en compañías e hicieron una tabla con estos y después hicieron una segunda tabla con la interpretación que se les da a cada uno.

Recolección de datos
Los datos para la red neuronal, ellos seleccionaron 100 compañías de prueba de las que 51 quedaron en bancarrota y 50 de ellas no, esta lista de compañías la obtuvieron de investigación donde el, de listas de 1980-1988 del wall Street Journal Index

Su ejecución
Para el experimento ellos entrenaron la red con 14 entradas de las variables ya mencionadas que seleccionaron y una salida de la red neuronal para la clasificación que daría como salida si quedara o no en bancarrota la compañía.

Para seleccionar la cantidad de capaz escondidas, ellos probaron con diferentes tipos de configuraciones hasta que encontraron una lo suficientemente óptima.

El resultado
Al parecer la neurona redujo su error mientras estaba siendo entrenada pero ellos no notaron ningún cambio en el aprendizaje de la red.

Conclusión
Mis conclusiones del resumen de esta investigación es que no se necesitan redes demasiado complicadas para lograr buenos resultados en el mundo real, si no que  una buena investigación y un buen análisis de los datos puede ser una parte realmente importante en la realización de una red neuronal.

Referencias:
http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=184054

martes, 6 de noviembre de 2012

Caso de uso para control de sistemas [Puntos extra]

Para la clase de esta semana en la materia de control de sistemas, se nos dio la oportunidad por puntos extra en esta clase, hacer una investigación sobre una aplicación o alguna investifación relacionada con la materia. Sin mas que añadir esto es lo que investigue. La investigación que leeí es la siguiente y el link de referencia viene al final de esta publicación:


Reactive Speed Control System Based on Terrain
Roughness Detection
Mattia Castelnovi, Ronald Arkin, Thomas R. Collins
Laboratorium DIST College of Computing School of ECE / GTRI
University of Genova Georgia Institute of Technology Georgia Institute of Technology


Sistema de control de la velocidad de acción basada en la detección de rugosidad de un terreno


[Imagen obtenida de: http://www.segway.cz/images/v/rmp400_idx.jpg]


La investigación trata sobre un sistema en el cual un robot modifica su velocidad y su reacción dependiendo del terreno por el cual se mueve. El paper se centra en la necesidad en muchas areas de la industria de controlar robots que se mueven por una superficie mediante su sistema de control con la seguridad de que el movimiento por la superficie no va a afectar el sistema de comunicación y navegación de un robot.

Para esto utiliza un sistema basado en un escaneo lineal de la vista de un laser el cual detecta la rigidez del terreno. Ademas de un sistema para modificar la velocidad de un carro.

Para su investigación ellos utilizan un Segway RMP el cual es una plataforma con movimiento la cual puede ser operada a distancia. Este puede operar con una velocidad de 3.5m y alcanzar una aceleración maxima de 2 metros por segundo cuadrado, tiene un rango de 15m y puede cargar hasta 50kg.
Además para su investigación utilizan un sensor laser SICK como entrada en el sistema enfocado a 45º hacia el suelo.

El sistema de control

EL primer problema con el que se puede notar que se enfrentan es que el laser necesita tener una medida para comparar si una superficie es lisa o rugosa para esto utilizan una medida base de una superdicie lisa para medir la internsidad de esos atributos.

Para obtener buenos parametros de medición de rugosidad de un terreno para el sistema siguierón los siguientes pasos:
1.- Primero calculan la altura del sensor utilizando la longitud de las ruedas y el ángulo de inclinación del sensor como parametros para obtener estos valores.
2.- Obtienen la posición del terreno a medir su rugosidad.
3.- Despues utilizan un sistema para evitar el ruido usando lo que me parece medir el promedio de siete medidas y tomar esto como una sola medida.
4.- Para este paso ya es calculada la rugosidad de entrada del sistema, en este punto utilizan cuatro medidas especificas las cuales en su mayoria son un promedio de 120 medidas de la altura del sensor y una entrada de rugosidad del mismo.


Control de velocidad del robot

La finalidad del sistema de control es que el usuario pueda interactuar libremente con el movimiento del robot teniendo el mismo robot la capacidad de protegerse en caso de que pueda sufrir algún daño moviendose en una superficie. Para lograr esto ellos utilizan dos parametros los cuales son los limites que delimitan un rango sobre el cuál puede estar la velocidad de movimiento del carrito. El algoritmo que presentan es el siguiente:

Pseudocódigo:

        Por cada uno de las cuatro parametros de los que se habló en el punto anterio
            Se recalculan los valores minimos y maximos para ese terreno.
            Si el parametro esta fuera del rango prestablecido se amplia el rango de rugosidad
        El rango final es igual a el rango de liso definido al principio y al rango de rugosidad modificado en pasos anteriores
        Despues si el rango final es mayor que cero se aumenta la velocidad, si es menor o igual a cero se disminuye.
        Si el rango de liso es 4 se pone la velocdiad en estado top-speed
        Si el rango de rugosidad es 4 se pone la velocidad en estado de safe-speed


Como se puede observar utilizan muchos rangos para definir si es necesario que sea modificada la velocidad del robot, además de que se utilizan medidas estandar para definir que pasaría si se llega a un estado donde el terreno es peligroso para el robot.

Conclusiones:
La lectura de el trabajo de estas personas me ayudo a entender como funciona un sistema de control profesional y entender mejor como construir sistemas complejos de control por medio de algoritmos mas simples.

Referencias:
http://ieeexplore.ieee.org/ielx5/10495/33250/01570230.pdf?tp=&arnumber=1570230&isnumber=33250

jueves, 1 de noviembre de 2012

Laboratorio Automatización entrega 5

Para esta semana en el laboratorio de esta clase nos toco realizar otro problema del libro del cual se muestra su referencia en la parte inferior de este post, y este fue el problema que elegí:




Solución:
Siendo el error de velocidad estatica Kv igual a 50 sec^-1 tenemos que K = 50 y podemos graficar el diagrama de Bode de:

 

function Null = diagrama1()
    num = [0 0 50];
    den = [1 1 0];
    w = logspace(-1, 2, 100);
bode(tf(num, den), w);
    title("diagrama de bode G(s) = 50/s(s+1)")
endfunction


Ahora el siguiente paso es determinar las frecuencias de esquinas w=1/T
y w=1/alfa*T del compensador. La magnitud de la modificación en la curva de magnitud debido a la inclusión del termino (T*s+1)/(alfa*T*s + 1) es:
tomando en cuenta que:
Ahora necesitamos encontrar la frecuencia de punto que hace que cuando el compensador es añadido, la magnitud total se vuelve 0. del diagrama de Bode anterior podemos encontrar frecuencia de punto donde |G1(jw)| = -8.239 dB lo cual ocurre aproximadamente en w = 11.4 rad/sec.

ahora con esto podemos obtener:



Entonces el compensador debería estar determinado por:
Donde Kc es:


Ahora podemos producir el siguiente diagrama de Bode de la función anterior.

function Null = diagrama2()
    num = [11.325 50];
    den = [0.03397 1];
    w = logspace(-1, 3, 100);
bode(tf(num, den), w);
    title("diagrama de bode")
endfunction

La función del sistema de lazo abierto es la siguiente:

El siguiente programa produce un diagrama de Bode de la función anterior.

function Null = diagrama3()
    num = [0 0 1000 4415.2];
    den = [3 91.3041 88.304 0];
    w = logspace(-1, 3, 100);
bode(tf(num, den), w);
    title("diagrama de bode")
endfunction

Ahora es necesario obtener la respuesta del escalón unitario y la rampa unitaria del sistema original que no tenia compensación. EL sistema original tenia la siguiente función de transferencia de lazo cerrado:
La función de transferencia del sistema con compensación debería ser la siguiente:



El siguiente código produce las respuestas de un impulso de escalón unitario de ambos sistemas:

function Null = diagrama4()
    num = [0 0 1];
    den = [1 1 1];
    numc = [0 0 1000 4415.2];
    denc = [3 91.3041 1088.304 4415.2];
    t = 0:0.01:8;
    c1 = step(tf(num, den),t);
    c2 = step(tf(numc, denc),t);
    plot(t,c1,t,c2);
    title("Respuesta a un escalon unitario sin compensacion y con sistema compensado");
    xlabel("t Sec");
    ylabel("Outputs");
    text(1,1.25,"Sistema compensado");
    text(2, 0.5,"Sistema no compensado");
endfunction
El siguiente código produce la respuesta de un impulso de rampa unitaria de ambos sistemas.

function Null = diagrama5()
    num = [0 0 0 1];
    den = [1 1 1 0];
    numc = [0 0 0 1000 4415.2];
    denc = [3 91.3041 1088.304 4415.2 0];
    t = 0:0.01:8;
    c1 = step(tf(num, den),t);
    c2 = step(tf(numc, denc),t);
plot(t,c1,t,c2, t, t);
    title("Respuesta a un impulso unitario sin compensacion y con sistema compensado");
    xlabel("t Sec");
    ylabel("Outputs");
    text(1,1.25,"Sistema compensado");
    text(2, 0.5,"Sistema no compensado");
endfunction

El código fue hecho para octave utilizando la librería de control y las gráficas con Gnuplot.

Referencias:

El problema fue sacado del libro:
Ogata, Katsuhiko. Modern Control Engineering / Katsuiko Ogata.
Tehran: A'eizh, 1381 = 2002.
964.: ill
Reprint of 4th ed. 2002, Prentice Hall, New Jersey.


Steganography

For this week in the information security and cryptography class we talk about the steganography, that is defined as the science or art of writing secret messages over an insecure channel in my case save the source code hidden on images of Lolcats. The principal characteristic of this science is that no one except the sender and intended recipient suspects about the existence of this message.

[image obtained from: "http://prismakhas.com/wp-content/uploads/steganography.jpg"]

My implementation
this week i made another python script, to hide the message in pictures i chose the LBS method borrowing the two least significant bits of some pixel colors to hide part of a ASCII character on them.

The hexadecimal representation of a color is a representation where every two hexadecimal numbers represent a intensity of the RGB colors Red, Green and Blue. Alternating the intensity of this colors we can obtain a complete set of most important colors.



[Image obtained from:"http://www.leapcms.com/images/hex-colours.jpg"]

To hide a single character on ASCII representation the i need at least eight bits because exist 128 characters on ASCII characters so i take the next seven bits of the hexadecimal color transformed to binary number where the bits with "1" are the borrowed bits.

     RED      GREEN     BLUE
00000111 00000011 00000011


It works because the change of these bits for a bits of a different characthers representation is imperceptible to the human eye.

The next image is one of the three lolcats with a hidden message and shows the noise of the least two bits of the red color. As we see there is a lot of noise and there is no easy way to notice patterns in the pixel shades.



My code

Enlace para descargar
http://dl.dropbox.com/u/20770926/image.py

Comando para esconder mensaje en imagen en linux

python image.py -mix nombre_imagen.png archivo_de_entrada.txt

Comando para separar mensaje de imagen en linux

python image.py -separate nombre_imagen.png archivo_de_salida.txt

Image.py
#!/usr/bin/python
from PIL import Image
import sys

image = []

def bin_text(n, digits):
    temp = bin(n)[2:]
    for i in range(digits-len(temp)):
        temp = "0" + temp
    return temp

def break_char(c):#char
    total_bits = 7

    c = bin(ord(c))[2:]
    for i in range(total_bits-len(c)):
        c = "0"+c
    return [c[:3], c[3:5],c[5:]]

def build_char(c):
    return chr(int(c,2))

def get_data(datafile):
    fl = open(datafile, "r")
    data = fl.read()
    fl.close()

    temp = []
    for i in data:
        temp.append(break_char(i))

    return temp

def mix_data(colors, data):
        R = (colors[0]&int( ("11111000"), 2))
        R = (R|int( (data[0]), 2))

        G = (colors[1]&int( ("11111001"), 2))
        G = (G|int( (data[1]+"0"), 2))

        B = (colors[2]&int( ("11111001"), 2))
        B = (B|int( (data[2]+"0"), 2))

        return (R, G, B)

def merge(picture, datafile):

    print "Abierndo archivo..."
    data = get_data(datafile)

    print "Abriendo imagen..."
    image = Image.open(picture)
    pic = image.load()

    total_pixel = image.size[0]*image.size[1]

    if (total_pixel) < len(data):
        print "Archivo demasiado grande para la imagen"
        sys.exit(0)

    len_data = bin_text(len(data), 21)

    len_data = [ [len_data[:3], len_data[3:5],len_data[5:7]], [len_data[7:10], len_data[10:12],len_data[12:14]], [len_data[14:17], len_data[17:19],len_data[19:]] ] 

    for h in range(3):
        i = h%image.size[0]
        j = int(h/image.size[0])
        pic[i,j] = mix_data(pic[i,j], len_data[h])


    print "Anadiendo ", len(data), "caracteres..."
    for h in range(3, len(data)):
        
        position = ( (3*(len(data)+h+(total_pixel%100))) + 4 )% total_pixel

        i = position%image.size[0]
        j = int(position/image.size[0])

        pic[i,j] = mix_data(pic[i,j], data[h])

    image.save(r"modified_"+picture+".bmp", "BMP")
    print "Datos agregados a la imagen."

def separate(picture, outputFile="output"):
    print "Abriendo imagen..."
    image = Image.open(picture)
    pic = image.load()

    total_pixel = image.size[0]*image.size[1]

    fl = open(outputFile,"w")

    len_fl = ""
    for h in range(3):
        i = h%image.size[0]
        j = int(h/image.size[0])

        (R, G, B) = pic[i,j]
        R = bin_text(R, 8)
        G = bin_text(G, 8)
        B = bin_text(B, 8)
        len_fl += R[5:]+G[5:7]+B[5:7]

    len_fl = int(len_fl, 2)

    print "Obteniendo ", len_fl, " caracteres..."
    for h in range(3, len_fl):
        position = ( (3*(len_fl+h+(total_pixel%100))) + 4 )% total_pixel

        i = position%image.size[0]
        j = int(position/image.size[0])

        (R, G, B) = pic[i,j]

        R = bin_text(R, 8)
        G = bin_text(G, 8)
        B = bin_text(B, 8)

        char = chr(int(R[5:]+G[5:7]+B[5:7] , 2))
        fl.write( char)

    fl.close()
    print "Caracteres obtenidos"
    

def main():
    if len(sys.argv) > 0:
        if sys.argv[1] == "-mix":
            # Nombre de la imagen, nombre del archivo a mezclar
            merge(sys.argv[2], sys.argv[3])
        elif sys.argv[1] == "-separate":
            separate(sys.argv[2], sys.argv[3])

main()

The Result
Next this are the three images with the source code shown above hidden in it's pixels hiding it using the same code.

Original image 01

[image obtained from:"http://www.netlingo.com/imagearchive/5338_lolcat_word_large.jpg"]

Same image with hidden message


Original image 05

[image obtained from:"http://www.myspacefx.net/graphics/cat/Funny_Graphics_and_Pics/lol-cats_gheck-out-my-guns.jpg"]

Same image with hidden message


Original image 06

[image obtained from:"http://images.sodahead.com/polls/000445149/polls_lol_cats_2_final_4936_632409_poll_xlarge.jpeg"]

Same image with hidden message
 

The other original images were obtain from this links
http://stuffpoint.com/lol-cats/image/28755-lol-cats-ikea-cat.jpg
http://legacy-cdn.smosh.com/smosh-pit/122010/lolcat-dumbledore-is-gay.jpg
https://i.chzbgr.com/completestore/12/10/19/fOLZEL9Z_UWpweSNH_gIMQ2.png


And for last this is part of the content of the output file result of separate the hidden message of the above images to demonstrate that it works:
usr/bin/python
from PIL import Image
import sys

image = []

def bin_text(n, digits):
    temp = bin(n)[2:]
    for i in range(digits-len(temp)):
        temp = "0" + temp
    return temp

def break_char(c):#char
    total_bits = 7

    c = bin(ord(c))[2:]
    for i in range(total_bits-len(c)):
        c = "0"+c
    return [c[:3], c[3:5],c[5:]]

...

References:
http://www.strangehorizons.com/2001/20011008/steganography.shtml
http://en.wikipedia.org/wiki/Steganography
http://www.garykessler.net/library/steganography.html

miércoles, 31 de octubre de 2012

Lógica temporal linea

Para esta semana en la clase de validación hablamos del tema de la lógica temporal lineal, en la cual se habla sobre operadores lógicos asociados con eventos en tiempo.
 


[Imagen obtenida de:"http://www.moma.org/collection_images/resized/051/w500h420/CRI_151051.jpg"]

Símbolos aprendidos de lógica temporal

Este símbolo representa un evento que en algún momento se cumple.
 
Este símbolo representa un evento que se cumple en el siguiente estado.

Este símbolo representa un evento que en cualquier estado se cumple.

Mi problema
Como tarea se nos encargo resolver un inciso de los problemas del capitulo 14 del siguiente curso del profesor Andrei Voronkov:
http://www.voronkov.com/lics.cgi

El inciso que elegí es el siguiente:
Ejercicio 14.7 inciso (3).
Considerando el sistema de transición con el siguiente grafo de transiciones de estados.
Es verdadero el siguiente enunciado?

Conclusión
El enunciado es verdadero ya que el enunciado denota que existe algún estado para el cuál se cumple el evento y en al menos en el estado inferior derecho "y" cumple que tiene valor uno.

Referencias:
http://www.voronkov.com/lics_doc.cgi?what=chapter&n=14
http://es.wikipedia.org/wiki/L%C3%B3gica_temporal

martes, 30 de octubre de 2012

Estabilidad en mi sistema

Como tarea para esta semana en la clase de Automatización y control de sistemas dinámicos nos toca hacer un análisis de la estabilidad del sistema en el cual estamos trabajando.

Nuestro sistema
El sistema en el que estamos trabajando recordando publicaciones pasadas es el de controlar la altura de una pelota dentro de un tubo con un abanico utilizando como sensor para hacer nuestro sistema de lazo cerrado un sensor de ultrasónico en la parte superior del tubo.

Aquí el diagrama de bloques del sistema




Análisis de estabilidad

Como puede observarse en el diagrama de arriba la función de transferencia en el sistema es la siguiente:

Análisis de estabilidad con raíces

Utilizando valores j = 0.1 y b = 0.25 para tales variables en las ecuaciones utilice octave para obtener las raíces de la función del denominador de la función de transferencia, podemos utilizar estos valores de las raíces como referencia para saber si nuestro sistema es estable.

Código:

function Null = estabilidad_raices()
    num = [0 0 1];
    den = [0.1 0.25 0];
    [R, P, K] = residue(num, den)
    sys = tf(num, den);
    rlocus(sys);

endfunction

Salida:
octave:118> estabilidad_raices()
R =

   4
  -4

P =

   0.00000
  -2.50000

K = [](0x0)
utilizando la función "flocus" nos da la siguiente gráfica de la posición de las raíces:

Conclusión:

Según el criterio de estabilidad de Routh, la región para la cual el sistema es inestable es para la cual los valores reales de las raíces son valores positivos. Y como los valores reales de las raíces son uno negativo y el otro cero, se puede llegar a la conclusión de que el sistema es estable.

Gráfica de Bode

Código:
function Null = estabilidad_bode()
    num = [0 0 1];
    den = [0.1 0.25 0];
    sys = tf(num, den);
    bode(sys)

endfunction

Conclusión:
Un sistema es estable si RM < 1 para los grados = -180º y si RM = 1 para grados = -180º el sistema es inestable.


Gráfica de Nyquist

Código:
function Null = estabilidad_nyquist()
    num = [0 0 1];
    den = [0.1 0.25 0];
    sys = tf(num, den);
    nyquist(sys)

endfunction


Referencias:
http://www.slideshare.net/tonivi99/sistemas-de-control
http://materias.fi.uba.ar/7609/material/S1000Estabilidad.pdf