martes, 27 de noviembre de 2007

Off-topic: Ingenieros Informaticos

Lo mal que está hoy en día el trabajo de ingeniero en informático no es ningún descubrimiento.

Buscando por el youtube he encontrado 1 vídeo ( referenciado por la profesora de BDA) que creo que puede ser bastante interesante a la vez que divertido.

Es triste que nos tengamos que reír de algo que nos afecta directamente y que además no tiene ninguna pinta de cambiar. Pero bueno, a mal tiempo buena cara.

Os dejo aquí el enlace al vídeo a ver si os gusta. Por desgracia lo que dice de forma sarcástica es realidad:

http://es.youtube.com/watch?v=mdP7noUwbR4

domingo, 25 de noviembre de 2007

Fotos placa gestion motores



Hola a todos

Como os dije he tenido un poco de tiempo para hacer unas fotos a la placa que gestionará los motores del nuestro robot rabotron. Como podemos ver en la primera imagen tenemos una bateria de 12 v voltios de entrada, aunque es regulada a 5 voltios por el 7805. Tambien podemos ver como a nuestra placa le hemos conectado una placa de pruebas de esas blancas donde hemos conectado leds y resistencias para poder ver a ojo el funcionamiento de la placa (indica direccion y fuerza de cada uno de los motores):



En esta foto podemos ver con más detalle los elementos que hay soldados en nuestra placa. Basicamente están todos menos el puente en H (l293) que lo soldaremos mas adelante, ya que aun no es de vital importancia:



En la siguiente imagen podemos ver las soldadoras por la cara de atrás de la placa ( es un poco rustico):


Por ahora la placa se va a quedar así y voy a ponerme a programar un driver para linux y player/stage que gestione dicha placa, y esta placa que gestione los motores.

jueves, 22 de noviembre de 2007

Primeras pruebas de visión

Una vez decido el formato de color elegido para la identificación de nuestra víctima, hemos de empezar con las primeras pruebas sobre el reconocimiento del objetivo a seguir. Para lo cual ya explicamos en un post anterior que usaríamos el modelo de color HSV (Hue, Saturatión, Value) también conocido como HSB debido a la mayor efectividad que obteníamos analizando colores en comparación con el formato de imagen RGB.

Para una correcta muestra del funcionamiento de nuestra captura de imagen, hemos decidido crear una ventana en la cual mostramos:
-La imagen original en el modelo de color RGB que está recibiendo nuestra cámara
-Una imagen binarizada que representa los puntos que realmente nos interesan de la imagen que estamos capturando.


Actualmente para calcular la imagen binarizada aplicamos un filtro del color que queremos buscar sobre la imagen original en formato HSB, analizando el matriz, la saturación y el brillo de cada píxel de la imagen.

El color que nuestro robot debe localizar lo calculamos a partir de una imagen de la víctima, a través de la cual obtenemos el perfil de matiz, saturación y brillo de nuestra víctima para poder realizar el posterior seguimiento.

Como demostración subiremos un primer vídeo del reconocimiento de una persona basándonos únicamente en el color de la ropa de la misma, para que vayamos haciendo nos una idea del objetivo que vamos persiguiendo en la zona de visión.

Como se puede apreciar hay ruido en la imagen y algunas zonas no reconocidas por problemas de sobras por el ángulo de incisión de la luz sobre la ropa y las arrugas de la misma.

Grabación de Vídeo en Linux

Para poder mostrar al publico externo a la Universidad de Alicante como actúa la visión del robot Rabotron, que mejor manera de realizar algún vídeo con el resultado de alguna de las pruebas que estamos realizando.


Para la captura de vídeo bajo linux de nuestro escritorio de trabajo hemos decidido utilizar el programa “recordMyDesktop”. El software se puede adquirir desde su página web o mediante los repositorios de Debian / Ubuntu.


En nuestro caso hemos optado por la segunda opción:


