Diferencia entre revisiones de «Futbol de Robots 2014»
(→Movimiento en torno al arco) |
(con) |
||
Línea 131: | Línea 131: | ||
Si bien es posible que el robot no varíe su distancia radial a la pelota y sea suficiente, en un escenario de alta precisión en donde el robot tiene un pateador con un desplazamiento limitado, es posible que se requiera un control más fino de la distancia a la pelota. | Si bien es posible que el robot no varíe su distancia radial a la pelota y sea suficiente, en un escenario de alta precisión en donde el robot tiene un pateador con un desplazamiento limitado, es posible que se requiera un control más fino de la distancia a la pelota. | ||
+ | |||
+ | == Paleta Futiá == | ||
+ | |||
+ | |||
+ | [[File:Futia.png|thumb|left|alt=Paleta Futia.|Paleta Futiá]] | ||
+ | |||
+ | La paleta Futiá, que es la manera con la que se interactúa con el plugin, se compone de los siguientes botones: | ||
+ | |||
+ | * Calibración Arco: Permite seleccionar el color para el arco mediante el uso de la cámara | ||
+ | * Calibración Pelota: Permite seleccionar el color para la pelota mediante el uso de la cámara | ||
+ | * Color Arco: Permite indicar el color para el arco en sus tres componentes | ||
+ | * Color Pelota: Permite indicar el color para la pelota en sus tres componentes | ||
+ | * Ir hacia la pelota: Ordena al robot a buscar e ir hacia la pelota | ||
+ | * Pelota visible: Indica si la pelota se encuentra actualmente en la cámara | ||
+ | * Posición arco: Retorna información de la ubicación del arco, si está visible | ||
+ | * Alinear con el arco: Ordena al robot a girar alrededor de la pelota hasta hallar el arco | ||
+ | * Debug: Utilizada para observar la calidad de la selección de los parámetros | ||
+ | * Threshold: Establece los parámetros para la tolerancia. | ||
+ | * Brillo: Ajusta el brillo de la cámara. | ||
== Primitivas Paleta FutRob == | == Primitivas Paleta FutRob == |
Revisión del 21:47 16 jun 2014
Contenido
Introducción
El problema planteado consistía en que un Butiá fuera capaz de resolver los siguientes problemas:
- Encontrar una pelota, fuere donde fuere que se encontrara respecto al robot
- Saber acercarse a la misma
- Saber reconocer el arco
- Saber girar en torno a la pelota hasta tener un buen ángulo al arco
- Patear la pelota, y si lo anterior se hizo de forma correcta, debería dirigirse al arco
Análisis del problema
Principalmente el problema puede descomponerse en dos grandes grupos:
- La ingeniería en el reconocimiento de los objetos ( captura y tratado de imágenes )
- Aspectos mecánicos, tales como el manejo de los motores y el accionamiento del pateador
Vision de Computadora
El problema de la detección del arco y la pelota se decidió resolver puramente utilizando un sensor ya incluido en la Ceibalita: la cámara. La cámara tiene la ventaja de ser un sensor de gran capacidad de captura de información pero requiere de un análisis cuidadoso. En principio, mucha de la complejidad ya viene resuelto por el uso de la librería PyGame aunque no así la algoritmia necesaria para incorporarla ni la calibración pura de un proceso no exacto.
La detección de los objetos se hizo mediante el uso de máscaras. Mediante la aplicación de las mismas, uno es capaz de reconocer las áreas de la imagen capturada que tienen un cierto parecido con la muestra que uno toma como base. Dos funciones sobre las que se basó la implementación fueron pygame.transform.threshold y pygame.mask.from_threshold.
Existen varios modos de manejo de colores. Entre ellos se encuentran RGB, normalmente usado para imágenes visualizadas por un humano, y HSV que descompone el color no en los colores que lo configuran, sino que más bien define un color como una tripleta de propiedades "Tono", "Saturacion" y "Brillo".
Máscaras utilizando RGB
El procesamiento de la imagen en torno a RGB no es tan conveniente como podría parecer. Inicialmente se creyó que podría diferenciarse fácilmente un rojo ( pelota ) y un verde ( pasto ) utilizando el anterior modo, pero ocurrieron inconvenientes.
- Por un lado, las luces. Se observó que los brillos, cuyo color se aproxima al (255, 255, 255), o sea blanco, genera problemas ya que en el caso de la pelota se tendría más verde que el que uno esperaría.
- Por otro lado, y como el robot ha de girar en torno a la pelota, también se tienen sombras, en donde el color de la pelota podría tener menos rojo que el esperado, generando también inconvenientes.
Utilizando RGB no era posible contemplar estos dos aspectos. El primer punto requeriría un criterio como "puede haber mucho verde sólo si hay mucho rojo" y el segundo "si hay poco verde también se puede permitir poco rojo".
Máscaras utilizando HSV
El uso del modo HSV permitió manejar de forma "nativa" los aspectos que con RGB se intentaban emular. El problema se reformuló, y de esta forma lo que en realidad se quería era seleccionar los colores cuyo tono fuera similar. De esta forma, la tolerancia clave que uno debía considerar era en la primer componente ( tono ), teniendo mayor libertad para la selección de las últimas dos.
HSV probó funcionar bastante bien. También presentó problemas en el sentido de que los colores muy claros o muy oscuros variaban su tono de forma más aleatoria. Esto generó ruido, aunque controlado.
El caso de los colores muy claros o muy oscuros no resultó problemático por dos aspectos. Primero, si bien había ruido, era lo suficientemente aleatorio como para no formar grandes acumulaciones de píxeles similares, por ende manejable. Segundo, el ruido no distorsionaba lo que efectivamente se deseaba reconocer, por lo que tampoco fue un problema en este aspecto.
Post-procesamiento
Incluso con una selección adecuada del modo y una calibración exhaustiva no se podían erradicar con certeza todas las posibles interferencias del medio ni las imprecisiones del dispositivo de sensado. Considerar que todo lo que había pasado la "prueba" de la máscara era lo que se deseaba reconocer no era por tanto factible. De esta manera fue necesario "revisar" el producto que la máscara generaba.
No es posible que la pelota se encuentre representada en la cámara por un área de 4 píxeles dadas las distancias que son factibles y dadas las dimensiones razonables de los esféricos a utilizar. De esta forma se consideraron ciertas cotas que los grupos de píxeles reconocidos deben cumplir. Estas cotas fueron básicamente cotas inferiores en los anchos y altos de los grupos reconocidos. De existir algún grupo de píxeles que las cumpla, se retorna ese como reconocido.
Para lo anterior se utilizó la función get_bounding_rects() que permite obtener, para cada agrupación de píxeles, un rectángulo que lo contiene. De esta forma se puede aproximar el tamaño del objeto reconocido. Las cotas de tamaño se aplican sobre estos rectángulos, más específicamente sobre las propiedades height y width de cada uno de ellos. En caso de existir un rectángulo que verifique esas restricciones, se retorna como resultado, brindando además información tal como la posición en la cámara ( top y left ).
Mecánica y actuadores
Otro flanco del problema, prácticamente independiente, era el manejo de la mecánica para lograr que el robot lograra su fin, ya sea éste ir hacia la pelota, obtener un buen ángulo de tiro o incluso patear al arco.
Mecánicamente, el robot Butiá, como muchos otros robots que no cuentan con omniwheels, sólo puede avanzar hacia adelante o hacia atrás. Cuenta con la posibilidad de lograr un movimiento en arco mediante un manejo de motores diferencial, pero no puede moverse hacia los costados. Esta limitación trajo consigo la siguiente discusión:
- Ir hacia la pelota frontalmente es muy simple, pero como el Butiá no puede desplazarse hacia el costado, resulta complejo el movimiento de rotación en torno a la pelota
- Por otra parte, girar en torno a la pelota de forma tangencial es muy simple, pero de esta forma se dificulta la acción de ir a la pelota.
Sin duda que resultaría interesante combinar los aspectos positivos de ambas opciones, de forma tal que:
- Para ir hacia la pelota se desplaza el robot frontalmente
- Para girar en torno a la misma, el desplazamiento se hace de forma lateral
La mecánica es imprecisa, no podemos asumir que las señales que se transmitan a un actuador físico se traducen en movimientos precisos en los cuales podemos confiar. Por esto es que se hace necesario una constante reevaluación de la situación, en contraposición a una actuación ciega. Esto nos obliga a mantener en la vista a la pelota en todo momento. Como se requiere no perder a la misma de vista, la combinación de ambas opciones no resulta factible porque:
- El robot no cuenta con la posibilidad de girar la laptop
- La pantalla no se puede girar, excepto en las XO, y en cuyo caso se requeriría que la pantalla no estuviera inclinada
- Implementar un sistema de rotación de la laptop y/o pantalla requeriría un esfuerzo importante, especialmente en aspectos mecánicos que impactaría en la portabilidad de la solución.
De esta forma se presenta la limitación de que la cámara debe estar fija y se ha de obtener el resultado deseado respetando esta restricción.
Analizando las dos alternativas posibles, la primera en la que la cámara se encuentra posicionada frontalmente y la segunda, en la que la cámara lo está de forma lateral, se decide optar por posicionar la cámara de forma lateral. De aquí en más, todo el análisis de las técnicas de desplazamiento se hace en base a esta decisión.
Análisis de los movimientos requeridos
Partiendo de la base de que la cámara estaba posicionada sobre uno de los costados ( el derecho fue el que se seleccionó finalmente) el único tipo de movimientos con los que se podía avanzar hacia la pelota eran del tipo de arcos, en donde uno motor giraba más rápido que el otro aunque en el mismo sentido, lo que permitía describir un movimiento comparable con un círculo. Avanzar de forma directa hacia la pelota no era posible dado que la misma se encontraría fuera de la vista y supondría un movimiento ciego.
Si asumimos que la pelota debería estar en la vista de la cámara, el movimiento más directo se haría cuando la pelota se encontrara en alguna de las regiones laterales de la pantalla, permitiendo así describir una espiral más cerrada.
En el caso del giro en torno a la pelota, la intención es la de mantener la pelota en el centro de la cámara de modo de que el giro tenga como centro la posición de la pelota.
Manejo de los motores
Tomando como base el hecho de contar con un servidor PyBot corriendo en el servidor local y a quién se le podía delegar sin mayores inconvenientes la tarea de efectivamente mover los motores como se le indicara, se redujo el problema del control de los motores a la función butia.set2MotorSpeed.
Primeras aproximaciones en el caso de ir a pelota
En los primeros intentos se consideraron velocidades constantes, definidas de forma arbitraria y que permitían un funcionamiento razonable. Se consideraron movimientos de recuperación, en donde el robot giraba en dos situaciones:
- Se pierde la pelota de vista. En este caso se gira de modo de volver a traer la pelota a la vista
- La pelota se acerca al centro, abandonando la zona lateral de la pantalla y limitando el acercamiento. En ese caso se gira para llevar a la zona lateral nuevamente.
Los movimientos de recuperación se realizaban con frecuencia, lo que limitaba la eficiencia del algoritmo, aunque no su eficacia. De esta forma se obutuvo un comportamiento que, si bien posiblemente no pueda compararse con el funcionamiento de un ente inteligente, sí lograba el objetivo establecido.
La condición de parada se fijó en el tamaño de la pelota. Si estaba lo suficientemente cerca tendría un tamaño en píxeles razonablemente grande. Esto presentó la necesidad en la práctica de que requeriría la calibración del tamaño de la pelota. Si bien lo anterior no supuso un inconveniente, se demostró que no era un buen indicador por sí mismo dado que no podía definirse con precisión la distancia a la que se encontraba la pelota a partir de su tamaño.
Ajustes de ir a pelota
Para minimizar los retardos ocasionados por los movimientos de recuperación, se ampliaron las franjas laterales aceptables y se calibraron las velocidades para funcionar en varios de los Butiá del laboratorio. Se lograron mayores grados de rendimiento sin impactar negativamente en el rendimiento del algoritmo.
Por otra parte se consideró que la pelota se encontraría a una distancia aceptable cuando se encontrara en la franja inferior de la pantalla. Esto restó importancia a la medición del tamaño de la pelota pero impuso la restricción de que la pantalla y el pateador deberían colocarse de tal manera que la pelota estuviera en el pateador cuando la cámara capturara a la misma en una franja inferior cuya dimensión sería parametrizable.
Movimiento en torno al arco
El movimiento alrededor del arco se demostró ser más sensible a movimientos imprecisos. Girar incorrectamente podría ocasionar acercarse demasiado a la pelota, o acercarse, y por ende requerir volver al paso de localización de la pelota. Por otra parte, establecer zonas, como en el caso anterior, requeriría muy frecuentes recuperaciones, haciendo muy ineficiente el movimiento.
De esta forma se requirió implementar:
- Un movimiento fluido
- Un movimiento preciso
Se mantuvo la idea de franjas, pero la franja principal se dotó de la capacidad de un reajuste "suave" y automático. Básicamente las velocidades de los motores se ligaron a una función de valoración. Como el movimiento alrededor de la pelota para alinear con el arco es en forma de arco, se nombran a cada uno de los motores de la siguiente manera:
- El motor que debe girar más rápido se denomina "externo"
- El motor que debe girar más lento se denomina "interno"
Y se reconocieron dos inconvenientes:
- La pelota se aparta del medio de la pantalla
- El robot se acerca o se aleja de la pelota radialmente.
Para el primer caso, se consideró que el responsable de solucionar la situación era el motor interno. Bastaba con girar según el desfasaje para devolver la pelota a la posición de equilibrio. Estando ésta última en el centro, este motor debía de mantenerse detenido.
Para el segundo caso, el acercamiento de la pelota se reguló con la velocidad externa, aumentándola en caso de querer aproximarse y disminuyendo en caso contrario.
Se observó que la combinación de ambos algoritmos era impredecible y que dificultaba el diagnóstico del comportamiento. Asumiendo que el robot no debería acercarse ni alejarse si la pelota se mantenía en el centro ( esto es, se asume que la cámara está perfectamente colocada ), se limitó el control a "la pelota está siempre centrada". Se quitó la regulación de la velocidad externa, manteniendo la misma constante y haciendo variar únicamente la velocidad interna.
Si bien es posible que el robot no varíe su distancia radial a la pelota y sea suficiente, en un escenario de alta precisión en donde el robot tiene un pateador con un desplazamiento limitado, es posible que se requiera un control más fino de la distancia a la pelota.
Paleta Futiá
La paleta Futiá, que es la manera con la que se interactúa con el plugin, se compone de los siguientes botones:
- Calibración Arco: Permite seleccionar el color para el arco mediante el uso de la cámara
- Calibración Pelota: Permite seleccionar el color para la pelota mediante el uso de la cámara
- Color Arco: Permite indicar el color para el arco en sus tres componentes
- Color Pelota: Permite indicar el color para la pelota en sus tres componentes
- Ir hacia la pelota: Ordena al robot a buscar e ir hacia la pelota
- Pelota visible: Indica si la pelota se encuentra actualmente en la cámara
- Posición arco: Retorna información de la ubicación del arco, si está visible
- Alinear con el arco: Ordena al robot a girar alrededor de la pelota hasta hallar el arco
- Debug: Utilizada para observar la calidad de la selección de los parámetros
- Threshold: Establece los parámetros para la tolerancia.
- Brillo: Ajusta el brillo de la cámara.
Primitivas Paleta FutRob
Al momento se han definido los siguientes primitivas :
- calibrarArco() : Permite cargar el color del arco a partir de la cámara
- calibrarPelota() : Permite cargar el color de la pelota a partir de la cámara
- colorArco(r,g,b) : Establece el color del arco sin usar la cámara
- colorPelota(r,g,b): Establece el color de la pelota sin usar la cámara
- irAPelota() : Hace que el robot vaya hacia la pelota.(Ver si es útil poner un parámetro para posicionar a determinada distancia de la pelota.)
- alinearArco() : Alinearse con el arco.
- patear() : Patea, independientemente de si hay pelota o no.
Y por otro lado:
- bool pelotaVisible() : Indica si la pelota se encuentra visible en la cámara
- bool arcoVisible() : Indica si el arco se encuentra visible en la cámara
- float distanciaAlArco(): Retorna la distancia al arco
- float distanciaPelota(): Retorna la distancia a la pelota
Estas ultimas son para dar algo más de flexibilidad. Por ejemplo, podríamos permitir, con las primitivas anteriores, combinado con las de butía de mover el robot, que alguien programara un algoritmo para un uso determinado.
Reuniones y progreso en el proyecto
Lunes 17 de Febrero de 2014
Se definieron varios puntos en esta reunion:
- Se descartó el uso del plugin de marcas dado a que no permitía resolver el problema de la detección frente a variación de los ángulos, además de requerir un fondo particular.
- Se decidió optar por el uso del plugin FollowMe, aunque modificado, para la detección del arco. La idea sería la de distinguir, por lo menos en un principio sólo los dos verticales, de modo de poder apuntar al arco. Las librerías subyacentes ( PyGame ) permiten la detección de múltiples objetos. Se constató que en el caso de FollowMe sólamente se utilizaba el primer objeto encontrado ( índice 0 ), por lo que podría ser un indicio de que es el camino a seguir.
- Si bien se consideró que en un principio se podría considerar el arco como dos verticales ( sin horizontal ) de modo que el objeto a observar se componiera de dos partes conexas para facilitar el reconocimiento, esta idea quedó de lado al considerar que se podría realizar un reconocimiento de los verticales si se intentaba aproximarlos a rectángulos, situación en la que el vertical no debería interferir demasiado.
- Se descartó la simplificación de colorear cada vertical de modo de diferenciarlos entendiéndose que existía una pérdida importante de generalidad.
- Se confirmó la idea de colocar la cámara al costado, para facilitar el alineamiento con el arco. El acercamiento inicial se realizará mediante una espiral, manteniendo siempre en la franja izquierda de la vista de la cámara a la pelota. La distancia con el objetivo se calculará mediante la cantidad de píxeles, y el alineamiento con el arco se realizará manteniendo la pelota en el medio de la pantalla de modo de hacer un movimiento tangencial y mantener la distancia.
- Se sugiere investigar PyGame reconoce figuras
- Se sugiere leer discucion de salimoo, para no repensar cosas
Aspectos a definir
- Zona de ubicacion de la pelota(en determinadas zonas puede tener vision parcial del arco y en pricipio estaría fuera del alance del proyecto)
- Aspectos mecánicos tales como la posición del pateador, si se utilizará algun soporte mecánico adicional y si la precisión de la cámara resulta adecuada o si es necesario utilizar sensores adicionales.
Lunes 3 de Febrero - Ideas
Busqueda - Posicionarse - Patear
Realizar la búsqueda frontal y girar el butiá para posicionarse, al girar el butiá surge la necesidad de girar la pantalla.
Se piensa en utilizar un motor AX12 para realizar el giro de la pantalla.
¿Aplicación a parte o plug-in para TurbleBots?
Contactar a Alan o Nico para el uso del plug-in.