Presentación
Este blog ha sido crado para la asignatura de Visión en Robótica del máster de Visión Artificial. El objetivo principal es ir subiendo los avances que vaya haciendo en las prácticas de esta asignatura. Tenemos tres prácticas que hacer. La primera es la práctica 0 en la que hay que instalar Gazebo y los componentes GazeboServer e Introrob del software JdeRobot que serán con los que trabajemos. En la práctica 1 hay que hacer el seguimiento de una línea de color con una sóla cámara y en la práctica 2 se realizará una reconstrucción 3D mediante un sistema estereoscópico.
viernes, 21 de junio de 2013
Pica 0 Mejoras
Ayer estuve haciendo algunas mejoras al programa. Incorporé información de color a los puntos 3d que se dibujan y además añadí una restricción de que la diferencia entre los parches no puede tener más de un cierto valor, así me quito falsas correspondencias. Como se puede ver en el vídeo, el color no lo representa del todo bien. En el pato sí que salen puntos amarillos, pero salen también muchos blancos. No se si es por la escala de la imagen que es demasiado grande al representarla (aunque ya he intentado cambiarla sin éxito) o que coge el color de otros puntos como el cielo.
jueves, 23 de mayo de 2013
Práctica 2 (Pica 0, Depuración)
He depurado todo el código para que se haga más rápido todo el proceso. Lo primero que he hecho ha sido separar la parte de procesado de la imagen de la de dibujado en el mundo. Ahora el procesado se hace en el thread de ejecución y el dibujado en el de gráficos.
En la parte en la cual recorría las dos lineas de retroproyección para encontrar el punto de menor distancia entre ambas rectas, he modificado el código de forma que he eliminado un bucle for y un condicional if.
En la parte en la cual busco correspondiencias entre puntos, he decidido poner una disparidad máxima y he cambiado la función de comparación de OpenCv (matchtemplate) por una propia en la que hago la diferencia absoluta de los dos Roi pixel a pixel y sumo todas las diferencias para obtener un único valor.
Para terminar he eliminado algunas variables que tenían datos redundantes.
Ahora el cálculo de puntos se hace mucho más rápido como puede verse en el vídeo. Lo que más tarda es el dibujado, que creo que podré mejorarlo utilizando otra función de pintado de los puntos.
En la parte en la cual recorría las dos lineas de retroproyección para encontrar el punto de menor distancia entre ambas rectas, he modificado el código de forma que he eliminado un bucle for y un condicional if.
En la parte en la cual busco correspondiencias entre puntos, he decidido poner una disparidad máxima y he cambiado la función de comparación de OpenCv (matchtemplate) por una propia en la que hago la diferencia absoluta de los dos Roi pixel a pixel y sumo todas las diferencias para obtener un único valor.
Para terminar he eliminado algunas variables que tenían datos redundantes.
Ahora el cálculo de puntos se hace mucho más rápido como puede verse en el vídeo. Lo que más tarda es el dibujado, que creo que podré mejorarlo utilizando otra función de pintado de los puntos.
martes, 21 de mayo de 2013
Practica 2 (pica 0)
Para que el robot coja él solo los puntos interesantes, he hecho un filtro de canny y he cogido sólo el borde (valor 255). He tenido muchos problemas en esta parte, ya que los valores que me devolvía la función Mat.at no eran correctos. He probado con muchos tipos de datos y con ninguno parecía darme valores adecuados. Al final he tenido que usar IplImage en vez de Mat y usar un ejemplo de introrob.
Como me funciona muy lento el algoritmo, en vez de hacer dos bucles for cada vez que entra una nueva imagen para recorrerla, he hecho que con cada nueva imagen coja un punto distinto.
jueves, 16 de mayo de 2013
Practica 2 (Pica 1)
He incorporado la búsqueda de correspondencias del punto clickado en la imagen izquierda con la derecha. Para ello, voy buscando mdiante una función de distancia, el parecido entre una Roi extraída alrededor del punto clikado en la imagen izquierda con la imagen derecha. Para que la búsqueda sea más rápida, extraigo la línea epipolar de la imagen derecha para después hacer la búsqueda alrededor de ésta.
Además he corregido un error que tenía a la hora de sacar la línea de retroproyección. No sacaba la línea de retroproyección del punto que más se parecía, sino el de la esquina superior izquierda de la Roi a la que pertenecía.
Además he corregido un error que tenía a la hora de sacar la línea de retroproyección. No sacaba la línea de retroproyección del punto que más se parecía, sino el de la esquina superior izquierda de la Roi a la que pertenecía.
lunes, 29 de abril de 2013
Práctica 2 (Pica 2)
He incorporado la búsqueda de correspondencias del punto clickado en la imagen izquierda con la derecha. Para ello, voy buscando mdiante una función de distancia, el parecido entre una Roi extraída alrededor del punto clikado en la imagen izquierda con la imagen derecha. Para que la búsqueda sea más rápida, extraigo la línea epipolar de la imagen derecha para después hacer la búsqueda alrededor de ésta.
Además he corregido un error que tenía a la hora de sacar la línea de retroproyección. No sacaba la línea de retroproyección del punto que más se parecía, sino el de la esquina superior izquierda de la Roi a la que pertenecía.
Además he corregido un error que tenía a la hora de sacar la línea de retroproyección. No sacaba la línea de retroproyección del punto que más se parecía, sino el de la esquina superior izquierda de la Roi a la que pertenecía.
martes, 9 de abril de 2013
Práctica 1(parte 4)
Alex y Fran me han comentado que medir el tiempo que tarda el robot en dar la vuelta con un cronómetro externo no es muy acertado, ya que mi ordenador es un poco lento y los tiempos real y simulado no concuerdan. Así que he vuelto a cronometrar al robot pero con el tiempo simulado que da gazebo. El robot tarda 3 minutos y 15 segundos en dar la vuelta, por lo que el tiempo es mejor de lo que pensaba.
jueves, 28 de marzo de 2013
Práctica 1 (parte 3)
Después de implementar el control con derivada para que el robot zigzaguee menos y de subir un poco las líneas del error para el giro, he implementado otras dos líneas por encima de las que ya tenía, de forma que puedo medir el error de lo que vendrá y anticiparse un poco más.
Con el error de estas líneas consigo saber hacia dónde irá la próxima curva y lo cerrada que es. De esta forma puedo adaptar la velocidad y el giro del robot.
Ahora la función que dice cuánto debe girar el robot, depende del error de giro de las dos líneas del principio, de la derivada de este error y del error de las nuevas líneas.
La velocidad del robot depende de la línea vertical que tenía desde un principio y del error de las nuevas líneas. De esta forma si lo que se aproxima es una curva muy cerrada, (hay mucho error en la anticipación) el robot empezará a ir más lento o a frenar.
Además he definido una serie de circunstancias para definir cuánto debe contribuir cada uno de los errores para el giro. Si las dos líneas superiores de error (las nuevas que tienen que dar la anticipación) no consiguen ver el camino, es porque el robot probablemente está en una curva muy cerrada. Lo que interesa es que el robot gire muy deprisa para perder el menor tiempo posible, por lo que la contribución al giro del error de las dos líneas inferiores (las del principio) es muy grande.
Cuando el robot va en línea recta, la contribución de este error es menor pero se tienen también en cuenta el error de las líneas superiores, para que el robot empiece a girar un poco antes de estar en la curva, y la derivada, para que no zigzaguee demasiado.
Cuando el robot va lento suele ser porque está en una curva no muy cerrada. Como me interesa que resuelva estas de forma rápida, cuando el robot va lento, la contribución de las líneas superiores al giro es mayor que cuando va deprisa (en línea recta).
Con el error de estas líneas consigo saber hacia dónde irá la próxima curva y lo cerrada que es. De esta forma puedo adaptar la velocidad y el giro del robot.
Ahora la función que dice cuánto debe girar el robot, depende del error de giro de las dos líneas del principio, de la derivada de este error y del error de las nuevas líneas.
La velocidad del robot depende de la línea vertical que tenía desde un principio y del error de las nuevas líneas. De esta forma si lo que se aproxima es una curva muy cerrada, (hay mucho error en la anticipación) el robot empezará a ir más lento o a frenar.
Además he definido una serie de circunstancias para definir cuánto debe contribuir cada uno de los errores para el giro. Si las dos líneas superiores de error (las nuevas que tienen que dar la anticipación) no consiguen ver el camino, es porque el robot probablemente está en una curva muy cerrada. Lo que interesa es que el robot gire muy deprisa para perder el menor tiempo posible, por lo que la contribución al giro del error de las dos líneas inferiores (las del principio) es muy grande.
Cuando el robot va en línea recta, la contribución de este error es menor pero se tienen también en cuenta el error de las líneas superiores, para que el robot empiece a girar un poco antes de estar en la curva, y la derivada, para que no zigzaguee demasiado.
Cuando el robot va lento suele ser porque está en una curva no muy cerrada. Como me interesa que resuelva estas de forma rápida, cuando el robot va lento, la contribución de las líneas superiores al giro es mayor que cuando va deprisa (en línea recta).
sábado, 23 de marzo de 2013
Práctica 1 (parte 2)
Hoy he hecho un par de cambios en el algoritmo. He subido un poco la líneas horizontales que dan el error para girar. Así el robot se anticipa un poco más a las curvas. También he implementado la corrección del error por derivada en el control de giro. Así el robot no va zigzagueando tanto en las líneas rectas. Con estos cambios he conseguido realizar el circuito en 4 minutos y 25 segundos, aunque el tiempo varía en cada vuelta.
He decidido no desplazar las lineas del centro de la imagen hacia la derecha, como decía en la anterior entrada, porque apenas se nota el desplazamiento que mencionaba y el robot queda muy lejos de salirse.
He decidido no desplazar las lineas del centro de la imagen hacia la derecha, como decía en la anterior entrada, porque apenas se nota el desplazamiento que mencionaba y el robot queda muy lejos de salirse.
viernes, 22 de marzo de 2013
Práctica 1
La práctica 1 consiste en programar un robot para seguir una línea azul. Concretamente el robot es un pioneer 2dx equipado con dos cámaras, aunque sólo podemos usar la izquierda. Por lo que nuestra información de entrada es algo como esto.
Lo primero que he hecho ha sido un filtro del color azul sobre los canales RGB, pero sólo de la mitad inferior de la imagen, ya que esto hace que el tiempo de cómputo sea menor y quita el cielo directamente. En vez de usar sólo un umbral por canal, tal y como venía en el ejemplo de MyAlgorithms.cpp, he usado dos. El resultado es el siguiente.
No se si se ve muy bien pero en las curvas hacia la izquierda se desvía un poco del centro de la línea a seguir. Ésto se debe a que la cámara que usamos es la izquierda y las líneas que extraen información de la imagen están centradas en la imagen. Por lo tanto tengo que desplazarlas un poco hacia la derecha.
El siguiente paso será subir la velocidad a la que se mueve el robot, ver hasta dónde puede llegar y convertir el sistema de control en un sistema PD o PID para mejorarlo.
Lo primero que he hecho ha sido un filtro del color azul sobre los canales RGB, pero sólo de la mitad inferior de la imagen, ya que esto hace que el tiempo de cómputo sea menor y quita el cielo directamente. En vez de usar sólo un umbral por canal, tal y como venía en el ejemplo de MyAlgorithms.cpp, he usado dos. El resultado es el siguiente.
Como el resultado es muy bueno, he decidido no hacer (por lo menos de momento) el filto sobre los canales HSV, ya que tendría que transformar la imagen a este espacio de color y eso lleva consigo un cómputo extra. Sin embargo si se quisiese llevar la aplicación a un entorno más real, con cambios de iluminación, el filtro tendría que hacerse en el espacio HSV, ya que es más robusto a estos cambios.
Para controlar del robot, de momento e implementado dos sistemas reactivos, uno para la velocidad de avance y otro para el giro. El primero contiene una línea vertical centrada en el medio y que cuenta el número de píxeles que se encuentran dentro de la línea a seguir (son de color blanco). La velocidad del robot es proporcional a este número de píxeles. Por lo tanto, el sistema de control no es proporcional a un error, sino al "acierto".
El segundo contiene dos líneas horizontales que se encuentran a la misma altura. Empiezan en cada uno de los dos extremos de la imagen y terminan en el punto donde se cortan con la línea vertical. El sistema consiste en contar el número de píxeles de estas líneas que pertenecen a la línea a seguir (píxeles blancos) y restarlos entre ellos. Por lo que el error en este control reactivo sería la diferencia de píxeles entre el lado derecho y el izquierdo. De esta forma se mide cuánto esta el robot desviado hacia uno de los lados respecto a la línea a seguir.
Las líneas que miden el número de píxeles son las que se muestran en rojo en la siguiente imagen (aunque no se ve en la imagen, cada línea llega hasta los laterales izquierdo, inferior y derecho de la imagen).
El robot tarda un poco más de 4 minutos y medio en dar una vuelta al circuito. Los resultados obtenidos con este sistema pueden verse en el siguiente vídeo, en el que se ve al robot haciendo una parte del circuito (hasta que se me cierra introrob).
El siguiente paso será subir la velocidad a la que se mueve el robot, ver hasta dónde puede llegar y convertir el sistema de control en un sistema PD o PID para mejorarlo.
jueves, 21 de marzo de 2013
Práctica 0
La práctica 0 consiste en instalar Gazebo y los componentes necesarios de Jderobot (GazeboServer e Introrob) para poder hacer las prácticas 1 y 2.
Gazebo es el emulador que utilizaremos para emular el robot y crear un mundo virtual con el que probar nuestros algoritmos.
Introrob es un componente de Jderobot creado para los estudiantes con el cual se puede manejar el robot y correr nuestro algoritmo, que debe estar en el archivo MyAlgorithms.cpp.
GazeboServer es el componente que conecta Gazebo con introrob.
Para instalar Gazebo he utilizado los repositorios oficiales y el gestor de paquetes Synaptic.
Una vez que funcionaba Gazebo he descargado los paquetes GazeboServer, Introrob y models de la página web de jderobot en la secciónTeaching y los he metido en una carpeta juntos.
http://jderobot.org/index.php/Teaching_robotics_with_jderobot
Para que GazeboServer e Introrob funcionen hay que compilarlos. Para ello en la terminal hay que ir a la carpeta build y compilarlos con cmake con los siguientes comandos.
cd (path)/GazeboServer/build
cmake ..
make
cd (path)/introrob/build
cmake ..
make
Al hacer cmake .. me decía que me faltaban algunas librerías que tuve que instalar con el siguiente comando.
sudo apt-get install (librería)
Después hay que meter los modelos descargados en la carpeta correspondiente de gazebo para poder cargarlos. Para ello en la carpeta /home/(usuario)/.gazebo he copiado todo lo que contiene el paquete models.
Una vez que ya se ha compilado todo es hora de lanzarlo.
Primero hay que lanzar GazeboServer. Para ello en la terminal hay que ir a la carpeta build de GazeboServer y lanzarlo dándole como entrada el mundo que queremos lanzar.
cd (path)/GazeboServer/build
gazebo ../jaramaSigueLineas.world
Después hay que lanzar introrob desde otra terminal. Para ello hay que ir a la carpeta de introrob y lanzarlo con lo siguientes comandos.
cd (path)/introrob/build
./build/introrob --Ice.Config=introrob.cfg
Introrob nos da la posibilidad de manejar el robot mediante el joystick y ver lo que ven sus cámaras. Además si le damos al botón de play, se ejecutará el código que hayamos metido en el archivo MyAlgorithms.cpp. Cada vez que se hace un cambio en este archivo hay que recompilar introrob, para ello sólo hay que ir a la carpeta build y hacer make con la terminal para que se puedan ejecutar los cambios.
cd (path)/introrob/build
make
Mi primer programa ha sido implementar un contador de iteraciones, para ello he hecho una variable que sumaba uno cada vez que se entraba en la función de MyAlgorithms y después lo mostraba en la terminal con printf("%d\n",cont);
Gazebo es el emulador que utilizaremos para emular el robot y crear un mundo virtual con el que probar nuestros algoritmos.
Introrob es un componente de Jderobot creado para los estudiantes con el cual se puede manejar el robot y correr nuestro algoritmo, que debe estar en el archivo MyAlgorithms.cpp.
GazeboServer es el componente que conecta Gazebo con introrob.
Para instalar Gazebo he utilizado los repositorios oficiales y el gestor de paquetes Synaptic.
Una vez que funcionaba Gazebo he descargado los paquetes GazeboServer, Introrob y models de la página web de jderobot en la secciónTeaching y los he metido en una carpeta juntos.
http://jderobot.org/index.php/Teaching_robotics_with_jderobot
Para que GazeboServer e Introrob funcionen hay que compilarlos. Para ello en la terminal hay que ir a la carpeta build y compilarlos con cmake con los siguientes comandos.
cd (path)/GazeboServer/build
cmake ..
make
cd (path)/introrob/build
cmake ..
make
Al hacer cmake .. me decía que me faltaban algunas librerías que tuve que instalar con el siguiente comando.
sudo apt-get install (librería)
Después hay que meter los modelos descargados en la carpeta correspondiente de gazebo para poder cargarlos. Para ello en la carpeta /home/(usuario)/.gazebo he copiado todo lo que contiene el paquete models.
Una vez que ya se ha compilado todo es hora de lanzarlo.
Primero hay que lanzar GazeboServer. Para ello en la terminal hay que ir a la carpeta build de GazeboServer y lanzarlo dándole como entrada el mundo que queremos lanzar.
cd (path)/GazeboServer/build
gazebo ../jaramaSigueLineas.world
Después hay que lanzar introrob desde otra terminal. Para ello hay que ir a la carpeta de introrob y lanzarlo con lo siguientes comandos.
cd (path)/introrob/build
./build/introrob --Ice.Config=introrob.cfg
Introrob nos da la posibilidad de manejar el robot mediante el joystick y ver lo que ven sus cámaras. Además si le damos al botón de play, se ejecutará el código que hayamos metido en el archivo MyAlgorithms.cpp. Cada vez que se hace un cambio en este archivo hay que recompilar introrob, para ello sólo hay que ir a la carpeta build y hacer make con la terminal para que se puedan ejecutar los cambios.
cd (path)/introrob/build
make
Mi primer programa ha sido implementar un contador de iteraciones, para ello he hecho una variable que sumaba uno cada vez que se entraba en la función de MyAlgorithms y después lo mostraba en la terminal con printf("%d\n",cont);
Presentación
Este blog ha sido crado para la asignatura de Visión en Robótica del máster de Visión Artificial. El objetivo principal es ir subiendo los avances que vaya haciendo en las prácticas de esta asignatura. Tenemos tres prácticas que hacer. La primera es la práctica 0 en la que hay que instalar Gazebo y los componentes GazeboServer e Introrob del software JdeRobot que serán con los que trabajemos. En la práctica 1 hay que hacer el seguimiento de una línea de color con una sóla cámara y en la práctica 2 se realizará una reconstrucción 3D mediante un sistema estereoscópico.
Suscribirse a:
Entradas (Atom)