apt-get install recordmydesktop


Como el software dispone de una versión gráfica y cómoda de usar hemos decido también instalarla


apt-get insta gtk-recordmydesktop


Más rápidamente podemos realizar la instalación conjunta


apt-get install recordmydeskto gtk-recordmydesktop


Una vez realizada la instalación tenemos un acceso directo al software de grabación en: Aplicaciones / Sonido y Vídeo / gtk-recordMyDesktop


Mediante el uso de la versión gráfica podemos seleccionar una sola ventana o la parte del escritorio sobre la que queremos realizar la grabación, así mismo también podemos modificar la calidad de sonido y audio de nuestro vídeo, el uso es realmente sencillo.


Nota: El vídeo grabado por defecto por el software recordmydesktop es en formato OGG.


Como transformar los video OGG a formato AVI:

Estamos teniendo bastante problemas al subir vídeo en formato OGG a youtube, por lo que hemos decido pasarlo al formato AVI antes de subirlos.

Para covertir video en formato OGG al formato AVI usaremos en nuestro caso el software MEncoder, el cual se instala al instalar el Mplayer.

Antes de instalar Mplayer debemos instalar primero el encoder de vídeo mp3 Lame, sino no será posible realizar la conversión de videos con Mplayer, muy importante instalar primero los codecs, sino no compilaremos el Mplayer sin la librería libmp3lame y nos dará un error al realizar la transformación del vídeo.

Para instalar Lame debemos seguir las siguientes pautas: (descargamos la versión 3.97)

# wget http://ufpr.dl.sourceforge.net/sourceforge/lame/lame-3.97.tar.gz
# gunzip -c lame-3.97.tar.gz | tar xvf -
# cd lame-3.97/
# ./configure && make && make install

Ahora llega el momento de instalar el Mplayer, en nuestro caso hemos descargado de la web oficial de Mplayer la versión Mplayer-1.0rc1, la instalación es bastante sencilla:

# tar xvjf MPlayer-1.0rc1.tar.bz2
# cd Mplayer-1.0rc1/
# ./configure
# ./make
# ./make install

Una vez instalado todo simplemente tenemos que ejecutar la orden para convertir nuestro vídeo en OGG a AVI:

# mencoder video_entrada.ogg -ovc lavc -oac mp3lame -o video_salida.avi

martes, 20 de noviembre de 2007

Programa de control del puerto serie / motores

Ya tengo la placa que gestiona los motores soldada. Todo menos el puente en H (L293), con lo que por ahora tengo las salidas del microcontrolador (pic 16f876) enganchadas a unos leds, con resistencias de 220 ya que la salida es de 5v. Con esto consigo ver el funcionamiento del pic y el pueroto serie de una forma gráfica.

En cuanto pueda subiré unas fotos de como va la placa que gestiona los motores y si me da tiempo algun video. Por ahora os voy a comentar el programa en c que he creado en el PICC para recibir datos desde el puerto serie (rs232) y transformarlo en señales para los motores.

Lo primero que queria comentar es que el codigo me he basado en uno que hay hecho por Internet. Y he ido modificando cosas para poder aplicarlo a mi caso (que ha sido bastantes modificaciones).

Basicamente hay una funcion principal que activa los dos pwm(RC1 y RC2):

setup_ccp1(CCP_PWM); //ccp1 modo PWM
setup_ccp2(CCP_PWM); //ccp2 modo PWM

Inicializamos el TIMER2 y activamos dos interrupciones, las interrupciones globales y la de RDA que es cuando recibe datos por el puerto serie.

Despues el programa se queda en un bucle infinito esperando que hayan datos que procesar.

La interrupcion de rda (serial_isr();) se activa cuando llega algo por el puerto serie, conforme va recibiendo datos los va acumulando en un buffer para despues procesarlos.

Por funciones tenemos:

Inicializa --> que inicializa todas las variables globales de nuestro programa.

