Dia 4 - Práctica 2

jueves, 24 de febrero de 2011
¿Qué tal?,

Ya han pasado otras dos semanas y aquí estamos de nuevo, esta vez con la práctica 2. En esta práctica profundizaremos en los sensores que se le puede incluir a bracitos!!, en concreto el sensor de ultrasonidos, de contacto, de luz y de sonido.

Para comenzar tuvimos que poner con las piezas necesarias cada sensor para su correcto funcionamiento, os ponemos las imágenes de cada sensor.

     Sensor de contacto                                             Sensor de luz                      
 
                          

   Sensor de sonido                                             Sensor de ultrasonido

                        



Con los sensores instalados, nos pusimos manos a la obra con la práctica. En primer lugar se nos pedía escribir un programa que mostrara la siguiente información en el display LCD del robot:

- Nombre del robot: Para este apartado usamos la función getName(), de la clase NXTCommDevice.

- Valor del sensor de ultrasonidos en mm: Para obtener el valor usamos la función getDistance().

- Valor del sensor de luz: Este apartado se divide en dos, el primero obtener el valor en crudo con la función readNormalizedValue() y el segundo calibrar los valores altos y bajos del ambiente donde nos encontremos con las funciones calibrateLow() y calibrateHigh() respectivamente.

- Tensión de la batería en Milivoltios: Para este apartado usamos la función getVoltageMilliVolt(), de la clase Battery.

- Memoria libre disponible en Bytes: Usamos la función getRuntime().freeMemory() de la clase Runtime.

Este apartado fue bastante fácil y no nos costo mucho, pero para no enrollarnos más , os mostramos una imagen donde se confirma el correcto funcionamiento de nuestro código.


Seguidamente pasamos a la instalación del sensor de sonido en nuestro robot. En esta parte realizamos un programa para que cuando se escuche una palmada el robot sea capaz de parar y reanudar su camino con otra palmada. Primero tuvimos que hacer una medida del sonido ambiente para que el sensor de sonido estuviera calibrado correctamente. Para  obtener el valor medido del sensor de sonidos  utilizamos la función readValue(). Hemos definido el valor de una palmada como el valor de una constante + el sonido ambiente, de este modo habrá una mayor posibilidad de que "Bracitos" se pare justo en el momento de la palmada.
Adjuntamos un vídeo que demuestre el correcto funcionamiento:






A continuación, seguimos con el siguiente apartado. El objetivo es lograr que "Bracitos" camine por su entorno y cuando choque contra un obstáculo, éste  debe retroceder y girar un número aleatorio de grados y continuar avanzando. Para el cálculo de este número aleatorio usamos la función Math.random. Además este número de grados será mostrado por pantalla en cada giro.




La siguiente parte de la práctica es muy similar a la anterior, pero con la clara diferencia que debe evitar los obstáculos, es decir, no chocar contra ellos. Para dectectar los obstaculos usamos el sensor de ultrasonidos. La distancia mínima que hay que tener con los obstáculos es de 20 centímetros.
Para mayor claridad, mostramos por pantalla el número de grados que gira el robot al toparse con un impedimento junto con a distancia que nos encontramos de él.



El siguiente apartado se nos pedía seguir la pared para salir de un laberinto.  Hemos definido un intervalo 'x', en el cual el robot anda en linea recta, a continuación usamos un controlador D, es decir, dependiendo de la distancia a la pared, si la distancia es < que la 'x' definida entonces el robot girará hacia un lado, y si lo supera girará al lado contrario.



Finalmente llegamos al último apartado. Es el más costoso y, por tanto, el que más puntos vale. Cuando se trabaja con sensores, existen variaciones del mismo modelo que influyen negativamente en el correcto funcionamiento de nuestra aplicación. Por ello, es necesario modelar las características particulares de los sensores que utilizamos.
Los pasos son los siguientes:

* Acercar y alejar el robot de la pared y anotar la distancia máxima y mínima que puede medir el sensor.
Mediante el uso de un metro, comprobamos que la distancia mínima que mide nuestro sensor es alrededor de 6cm, y la distancia máxima 254cm. Podemos comprobar que el sensor tiene una exactitud bastante grande.




* Situar el robot a 40 centímetros de la pared y girar el robot de manera que el ángulo con respecto a la pared aumente. Estos giros deben ser menores o iguales a 10 grados. Anotar el máximo ángulo que podemos girar para que los valores sean válidos.

Para este apartado pusimos al robot en perpendicular a la pared, y mediante giros de 10º ibamos comprobando la distancia que podia medir el sensor. Esto nos dió que a distancias entre el intervalo [-55º | +55º] el sensor de ultrasonidos deja de darnos la distancia correcta.

