Dota a tu robot del control de movilidad de un verdadero Mars Rover: primera parte
Los robots, sobre todo los que tienen ruedas, pueden dividirse en dos clases: los que se mueven únicamente mediante la detección y evitación de obstáculos, y aquellos que se desplazan por una ruta planificada siguiendo un mapa electrónico interno. La mayoría de robots móviles que se usan por motivos de ocio suelen moverse mediante la detección de obstáculos. Esta visión tan simple se basa en la idea de que correr de un sitio a otro evitando objetos es mucho más divertido (¡y sencillo!) que programar un movimiento preciso a lo largo de un trayecto predeterminado.
Control de movilidad
Un robot "profesional", como el Mars Rover Curiosity, tiene que desplazarse con precisión y evitar al mismo tiempo chocar con grandes rocas o caer en huecos pequeños.
Si quieres hacerte una idea del nivel de complejidad del hardware y el software de movilidad de un robot, echa un vistazo a este informe sobre el sistema de movilidad de los predecesores del Curiosity, los Mars Exploration Rovers Opportunity and Spirit. En la página 3 del informe, en el diagrama de bloques de la Figura 2, se describe el sistema de navegación básico: en este artículo y en el siguiente se explica cómo funciona el bloque marcado como MOT y cómo (y por qué) se puede añadir su funcionalidad basada en el algoritmo PID a un robot menos exótico sobre el planeta Tierra.
Control PID
El principio básico del control PID es muy fácil de entender y se puede aplicar a cualquier sistema en el que se incluya un actuador electromecánico (por ejemplo, un motor) que tenga que accionarse a una velocidad determinada o desplazarse hasta una posición exacta. El hardware adicional necesario incluye un sensor, que proporciona información sobre la velocidad o la posición real del actuador, y una unidad de procesador, que ejecuta el algoritmo de control. El procesador compara la salida mecánica deseada (punto de ajuste) con el valor real detectado y genera una señal de control modificada para cancelar cualquier diferencia (error). Este algoritmo, sin embargo, no se limita a los sistemas móviles: puede ser igual de efectivo para garantizar que se mantenga una temperatura precisa durante un proceso químico industrial o un determinado nivel de líquido en un depósito. En este caso me centraré en el control del motor.
¿Por qué necesitan controles de movilidad los robots pequeños?
Los robots de ocio suelen tener formato de "carrito", con dos ruedas que se accionan individualmente (una a cada lado del chasis) y una rueda giratoria en uno o ambos extremos. El requisito más importante es conseguir que el robot recorra una distancia especificada siguiendo una línea totalmente recta. ¿Parece fácil, verdad? Sin embargo, necesitamos dos cosas para que esto ocurra:
- Ambas ruedas deben girar exactamente a la misma velocidad.
- Debe haber un sensor en ambas ruedas para proporcionar información sobre la distancia recorrida.
Cumplir el requisito 1 no es fácil, ya que es probable que dos motores aparentemente idénticos, con la misma potencia de entrada, giren a velocidades ligeramente distintas. En ese caso, el robot se desplazará siguiendo un arco gradual, no en línea recta. Por eso necesitamos obtener información a través de un sensor de giro de la rueda que trabaja en un bucle de control cerrado. Para nuestro carrito, necesitaremos un bucle independiente para cada rueda. Por suerte, los sensores montados en las ruedas también proporcionan información para que podamos calcular la distancia recorrida por cada rueda, lo que nos permite cumplir el requisito 2.
El control PID en teoría
PID significa "proporcional integral derivativo" y describe los tres procesos matemáticos aplicados a una señal de retroalimentación de errores en un sistema de control de bucle cerrado para obtener un factor que permita corregir el error. Veamos el algoritmo en todo su esplendor de cálculo integral/diferencial:
Donde el primer término es el componente de retroalimentación proporcional, el segundo es el integral y el tercero es el derivativo. e(t) es la diferencia entre la salida deseada (el punto de ajuste) y la salida real. c(t) es la salida de control del actuador actualizada.
Un sistema de control de bucle cerrado con los tres términos tiene este aspecto(Fig.1):
En mi ejemplo de robot móvil, el actuador es un servomotor de rotación continua y el sensor es una unidad de haz infrarrojo reflejado que funciona con ranuras en la rueda de carretera. Este tipo de sensor, a veces denominado "tacómetro", comunica la información real de velocidad de giro de la rueda como un tren de impulsos de velocidad variable: cuanto mayor sea la velocidad, mayor será la frecuencia de impulso. El código del programa de control compara la velocidad real con el valor deseado o "punto de ajuste", y la diferencia es la entrada de error e(t) del algoritmo PID. El resultado es una salida de control c(t) que acciona el motor con un valor que reduce el error a cero (en algún momento). Las tres constantes KP, KI y KD suelen ser valores estimados (supuestos) inicialmente antes de optimizarse en un programa de simulación o en el hardware real del sistema, un proceso conocido como "ajuste".
El control PID en la práctica
Supongo que no te apetece mucho codificar la integración y la diferenciación para el funcionamiento en tiempo real. No te preocupes: por suerte, la fórmula anterior es para el tiempo continuo, pero, al tratarse de una aplicación "digital", trabajamos con datos de ejemplo medidos a intervalos discretos. Y lo que es aún mejor: según el nivel de control necesario, es posible prescindir de alguno de los términos I o D, o incluso de ambos. Para decidir qué parte de todo el algoritmo PID es necesaria para una tarea concreta, tenemos que entender la contribución de cada término
El término proporcional (o ganancia)
El término P no solo es esencial, sino que resulta el más fácil de entender e implantar: su contribución a la señal de control es una proporción, definida por KP, del error detectado. Por tanto, KP < 1. ¿Por qué no hacer que KP sea igual a 1 y cancelar todo el error de una vez? El problema es que el sistema electrónico puede convertir una señal de error en una señal de control revisada mucho más rápido de lo que el sistema mecánico puede reaccionar al cambio. El resultado puede ser una oscilación continua, con la aceleración y desaceleración del motor por encima y por debajo del punto de ajuste. Por este motivo, la proporción del error se retroalimenta en cada intervalo y la velocidad se lleva lentamente hasta su valor de punto de ajuste. Además, si se retroalimenta muy poco, habrá que esperar bastante desde el encendido hasta que se alcance la velocidad necesaria. Para el sistema de tiempo discreto, por tanto:
CP(n) = KP x E(n)
Observa que la señal de control se reduce a cero al mismo tiempo que el error, lo que de algún modo resulta contraproducente. Hay dos formas de abordarlo. La primera es descubrir qué entrada de control se necesita para la velocidad de ajuste deseada ejecutando el "bucle abierto" de hardware, y añadir después este valor "de referencia" como una constante a la ecuación anterior. La segunda opción es añadir el término integral descrito a continuación, que pondrá a cero el valor objetivo automáticamente.
El término integral (o restablecimiento)
Al integrar la señal de error se obtiene un valor de error acumulado respecto al intervalo de tiempo t. Si no hay ninguna entrada de referencia de control como la descrita arriba, su valor debe aumentar desde el arranque hasta estabilizarse en el punto de ajuste. Normalmente, su función es compensar un error fijo (desviación) en la medición del sensor. Si KI es demasiado alto, sin embargo, puede provocar inestabilidad. En el sistema de tiempo discreto, la fórmula es una simple suma o, si queremos ser más precisos, una acumulación:
A(n) = A(n-1) + E(n) where A(n) = Accumulated Error
CI(n) = KI x A(n)
El término derivativo (o rapidez)
Ahora tenemos un componente totalmente adicional que mejora el rendimiento al reducir la oscilación transitoria que se produce al utilizar valores altos de KP o KI. Este término mide la rapidez de cambio de la salida y reduce la señal de control conforme la primera se acerca al valor de punto de ajuste. Basta con tener el valor correcto de KD para evitar que se produzca un sobreimpulso en la salida y, con él, una sobrecorrección. De esta forma, obtenemos una respuesta de control inicial más fuerte frente a transitorios grandes y repentinos, que se va suavizando conforme el error se acerca a cero. El término D puede mejorar la respuesta de un sistema a los cambios bruscos en el punto de ajuste, por ejemplo, pero pueden surgir problemas debido a su sensibilidad al ruido en la señal de retroalimentación. En la práctica este término derivativo en apariencia tan complejo se traduce simplemente en restar el valor de error actual del valor anterior:
CD(n) = KD x (E(n-1) – E(n))
En otras palabras, el componente de control es positivo cuando el error mejora, lo que refuerza el efecto de los términos P y D. Si la salida detectada supera el punto de ajuste, el término D será negativo para reducir la entrada de control total hasta que vuelva a mitigarse el error.
Las distintas combinaciones de P, I y D
No es necesario usar el algoritmo de control PID al completo. El diseñador debe elegir la combinación adecuada de estos tres términos para una aplicación específica en función de las características del sistema que se va a controlar. Hay que tener en cuenta dos detalles:
- La rapidez con la que debe reaccionar el sistema a un aumento repentino del error, tanto durante el arranque inicial como con los cambios en el punto de ajuste (con un comando de dirección, por ejemplo). Esta es la respuesta "transitoria".
- La exactitud con la que se debe seguir el punto de ajuste. Esta es la respuesta de "estado estable".
En la Fig.2se muestran las curvas de rendimiento de algunas de las combinaciones de los términos P, I, D usadas con frecuencia. La curva azul en cada caso es el estado de salida real (velocidad, posición, temperatura, etc.) respecto al punto de ajuste deseado (línea de puntos rojos). Imaginemos que la curva representa la velocidad de un motor respecto al tiempo t, que se enciende a t = 0.
(a) Proporcional solo con una referencia de control fija. Se estima la referencia o se obtiene un valor a través de la experimentación. Un factor KP grande garantiza un aumento rápido desde el estado de reposo, pero el sobreimpulso y la oscilación transitoria son muy altos. Si se produce un error al estimar la referencia, la velocidad del estado estable es de algún modo inferior al valor de punto de ajuste solicitado.
(b) Proporcional e integral. Se mantiene el mismo valor KP , pero, al sustituir la referencia fija con el término integral, obtenemos el valor de punto de ajuste en algún momento, después de que se produzcan grandes sobreimpulsos.
(c) Proporcional, integral y derivado. En teoría, basta con tener el valor de KD KD correcto para conseguir algo mágico: la oscilación transitoria se amortigua casi por completo y se alcanza el estado estable en un periodo de tiempo muy breve.
Ajuste del bucle
Los cálculos son sencillos, y se puede ejecutar un controlador básico para un robot móvil en una placa de microcontrolador de bajo coste, como Arduino. Lo más difícil es seleccionar los valores para los factores K. La experiencia es muy importante al intentar hacer un ajuste manual. A veces podemos ejecutar el sistema en "bucle abierto" con la retroalimentación desconectada para hacernos una idea de sus características. Se pueden realizar simulaciones y determinar los valores combinando la experiencia con el ensayo y el error. También hay sofisticados problemas de ajuste. En la práctica, para controlar pequeños motores como este, es fácil conseguir resultados satisfactorios con algunas conjeturas y pruebas.
Próximamente en la Part 2
Para estos artículos he usado mi estimado BoE-Bot de Parallax, equipado con tacómetros y una placa de procesador dsPIC33 de Microchip en formato Arduino como cerebro. Las MCU modernas, como la dsPIC, incluyen hardware especial para el control y la detección del motor, como las unidades de comparación de salida, captura de entrada y codificador de cuadratura. Examinaré la implementación del algoritmo PID codificado en mi versión del lenguaje Forth, FORTHdsPIC, y los controladores del código de montaje "directamente sobre el hardware" para los sensores del tácometro y el control del motor.
Si te has quedado con ganas de más, puedes seguir mi cuenta de Twitter. donde publico enlaces a artículos interesantes sobre electrónica y tecnologías relacionadas, y retuiteo información sobre robots, exploración espacial y otros temas.