inicbuffer --> inicializa el buffer de caracteres leidos y lo pone todo a 0x00. Indispensable limpiarlo despues de usarlo, ya que se puede quedar basura que haga un funcionamiento anomalo.

addcbuffer --> Va añadiendo caracteres al buffer, en el caso de que un caracter sea un intro (0x0D) o un espacio (0x20) se corta la ejecucion para procesar los comandos.

aentero --> Convierte la cifra obtenida en caracteres a numero entero, aqui tambien vemos si el valor es negativo, en dicho caso el motor irá en sentido contrario.

procesa_comando --> Una vez que se han introducido los comandos esta funcion es la encargada de sacar los valores (iluminar leds) correspondientes que más adelante moverán los motores.

La forma de usar el programa es pasando valores por el puerto serie de la siguiente forma:
valor1 (espacio) valor2 (intro)

Por ejemplo para mover los motores hacia adelante de una forma continua podria ser:
50 50

Para mover un motor hacia adelante despacio y otro hacia atras muy rapido sería:
8 -100


A continuacion os pego el codigo entero del pic:



//-----------------------------------------------------------------

#include <16f876a.h> // Definiciones del PIC 16F876A
#include <
stdlib> //stdlib.h para el atoi
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT // Los Fuses de siempre
#use delay(clock=4000000) // Oscilador a 4 Mhz
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)// RS232 Estándar



// CONSTANTES /////////////////////////////////////////////////////////////////

int const lenbuff=5; // Longitud de buffer, Ajustar
// a lo que desees (o te sea posible)


// VARIABLES EN RAM ///////////////////////////////////////////////////////////

int motder,motizq;
int sentido, sentidoder, sentidoizq;
int xbuff=0x00; // Índice: siguiente char en cbuff
char cbuff[lenbuff]; // Buffer
char rcvchar=0x00; // último carácter recibido
int1 flagcommand=0; // Flag para indicar comando disponible
char arg[lenbuff]; // para pasar el negativo



// Declaración de Funciones ///////////////////////////////////////////////////

void inicializa(void);
void inicbuff(void); // Borra buffer
int addcbuff(char c); // añade carácter recibido al buffer
void procesa_comando(void); // Procesa comando
int aentero(void); // Pasa el buffer a un entero



// INTERRUPCIONES /////////////////////////////////////////////////////////////

#int_rda
void serial_isr() { // Interrupción recepción serie USART

rcvchar=0x00; // Inicializo carácter recibido
if(kbhit())
{ // Si hay algo pendiente de recibir ...
rcvchar=getc(); // lo descargo y ...
addcbuff(rcvchar); // lo añado al buffer y ...
printf("Recibo: %c ",rcvchar);
}
}



// Desarrollo de Funciones ////////////////////////////////////////////////////


void inicializa()
{
motder=motizq=0;
sentido=sentidoder=sentidoizq=0;
xbuff=0x00; // Índice: siguiente char en cbuff
inicbuff(); //char cbuff[lenbuff]; // Buffer
rcvchar=0x00; // último carácter recibido
flagcommand=0; // Flag para indicar comando disponible
}


void inicbuff(void) // Inicia a \0 cbuff -------------------
{
int i;

for(i=0;i Habilita Flag para procesar
flagcommand=1; // Comando en Main
motizq=aentero(); // Paso a entero
sentidoizq=sentido;// Cambio sentido
inicbuff(); // Borra buffer
break;

case 0x20: // Espacio
motder=aentero(); // Paso a entero
sentidoder=sentido;// Cambio sentido
inicbuff(); // Borra buffer
break;

default:
cbuff[xbuff++]=c; // Añade carácter recibido al Buffer
}
}


