Trabajo descartado

monkeyserna edited this page May 24, 2014 · 10 revisions

Trabajo descartado

A lo largo de todo el desarrollo del proyecto han habido una serie de funcionalidades que se han implementado, pero que por diferentes motivos han sido descartados de la versión final. En este apartado se explica qué es lo que hacían y por qué fueron finalmente descartados.

Aplicación Android nativa

En un principio, la aplicación Android estaba desarrollada de forma nativa, empleando la API oficial de Android y lenguaje Java.

Cuando se decidió realizar el modo de programación de bloques gráficos, se escogió Blockly como lenguaje sobre el que basar este modo de control del robot. Blockly está escrito en Javascript y se ejecuta sobre una página web. En un principio se intentó ejecutar Blockly sobre el elemento WebView que proporciona la API de Android para mostrar páginas web. Por desgracia, este elemento tiene un problema conocido: cuando es necesario escribir un dato (ya sea un número o una cadena de texto) no se despliega el teclado virtual de algunos dispositivos Android (y concretamente el dispositivo empleado en el desarrollo de la aplicación es uno de ellos), por lo que no es posible introducir datos.

Se realizó una profunda investigación acerca de parches y soluciones realizadas por otros desarrolladores que se encontraron con este problema, aunque por desgracia ninguna tuvo resultados satisfactorios. Se implementaron distintos intentos para provocar que se despliegue el teclado, aunque ninguno tuvo éxito.

Se barajó por tanto la opción de ofrecer todos los elementos de entradas con barras desplegables (pudiendo escoger el valor dentro de listas definidas), aunque esto limitaba enormemente las posibilidades. Se descartó también esta opción.

Finalmente se optó por ejecutar el modo de programación sobre PhoneGap, un framework de desarrollo de aplicaciones móviles basado en tecnologías web. Esto solucionó el problema con el despliegue del teclado virtual en Android.

Pero en este punto se presentaba otro problema: Existían dos aplicaciones para controlar el robot, una para cada modo de control. Cada aplicación estaba realizada en un lenguaje de programación distinto. El modo de programación en JavaScript, y el modo de conducción libre en Java, por lo que la tarea de unir las dos aplicaciones en una no resultaba un proceso trivial.

Se optó por tanto por descartar la aplicación nativa escrita en Java, y reescribir desde cero el modo de conducción libre en JavaScript, empleando la API de PhoneGap.

Comunicacion Android-Raspberry mediante protocolo UDP

Cuando se decidió migrar el modo de conducción libre de Java a JavaScript, se presentó otro problema. PhoneGap está basado en tecnologías web, y el código se escribe principalmente en JavaScript (además de HTML y CSS para las interfaces). Por desgracia, no existe ninguna librería en JavaScript para enviar datagramas UDP, ya que las páginas web se ejecutan sobre TCP/IP.

Por otra parte, la comunicación UDP desarrollada presentaba algunos fallos de sincronización al perder paquetes críticos, por lo que en algunos casos el robot recibía comandos erróneos y su comportamiento se volvía inestable. Se implementaron distintos mecanismos para solucionar estos problemas, como la numeración de paquetes y un ACK, aunque el rendimiento pasó a ser muy similar al del protocolo TCP/IP. Se hizo por tanto una pequeña comparativa de rendimiento entre UDP (con ACK y numeración de paquetes) y WebSocket, y finalmente se decidió que la pérdida de rendimiento era asumible.

Por tanto, se descartó el servidor de datagramas realizado en Python, a cambio de un servidor de WebSocket, realizado en el mismo lenguaje.

Por el lado del cliente (la aplicación PhoneGap), se realizó una implementación de la comunicación mediante la librería WebSocket de JavaScript.

Modo rastreador: Implementación en Arduino

Este proyecto nació a partir de un curso de Robótica aplicada con Arduino. En este curso se nos porporcionó tanto la placa Arduino Due como la GoShield-GR, y los estudiantes realizamos un robot siguelineas en código Arduino. Al final del curso el robot era capaz de seguir lineas, y tomar decisiones en intersecciones mediante unas marcas definidas en el circuito de forma autónoma.

Se planteó por tanto la opción de utilizar el código implementado en el curso para añadir un nuevo modo al Robot: El modo rastreador. Este modo, a diferencia de los otros dos (conducción libre y programación gráfica) no tendría intervención del usuario más allá de activar y desactivar el modo rastreador, ya que el robot realizaría de forma independiente la ejecución.

Finalmente, se descartó esta opción para promover el uso del modo Code. Dado que el modo de programación gráfica proporciona todas las herramientas necesarias para realizar la misma actividad, resultaba innecesario implementar este modo. En su lugar, se proporciona el código de un siguelineas realizado en el modo Code, disponible en el apartado Ejemplos de la explicación del modo de programación gráfica.

Lectura del sonar mediante Arduino

Inicialmente, era Arduino quien se encargaba de realizar la lectura del sonar.

En un principio se realizó una implementación secuencial de la lectura. Pero esto presentaba un inconveniente: Cuando el sonar no recibía la señal emitida (el objeto más cercano estaba a más de 3 metros, o con una inclinación que desviaba la señal emitida), se producían largos bloqueos en el código a la espera de recibir esta señal de vuelta, afectando al funcionamiento general de Arduino.

