Coche con control remoto NXT-G: versión PID + sensor de rotación

Hace tiempo construimos un coche controlado remotamente que hacía uso del sistema NXT. Se trataba de un coche con tracción y dirección pensado para competir en los concursos mensuales de electricBricks. El primer modelo se controlaba con un teléfono móvil con la aplicación oficial de LEGO, que permitía controlar el funcionamiento de los motores conectado vía Bluetooth. Dadas las limitaciones de la aplicación, este sistema no tuvo mucho éxito.

Más adelante diseñamos un joystick para poder controlar un robot de sumo. Este sistema funcionó bastante mejor, tanto que nuestro robot ocupó el primer puesto en la competición. Podéis ver un artículo sobre este robot aquí. Este robot demostró que en las competiciones de sumo, un vehículo con el sistema Mindstorms es tan competente como uno con Power Functions.

Para la primera edición de la Carrera de Karts electricBricks construimos un kart que hacía uso del sistema Mindstorms y que se controlaba con otro robot que hacía las veces de mando. Ambos estaban conectados por Bluetooth, y el mando enviaba órdenes que el kart interpretaba para manejar la tracción y la dirección. La programación estaba hecha en Lejos, y podéis ver un artículo sobre el kart aquí. Este modelo funcionaba mucho mejor que el primero porque el mando programado permitía un mayor control sobre los movimientos del vehículo. Aún así, existían dos problemas: el tiempo entre la emisión de la orden y su ejecución y la acumulación de errores en el mecanismo de la dirección, que al final hacía que el coche fuese poco manejable.

En principio parece que hemos encontrado una solución al problema de la dirección programando en el software gráfico NXT-G. Se trata del nuevo bloque de HiTechnic PID, que podéis descargar en este enlace: http://www.hitechnic.com/file.php?f=802-HTMotorPID.zip. Este bloque permite un control muy fino sobre los motores, haciendo uso del mecanismo de control denominado PID (proporcional integral derivativo). Dicho de una forma sencilla, este tipo de control permite calcular el error entre un valor deseado y un valor medido y aplicar una acción que corrija ese error. Es decir, si nosotros le decimos al motor que gire 60º, y tras moverse mide que en realidad ha girado 59º, entonces se movería 1º más para compensar ese error. Por tanto, este bloque es idóneo para corregir el principal fallo de la acumulación de error del motor encargado de la dirección del vehículo.

El funcionamiento de este bloque parte de definir un punto de inicio o “set point” para indicarle después una nueva posición tomando como referencia al set point. Vamos a explicarlo con ejemplos: primero apuntamos a las 12 con una aguja conectada al motor, y reseteamos el valor del set point para tomar ese punto como el nuevo set point. Si quiero apuntar a las 3, tendría que indicar un valor de 90 respecto al set point. En ese caso el motor se movería 90º a la derecha.

Ahora imaginemos que queremos apuntar a las 9. Podría indicar 270, y se movería tres cuartos de vuelta hacia la derecha, o -90, y se movería un cuarto de vuelta hacia la izquierda.

Si le indico que se mueva hasta el punto 90, y después quiero que haga un giro de 180º en sentido contrario, debo indicarle que se mueva hasta el -90.

También se le pueden dar valores mayores de 360. Si quiero que de 2 rotaciones y media, debería indicarle un valor de 900 (360 x 2 + 180).

Por último, para volver al set point basta con darle un valor de 0.

Tenemos varias formas de definir el set point, lo que indirectamente nos sirve para otros usos de este bloque. En primer lugar podemos definir el set point como la posición en la que se encuentra el motor. También podemos definirlo como el límite del movimiento hacia adelante o el límite del movimiento hacia atrás. Esto nos sirve para que el motor avance hasta que algo se lo impida, y entonces sitúa esa posición como set point. Es una forma muy cómoda de decirle al motor que avance “hasta que no pueda más” y una forma de proteger los motores y evitar que se fuercen. Por último, también se puede situar el set point en el centro. En este caso el motor avanza hasta su límite hacia adelante, luego hacia atrás, y calcula el punto medio entre ambos.