int aentero () //pasa el buffer a un entero
{

int retorno,i;


if(cbuff[0]=='-')
{
sentido=0;

i=1;

do{ // Extraemos argumento del buffer
arg[i-1]=cbuff[i]; // copiamos a arg sin el '-'
}while(cbuff[++i ]!=0x00);

retorno=atoi(arg);
}
else
{
sentido=1;
retorno=atoi(cbuff);
}
printf("A entero: %d\n",retorno);

return retorno;
}

// Programa Principal /////////////////////////////////////////////////////////

void main()
{

setup_ccp1(CCP_PWM); //ccp1 modo PWM
setup_ccp2(CCP_PWM); //ccp2 modo PWM

setup_timer_2(T2_DIV_BY_16, 127, 1); // 488Hz (con XT=4MHz) esta frecuencia la podes variar cambiando los valores, fijate en el datasheet del micro que uses, que vienen las relaciones para calcular lo inherente a la frecuencia y al duty.
inicbuff(); // Borra buffer al inicio

printf("Soy el Pic y estoy activo\n");
enable_interrupts(int_rda); // Habilita Interrupción RDA
enable_interrupts(global); // Habilita interrupciones

do {

if(flagcommand) procesa_comando(); // Si hay comando pendiente
// de procesar ... lo procesa.

} while (TRUE);

}

// Procesador de Comandos /////////////////////////////////////////////////////

void procesa_comando(void)
{

flagcommand=0; // Desactivo flag de comando pendiente.

printf ("procesa comando: %d\n",motder);
printf ("procesa comando: %d\n",motizq);

if(sentidoder!=0)
{
printf ("Enciende DER\n");
output_high(PIN_C3);
}
else
{
printf ("Apaga DER\n");
output_low(PIN_C3);
}

set_pwm1_duty(motder); // Se cambia el ancho con el valor obtenido en canal 0.

if(sentidoizq!=0)
{
printf ("Enciende IZQ\n");
output_high(PIN_C4);
output_high(PIN_C5);
}
else
{
printf ("Apaga IZQ\n");
output_low(PIN_C4);
output_low(PIN_C5);
}

set_pwm2_duty(motizq); // Se cambia el ancho con el valor obtenido en canal 0.

inicializa(); // Borra buffer
}

--------------------------------

Espero que os sea de ayuda.
UN SALUDO

jueves, 8 de noviembre de 2007

Ya va el puerto serie

Por fin puedo escribir para dar buenas noticias. Como recordáis os comenté que tenia problemas porque aparentemente la placa con la gestión de los motores debería de funcionar perfectamente y no lo hacía. Pues bien después de mucho esfuerzo, sudores y tres intentos de suicidio he conseguido que funcionara.

Voy a explicar los problemas que localicé. La primera lección chicos para el éxito del proyecto es la siguiente premisa: "No meteré 12 voltios donde van 5". Sí, como oís, al meter mas voltaje me cargué varios componentes de la placa (¿varios? queria decir casi todos). Como ya comenté la otra vez comprar componentes en Alicante es como buscar un balneario en Somalia. El PIC 16F876 fui a comprarlo a una tienda que lo ofertan en el catalogo en inet y recibieron con un: ¿que quieres piratear? Yo flipando. Es como si vas a la ferreteria a comprar un cuchillo y te preguntan ¿A quien vas a matar? Bueno en fin.... Despues de patearme toda alicante he encontrado un sitio donde si que lo tenian, y les he comprado todos los que le quedaban, o sea 5.

Una vez resuelta la papeleta de los componentes, resulta que tenia retorno las pistas de enviar y recibir, Rx Tx. Despues de comerme muchos dias la cabeza resulta que comprendí que la pasta de soldadura es conductora. Toda mi desesperacion se fué en cuanto limpié toda la pasta.

Conclusiones: tengo la placa funcionando a la perfeccion. Al final resulté ser una chorrada. Pero una chorrada que me ha llevado bastante tiempo. Espero poder quedar con mi "jefe de proyecto" para enseñarle los resultados.

El siguiente paso será programar el driver.