Se planteó por tanto realizar una implementación basada en interrupciones. Es decir, conectar el pin de recepción de la señal a un pin de interrupciones externas de la placa Arduino. Pero las interrupciones presentan otro grave problema: mientras se está ejecutando el código asociado a la interrupción, toda comunicación serie se pierde, por tanto podría ocurrir que la Raspberry enviase comandos que Arduino nunca recibiría. O lo que es peor, recibir solo una parte de ellos y provocar una desincronización. Tras unas pruebas de implementación, se descartó también esta opción.

La solución adoptada (que no fue la definitiva) fue la de delegar la lectura del sonar a un microcontrolador secundario (concretamente el ATTiny85v) , y que éste enviase por comunicación I2C las lecturas efectuadas del sonar.

Sonar controlado desde microcontrolador secundario ATTiny85v

Arduino Due fue inicialmente el encargado de realizar las lecturas del sonar. Sin embargo, esta lectura producía una serie de fallos que dieron lugar a adoptar una solución: emplear un microcontrolador secundario para realizar la lectura del sonar.

Se escogió el micrococontrolador ATTiny85v por su bajo consumo y diminuto tamaño, y porque (en un principio) era capaz de efectuar esta tarea. El objetivo era realizar continuamente lecturas y enviarlas por comunicación I2C a Arduino Due.

Se presentó un problema: En el apartado 15.2.4 del datasheet de este microcontrolador se especifica que este chip es capaz de realizar comunicaciones I2C. Sin embargo, a diferencia de otros chips Atmel, su implementación no está realizada por hardware, y es necesario escribir este protocolo de comunicación por software.

Se empleó la librería TinyWire para realizar esta comunicación. En un principio dio resultados satisfactorios y la comunicación se realizaba correctamente, Arduino Due recibía correctamente las lecturas del sonar. Pero a medida que se fueron realizando pruebas empezaron a ocurrir fallos en la comunicación, y ésta se perdía fácilmente. No era por tanto un método de comunicación estable, y los fallos (aunque no muy frecuentes) no eran aceptables.

En este punto se plantearon una serie de protocolos alternativos con los que realizar la comunicación, aunque finalmente se descartaron todos dado que el tiempo de programación podía llegar a ser excesivo.

La solución definitiva fue delegar la lectura del sonar al último procesador disponible: la Raspberry Pi.

Módulo de frenado de emergencia

El modo de conducción libre contó inicialmente con un módulo de frenado de emergencia. Esta funcionalidad consistía en realizar lecturas constantes del sonar, y cuando se detectase un objeto a menos de 10cm, realizar un frenado de emergencia para prevenir colisiones frontales.

El primer problema derivado de este módulo fueron los falsos positivos. Dado que el sonar tiene unas prestaciones limitadas, algunas lecturas erróneas provocaban un bloqueo improcedente del robot. Esto se palió por medio del descarte de valores atípicos, realizando la media truncada de varias lecturas.

Se decidió descartar esta funcionalidad ya que el problema no se solucionó por completo, y en ocasiones se producían bloqueos en los motores improcedentes. Por otra parte, la funcionalidad que éste módulo aportaba al proyecto era bastante reducida con respecto al impacto en el consumo eléctrico que provocaba el hecho de tener constantemente el sonar en funcionamiento.

Otro motivo del descarte de esta funcionalidad era para promover el uso del modo Code. Esta funcionalidad puede ser implementada mediante el modo de programación gráfica, motivo final para descartar esta funcionalidad. A cambio, se ofrece esta implementación realizada mediante bloques gráficos en el apartado Ejemplos de la explicación del funcionamiento del modo de programación gráfica.

Movimiento horizontal de la cámara

Otra funcionalidad descartada ha sido el desplazamiento horizontal de la cámara y el sonar mediante un servomotor. La cámara y el sonar están adheridas a una base que reposa sobre un par de servos. Uno de ellos controla la inclinación vertical y el otro la inclinación horizontal.

En un principio, ambos servos estaban activos y disponibles, aunque finalmente se decidió descartar el servo horizontal por varios motivos. En primer lugar, hay que tener en cuenta que el robot puede desplazarse, por lo que cualquier ángulo es capaz de ser captado con la cámara empleando únicamente un servo de inclinación vertical y controlando el desplazamiento del robot.

Por otra parte, dificulta la usabilidad del proyecto, ya que añade un componente nuevo con unas funcionalidades prescindibles. También se ha tenido en cuenta el impacto en el consumo eléctrico que conlleva mantener este servo. Por último, su rango de giro está muy limitado, debido a las colisiones con los cables que tiene a su alrededor.

Servidor RTSP para el streaming de la cámara

La opción más lógica para realizar una emisión de la cámara en tiempo real era emplear el protocolo RTSP (Real Time Streaming Protocol). Por desgracia, los resultados obtenidos fueron bastante decepcionantes, ya que el cliente recibía la señal con varios segundos de retraso. Tras reducir el tamaño del buffer y la calidad del vídeo, seguía existiendo un retardo de varios segundos.

Buscando posibles soluciones a este inconveniente, apareció la opción de emitir la señal de la cámara a través de un servidor de imágenes (MotionJPEG). Este sistema consiste en refrescar la imagen de una página web por cada frame capturado por la señal de vídeo. Sorprendentemente, a pesar de realizar más cálculos y que la transmisión sea por TCP/IP, el retardo que proporciona es mucho bajo. De hecho, los mejores resultados de las pruebas realizadas obtienen un retardo menor que 0.1 segundo, retardo casi imperceptible para la mayoría de humanos.

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.