Vehículo y mando.

En el caso de nuestro robot hemos usado el bloque PID para tres funciones. La primera es un autocentrado de las ruedas de la dirección. Nada más ejecutar el programa hacemos que se sitúe el set point en la mitad del movimiento. Esto hace que las ruedas giren hacia la derecha hasta el tope, luego a la izquierda hasta el tope y sitúa el set point en el punto central de esos dos topes. A continuación le indicamos que avance hasta el valor 0 (hasta el set point) y la dirección se alinea con mucha precisión.

Sistema de dirección.

La segunda función en la que usamos el PID es para la dirección. Para girar la dirección le indicamos un valor de 40 o -40 respecto del set point, y a continuación le decimos que vuelva al valor 0. Esto es una mejora muy notable respecto al movimiento con el bloque de motor, ya que al girar varias veces, la acumulación de de pequeños errores al final provocaba que las ruedas no volvieran al centro exacto, y por tanto el robot dejaba de avanzar recto cuando tenía que hacerlo.

Sistema de tracción.

Por último, la tercera función en la que usamos el bloque PID es para controlar una pequeña pinza que le hemos añadido al vehículo. Al iniciar el programa los que le indicamos es que abra la pinza hasta que no pueda más. Cuando le indicamos a la pinza que se cierre, ésta se cierra hasta que no puede más, que es cuando ambos brazos de la pinza contactan con la superficie del objeto. Hacerlo de este modo nos permite cerrar la pinza sobre objetos de diferente tamaño, porque al darle un valor fijo de movimiento nos limitamos a coger cosas con el mismo tamaño, a no ser que le pongamos un sensor en los brazos de la pinza para detectar cuándo se agarra el objeto. Por tanto, nos ahorramos un sensor y podemos coger objetos de diferentes tamaños.

Para que la pinza ejerza cierta fuerza sobre el objeto para que éste no se caiga, lo que hacemos es aprovechar que ha situado el set point cuando la pinza ha agarrado el objeto y a continuación le indicamos que se mueva hasta el valor 2. Esto hace que el motor se fuerce un poco he intente moverse dos grados, por lo que ejerce presión continua sobre el objeto porque éste impide el movimiento. El programa se bloquearía en este punto, por eso hay que quitarle la opción de esperar hasta finalización.

Pinza.

Los movimientos de dirección, tracción y apertura y cierre de la pinza se controlan desde otro NXT que actúa como mando del vehículo. La dirección se controla con un volante que al girar a la izquierda presiona un sensor de contacto, y al girar a la derecha presiona otro sensor de contacto. El vehículo, al recibir la orden, hacer girar la dirección en el sentido indicado por el mando.

Mecanismo del volante del mando.

La tracción hace uso del nuevo sensor de rotación HiTechnic. Con este sensor de rotación tenemos un control mucho más preciso sobre el giro de un eje que con el tacómetro interno del motor NXT, usando su correspondiente bloque para el NXT-G, que podéis descargar desde este enlace: http://www.hitechnic.com/file.php?f=367-Angle%20Sensor.zip. Además es mucho más cómodo porque no hay que ejercer tanta fuerza como la que se ejerce al mover el motor. En este caso no hemos ensamblado directamente la palanca de control con el eje que entra en el sensor, sino que el movimiento de la palanca lo multiplicamos al doble con una pareja de engranajes. Esto nos permite obtener ángulos mayores, ya que cuando movemos la palanca 50º, el sensor detecta un movimiento de 100º. Al tener menos recorrido podemos tener una valores desde -100º a 100º con un movimiento cómodo de la mano. Además hemos enganchado una goma elástica para que al soltar la palanca ésta vuelva a su posición vertical, que se corresponde con los 0º.

Mecanismo de la palanca.

Por último, hemos colocado otro sensor de contacto a modo de gatillo. Al pulsar este gatillo, la pinza se cierra, y al pulsar de nuevo se abre.

Gatillo.

A continuación mostramos los programas que hacen posible el funcionamiento de los robots. En primer lugar mostramos el del mando:

Como podemos ver son tres líneas de programación en paralelo que controlan las tres funciones del vehículo. La línea superior se encarga de la tracción del vehículo. Primero calibramos el sensor de rotación para que la posición inicial de la palanca sea el valor 0. Después entre en el bucle en el que primero tomamos el valor del sensor y lo enviamos mediante bluetooth al buzón 3 del vehículo. Para que se corresponda el movimiento hacia adelante de tracción con un movimiento hacia adelante de la palanca del mando, cambiamos el signo del valor del sensor multiplicándolo por -1. A continuación tomamos ese mismo valor, lo escribimos tras el texto “drive”, y lo introducimos en una variable de texto que usaremos más adelante.

En la tercera línea de programa controlamos la pinza del vehículo. Abrimos un bucle y escribimos el texto “empty” en otra variable de texto para indicar que la pinza está vacía. Esperamos a presionar el gatillo y enviamos un “1” por bluetooth al buzón 4 del vehículo. También escribimos la palabra “closing” en la misma variable para indicar que la pinza se está cerrando y tras dos segundos escribimos la palabra “full” para indicar que la pinza tiene algo cogido. Esperamos a presionar otra vez el gatillo y entonces enviamos por bluetooth un “0”. También escribimos el texto “opening” en la variable para indicar que la pinza se está abriendo y tras una espera de 2 segundos el bucle acaba (donde se mostraría de nuevo empty y se esperaría a pulsar el gatillo de nuevo).

Por último, en la segunda línea abrimos un bucle y en primer lugar encontramos una bifurcación en la que comprobamos si se pulsa el sensor de contacto 3 (cuando el volante gira a la izquierda). Si es verdadero enviamos un “1” por bluetooth al buzón 2 del vehículo y guardamos en otra variable de texto lo siguiente: “< steering", para indicar que giramos a la izquierda. Si es falso comprobamos si pulsamos el sensor 4 (volante a la derecha), en cuyo caso, si es verdadero enviamos un "2" por bluetooth y escribimos en la variable "steering >“. Si es falso entonces enviamos un valor 0, guardando en la variable un “steering” sin más, para indicar que no estamos girando. Por último, tomamos las tres variables de texto de las tres líneas de programa y las mostramos en pantalla en líneas diferentes, para indicarnos las tres funciones del vehículo.

Ahora vamos a ver el programa para el vehículo:

Al principio podemos ver tres bloques PID. El primero mueve el motor C, que abre la pinza hasta que no puede más y sitúa el set point. Después con el motor A (la dirección) haya el set point en el punto intermedio entre el límite de giro a la derecha y a la izquierda. Depués mueve el motor A hasta ese set point. Luego el programa se divide en tres líneas.

La primera toma el valor del buzón 2, que controla la dirección. Tomamos el número que contiene el mensaje y lo introducimos en una bifurcación (con vista plana) numérica de tres opciones, en donde en la opción “0” no hace nada. En la opción “1” movemos mediante el PID el motor A hasta el valor 40, lo que gira las ruedas a la izquierda, y esperamos a que recibamos por bluetooth el valor “0” para a continuación mover el motor hasta el set point, lo que centra las ruedas. En la opción “2” hacemos lo mismo que en la “1”, sólo que lo movemos hasta el valor -40 para girar el volante en el otro sentido.

La segunda línea de programa controla la tracción. Primero tomamos el valor que recibimos del mensaje bluetooth del buzón 3 y lo guardamos en una variable numérica. También se muestra ese mismo número en pantalla; esto sólo nos sirve para comprobar que el vehículo esté recibiendo señal del mando. Después tomamos el valor de la variable y lo comparamos con 0. Si es verdadero, no hacemos nada. Si es falso hacemos una comparación para ver si es mayor que cero. Si es verdadero movemos el motor de la tracción hacia atrás (que se corresponde con un movimiento hacia adelante del vehículo) con tanta potencia como el valor de la variable. Si es falso movemos el motor en sentido contrario (para que el vehículo vaya para atrás) con la potencia de la variable.

Por último, aquí os dejamos un vídeo con el funcionamiento del robot:

Comments are closed.