* Colocar el robot a una distancia de la pared de 20, 30, 40, 50, 60, 70, 80, 90 y 100 centímetros y apuntar el valor que nos indique el sensor de ultrasonidos. La finalidad de esto es conocer si el sensor tiene un error sistemático.


las medidas de toda la tabla están en cm

Observando la tabla podemos apreciar que la diferencia máxima, medida en centímetros, entre la distancia real y la distancia medida es 2 centímetros. Por tanto, podemos asegurar que el sensor funciona de manera más que aceptable.
Para el cálculo del error sistemático de nuestro sensor, basta con realizar el sumatorio de las medidas resultantes de la diferencia entre la distancia real y la marcada por el sensor y dividirla entre las nueve medidas tomadas, es decir, 14/9=1,5555556 cm.

* Calcular la incertidumbre del sensor en el eje X. Para ello, colocamos el robot a una distancia de la pared de 40, 50, 60, 70, 80, 90, 100, 110 y 120 centímetros. Por cada distancia tomamos 10 medidas distintas, desconectado y volviendo a conectar el sensor de ultrasonido para cada una de las medidas. Anotar la diferencia entre la distancia medida y la distancia real (xi − x).

las medidas de toda la tabla están en cm
Observado la tabla podemos apreciar claramente que en el eje X el error sistemático es ínfimo, siendo su error mas grande 0.3 centímetros para una distancia de 40 centímetros. Para el resto de valores los resultados son los esperados ya que la distancia marcada por nuestro sensor se corresponde prácticamente con la distancia real.


* Calcular la incertidumbre del sensor en el eje Y. Para realizar este calculo, colocamos el robot en el origen de coordenadas. Mediante el uso de un folio vamos a determinar a qué distancia del eje X comienza a detectar el obstáculo. Colocamos el folio a 10, 20, 30, 40, 50, 60 y 80 centímetros del eje X y apuntamos en qué momento es percibido por el sensor. Realizar el mismo proceso colocando el elemento a la altura del eje X que está a 40, 50, 60, 70, 80, 90, 100, 110, 120 centímetros del robot.

Este apartado destaca por su pesadez a la hora de tomar valores. Plasmamos los resultados en la siguiente tabla:

las medidas de toda la tabla están en cm

Si observamos la tabla podemos ver como más o menos se dibuja el cono de apertura descrito en el guión de la práctica. El valor medio más elevado, siendo asi la cumbre del cono, es a una distancia de 80 centímetros en el eje de la X ya que ve el obstáculo a 14.5 centímetros en el eje de la Y.
En este caso la precisión es menor que anteriormente ya que el sensor tiene mayor dificultad de reconocer los objetos que no están en su vertical.

Añadimos un par de fotos para demostrar la toma de medidas.


* Hallar la matriz de covarianza, ya usada en la práctica anterior.

A continuación mostraremos las 10 covarianzas que se corresponden con las nueve medidas dadas en el guión.


1º Medida (40 cm)    2º Medida (50 cm)    3º Medida (60 cm)


| 0.21 -0.18 |                  | 0.09 -0.14 |                | 0.00 0.00 |
| -0.18 0.44 |                  | -0.14 0.64 |                | 0.00 0.25 |


4º Medida (70 cm)    5º Medida (80 cm)    6º Medida (90 cm)


| 0.00 0.00 |                   | 0.00 0.00 |                 | 0.00 0.00 |
| 0.00 0.56 |                   | 0.00 0.25 |                 | 0.00 0.21 |


7º Medida (100 cm)  8º Medida (110 cm)   9º Medida (120 cm)

| 0.00 0.00 |                   | 0.00 0.00 |                 | 0.00 0.00 |
| 0.00 0.16 |                   | 0.00 0.29 |                 | 0.00 0.40 |


En conclusión hemos realizado una covarianza general con los nueve resultados mostrados anteriormente. La matriz es la siguiente:


| 0.03   -0.035 |
| -0.32  0.35    |




Así son las cosas y así se las hemos contado.

Día 3 - Práctica 1

martes, 8 de febrero de 2011
Buenas,

Durante estas dos últimas semanas hemos estado elaborando la práctica 1. Se trata de una toma de contacto con el API que proporciona LeJOS, en donde manejaremos el uso básico de los motores y de la pantalla LCD.

Lo primero que hicimos fué configurar el eclipse siguiendo las instrucciones que vienen en la documentación entregada, no nos costo nada puesto que estaba muy bien explicado cada paso.

