LEGO Mindstorms NXT Sigue Líneas Proporcional

SigueLineas-150x120El algoritmo básico de un sigue lineas consiste en realizar un zig zag cabeceando sobre una línea a medida que se avanza. La ventaja de esta solución es la simplicidad, pero se traduce en un mayor espacio recorrido y por ende en una velocidad menor. Sin embargo existen soluciones alternativas que permiten un movimiento que evita el cabeceo de la solución anterior. Anímate a probar nuestro LEGO Mindstorms NXT Sigue Líneas Proporcional.

En el algoritmo básico se aplica una potencia constante al motor, que es la que definimos gráficamente al seleccionar el icono del motor. Esta potencia se mantiene constante durante la ejecución del programa en esta resolución. El cabeceo puede llegar a ser excesivo en algunos casos y provocar que el robot se salga de la línea.

El siguiente es el programa del sigue líneas básico.

LEGO Mindstorms NXT Sigue Líneas Proporcional

Sigue lineas básico en NXT-G

Existe sin embargo la posibilidad de programar los motores con un valor de potencia variable. Con esta idea en mente podemos conseguir que la potencia del motor dependa de las lecturas del valor de luminosidad de forma proporcional. En este sistema el control de la potencia del motor depende de la realimentación del valor recibido por el sensor. En el sistema de control más básico la lectura del sensor de luminosidad se interpretar de forma booleana, de manera que a partir de un umbral decidimos si estamos sobre la línea o fuera de ella y aplicamos la potencia al motor izquierdo o derecho según corresponda (en una construcción en la que la tracción es -puede ser- diferencial.

Frente a la versión básica anterior, esta segunda versión hará uso de todo el rango de valores continuo que puede encontrarse el sensor de luminosidad. Para comprobar de qué estamos hablando basta tomar el sensor de luminosidad y realizar medidas:

Medidas sensor luminosidad

  • Si lo colocamos sobre la superficie blanca recibimos el valor máximo de luz reflejada.
  • Si lo colocamos sobre la línea, que normalmente será negra, recibimos el valor mínimo de luz reflejada.
  • Pero… ¿Que está sucediendo si colocamos el sensor sobre el borde de la línea? Como la luz que recibimos reflejada procede de una superficie, y no de un punto, el valor de la lectura recibida por el sensor depende de la cantidad de luz que se refleja en esa superficie, es decir, que si el spot que vemos como rojo contiene parte de negro y parte de blanco tendremos un valor intermedio entre el valor que recibimos cuando el spot está sobre negro y el valor recibido cuando el spot está sólo sobre blanco. El valor exacto depende de la proporción de negro y blanco.

La posible continuidad de esta lectura nos permite dotar de una mayor inteligencia al comportamiento de nuestro robot. Con tracción diferencial, de lo que trataremos es de dar una potencia a ambos motores continuamente, pero en un valor proporcional a la lectura del sensor recibida. Debemos de tener en cuenta el rango de entrada del sensor, que hay que conocer previamente, y adaptar este rango de valores a los que nos serán de utilidad en nuestro motor (potencias del 30% no consiguen mover el motor, por ejemplo, y potencias superiores a 100 tampoco son válidas). Esta adaptación es una operación de escalado que haremos mediante varias operaciones matemáticas sencillas.

Vamos a ver el programa.

Como podéis comprobar es muy largo, lo que dificulta su comprensión, por eso hemos untilizado la herramienta MiBloque para encapsular algunos elementos, que luego veremos por separado.

Con Bloques Simple_

El primer bloque es VariableIni, donde damos a las variables un valor inicial.

Bloque Variables_

En este programa, hemos realizado unas mediciones previas para los valores máximo y mínimo que tenemos en el tapete de pruebas (fondo blanco con línea negra).
La variable potencia será la velocidad de inicio que tienen nuestros motores (antes de la corrección). La variable ganancia nos dará el valor del giro (qué motor gira más rápido en función de las mediciones del sensor de luz).

Un vez les hemos dado el valor inicial, realizamos una serie de operaciones para definir el Rango y el PuntoMedio. De eso se encarga el bloque de Asignación de valores.

El Rango es máximo-mínimo. Y el PuntoMedio es (máximo+mínimo)/2.

Ahora queremos que nos muestre en pantalla el valor de las lecturas, el bloque encargado se llama MuestraPantalla y simplemente lee el valor de la variable y lo imprime en pantalla haciendo uso del bloque conversor de Número a Texto.

Bloque Pantalla_

Finalmente, tras una pausa de 5 segundos llega el bloque de SigueLineas.

Bloque SigueLineas_

Para poder seguir la línea de forma suave, debemos aplicar una corrección a la variable Potencia que inicializamos antes. Esta corrección se calcula con la lectura actual, el rango y la ganancia.

Debemos tener en cuenta que la Ganancia la definimos nosotros, si bien una ganancia grande nos hará ir más fluidos, si la hacemos demasiado grande se producirá un enorme cabeceo debido a una sobre corrección, además de que perderemos la posibilidad de hacer ciertas curvas al aumentar el tiempo de reacción.

En este caso anterior hemos supuesto de que conocíamos unas condiciones iniciales en el tapete, si no conocemos esas condiciones, podemos añadir un bloque que calibre el sigue líneas almacenando los valores de máximo y mínimo.

Bloque Calibrado_

Para que este calibrado funcione necesitamos inicializar la variable Maximo a 0 y la variable Minimo a un valor lo más alto posible, pues lo que haremos es leer de forma continua y comparar con los valores que ya están almacenados en las variables.

Este sería el programa con calibración

Con Bloques Completo_

A parte del nuevo bloque de calibrado hemos tenido que añadir un pequeño giro hacia la derecha (con el objetivo de leer valores dentro y fuera de la linea) y posteriormente un giro hacia la izquierda para recuperar la posición inicial.
El programa sin encapsular quedaría así

Completo_

El bloque de calibrado automático está inspirado en el trabajo de Dave Parker.

facebooktwittergoogle_plusredditpinterestlinkedinmailfacebooktwittergoogle_plusredditpinterestlinkedinmail

facebooktwittergoogle_pluslinkedinrssyoutubefacebooktwittergoogle_pluslinkedinrssyoutube

Comments are closed.