Los apartados de la práctica son los siguientes:

- BasicMotor1: Debíamos crear un programa que al tocar un botón el motor se moviera hasta que volviéramos a tocar otro botón. Para conseguir este primer objetivo, hemos utilizado las funciones:
  • Button.waitForPress(), permite recoger la pulsación de un botón del ladrillo.
  • Motor.A.forward(), su funcion es mover hacia alante el motor A.
  • Motor.A.stop(), detiene instantáneamente el motor A.


- BasicMotor2: En este segundo apartado, debíamos conseguir que el motor rotase 45º al pulsar un botón. Fue una tarea sencilla y las funciones utilizadas fueron Button.waitForPress() y Motor.A.rotate(45).



- BasicMotor3: Se debe obtener el mismo resultado que en el apartado anterior pero usando el método rotateTo(). El funcionamiento de rotateTo() es similar a rotate(), pero la única diferencia es que hay que reiniciar la odometría del motor para que el motor gire. Esto se consigue con la función Motor.A.resetTachoCount().



- Visualización de la odometría del motor: En este apartado, se nos pedía escribir un programa que mostrara constantemente la posición del motor (grados de giro) en el LCD del ladrillo. El angulo mostrado debia estar en el rango [0.360]. En sí lo sacamos rápido, aunque nos costó un rato mostrar el ángulo correcto y no ángulos negativos o superiores a 360º.





- Cuadrado de calibración de movimiento: Consiste en poner un lápiz próximo al eje de rotación del robot de manera que dibuje su trayectoria en el suelo a medida que se desplaza. Lo lados del cuadrado dibujado deben ser de 40 cm cada uno. El proceso ha de repetirse para 10 iteraciones.

Esta parte se nos atragantó un poco, porque al principio no eramos capaces de meter un bolígrafo en un espacio tan pequeño. Pero tras varias chapuzas, llego la versión final y hemos de decir que nos quedó bastante bien centrado con respecto a los ejes de las ruedas.



Haga click en la imagen para agrandar!!

Tras ponerle las piezas necesarias, nos pusimos a hacer el programa en sí, el cual no tenía mayor complicación. En el siguiente vídeo os mostramos como funciona:



Como podemos observar en el vídeo, el cuadrado lo hace aparentemente perfecto. Aunque no se aprecia la linea que va haciendo el robot en el vídeo, hemos remarcado cada linea en cada una de las 10 iteraciones para que quedase mas vistoso y este es el resultado.Hay que decir que al ser una cartulina, una mina de lápiz no da para mas...y no pinta como nos gustaría.Por otro lado, lo hemos probado en un folio normal y pinta con normalidad.

Haga click en la imagen para agrandar!!




En la imagen anterior tenemos donde empezaba y acababa nuestro robot cada vez que iniciábamos el programa. Podemos observar una desviación clara pero esto sucede a esta velocidad, ya que si bajamos la velocidad el programa tendría una precisión de 99.9%. En las aulas de Linux probamos a hacerlo a baja velocidad y el resultado fue un cuadrado perfecto.

- Cálculo de la matriz de covarianza: Se trata de realizar un estudio estadístico para conocer el grado de incertidumbre del movimiento (error cometido) sobre el circuito anterior. A continuación se adjunta una tabla que muestra la desviación, en centímetros, durante diez iteraciones en el eje de las X y de las Y:
 
  Por tanto, la matriz de covarianza resultante es la siguiente:

 siendo el punto medio: (-0,7 . 1,6).

Cada dato de la matriz se corresponde con la incertidumbre de los cuatros ejes del cuadrado.


- Visualización de la trayectoria: Para solucionar este apartado, modificamos el código del cuadrado y lo actualizamos. Para ello mostramos en el LCD constantemente la posición x, y y los grados del motor sin trampa. Decimos sin trampa, ya que para hallar las nuevas posiciones no lo hicimos sumando 90º grados "a pelo" sino que lo hicimos con la función navigator.getAngle(). Así podemos observar correctamente la desviación del robot al realizar la trayectoria.


A continuación mostraremos dos videos, uno con velocidad normal y otro con velocidad baja, para que se pueda apreciar que a velocidades bajas no sale un cuadrado perfecto.


Velocidad Normal:






Velocidad Baja:






Ha sido una práctica muy interesante donde nos ha ayudado para familiarizarnos con bracitos, cada vez sabemos indicarle que haga mas cosas, en concreto con el uso de los motores, dentro de nada le tendremos en un gimnasio haciendo pesas porque se masca la tragedia para las proximas prácticas.



Así son las cosas y así se las hemos contado...