Memoria de la Tesis - Universidad de Buenos Aires
Transcripción
Memoria de la Tesis - Universidad de Buenos Aires
jorge ezequiel espósito D I S E Ñ O , I M P L E M E N TA C I Ó N Y VA L I D A C I Ó N D E UNA BIBLIOTECA DE ALGORITMOS DE CONTROL PA R A S I S T E M A S E M B E B I D O S [ 16 de abril de 2013 at 16:46 – version 1.0 ] [ 16 de abril de 2013 at 16:46 – version 1.0 ] D I S E Ñ O , I M P L E M E N TA C I Ó N Y VA L I D A C I Ó N D E U N A B I B L I O T E C A D E A L G O R I T M O S D E C O N T R O L PA R A S I S T E M A S EMBEBIDOS Tesis de Grado jorge ezequiel espósito Departamento de Electrónica Facultad de Ingeniería Universidad de Buenos Aires Febrero 2013 – version 1.0 Director: Dr. Ing. Ariel Lutemberg Codirector: Dr. Ing. Anibal Zanini [ 16 de abril de 2013 at 16:46 – version 1.0 ] Jorge Ezequiel Espósito: Diseño, Implementación y Validación de una Biblioteca de Algoritmos de Control para Sistemas Embebidos, Tesis de Grado, Febrero 2013 [ 16 de abril de 2013 at 16:46 – version 1.0 ] RESUMEN El objetivo principal de este trabajo es diseñar, implementar y validar una biblioteca de algoritmos de control para ser utilizada en un Real Time Control System - Sistema de Control de Tiempo Real (RTCS). Los sistemas dinámicos modernos están compuestos por diversos procesos que necesitan ser controlador para cumplir con los requerimientos de la aplicación. Para cumplir con dichos requerimientos, es habitual que se utilicen sistemas embebidos que deben ejecutar diferentes algoritmos de control de manera concurrente y a la vez deben ejecutar otras tareas como atender protocolos de comunicación, administrar interfaces gráficas de usuario, etc. La biblioteca desarrollada en esta tesis atiende en forma autónoma las tareas asociadas a los algoritmos de control, de modo que el programador pueda concentrar sus esfuerzos en las otras tareas de diseño del sistema embebido. La misma administra de manera eficiente los diferentes controladores instanciados. Los resultados presentados, demuestran que la biblioteca puede ser efectivamente portada a un microcontrolador económico como el LPC1769 Cortex-M3 y desarrollar en el mismo un excelente desempeño general. Además del objetivo principal, se plantean los siguientes objetivos secundarios: 1. Conseguir que esta biblioteca de algoritmos de control para sistemas embebidos, sea independiente del microcontrolador y del Real Time Operating System - Sistema Operativo de Tiempo Real (RTOS) que se utilicen en aplicaciones de la misma. Se pretende implementar una solución libre, gratuita y con una estructura tal que le permita ser flexible y escalable. 2. Lograr que la biblioteca pueda instanciar un número genérico de algoritmos de control (limitado en función de los recursos del hardware utilizado) y que los mismos se ejecuten de manera concurrente cumpliendo con restricciones temporales duras. Esta característica es particularmente útil en los sistemas dinámicos modernos que están compuestos de muchos procesos a controlar. 3. Incluir en el sistema RTCS, por lo menos un esquema de scheduling con su respectivo test de schedulability. Esto último tiene como finalidad poder garantizar que los algoritmos de control instanciados cumplan con las restricciones temporales impuestas. 4. Incluir en el sistema RTCS los algoritmos de control Proportional Integrative Derivative - Proporcional Integrativo Derivati- v [ 16 de abril de 2013 at 16:46 – version 1.0 ] vo (PID) y Dynamic Matrix Control - Control por Matriz Dinámica (DMC). La implementación de la biblioteca y de los algoritmos de control se realiza en el lenguaje de programación estándar C y la validación de los mismos se realiza mediante la técnica Hardware In the Loop (HIL) a partir de comprar los resultados que se obtienen al ejecutar los algoritmos en la libRTCS y en el Matlab. Se pretende disponer de un esquema con varios controladores PID (cada uno ejecutándose a una frecuencia diferente) y varios controladores DMC que puedan manejar las referencias de los primeros con el objetivo de optimizar el desempeño de un sistema dinámico en algún sentido. 5. Adaptar los algoritmos de control para que puedan ser ejecutados en microcontroladores de bajos recursos, que no poseen Float Unit Point - Unidad de Punto Flotante (FPU). Por último, cabe destacar, que la innovación en este trabajo está dada por: Aportar una biblioteca de algoritmos de control para sistemas embebidos que es independiente del microcontrolador y del RTOS utilizados en cada aplicación, que puede ejecutar diferentes algoritmos de control en tiempo real de manera concurrente, que es flexible, fácilmente expansible con nuevas estrategias de control y soporta diferentes test de schedulability. Realizar la portación de la biblioteca de algoritmos de control implementada a un procesador con tecnología Cortex-M3. Dentro del gran abanico de procesadores de 32 bits modernos que existen en la actualidad, el Cortex-M3 puede ser considerado un procesador de recursos medios a bajos. Hacer la portación de una biblioteca de código que permite implementar sistemas de control de tiempo real a un procesador como el Cortex-M3 es un trabajo innovador y de gran utilidad práctica, tanto en el ámbito académico como en el ámbito industrial. En el Capítulo 1 se presenta una introducción a la temática de esta tesis. En el Capítulo 2 se presenta el marco teórico necesario para este trabajo. En el Capítulo 3 y en el Capítulo 4 se aborda el objetivo principal y los objetivos secundarios 1, 2, 3, 4 y 5. La validación de los algoritmos de control implementados y los resultados obtenidos son presentados en el Capítulo 5. vi [ 16 de abril de 2013 at 16:46 – version 1.0 ] You can’t connect the dots looking forward. You can only connect them looking backwards. You’ve got to find what you love. Stay Hungry. Stay Foolish. Steve Jobs, Stanford University, Junio 2005 AGRADECIMIENTOS Unos días antes de finalizar mi tesis de grado, comencé a pensar en cómo iba a realizar la escritura de estos agradecimientos. Durante esos días, me surgió la inquietud de cómo debería ordenar las menciones de las personas sin que dicho orden implicara necesariamente una jerarquía de importancias. Como considero que todas las personas que voy a nombrar a continuación fueron importantes en mi vida de diferentes maneras y como no quiero que la aparición de las menciones signifique importancia alguna, decidí presentar mis agradecimientos en función del momento en el cual las personas fueron entrando en mi vida. Iniciando los agradecimiento de manera cronológica, las primeras personas que entraron en mi vida fueron mis padres, Rafael Espósito y Susana Capobianco. Si no fuese por ellos, por sus enseñanzas, por los valores que supieron transmitirme, por el esfuerzo que hicieron para que a mi nunca me falte nada y por el amor que siempre me dieron, yo nunca podría haber llegado a este momento en mi vida. Por todo, les voy a estar siempre agradecidos. Quiero que sepan que concidero que son dos personas maravillosas y que estoy orgulloso de los padres que tengo. Continuando, las siguientes personas que entraron en mi vida fueron mis abuelos Saveria Capobianco, Rafael Ramón Espósito, Norma Kosic y Ana Gladis. Gran parte de mi crianza estuvo a cargo de ellos, y también concidero que nunca podría haber llegado a este momento en mi vida sin toda la dedicación, la ayuda constante, la comprensión y el amor que todos y cada uno de ellos me dieron. A mi abuela Beba (Saveria) siempre la voy a recordar como la persona con el alma más hermosa que conocí en toda mi vida, gracias por enseñarme a ser una buena persona. Mi abuelo Rafael es una persona que tiene un corazón enorme, gracias por enseñarme que la familia es lo primero y gracias por iniciarme en el camino que hoy es mi profesión. Mi abuela Norma es una persona con una humanidad y un amor para entregar inagotables, gracias por enseñarme a ser sensible, a querer y a respetar al projimo. Luego, llegaron a mi vida mis tios, Marcelo Espósito, Virginia Espósito, Claudia Sesti y Gabril Andrés. Siempre les voy a estar agradecidos por contenerme en los momentos difíciles, por los hermosos momentos que me hicieron vivir y por haberme enseñado a crecer. Avanzando en la línea del tiempo, llegó vii [ 16 de abril de 2013 at 16:46 – version 1.0 ] mi hermano, Diego Espósito. A él, debería dedicarle una sección de agradecimientos entera. Desde que yo tenía solo 4 años, comparto con el una amistad inigualable. Diego, gracias por enseñarme a ser una mejor persona y por siempre entenderme y motivarme a que siga adelante. Hermano de sangre, de vida y de corazón realmente a vos te debo gran parte de la persona que soy. Finalmente, de parte de mi familia, llegaron todos mis primos: Barbara Espósito, Mateo Espósito, Matias Andrés y Brisa Delfina. A todos ustedes, les agradezco de corazón que me hayan alegrado la vida. Continuando con los agradecimientos, me permito una ruptura en el avance cronológico, para mencionar a mi novia Mariana Bahnyckjy. Nos conocimos cuando estabamos iniciando nuestras respectivas carreras universitarias y desde ese entonces fuimos inseparables. Mariana es la persona que conozco que más respeta a sus propios ideales, y yo estoy realmente orgulloso de tener a mi lado a una mujer con los valores que ella tiene y persigue. Pero por sobre todas las cosas, quería destacar el amor que me entregó durante todos estos años de relación y que me sigue entregando día tras día. Gracias a vos, el esfuerzo, el trabajo y la vida en sí tiene un sentido muy fuerte. También creo que me hubiese sido imposible llegar a este momento de mi vida sin tu ayuda. En cuanto a este trabajo en particular se refiere, le debo a mi novia la digitalización de todas las imágenes. También quería agradecerle a toda su familia, Igor Bahnyckyj, Elsa Cardoso, Nicolas Bahnyckyj, y a sus tíos, por haberme incluido desde el comienzo en la familia y por siempre estar presentes para conterme y ayudarme. Volviendo a seguir la línea del tiempo, les quiero dar las gracias primero a dos grandes amigos de la vida, Matias Klaut y Nicolas Bazerque, ya que con ellos crecí como persona y pasé gran parte de mi infancia. Continuando, quería también agracederles a todos mis amigos de la secundaria, Francisco Troiano, Santiago di Tada, Nicolas Demner, Pablo Canziani, Sebastián Calligaro, Juan Martín Balán, Martín Paramidani, Joaquin Zoilo, Pablo Roca y Pablo Massad, que hace tiempo dejaron de ser solo amigos de la secundaria y pasaron a ser amigos de la vida. Gracias a todos ustedes por siempre estar presentes para ayudarme a pasar los momentos difíciles y por los grandes momentos de alegría y diversión que pasamos juntos. Terminada la secundaria, inicié la universidad y en ese contexto conocí a muchas personas que hoy en día son realmente importantes en mi vida. Ante todo, quería extenderles un especial agradecimiento a mis amigos de carrera Federico Roasio y Daniel Schermuk. Solo ellos son los que realmente conocen los momentos complicados que pasamos. Sinceramente creo que la mayoría de las veces pudimos sobreponernos y seguir adelanta gracias a que estábamos unicos como un gran equipo. A ambos les debo realmente mucho y de corazón espero que sigamos en contacto toda la vida. También quería agradecerle especialmente a Melina Maiten García, con ella curse el CBC y el viii [ 16 de abril de 2013 at 16:46 – version 1.0 ] primer año en la FIUBA. Por ser una excelente persona, una muy buena amiga y por haberme presentado a mi novia, le voy estar siempre muy agradecido. Tampoco quería dejar de mencionar a otros compañeros y amigos de carrera con los que cursé algunas materias de la facultad y con los cuáles todavía mantengo una excelente relación: Matias Stahl, Fernando Gama, Alan Kharsansky, Claus Rosito, Nicolas Fernandez, Andres Manikis, Claudio Pose y Federico Zacchigna. Es el turno de mencionar a mi director de tesis, el Dr. Ing. Ariel Lutenberg. Le quiero agradecer por la gran dedicación y la enorme cantidad de tiempo que invirtió en el desarrollo de esta tesis. Quiero realmente destacar la fuerza y la motivación con la que hace su trabajo. Sin su ayuda el presente trabajo no hubiese sido posible. También quiero destacar los aportes que hace a la Facultad de Ingeniería de la Universidad de Buenos Aires, en particular, al Departamento de Electrónica. También quiero agradecerle a mi co-director de tesis, el Dr. Ing. Anibal Zanini, por todo lo que me enseño sobre control digital y por los importantes aportes que hizo en este trabajo. Por último, quiero extenderles mis agradecimientos a los jurados que se tomaron el trabajo y el tiempo necesario para leer el presente trabajo: el Ing. Juan Manuel Cruz, el Ing. Carlos Godfrid y el Ing. Guillermo Campiglio. Quiero agradecerle en general, a todos los integrantes del Laboratorio de Sistemas Embebidos (LSE) de la FIUBA. Mi trabajo de tesis se desarrolló dentro de este laboratorio. Fueron muchos los conocimientos y la experiencia profecional que adquirí al involucrarme en el LSE durante mis últimos años de carrera. Espero no estar dejando a nadie fuera de esta lista tan extensa. A todos les voy a estar siempre muy agradecidos, por la ayuda que me brindaron en las diferentes etapas de mi vida. Este trabajo está dedicado para todos ustedes. ix [ 16 de abril de 2013 at 16:46 – version 1.0 ] [ 16 de abril de 2013 at 16:46 – version 1.0 ] ÍNDICE GENERAL 1 introducción 1 1.1 Motivación 1 1.2 Prospección 2 1.3 Clasificación de los algoritmos de control 4 1.4 Introducción a los algoritmos digitales de control 7 1.4.1 Esquema general de los algoritmos digitales de control 8 1.4.2 Algoritmos digitales de control y muestreo de los procesos 9 1.4.3 Implementación de los algoritmos de control digitales 10 1.5 Soluciones existentes en el mercado 11 1.6 Conclusiones 14 2 desarrollo teórico 17 2.1 Sistemas de Control de Tiempo Real (RTCS) 17 2.1.1 Sistemas Operativos de Tiempo Real 19 2.2 Desarrollo teórico de los algoritmos de control digitales 28 2.2.1 Desarrollo teórico del controlador PID Digital 29 2.2.2 Desarrollo teórico del controlador DMC 32 2.3 Algoritmos de control 38 3 diseño e implementación 39 3.1 Diseño de la biblioteca de algoritmos de control 39 3.2 Implementación de la biblioteca de algoritmos de control 42 3.2.1 Módulo principal 43 3.2.2 Módulo de interfaces 46 3.2.3 Módulo de administración de tareas 49 3.2.4 Módulo de controladores 50 3.3 Resumen de características de la biblioteca de algoritmos de control 57 4 plataforma de hardware y aplicación 59 4.1 Hardware 60 4.1.1 Presentación de la plataforma de hardware 60 4.1.2 Diseño e implementación de la plataforma de hardware 64 4.2 Firmware 66 4.2.1 IDE y compilador 66 4.2.2 Esquema general de firmware para microcontroladores modernos 67 4.2.3 Firmware del microcontrolador RTCS 72 xi [ 16 de abril de 2013 at 16:46 – version 1.0 ] xii índice general Firmware del microcontrolador de sistemas dinámicos 80 4.3 Conclusiones 81 5 resultados obtenidos 83 5.1 Validación del módulo de medición de intervalos de tiempo 84 5.2 Validación de los algoritmos de control implementados 85 5.2.1 Esquema general de validación 85 5.2.2 Sistemas dinámicos discretos utilizados 88 5.2.3 Resultados de la validación de los algoritmos de control 90 5.3 Análisis de desempeño de la libRTCS 108 5.4 Conclusiones 111 6 conclusiones 113 6.1 Principales aportes del trabajo realizado 113 6.2 Resumen de los capítulos del trabajo realizado 115 6.3 Trabajo futuro 116 a apéndice 119 a.1 Algoritmo PID desarrollado en Matlab 119 a.2 Algoritmo DMC SISO desarrollado en Matlab 120 a.3 Biblioteca de recursos matemático DSPlib 122 a.4 Algoritmo PID implementado en el lenguaje de programación C 123 a.5 Algoritmo DMC SISO implementado en el lenguaje de programación C 124 4.2.4 bibliografía 127 [ 16 de abril de 2013 at 16:46 – version 1.0 ] ÍNDICE DE FIGURAS Figura 1.1 Figura 1.2 Figura 1.3 Figura 2.1 Figura 2.2 Figura 3.1 Figura 3.2 Figura 3.3 Figura 4.1 Figura 4.2 Figura 4.3 Figura 4.4 Figura 4.5 Figura 4.6 Figura 4.7 Figura 4.8 Figura 4.9 Figura 4.10 Figura 4.11 Figura 4.12 Figura 4.13 Figura 5.1 Figura 5.2 Figura 5.3 Figura 5.4 Sistema dinámico a lazo abierto 3 Sistema dinámico a lazo cerrado 3 Esquema general de trabajo de los algoritmos de control digitales 8 Multiplexación del uso del CPU del RTOS 22 Diagrama de estados de las tareas en un RTOS 24 Esquema general de la libRTCS 40 Esquema de una lista simplemente enlazada 44 Lista de controladores almacenando diferentes tipos de controladores 53 Diagrama en bloques de un núcleo Cortex-M3 60 Diagrama en bloques del microcontrolador LPC1769 Target board 63 Target board LPC1769 63 Esquemático de la plataforma de hardware 65 Circuito impreso de la plataforma de hardware 65 Fotografía de la plataforma de hardware utilizada 66 Diseño general del firmware 68 Ejemplos de bibliotecas incluídas en el nivel API 68 Ejemplos de interfaces públicas de periféricos en el nivel BSP 69 Diagrama de flujo del firmware del microcontrolador RTCS 72 Protocolo de comunicación implementado entre los microcontroladores 76 Diagrama de flujo del firmware del microcontrolador de sistemas dinámicos 81 Esquema del procedimiento de validación de los algoritmos de control 86 Respuesta al escalón del primer sistema dinámico a lazo abierto 89 Respuesta al escalón del segundo sistema dinámico a lazo abierto 89 A la izquierda la salida simulada en Matlab y a la derecha la salida en tiempo real simulada en el LPC1769 para el primer sistema dinámico y el PID float 92 xiii [ 16 de abril de 2013 at 16:46 – version 1.0 ] 61 Figura 5.5 Figura 5.6 Figura 5.7 Figura 5.8 Figura 5.9 Figura 5.10 Figura 5.11 Figura 5.12 Figura 5.13 Figura 5.14 Figura 5.15 Comparación de la salida simulada y la salida en tiempo real para el primer sistema dinámico y el PID float 93 A la izquierda la acción de control simulada en Matlab y a la derecha la acción de control en tiempo real simulada en el LPC1769 para el primer sistema dinámico del PID float 94 Comparación de la acción de control simulada en Matlab y la acción de control simulada en tiempo real en el LPC1769 para el primer sistema dinámico y para el PID float 95 A la izquierda el tiempo de computo y a la derecha el tiempo de procesamiento del algoritmo PID float para el primer sistema dinámico en el LPC1769 95 A la izquierda la salida simulada en Matlab y a la derecha la salida en tiempo real simulada en el LPC1769 para el segundo sistema dinámico y el PID float 98 Comparación de la salida simulada y la salida en tiempo real para el segundo sistema dinámico y el PID float 98 A la izquierda la acción de control simulada en Matlab y a la derecha la acción de control en tiempo real simulada en el LPC1769 para el segundo sistema dinámico del PID float 99 Comparación de la acción de control simulada en Matlab y la acción de control simulada en tiempo real en el LPC1769 para el segundo sistema dinámico y para el PID float 99 A la izquierda el tiempo de computo y a la derecha el tiempo de procesamiento del algoritmo PID float para el segundo sistema dinámico en el LPC1769 100 A la izquierda la salida simulada en Matlab y a la derecha la salida en tiempo real simulada en el LPC1769 para el primer sistema dinámico del DMC float 104 A la izquierda la acción de control simulada y a la derecha la acción de control en tiempo real para el primer sistema dinámico del DMC float 104 xiv [ 16 de abril de 2013 at 16:46 – version 1.0 ] Figura 5.16 A la izquierda el tiempo de cómputo y a la derecha el tiempo de procesamiento del algoritmo para la primera planta del sistema dinámico del DMC float 105 Í N D I C E D E TA B L A S Tabla 4.1 Tabla 4.2 Tabla 5.1 Tabla 5.2 Tabla 5.3 Tabla 5.4 Tabla 5.5 Tabla 5.6 Tabla 5.7 Tabla 5.8 Tabla 5.9 Tabla 5.10 Tabla 5.11 Tabla 5.12 Características del núcleo Cortex-M3 61 Características del microcontrolador LPC1769 62 Medición de intervalos de tiempos 84 Parámetros del PID float para el primer sistema dinámico utilizado 91 Diferencias entre las señales obtenidas en Matlab y en el LPC1769 93 Parámetros del PID float para el segundo sistema dinámico utilizado 97 Resultados obtenidos al realizar la validación del algoritmo de control PID double en el LPC1769 para el primer sistema dinámico 101 Resultados obtenidos al realizar la validación del algoritmo de control PID double en el LPC1769 para el segundo dinámico 102 Parámetros del DMC SISO float para el primer sistema dinámico utilizado 103 Resultados obtenidos al realizar la validación del algoritmo de control DMC SISO float en el LPC1769 para el primer sistema dinámico 107 Parámetros del DMC SISO float para el segundo sistema dinámico utilizado 107 Resultados obtenidos al realizar la validación del algoritmo de control DMC SISO float en el LPC1769 para el segundo sistema dinámico 108 Consumos de memoria de la libRTCS en el microcontrolador Cortex-M3 LPC1769 109 Máximas frecuencias de ejecución de los algoritmos de control de la libRTCS en el microcontrolador Cortex-M3 LPC1769 110 xv [ 16 de abril de 2013 at 16:46 – version 1.0 ] xvi Código Tabla 5.13 Resultados de utilizar la libRTCS en diferentes escenarios de control concurrentes en el microcontrolador Cortex-M3 LPC1769 111 CÓDIGO Código 1 Código 2 Código 3 Código 4 Código 5 Código 6 Código 7 Código 8 Código 9 Código 10 Código 11 Código 12 Código 13 Código 14 Código 15 Código 16 Código 17 Código 18 Código 19 Código 20 Código 21 Implementación de un lazo de control periódico en un RTOS utilizando la primitiva Delay() 26 Implementación de un lazo de control periódico en un RTOS teniendo en cuenta el tiempo de ejecución de un controlador 27 Implementación de un lazo de control periódico en un RTOS utilizando la primitiva DelayUntil() 27 Implementación de un lazo de control periódico en un RTOS utilizando la primitiva DelayUntil() y seprando la función RunController 27 Implementación final de un lazo de control periódico en un RTOS 28 Estructuras utilizadas para implementar la lista simplemente enlazada 43 Interfaz pública para manejar la lista simplemente enlazada 44 Interfaz pública del módulo principal 45 Interfaz pública del módulo de interfaces (microcontrolador) 47 Interfaz pública del módulo de interfaces (RTOS) Interfaz pública del módulo de administración de tareas 49 Interfaz pública del controlador genérico 51 Interfaz pública del controlador PID 54 Interfaz pública del controlador DMC 56 Interfaz pública para controlar un timer 74 Interfaz pública para controlar una Universal Asynchronous Receiver Transmitter (UART) 74 Interfaz pública del RTOS 75 Interfaz pública del la libRTCS 77 Aplicación de la libRTCS 77 Diferencias entre los prototipos de la funciones de la libRTCS con el timer y el FreeRTOS 79 Similitudes entre los prototipos de la funciones de la libRTCS con el timer y el FreeRTOS 79 [ 16 de abril de 2013 at 16:46 – version 1.0 ] 48 Código 22 Código 23 Código 24 Código 25 Código 26 PID desarrollado en Matlab 119 DMC desarrollado en Matlab 120 Operaciones matriciales utilizando la libDSP PID implementado en C 123 DMC implementado en C 124 122 ACRÓNIMOS SISO Single Input Single Output - Una Entrada Una Salida MIMO Multiple Input Multiple Output - Múltiples Entradas Múltiples Salidas LTI Linear Time Invariant - Lineal Tiempo Invariante PID Proportional Integrative Derivative - Proporcional Integrativo Derivativo LQR Linear Quadratic Regulator - Regulador Cuadrático Lineal LQG Linear Quadratic Gaussian - Regulador Cuadrático Gaussiano MPC Model Predictive Control - Control Predictivo basado en Modelo RTOS Real Time Operating System - Sistema Operativo de Tiempo Real RTCS Real Time Control System - Sistema de Control de Tiempo Real OOP Object Oriented Programming - Programación Orientada a Objetos HAL Hardware Abstraction Layer - Capa de Abstracción de Hardware DMC Dynamic Matrix Control - Control por Matriz Dinámica ADC Analog Digital Converter - Conversor Analógico Digital DAC Digital Analog Converter - Conversor Digital Analófico RMS Rate Monotonic Scheduling IDEs Integrated Development Environment - Entornos Integrados de Desarrollo xvii [ 16 de abril de 2013 at 16:46 – version 1.0 ] xviii acrónimos IDE Integrated Development Environment - Entorno Integrados de Desarrollo FPU Float Unit Point - Unidad de Punto Flotante HIL Hardware In the Loop POSIX Portable Operating System Interface PLC Programmable Logic Controller COTS Commercial Off The Shelf CPU Central Processing Unit GUI Graphical User Interface UAV Unmanned Aerial Vehicle WCET Worst Case Execution Time UART Universal Asynchronous Receiver Transmitter CMSIS Cortex Microcontroller Software Interface Standard EDF Earliest Deadline First [ 16 de abril de 2013 at 16:46 – version 1.0 ] 1 INTRODUCCIÓN En este capítulo, inicialmente se presentan las motivaciones del trabajo. Luego se presenta una breve introducción a los algoritmos de control existentes en la actualidad, poniendo especial atención en los algoritmos de control digitales que pueden ser implementados en sistemas digitales. Se parte de realizar una prospección para indicar el estado del arte en el que se encuentra el área de investigación y para presentar la necesidad que este trabajo pretende ayudar a solucionar. Luego se realiza una introducción teórica al control digital haciendo especial énfasis en los problemas que aparecen en la implementación de los algoritmos de control. Por último se presentan las diferentes soluciones que existen en el mercado con sus respectivas ventajas y desventajas. 1.1 motivación En este trabajo se presenta el diseño e implementación de una biblioteca de algoritmos de control para sistemas embebidos. Esta biblioteca pretende ser una solución completa para sistemas dinámicos que requieren utilizar múltiples lazos de control, a partir de utilizar un sistema embebido de pequeño tamaño, poco consumo de energía y bajo costo. Las motivaciones del presente trabajo nacen de necesidades concretas tanto en el ámbito académico como en el ámbito industrial. Por un lado, en el Laboratorio de Sistemas Embebidos (LSE), nuestro grupo de investigación trabaja continuamente con sistemas dinámicos que necesitan ser controlados mediante diferentes estrategias (quadrotores, hexacopteros, etc.). En muchos casos el objetivo de estudio no es el control del sistema dinámico en sí, pero inevitablemente se debe invertir un tiempo considerable en implementar alguna estrategia de control automático para poder manipular el sistema. Este trabajo pretende solucionar este problema, desarrollando una base sólida de algoritmos de control que puedan ser utilizados directamente en diferentes sistemas dinámicos. Por otro lado, en el ámbito industrial, existen soluciones caras, complejas de utilizar, difíciles de adaptar a las necesidades de la aplicación, que requieren de un hardware y de un software propietario de la solución y por sobre todo no están preparadas para ser utilizadas en sistemas embebidos de bajos recursos. En este sentido, el presente trabajo, pretende dar una solución abierta, gratuita, independiente 1 [ 16 de abril de 2013 at 16:46 – version 1.0 ] 2 introducción del microcontrolador y del sistema operativo de tiempo real RTOS que se desee utilizar en la aplicación. De la gran variedad de técnicas de control que existen en la actualidad, en este trabajo se decide desarrollar una versión del controlador PID digital y una versión del controlador predictivo DMC. La primera estrategia de control es elegida por su simplicidad tanto a nivel teórico como a nivel de implementación y por los buenos resultados que se consiguen en la práctica en sistemas dinámicos simples. La segunda estrategia de control es elegida por tratarse de un algoritmo de control predictivo extensible a sistemas Multiple Input Multiple Output - Múltiples Entradas Múltiples Salidas (MIMO) que optimiza una función de costos para determinar las acciones de control y también por el desafío académico que representa la problemática de adaptar un algoritmo de elevado costo computacional en un sistema embebido de bajos recursos. Ambas estrategias de control son usualmente combinadas en soluciones para control de procesos industriales con excelentes resultados. A lo largo del trabajo se detallan los principales factores involucrados en la implementación de los algoritmos de control en sistemas embebidos de bajos recursos y las técnicas utilizadas para validar el funcionamiento de los mismos. También se muestran las principales complicaciones que aparecen y las soluciones a las mismas. Se presenta la implementación de la biblioteca, detallando en particular, las técnicas utilizadas para generar un sistema flexible, escalable e independiente del hardware y del RTOS utilizado. Finalmente se presentan los resultados obtenidos al utilizar la biblioteca en el microcontrolador LPC1769 del fabricante NXP con tecnología ARM Cortex-M3 en conjunto con el Sistema Operativo de Tiempo Real FreeRTOS. También came mencionar, que parte de la motivación de este trabajo es aportar un trabajo en el cual se combinan diferentes áreas de la ingeniería que usualmente no son encontradas juntas en la bibliografía. Las áreas de incumbencia involucradas en este trabajo son: sistemas de control digitales, sistemas operativos de tiempo real, programación y sistemas embebidos. En muchos de los trabajos publicados se hace énfasis en la teoría de control, en cambio en la presente tesis se hace énfasis en las consideraciones prácticas que hay que tener en cuenta al implementar sistemas de control en aplicaciones de tiempo real duras. También se aborda la temática de scheduling y los diferentes test de schedulability que permiten determinar si un conjunto de controladores que se ejecutan de manera concurrente pueden o no cumplir con las restricciones temporales impuestas. 1.2 prospección El control automático es una rama multidisciplinaria de la ingeniería que se focaliza en el estudio y en la manipulación de sistemas [ 16 de abril de 2013 at 16:46 – version 1.0 ] 1.2 prospección dinámicos. En diversas aplicaciones prácticas, se requiere que la salida de un sistema dinámico se comporte de una determinada manera frente a una determinada excitación de entrada o acción de comando. Si el sistema dinámico no está controlado, es decir se encuentra a lazo abierto, es posible que la salida del mismo no tenga el comportamiento deseado como se muestra en la Figura 1.1 [1]. Figura 1.1: Sistema dinámico a lazo abierto El control automático se basa en la técnica de realimentación para así lograr manipular la dinámica del sistema según los requerimientos de la aplicación. Como se puede observar en la Figura 1.2, la salida del sistema es sensada y luego comparada con la referencia de entrada para obtener la señal de error. Esta última es utilizada como entrada del controlador, el cual se encarga de generar la acción de control para que el sistema dinámico se comporte según los requerimientos establecidos. Este esquema se llama sistema de control a lazo cerrado. Figura 1.2: Sistema dinámico a lazo cerrado En la práctica se utiliza el control automático para conseguir diferentes objetivos (estabilidad, seguimiento de referencias, optimización de una función de costos, propiedades de robustez, etc.), lo cual da lugar a que existan diferentes estrategias de control, cada una con sus respectivas ventajas y desventajas. Estas características serán discutidas brevemente en la siguiente sección. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 3 4 introducción Desde la década del 60, los sistemas electrónicos de control automático son ampliamente utilizados en una gran variedad de aplicaciones. Entre ellas, se pueden destacar, las industrias aeroespacial, automotriz, naval, química, petrolera, etc. Estos sistemas fueron rápidamente incorporados en las diferentes industrias por sus grandes ventajas: Aumento de la productividad. Mejoras en la calidad de los productos. Mejoras en la robustez de los procesos de producción. Optimización en el uso de la energía. Optimización en el uso de los materiales. En la actualidad, la mayoría de las estrategias de control utilizadas en la práctica, pertenecen a la categoría llamada control digital. Esto se debe principalmente a los grandes avances tecnológicos que se produjeron en las últimas décadas en el área de la electrónica y la informática. Las señales analógicas involucradas en los sistemas dinámicos son digitalizadas y el algoritmo de control puede ser procesado digitalmente por microcontroladores, FPGAs (Field Programmable Gate Array), DSPs (Digital Signal Processing), ASICs (Application Specific Integrated Circuit), etc. En el mercado existen soluciones que implementan diferentes estrategias de control para que las industrias puedan utilizarlas para automatizar sus procesos y/o productos. Estas soluciones suelen ser caras, complejas de utilizar (requieren de personal altamente capacitado), difíciles de adaptar a las necesidades de la aplicación y requieren de un hardware y de un software propietario de la solución. Por estos motivos, en este trabajo se tiene como objetivo diseñar una biblioteca de algoritmos de control para sistemas embebidos de bajos recursos que sea libre, gratuita, fácil de utilizar, fácil de adaptar a las necesidades de la aplicación y que sea independiente de la plataforma de hardware a utilizar. Se pretende que la misma sea flexible y expandible, ya que las estrategias de control que existen en la actualidad son muchas y solo algunas serán elegidas para ser implementadas en este trabajo. La justificación sobre que algoritmos serán diseñados, implementados y validados se presenta en la Sección 1.6. 1.3 clasificación de los algoritmos de control Existen diferentes características de los sistemas dinámicos a controlar que permiten hacer una primera clasificación de los tipos de sistemas de control que existen. En función del tipo de variable temporal que utilizan las ecuaciones que modelan al sistema: [ 16 de abril de 2013 at 16:46 – version 1.0 ] 1.3 clasificación de los algoritmos de control • Sistemas de control de tiempo continuo. • Sistemas de control de tiempo discreto. En función de la cantidad de entradas y salidas que tiene un sistema: • Sistemas de control SISO (Single Input Single Output). • Sistemas de control MIMO (Multiple Input Multiple Output). En función del tipo de ecuación que modela el comportamiento del sistema: • Sistemas de control modelados mediante ecuaciones diferenciales lineales. • Sistemas de control modelados mediante ecuaciones diferenciales no lineales. En función de la variabilidad temporal de los parámetros que describen al sistema: • Sistemas tiempo invariante. • Sistemas tiempo variante. En particular, en el presente trabajo, se estudian diferentes algoritmos de control para sistemas modelados en tiempo discreto, con múltiples entradas y salidas (MIMO), y del tipo Linear Time Invariant - Lineal Tiempo Invariante (LTI). Dentro de esta clase particular de sistemas existen una gran variedad de técnicas y algoritmos de control, cada una con sus respectivas ventajas y desventajas. A continuación se presenta un breve resumen a las técnicas de control más utilizadas para estos sistemas: Discretización de controladores en tiempo continuo: una posible técnica para generar controladores discretos es tomar como punto de partida un diseño en tiempo continuo y luego realizar una aproximación en tiempo discreto de dicho controlador. En general, el problema que tiene esta técnica es que se requieren tiempos de muestreo muy pequeños para que el controlador aproximado funcione correctamente. Un ejemplo clásico de discretización de controladores en tiempo continuo en el controlador PID. Sin embargo, también puede implementarse directamente un controlador PID discreto sin pasar previamente por un diseño continuo [2]. Diseño de controladores mediante realimentación de estados: esta técnica de diseño de algoritmos de control también se conoce bajo el nombre de pole placement. La técnica de ubicación de polos (pole placement) es general y se utiliza para diseñar un controlador para un sistema dinámico cuyo modelo puede estar [ 16 de abril de 2013 at 16:46 – version 1.0 ] 5 6 introducción expresado tanto como función de transferencia como en variables de estado. La misma, consiste en utilizar un observador para estimar los valores de los estados del sistema y luego realimentar a los mismos para ubicar los polos de dicho sistema a lazo cerrado de manera tal que se cumplan las especificaciones de diseño. Esta técnica no necesariamente lleva a un seguimiento de referencias sin error, pero se le puede agregar un efecto integral sin dificultad. Cabe aclarar, que si los estados del sistema son medibles y no tienen ruido, no es necesario utilizar un observador sino que se puede realizar una realimentación directa de los mismos [2]. Controladores óptimos: en esta técnica de diseño de algoritmos de control se busca encontrar las acciones de control que son necesarias aplicar al sistema para optimizar el comportamiento del mismo en algún sentido. La optimización toma la forma de una función cuadrática de costos que involucra el desvió que existe entre los valores deseados para las variables del sistema y los valores medidos. La función cuadrática, por lo general, también incluye una medida del esfuerzo de control necesario para de poder de esta manera minimizar la energía requerida para controlar al sistema. Los algoritmos más utilizando en esta categoría son el controlador Linear Quadratic Regulator - Regulador Cuadrático Lineal (LQR) y el controlador Linear Quadratic Gaussian - Regulador Cuadrático Gaussiano (LQG). [2] Controladores robustos: esta tipo de técnica se utiliza cuando se desean eliminar los efectos que producen las incertezas en el modelo del sistema y las variaciones en el mismo sobre la performance del algoritmo de control. Un ejemplo de este tipo de controladores es el controlador H∞ (H - infinito). Este tipo de controladores requiere un mayor costo computacional que las soluciones clásicas. Control predictivo: también conocidos bajo las siglas en inglés Model Predictive Control - Control Predictivo basado en Modelo (MPC), son algoritmos de control utilizados para controlar sistemas complejos. Los mismos se basan en la predicción de los cambios de las variables dependientes del modelo causados por la predicción de los cambios de las variables independientes. En general, los sistemas complejos están compuestos por subsistemas previamente estabilizados mediantes controladores simples y clásicos como por ejemplo PID. En dichos sistemas, las variables independientes son las referencias de los PID y los valores de las acciones de control son obtenidas a partir de optimizar una determinada función de costos. Este tipo de algoritmos de control son ampliamente utilizados en la industria, en gran medida debido a la capacidad que tienen de soportar restriccio- [ 16 de abril de 2013 at 16:46 – version 1.0 ] 1.4 introducción a los algoritmos digitales de control nes en el proceso de optimización. Un ejemplo de este tipo de algoritmos es el controlador DMC utilizado en este trabajo [3]. 1.4 introducción a los algoritmos digitales de control Hasta la década del 60, los sistemas de control automáticos estaban completamente implementados con dispositivos analógicos. Pero a partir del gran desarrollo que tuvo la electrónica digital, los controladores comenzaron a incluir cada vez más dispositivos digitales. Es por este motivo que actualmente un de las ramas más desarrolladas del control automático es el control digital. Esto produjo que se diseñen nuevos algoritmos de control de gran desempeño y eficiencia. La utilización de este tipo de sistemas digitales (hoy en día conocidos como sistemas embebidos) en la implementación de sistemas de control tiene diferentes ventajas, entre ellas se pueden destacar: Permiten implementar controladores complejos y avanzados de gran performance. Permiten utilizar soluciones numéricas a los problemas matemáticos involucrados en los controladores. Permiten ejecutar algoritmos de control de manera concurrente. Permiten añadir protocolos de comunicación. Permiten añadir interfaces gráficas de usuario. En la bibliografía disponible actualmente es común encontrar detallados desarrollos teórico respecto a los algoritmos de control digital, pero por otro lado, es mucho más escasa la información disponible respecto a la implementación de dichos algoritmo en sistemas embebidos. Por este motivo, en muchas aplicaciones prácticas, las ventajas enumeradas no son correctamente utilizadas y el gran potencial que tienen los sistemas embebidos de implementar controladores digitales no es aprovechado en su totalidad. En un sistema que ejecuta tareas de manera concurrente, es fundamental realizar un análisis temporal que permita determinar si todas las restricciones temporales van a ser correctamente cumplidas. Si alguna de las tareas que se encarga de ejecutar un algoritmo de control, no logra cumplir con los requerimientos temporales, el control automático del proceso en cuestión es susceptible a fallar comprometiendo gravemente la seguridad de todo el sistema. Esta falla puede implicar un gran peligro para vidas humanas (por ejemplo en aplicaciones industriales) y/o una gran pérdida de dinero por la destrucción de un sistema o parte del mismo. Por este motivo, se dice que los sistemas embebidos que son utilizados para implementar algoritmos de control, deben cumplir con condiciones temporales duras. Para poder satisfacer dichas [ 16 de abril de 2013 at 16:46 – version 1.0 ] 7 8 introducción condiciones temporales, por lo general, se utilizan RTOS, y cuando la aplicación lo requiere, se utilizan también sistemas tolerantes a fallas [4] [5]. 1.4.1 Esquema general de los algoritmos digitales de control La gran mayoría de los algoritmos de control digital incluyen los siguientes elementos y aplican el esquema general de trabajo indicado en la Figura 1.3: Figura 1.3: Esquema general de trabajo de los algoritmos de control digitales Sistema dinámico: es la planta física que se quiere controlar para obtener salidas que cumplan con los requerimientos de la aplicación. Muestreo y CAD): El Conversor Analógico Digital o ADC (por sus siglás en inglés) junto con el muestreo, es el módulo que se encarga de muestrear las señales analógicas y luego transformar las muestras en valores digitales para poder obtener las señales que son procesadas por la computadora. CDA y retenedor: El Conversor Digital Analógico o DAC (por sus siglás en inglés) junto con el retenedor, es el módulo que se encarga de generar muestras analógicas a partir de las señales [ 16 de abril de 2013 at 16:46 – version 1.0 ] 1.4 introducción a los algoritmos digitales de control digitales y luego aplicar un retenedor para poder obtener las señales analógicas que excitan al sistema dinámico. Red de comunicación: los sistemas dinámicos modernos están compuestos por diferentes procesos. Habitualmente cada proceso incluye su propio CAD y CDA. La computadora digital se comunica con cada proceso mediante una red de comunicación. En la práctica se utilizan diferentes tipos de protocolos de comunicación según los requerimientos de la aplicación. Cada protocolo de comunicación normaliza sus propiedades temporales, eléctricas y lógicas. Computadora digital: es el módulo que implementa y ejecuta el algoritmo de control. La computadora digital puede estar compuesta por microcontroladores, FPGAs, DSPs, ASICs o un conjunto de las anteriores. Más allá de cuál sea el hardware que se utilice para implementar la computadora digital, siempre se incluye un RTOS que le otorgue al sistema la capacidad de cumplir con restricciones temporales duras. 1.4.2 Algoritmos digitales de control y muestreo de los procesos En la sección anterior se presentaron los componentes típicos de un sistema de control digital. Para desarrollar correctamente un sistema de control digital, debe entenderse en detalle como dicho control interactúa con procesos físicos que transcurren en tiempo continuo. Los componentes que le permiten al controlador digital interactuar con procesos de tiempo continuo son el Analog Digital Converter Conversor Analógico Digital (ADC) y el Digital Analog Converter Conversor Digital Analófico (DAC). Como se mencionó anteriormente, el ADC está compuesto por un muestreador, un cuantificador y un codificador. El muestreador se encarga de convertir una señal de tiempo continuo x (t) en una señal de tiempo discreto x [n]. Luego, el cuantificador se encarga de transformar la señal de tiempo discreto x [n] en una nueva señal de tiempo discreto pero con valores de precisión finita xq [n]. Por último, el codificador transforma la señal discreta cuantificada en una señal digital xd [n] que es finalmente almacenada en la computadora digital. Por lo general se utilizan ADC con una resolución que va desde los 8 hasta los 16 bits, lo cual otorga entre 28 y 216 niveles de cuantificación respectivamente. Esta resolución, generalmente, es mayor que la precisión de medición de un sensor físico. Por otro lado, el DAC primero se encarga de transformar una señal digital yd [n] en una señal discreta de precisión finita yq [n]. Luego se obtiene la señal reconstruida yr (t) a partir de utilizar un filtro de reconstrucción que se encarga de interpolar los valores intermedios [ 16 de abril de 2013 at 16:46 – version 1.0 ] 9 10 introducción entre dos muestras consecutivas de la señal digital. El filtro de reconstrucción más utilizado en la práctica es el retenedor de orden cero. Uno de los objetivos típicos de un sistema digital de control es medir la señal de referencia y la señal de salida, para luego procesar dichas señales a través de un determinado algoritmo y producir la señal de control adecuada para que dichas señales sean lo más parecidas posibles cumpliendo con los requerimientos del sistema. Para poder cumplir con este objetivo, las señales involucradas deben ser correctamente muestreadas y reconstruidas. Para muestrear correctamente una señal debe respetarse el teorema de muestreo de Nyquist-Shannon. Este teorema afirma que si una señal en tiempo continuo no posee frecuencias por arriba de w0 entonces dicha señal puede ser reconstruida por muestras de las mismas adquiridas a una frecuencia ws mayor o igual que 2w0 . Este teorema también demuestra cuál es el filtro h(t) de reconstrucción perfecta: h(t) = sin(ws t/2) ws t/2 (1.1) El filtro de reconstrucción perfecta no es causal, motivo por el cual es imposible utilizar al mismo en la práctica. Como antes se mencionó, se utilizan otros filtros como el retenedor de orden cero. Para una señal discreta yq [n], la señal reconstruida yr (t) a partir de un retenedor de orden cero de tiempo de retención h se obtiene de la siguiente manera: yr ( t ) = n yq [n] nh ≤ t < (n + 1)h; (1.2) Por último, es importante utilizar filtros anti-aliasing si se decide utilizar una frecuencia de muestreo ws y la señal a muestrear tiene frecuencias superiores a ws /2. La frecuencia ws /2 es conocida como la frecuencia de Nyquist w N . Toda componente de frecuencia superior a w N en la señal a muestrear, debe ser correctamente atenuada a partir de utilizar un filtro anti-aliasing. 1.4.3 Implementación de los algoritmos de control digitales Por lo general, la implementación de un algoritmo de control digital en una computadora involucra los siguientes pasos: 1. Conversiones analógicas digitales de las salidas y las referencias. En el caso de sistemas Single Input Single Output - Una Entrada Una Salida (SISO), en este paso se obtiene la salida del sistema y[n] y la referencia r [n]. 2. Computo de la señales de control. En el caso de sistemas SISO, se obtiene u[n]. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 1.5 soluciones existentes en el mercado 3. Conversiones digitales analógicas de las señalaes de control. 4. Actualización de las variables involucradas en el algoritmo de control. En la enumeración anterior, se observa que la implementación del algoritmo de control está hecha de manera tal que sea minimizado el retardo de computo que existe entre la medición de las señales de entrada (uso del ADC) y la generación de las señales de salida (uso del DAC). El retardo de computo también se conoce en la bibliografía bajo el nombre de latencia entrada-salida y se representa mediante la letra griega τ. El intervalo de tiempo que existe entre uso y uso del ADC se denomina tiempo de muestreo h. Ambos intervalos de tiempo son susceptibles de sufrir variaciones conocidas como jitters. Idealmente el jitter en el tiempo de muestreo y el jitter en el tiempo de computo deberían ser cero. En la práctica, estos jitters nunca llegan a ser cero, pero existen diferentes técnicas que permiten minimizarlas o compensarlas [6] [7]. En general, los algoritmos de control digital, se implementan a partir de utilizar un Sistema Operativo de Tiempo Real (RTOS). Estos sistemas, permiten entre otras cosas, que un procesador sea utilizado para ejecutar concurrentemente más de una tarea. Dichas tareas son las encargadas, entre otras cosas, de ejecutar algoritmos de control, atender protocolos de comunicación, disparar alarmas, manejar Graphical User Interface (GUI), etc. En estos sistemas, es muy común que se utilicen diferentes recursos para sincronizar la ejecución de las tareas. Si la ejecución de una tarea que implementa un algoritmo de control se ve demorada, se producen variaciones en el tiempo de muestro h. Por otro lado, muchos de los algoritmos de control implementados en la práctica, utilizan procesos de optimización cuyos tiempos de ejecución dependen de los datos disponibles en cada iteración del lazo de control. Por este motivo, se producen variaciones en los tiempos de computo de los algoritmos de control. Ambas variaciones en los intervalos de tiempo, producen una degradación de la performance del algoritmo de control y, en algunos casos, puede ocasionar que la planta controlada se vuelva inestable [8]. En el Capítulo 2, en particular en la Sección 2.1 se realiza una introducción a los Sistemas de Control de Tiempo Real en donde se explica cómo se utilizan los RTOS y como se implementan correctamente los algoritmos de control digitales para reducir la variación en dichos intervalos de tiempo. 1.5 soluciones existentes en el mercado Los Sistemas de Control de Tiempo Real (RTCS) son ampliamente utilizados en diferentes aplicaciones, desde el simple control digital de la temperatura de un horno hasta el más complejo de los satélites. Por este motivo, en los últimos años surgieron un gran número de [ 16 de abril de 2013 at 16:46 – version 1.0 ] 11 12 introducción soluciones, que se adaptan a los requisitos de las diferentes aplicaciones. Las soluciones que existen actualmente en el mercado se pueden clasificar en tres grupos: Soluciones basadas en sistemas operativos Commercial Off The Shelf (COTS): Existen sistemas de control de tiempo real implementados sobre sistemas operativos COTS, como por ejemplo Windows. Las principales desventajas de este tipo de soluciones es que, por un lado, dependen de un hardware propietario que se conecta al sistema operativo COTS para proveer al mismo de una interfaz de comunicación con los procesos físicos reales. Por otro lado, también dependen de una solución de software propietaria para implementar los diferentes algoritmos de control, como por ejemplo Matlab. También, este tipo de soluciones suelen ser relativamente caras y no viables para determinadas aplicaciones. Por ejemplo, en el caso de las naves Unmanned Aerial Vehicle (UAV) de escala reducida, es imposible utilizar este tipo de soluciones COTS. Por último, este tipo de sistemas operativos COTS no son de tiempo real. Esto representa un problema, ya qué como se explicó anteriormente, si el sistema de control digital tiene variaciones temporales (jitter) en el tiempo de muestreo y/o en el tiempo de computo, la performance del controlador se ve degrada. En los sistemas operativos COTS se debe recurrir a técnicas de compensación del jitter para que sea viable la implementación de los controlador y la performance de los mismos no se vea degrada. Por otro lado, la principal ventaja que tiene este tipo de soluciones, es la gran cantidad de bibliotecas de software de control de alto nivel que existen disponibles. Soluciones basadas en plataformas de hardware cerradas: Este tipo de soluciones son ampliamente utilizadas en la industria. En su mayoría están basadas en dispositivos electrónicos como los Programmable Logic Controller (PLC). Los PLC, en general, son una plataforma de hardware completamente cerrada y poco flexible. Es decir, en cuanto a control automático se refiere, la plataforma es poco flexible porque solo incorpora un conjunto de funcionalidades específicas y al ser cerrada dichas funcionalidades no siempre pueden ser adaptadas a los requerimientos de la aplicación. La ventaja que tienen estas soluciones es su robustez. Dada la gran cantidad de años de experiencia que acumularon los fabricantes de PLC industriales, consiguieron generar productos muy robustos. Esta característica es fundamental en la industria, ya que una falla en un lazo de control en un sub-proceso del sistema global puede ocasionar grandes daños a toda la instalación lo cual a su vez pone en riesgo la vida de las personas y producen grandes pérdidas de dinero. Otra [ 16 de abril de 2013 at 16:46 – version 1.0 ] 1.5 soluciones existentes en el mercado de las ventajas que tienen este tipo de soluciones es que, por lo general, vienen preparadas para ser utilizadas para controlar procesos distribuidos. Soluciones basadas en sistemas embebidos: En los últimos años, la cantidad de aplicaciones que comenzaron a requerir lazos de control aumentó en gran medida. Esto último se justifica observando el incremento que existe en el uso de aplicaciones como por ejemplo: brazos robóticos industriales, naves aéreas no tripuladas, vehículos terrestres no tripulados, sistemas de lentes en cámaras fotográficas y cámaras de video, etc. En este tipo de sistemas, muchas veces no es factible utilizar las soluciones basadas en sistemas operativos COTS o basadas en PLC debido a cuestiones de energía, tamaño, capacidad de procesamiento, etc. Por este motivo, las soluciones basadas en sistemas embebidos obtuvieron una gran importancia en los últimos años. Estas soluciones, por lo general, involucran la utilización de un microcontrolador en conjunto con un RTOS. Para cada aplicación en particular, se diseña y se implementa el controlador digital necesario para la aplicación. Una de las principales ventaja de este tipo de soluciones es que son completamente adaptables a los requerimientos de la aplicación. Por otro lado, una de las principales desventaja es que se debe realizar todo el diseño y la implementación del controlador digital, lo cual puede significar la inversión de una gran cantidad de tiempo y dinero. Dada la gran explosión que tuvieron en los últimos años las soluciones basadas en sistemas embebidos en combinación con el gran avance tecnológico que se dio en el área de los microcontroladores, cada vez son más las aplicaciones que utilizan a estos último en conjunto con un RTOS para implementar los lazos de control. Esto se debe a las grandes ventajas que tienen este tipo de soluciones: flexibilidad, escalabilidad, tamaño, consumo de energía, etc. Como se explicó anteriormente este tipo de soluciones involucra el desarrollo y la implementación de un controlador digital, lo cual representa una inversión de tiempo y dinero. Como muchas de las aplicaciones no tienen como objetivo principal implementar un lazo de control sino que más bien requieren utilizar un lazo de control para solucionar un problema concreto, se generó una clara necesidad en el mercado. Es decir, se necesita un componente que permita ahorrar tiempo y dinero en el momento de implementar un lazo de control digital, pero que a la vez sea suficientemente flexible y robusto para cumplir con los requerimientos de las aplicaciones modernas. Con la aparición de los microcontroladores de 32 bits económicos, la industria de los sistemas embebidos se vio completamente revolucionada. Estos nuevos microcontroladores también comenzaron a [ 16 de abril de 2013 at 16:46 – version 1.0 ] 13 14 introducción incluir muchos más recursos que sus predecesores: más cantidad de memoria de programa y memoria de variables, más puertos de comunicación, más velocidad de procesamiento, etc. Gracias a todos estos avances, fue posible comenzar a programar a estos microcontroladores en lenguajes de programación de nivel más alto que el tradicional assembler como por ejemplo los lenguajes de programación C y C++. El exceso de recursos consumidos al programar con estos lenguajes de programación se volvió menos significativo y comenzaron a ser ampliamente utilizados. Esto trajo aparejada una ventaja adicional fundamental: la posibilidad de construir bibliotecas de software portables a diferentes plataformas de hardware que den soluciones a problemas concretos. En los párrafos anteriores, se mencionó la necesidad que apareció en el mercado de contar con un componente que permita agregar rápidamente lazos de control a una aplicación. En este trabajo se pretende diseñar, implementar y validar dicho componente a partir de desarrollar una biblioteca específica de código que permita implementar sistemas operativos de tiempo real. 1.6 conclusiones En este capítulo, primero se presentaron cuáles fueron las motivaciones del presente trabajo. Luego se realizó una prospección en la temática de implementación de controladores digitales, para conocer cual es el esado del arte de esta área. A partir de la prospección realizada y partir de analizar las problemáticas existentes tanto a nivel académico como a nivel comercial, se encontró una clara necesidad. Con el objetivo de satisfacer dicha necesidad, en esta trabajo, se realiza el diseño, la implementación y la validación de una biblioteca de algoritmos de control para sistemas embebidos que permite implementar sistemas de control de tiempo real. A partir de toda la información analizada, se concluye que dicha biblioteca de código debe tener las siguientes características: La biblioteca de código debe ser portable a diferentes microcontroladores. La biblioteca de código debe ser compatible con diferentes RTOS y debe ser fácilmente portable a los mismos. Debe incluir diferentes tipos de algoritmos de control digital para poder cubrir las necesidades de una amplia gama de aplicaciones. Debe poder instanciar y ejecutar concurrentemente diferentes algoritmos de control para poder controlar muchos sub-procesos de un sistema. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 1.6 conclusiones Debe incluir mecanismos que permitan determinar si un conjunto de lazos de control concurrentes pueden cumplir o no con los requerimientos temporales impuestos. La biblioteca de código debe ser flexible y escalable, para poder incluir fácilmente nuevos algoritmos de control. Para lograr diseñar e implementar una biblioteca de código que incluya todas estas características, se necesita disponer de un amplio conocimiento teórico en los siguientes temas: Sistemas de control de tiempo real. Sistemas operativos de tiempo real. Teoría de los controladores digitales a implementar. Implementación de algoritmos en computadoras. Complejidad de los algoritmos y recursos que consumen. Diseño e implementación de bibliotecas de código flexibles y escalables. En el Capítulo 2 se hace una introducción teórica a todos estos temas. Luego en el Capítulo 3 se presenta el diseño de la biblioteca de código. Finalmente en el Capítulo 4 y en el Capítulo 5, se aplica la biblioteca desarrollada en este trabajo en una plataforma de hardware concreta y se presentan los resultados obtenidos. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 15 [ 16 de abril de 2013 at 16:46 – version 1.0 ] 2 DESARROLLO TEÓRICO En este capítulo se presenta el marco teórico utilizado para implementar la biblioteca de algoritmos de control. Primero se presenta la problemática que existe al implementar un sistema embebido que ejecuta de manera concurrente (al mismo tiempo o simultáneamente) diferentes algoritmos de control. Para dar soluciones a dicha problemática, se hace una breve introducción a los RTOS y a la teoría de scheduling que permite determinar si un conjunto de tareas puede cumplir con los requisitos temporales deseados. Por otra parte, también se presenta la teoría de las estrategias de control estudiadas en este trabajo: el controlador PID y el controlador DMC. La teoría presentada es necesaria para obtener los algoritmos que finalmente serán implementados en la biblioteca de algoritmos de control utilizando el lenguaje de programación C. 2.1 sistemas de control de tiempo real (rtcs) Tradicionalmente, cuando se implementaban sistemas de control digitales, se asumía que la plataforma utilizada podía proveer al sistema de control un tiempo de muestreo determinístico y equidistante (que son las bases tradicionales de la teoría de control digital). Sin embargo, muchas de las plataformas comúnmente utilizadas para implementar sistemas de control no son capaces de dar ninguna garantía de determinismo temporal. Por ejemplo, este es el caso de los sistemas operativos COTS como Windows. Este tipo de sistemas operativos introducen gran indeterminismo temporal en la administración de las tareas. El impacto que este indeterminismo temporal puede tener sobre los controladores digitales es desbastador, ya que la estabilidad y la performance del mismo puede ser completamente degradada. En resumen, la antigua metodología de desarrollar por separado del controlador digital por un lado y de la implementación del mismo por el otro, producía resultados negativos en el comportamiento del sistema de control. En la actualidad, cuando se desarrollan sistema de control de tiempo real (RTCS), se combina el diseño teórico del controlador digital con las consideraciones necesarias relacionadas con la implementación. De esta manera, se logra mejorar en gran medida el desempeño del mismo. Para reducir el indeterminismo temporal que existe en las plataformas tradicionalmente utilizadas, se comenzaron a utilizar Sistemas Operativos de Tiempo Real RTOS [4] [9]. Entonces, los RTCS modernos incluyen: 17 [ 16 de abril de 2013 at 16:46 – version 1.0 ] 18 desarrollo teórico Una computadora digital para ejecutar los algoritmos de control. Un Sistema Operativo de Tiempo Real (RTOS) para administrar los tiempos de ejecución de los algoritmos de control. La gran mayoría de los RTCS modernos son implementados en sistemas embebidos que son partes de un sistema más grande. Esos sistemas embebidos incorporan microcontroladores y un RTOS. Ejemplos donde se usan estos tipos de sistemas son: la industria automotriz, robos industriales, aplicaciones aeroespaciales como aviones y satélites, etc. En la industria de manufactura, estos sistemas deben ser muy flexibles ya que el número de lazos de control y sus respectivos parámetros varían dinámicamente. En general, muchos RTCS implementados en sistemas embebidos para aplicaciones específicas se desarrollan sin utilizar ninguna biblioteca de código específica y a partir de utilizar lenguajes de programación como C o C++. Por otro lado en el caso de la industria, donde existe gran cantidad de procesos a controlar de manera distribuida, se utilizan diferentes PLCs interconectados mediante una red de comunicaciones. Estos sistemas de control distribído incluyen ricas interfaces gráficas de usuario para que se puedan configurar los parámetros de los diferentes lazos de control. Tanto en el caso de los sistemas embebidos para aplicaciones específicas como en el caso de sistemas de control distribuidos para procesos industriales con PLCs, en general, se utilizan computadoras digitales y Sistemas Operativos de Tiempo Real. Por este motivo, una solución correctamente implementada de un controlador digital, requiere tanto de buen conocimiento en el área de control como también de buen conocimiento en la teoría de sistemas de tiempo real. En el mercado, existen soluciones sobre sistemas operativos COTS (por ejemplo Windows) que dependen de software y hardware específicos (por ejemplo Matlab) y también existen soluciones sobre plataformas completamente cerradas (por ejemplo PLCs Siemens). En este trabajo se pretende diseñar, implementar y validar un sistema de control de tiempo real, encapsulado en la forma de una biblioteca de algoritmos de de control. Esta biblioteca pretende ser independiente de la plataforma de hardware y del RTOS utilizados. Se busca que la misma sea una solución libre y abierta, para que pueda ser utilizada en diferentes aplicaciones que requieren de diferentes lazos de control ejecutándose de manera concurrente. Para poder explicar el diseño y la implementación de la biblioteca de algoritmos de control, se debe realizar una introducción a los sistemas operativos de tiempo real y a los esquemas de scheduling. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 2.1 sistemas de control de tiempo real (rtcs) 2.1.1 Sistemas Operativos de Tiempo Real 2.1.1.1 Introducción y clasificación Un RTOS debe responder a eventos periódicos (por ejemplo el tiempo de muestreo en sistemas de control) y a eventos aperiódicos (por ejemplo alarmas, protocolos de comunicación asincrónicos, etc.). Una primera clasificación de los RTOS podría ser en función del grado de rigidez que se requiere en el cumplimiento de los tiempos: Sistemas Operativos de Tiempo Real Duros: En este tipo de sistemas las restricciones temporales impuestas deben ser cumplidas de manera estricta. Ejemplos de este tipo de sistemas son: los controladores del sistema de vuelo de un avión, el freno de los automóviles, etc. Sistemas Operativos de Tiempo Real Suaves: En este tipo de sistemas, las restricciones temporales son importantes, pero este seguirá funcionando si se falla en cumplir alguna de dichas restricciones. Ejemplos de este tipo de sistemas son: interfaces gráficas de usuario, alarmas secundarias, etc. En la actualidad, los Sistemas Operativos de Tiempo Real duros adquirieron una gran relevancia en los sistemas embebidos y se convirtieron en un área de gran interés y de investigación científica. Esto se debe a la gran cantidad de aplicaciones actuales que requieren cumplir con condiciones temporales estrictas, como son los sistemas de control digital de tiempo real. En general, en este tipo de sistemas se ejecutan de manera concurrente diferentes lazos de control. El trabajo que hay que realizar para atender a todos los eventos generados por estos lazos de control concurrentes, constituyen el conjunto de tareas que administra el RTOS. Los diferentes lazos de control, típicamente funcionan a diferentes frecuencias y son unos independientes de los otros. También, en algunos casos, los lazos de control deben estar sincronizados (controladores en cascada) [4]. Los RTOS están preparados para funcionar sobre distintas plataformas de hardware. En función del número de procesadores CPUs que puede utilizar el RTOS, se puede realizar una segunda clasificación: single-core: Solo utiliza un núcleo, y la asignación del mismo debe ser multiplexado entre las diferentes tareas que el RTOS está administrando. RTOS RTOS multi-core: Utiliza más de un núcleo. Es más complejo que el RTOS single-core, ya que debe tomar la decisión adicional de que tarea se ejecuta en qué núcleo. La memoria es compartida entre los diferentes núcleos. RTOS distributed: Es similar al RTOS multi-core, con la diferencia que los núcleos no comparten memoria de manera directa. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 19 20 desarrollo teórico La función principal de un RTOS es administrar un conjunto de tareas instanciadas, de manera tal de cumplir con los requerimientos temporales impuestos al sistema. Un RTOS se define por: Los evetos externos que debe atender. Las respuestas que el mismo debe producir ante los evetos. Los requermientos temporales que deben cumplir dichas respuestas. El encargado de administrar el tiempo de uso de un núcleo o Central Processing Unit (CPU) de cada tarea es el scheduler. Su función, es determinar que tarea debe estar en ejecución en cada momento. Cada tarea se ejecuta dentro de un contexto, que está definido por: el program counter, el stack pointer, los registros del CPU y el contenido de la pila en uso. Cuando el scheduler determina que la tarea actual debe ceder el uso del CPU a otra tarea, se produce un cambio de contexto. En dicho instante, se ejecuta otro componente del RTOS llamado dispatcher el cual se encarga de guardar el contexto de la tarea actual y reemplazarlo por el de la nueva tarea. En función de como se decide que una nueva tarea acceda al uso del CPU, los RTOS también se pueden clasifican según: Cooperative mode: El cambio de contexto ocurre cuando la tarea en ejecución decide liberar el uso de un núcleo. Preemptive mode: El cambio de contexto ocurre por decisión del scheduler. Existen diferentes algoritmo de scheduling que definen los criterios de decisión que el RTOS utiliza para producir los cambios de contexto. En general, los RTOS preemtivos utilizan prioridades para las tareas. La tarea con mayor prioridad que está lista para ejecutarse es la que adquiere el uso del CPU. A su vez, los RTOS preemptivos pueden clasificarse según: • Fixed priority preemptive RTOS: Las prioridades de las tareas son definidas en tiempo de compilación, y las mismas se mantienen constantes durante el ciclo de vida de la tarea. • Dynamic priority preemtive RTOS: Las prioridades de las tareas son definidas en tiempo de ejecución, en función de parámetros de las tareas, como por ejemplo el tiempo de expiración de las mismas. • Mixed priority preemtive RTOS: Este tipos de sistemas soporta tareas con prioridades fijas y tareas con prioridades que cambian dinámicamente. Si un RTOS estuviese ejecutándose sobre una plataforma de hardware multi-core sería posible, desde un punto de vista teórico, asignar un [ 16 de abril de 2013 at 16:46 – version 1.0 ] 2.1 sistemas de control de tiempo real (rtcs) núcleo a cada tarea del conjunto y realizar el procesamiento realmente en paralelo (siempre y cuando hayan disponible la misma cantidad de núcleros que tareas). En la actualidad, el caso más habitual, los RTOS se ejecutan sobre una plataforma de hardware single-core. En este caso, es necesario multiplexar de alguna manera la asignación del único núcleo entre todas las tareas que el RTOS debe administrar. La manera en la cual esta multiplexación es realizada, permite generar otra clasificación del los RTOS. Habitualmente esto se conoce como esquemas de scheduling y que resulta en la siguiente clasificación [10]: Clock Driven RTOS: Para aplicaciones de tiempo real en las cuales el conjunto de tareas en ejecución no cambia dinámicamente, se utilizan los esquemas de scheduling clock driven. La secuencia de ejecución de las tareas, es prefijada antes de que el sistema inicie. En este esquema, el scheduler se efectúa en base al reloj del sistema. A continuación se presentan dos esquemas que entran en esta categoría. • Cyclic: Es la manera más primitiva de multiplexación de tareas en un núcleo. El usuario ejecuta manualmente las tareas de forma secuencial. La principal desventaja de este método es que se genera código complejo, difícil de interpretar y poco escalable. • Table Driven: Es una mejor alternativa al caso anterior, ya que el ciclo de ejecución de tareas se construye automáticamente a partir de una tabla definida por el usuario. Este esquema se conoce también con el nombre off-line static scheduler. Durante la programación de un sistema de este tipo, se especifica la tabla que define el ciclo de ejecución de tareas, es decir, que la decisión de cómo estas últimas se multiplexan no se realiza dinámicamente mientras el sistema está on-line. La ventaja de este esquema de scheduling es que se obtiene un alto nivel de determinismo temporal. La desventaja es que el sistema obtenido es muy rígido, y el scheduler tiene que ser modificado cada vez que el conjunto de tareas cambia. Es habitual encontrar este esquema en sistemas de tiempo real que permanecerán fijos y sin cambios por largos períodos de tiempo. Event Driven RTOS: Para aplicaciones de tiempo real en las cuales el conjunto de tareas en ejecución cambia dinámicamente on-line, se utilizan los esquemas de scheduling event driven. En estos casos se aplican técnicas de programación concurrentes para que el RTOS pueda multiplexar el uso del CPU entre las diferentes tareas. Es decir, el núcleo disponible es compartido por un conjunto de tareas y el RTOS decide en cada paso del sistama que tarea debe estar en ejecución. Idealmente, el RTOS toma la decisión de manera tal que todas las restricciones temporales [ 16 de abril de 2013 at 16:46 – version 1.0 ] 21 22 desarrollo teórico impuestas sean cumplidas. De esta manera, parece que las tareas se están ejecutando realmente en paralelo. En realidad, el RTOS hace que las tareas compartan el único núcleo disponible produciendo lo que se conoce bajo el nombre de cambios de contexto. Este tipo de esquema también se conoce como time-sharing concurrency. Este concepto se representa en la Figura 2.1. Figura 2.1: Multiplexación del uso del CPU del RTOS Este tipo de esquema de scheduling es el que lidera el mercado con más soluciones de hardware y software disponibles. La principal desventaja que tiene es las complicaciones prácticas que existen para asegurar que todas las restricciones temporales serán cumplidas. Sin embargo, se desarrolló mucha teoría en esta área y actualmente existen test de schedulability que permiten determinar si un conjunto de tareas puede o no cumplir con las restricciones temporales impuestas. La principal ventaja que tiene es la gran flexibilidad que presenta para adaptarse a nuevas aplicaciones. A continuación se presentan dos esquemas que entran en esta categoría. En estos esquema, el scheduler se ejecuta en base a los eventos que ocurren. • Rate Monotonic Scheduler: Este tipo de esquema de scheduling es utilizado en fixed priority preemptive RTOS. Básicamente, este esquema consiste en asignar la prioridad más alta a la tarea con mayor frecuencia de ejecución. En la Sección 2.1.1.3 se detalla ampliamente este esquema de scheduling ya que resulta relevante para los RTCS. • Erliest Deadline First: Este tipo de esquema de scheduling es utilizado en dynamic priority preemtive RTOS. En este caso, el RTOS cambia dinámicamente las prioridades de la tarea en función de los tiempos de expiración de las mismas. La tarea que esté más próxima a expirar es a la que se le asigna la prioridad más alta. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 2.1 sistemas de control de tiempo real (rtcs) Hybrid RTOS: Por último, en este tipo de esquema el scheduler se ejecuta en base al reloj del sistema y en base a los eventos que ocurren. 2.1.1.2 Programación concurrente En este trabajo nos enfocamos en los Sistemas Operativos de Tiempo Real, single-core, preemtive y fixed priority. Cabe aclarar que fixed priority significa que el RTOS no modifica automáticamente las prioridades de las tareas, pero si lo puede realizar el usuario durante la ejecución del sistema. En este tipo de RTOS, por lo general una tarea puede estar en uno de los siguientes cuatro estados: Running state. Ready state. Blocked state. Suspended state. Las tareas que están en estado ready tienen acceso a los recursos que necesitan para ejecutarse, pero no tienen acceso al núcleo o CPU. Las tareas que están en este estado, por lo general, están almacenadas en un contenedor FIFO (First-In-First-Out) del RTOS en función de la prioridad de las mismas. La tarea que está en estado running, es la primera tarea de esta fila (con la mayor prioridad) y es la que tiene acceso al CPU. Por otro lado, las tareas que están en estado blocked están esperando que algún recurso del RTOS se libere (por ejemplo un semáforo o un mutex o a la espera de que expire algún tiempo). El RTOS ejecuta el scheduler cada un número determinado de ticks del reloj del sistema o cuando ocurre algún evento particular. Cuando se ejecuta este módulo, si se libera algún recurso que estaba siendo esperado por una tarea en estado blocked, la misma pasa al estado ready. Luego el scheduler determina cual es la tarea con mayor prioridad en estado ready. Si la misma tiene mayor prioridad que la tarea que en dicho momento se encuentra en estado running se produce un cambio de contexto. Por último, el estado suspended se ubican las tareas que el usuario del RTOS decidió suspender temporalmente. Las tareas en el estado suspended solo pueden volver a alguno de los otros tres estádos cuando es quitada del mismo explícitamente por el usuario del RTOS y no cuando algún recurso es liberado con en el caso blocked. En la Figura 2.2 se puede observar un diagrama de estados que resume lo explicado en este párrafo. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 23 24 desarrollo teórico Figura 2.2: Diagrama de estados de las tareas en un RTOS 2.1.1.3 Teoría de scheduling En los RTOS duros, es fundamental que los requerimientos temporales siempre sean cumplidos. Por este motivo, antes de que el sistema inicie, es necesario ejecutar un análisis que permita determinar si un conjunto de tareas puede cumplir o no con dichos requerimientos temporales. Si el análisis concluye que los requerimientos temporales no pueden ser cumplidos, el sistema no debería iniciar. Este tipo de análisis, requiere introducir la teoría de scheduling. Los RTOS, como se mencionó anteriormente, reaccionar ante eventos que necesitan ser procesados por el CPU. Asociado con cada enveto, existe una tarea que debe ejecutar un determinado código. Cada tarea dispone de un deadline impuesto por los requerimientos temporales del sistema y requiere un tiempo de CPU para ejecutar su correspondiente código. En general, se considera el peor caso de ejecución de la tarea, es decir, el caso en el cual más tiempo de CPU demanda ejecutar su correspondiente código. Obtener el tiempo de CPU es complicado tanto desde un punto de vista teórico como práctico, ya que dicho tiempo depende de la plataforma de hardware utilizada y de encontrar cual es el peor caso de funcionamiento de la tarea. Por una cuestión de portabilidad entre diferentes plataformas de hardware, se decide medir los tiempos de ejecución en lugar de hacer un análisis teórico de los algoritmos. Se puede argumentar que desde el punto de vista de obtener el peor caso de funcionamiento, la medición del tiempo de ejecución no es una solución del todo correcta. Esto es así, porque el tiempo de ejecución de un algoritmo depende tanto del volumen de los datos como de los datos en sí. Entonces, [ 16 de abril de 2013 at 16:46 – version 1.0 ] 2.1 sistemas de control de tiempo real (rtcs) prácticamente es imposible someter al algoritmo a todas las combinaciones de entrada posibles y determinar el peor tiempo de ejecución. De todos modos, este obstáculo puede ser superado ya que en los algoritmos de control implementados en este trabajo no tienen muchas bifurcaciones en el código o casos particulares para analizar. Entonces la medición directa del tiempo de ejecución resulta ser una buena estimación del peor caso de ejecución de una tarea. En el Capítulo 3 se explica en detalle cómo se implementa la medición de tiempos de procesamientos de las tareas. En la implementación de RTCS, habitualmente se utiliza un RTOS preemtive y de prioridades fijas. En este tipo de sistema, puede ser utilizado el esquema de scheduling Rate Monotonic Scheduling (RMS). Este esquema puede ser sometidos a test de schedulability relativamente simples para determinar si un conjunto de tareas puede o no cumplir con las condiciones temporales impuestas. Bajo ciertas condiciones, para RTOS con esquema de scheduling RMS, se puede derivar un test de schedulability básico. La demostración de los teoremas presentados a continuación se encuentra en [11]. A continuación se presentan las condiciones necesarias y las hipótesis para que sea válido aplicar el test de schedulability RMS básico. El sistema solo incluye tareas periódicas con intervalo de tiempo constantes. Cada tarea debe ser procesada antes de que la misma se vuelva a ejecutar. Las tareas son independientes entre sí y la ejecución de las mismas no dependen de que se liberen recurso del RTOS (semáforos, mutes, etc.). El tiempo de ejecución de cada tarea es constante o se considera siempre el peor caso de ejecución de las tareas. El RTOS es ideal, desde el punto de vista que el cambio de contexto no consume tiempo. Se define Ti como el período de la tarea i, Ci como el peor tiempo de procesamiento de dicha tarea y n es la cantidad de tareas que están instanciadas en el RTOS. Por otro lado, se define la utilización del CPU Ui de la tarea i como: Ui = Ci Ui (2.1) En [11] se demuestra el siguiente test de schedulability suficiente, para el esquema de asignación de prioridades fijas RMS: n n Ci 1/n U = ∑ Ui = ∑ ≤ n 2 −1 T i =1 i =1 i [ 16 de abril de 2013 at 16:46 – version 1.0 ] (2.2) 25 26 desarrollo teórico Es decir, para una determinada cantidad n de tareas, si U resulta 1/n ser menor igual que n 2 − 1 entonces el conjunto de tareas resulta ser scheduelable. Para n tendiendo a infinito, el límite superior de utilización del CPU tiene a ln(2) = 0,69. También en [11], se demuestra otro teorema que afirma que si existe alguna asignación de prioridades fijas posibles para que un conjunto de tareas sea administrable entonces la asignación de prioridades RMS también logra admministrar dichas tareas. El test de schedulability presentado en la Ecuación 2.2 es utilizado en RTOS con tareas de prioridades fijas, asignadas según el esquema RMS. También existen test de schedulability para RTOS con tareas de prioridades diámicas. Las prioridades son asignadas dinámicamente en función del deadline de las tareas. Aquella tarea que tenga el deadline más próximo será asignada con la prioridad más alta, mientras que aquella tarea que tenga el deadline más lejano será asginada con la prioridad más baja. Este algoritmo de asignación de memoria dinámica es conocido bajo el nombre Earliest Deadline First (EDF) [12]. La asignación de prioridades dinámica EDF es óptima en el sentido de que si un conjunto de tareas puede ser administrado correctamente por alguna asignación de prioridades, también puede ser administrada por este método. En [11] se demuestra que si se utiliza la asignación dinámica de prioridades EDF, entonces un conjunto de n tareas es administrable si: U= n n i =1 i =1 Ci ∑ Ui = ∑ Ti ≤1 (2.3) La Ecuación 2.3 se utiliza como test de schedulability para las tareas cuyas prioridades son asignadas dinámicamente mediante el esquemas EDF. 2.1.1.4 Utilización de RTOS en Sistemas de Control de Tiempo Real (RTCS) La utilización de un RTOS en un sistema de control de tiempo real permite que el mismo pueda ejecutar controladores de manera concurrente. Si a esto último, se le agregar un módulo que ejecuta un test de schedulability se logra implementar un sistema de control digital muy escalable y seguro. En esta sección, se explica cómo se utilizan las tareas de un RTOS para ejecutar un lazo de control genérico [4]. La manera más simple de implementar un lazo de control genérico, en un sistema operativo de tiempo real, en el contexto de una tarea periódica es el presentado en el Código 1. Código 1: Implementación de un lazo de control periódico en un RTOS utilizando la primitiva Delay() [ 16 de abril de 2013 at 16:46 - version 1.0 ] 2.1 sistemas de control de tiempo real (rtcs) while (true) { RunController (); Delay (h); } 27 La implementación presentada en el Código 1 no es correcta ya que no se toma en cuenta el tiempo que se tarda en ejecutar el controlador. En este caso, el tiempo de muestreo termina siendo mayor que h. Por otro lado, tampoco tiene en cuenta que el tiempo de ejecución del controlador puede variar en función de los datos disponibles en cada vuelta del lazo de control. A continuación se presenta una implementación que si tiene en cuenta el tiempo de ejecución del controlador: Código 2: Implementación de un lazo de control periódico en un RTOS teniendo en cuenta el tiempo de ejecución de un controlador while (true) { startTime = GetTickCount (); RunController (); endTime = GetTickCount (); Delay (h - (endTime - startTime)); } La implementación presentada en el Código 2 es más correcta que la presenta en el Código 1. De todos modos si se produce un cambio de contexto luego de medir el tiempo al finalizar el controlador, el tiempo de espera h − (endTime − startTime) no va a ser correcto. Nuevamente el tiempo de muestreo es susceptible a tener variaciones y la performance del controlador se verá degradada. La solución correcta para implementar un lazo de control en el contexto de una tarea periódica es utilizar una primitiva que permita realizar un tiempo de espera absoluto: Código 3: Implementación de un lazo de control periódico en un RTOS utilizando la primitiva DelayUntil() lastWakeUpTime = GetTickCount (); while (true) { RunController (); DelayUntil (&lastWakeUpTime, h); } En el Código 4, se separa la función RunController en tres partes: la conversión analógica digital, la la ejecución específica del controlador y el conversión digital analógica. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 28 desarrollo teórico Código 4: Implementación de un lazo de control periódico en un RTOS utilizando la primitiva DelayUntil() y seprando la función RunController lastWakeUpTime = GetTickCount (); while (true) { ADC (); RunController (); DAC(); DelayUntil (&lastWakeUpTime, h); } Finalmente, tomando como base el Código 4, se obtiene en el Código 5 la implementación de un lazo de control: Código 5: Implementación final de un lazo de control periódico en un RTOS lastWakeUpTime = GetTickCount (); while (true) { ADC (); CalculateControllerOutput (); DAC (); UpdateController; DelayUntil (&lastWakeUpTime, h); } Se puede observar en el Código 5, que se busca minimizar el tiempo de computo. Para esto, una vez realizada la medición con el ADC, se hacen solo los cálculos necesarios para obtener la salida de control y cuanto antes enviarla al DAC. Luego se realizan todos los cálculos adicionales para fijar el nuevo estado del controlador y dejarlo preparado para la siguiente iteración. 2.2 desarrollo teórico de los algoritmos de control digitales En la Sección 2.1 se realizó una introducción teórica a los sistemas de control de tiempo real. Como en la actualidad, estos sistemas utilizan sistemas operativos de tiempo real, en la Sección 2.1.1, se realizó una breve introducción teórica sobre esta temática. El principal objetivo de este trabajo es diseñar e implementar una biblioteca de código que funciones como un Sistema de Control de Tiempo Real en diferentes aplicaciones prácticas de control. Para cumplir con este objetivo y que la biblioteca resulte útil, deben incluirse en la misma diferentes estrategias de control digital. En esta sección se detalla la teoría de dos algoritmos de control que luego serán implementados en la biblioteca en el Capítulo 3. Estos algoritmos son: PID y DMC SISO. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 2.2 desarrollo teórico de los algoritmos de control digitales 2.2.1 Desarrollo teórico del controlador PID Digital El controlador PID es sin lugar a duda el algoritmo de control más utilizado en la práctica. Por este motivo, en este trabajo se decide desarrollar la teoría de este controlador e incluirlo en la biblioteca. La gran relevancia que tiene este controlador se debe principalmente a dos motivos. Por un lado, desde un punto de vista teórico, es simple de analizar y entender. Por otro lado, desde un punto de vista práctico, es fácil de implementar y otorga muy buenos resultados. En la Ecuación 2.4 se presenta la expresión teórica de este controlador (para el caso de tiempo continuo). u ( t ) = K p e ( t ) + Ki Z t 0 e(s)ds + Kd d (e(t)) dt (2.4) Donde u(t) es la acción de control y e(t) es el error obtenido como la diferencia entre la referencia o set point r (t) y la salida del proceso y(t) (todas las señales son función del tiempo). Por otro lado K p , Ki y Kd son las constantes proporcional, integrativa y derivativa respectivamente. Estas constantes son los parámetros del controlador PID. Ajustando dichos parámetros, se puede modificar la respuesta de un proceso para que cumpla con los requerimientos de diseño impuestos. Inicialmente, los controladores PID eran completamente analógicos. Con el aparición de las computadoras digitales, los controladores analógicos comenzaron a ser reemplazados por una aproximación discreta de los mismos e implementados en la forma de un algoritmo dentro de dichas computadoras. Para lograr esta aproximación, se utilizan frecuencias de muestreo lo suficientemente elevadas como para que la discretización del controlador analógico no afecta la performance del mismo. En las últimas décadas, con el avance de la teoría de control digital, muchos esquemas de control pasaron a ser directamente diseñados de manera digital. Durante la gran cantidad de años que el controlador analógico PID fue utilizado en la práctica, se fueron realizando cambios que producen mejoras en la performance del controlador. Por un lado, se observó que es mejor no aplicar el término derivativo a la referencia r (t). Por otro lado, también se observaron mejoras al dejar actuar la parte proporcional solo sobre una fracción b de la referencia r (t) [2]. Con estos cambios, la Ecuación 2.4 resulta: u(t) = K p (br (t) − y(t)) + Ki Z t 0 (r (s) − y(s)) ds − Kd [ 16 de abril de 2013 at 16:46 – version 1.0 ] d (y(t)) (2.5) dt 29 30 desarrollo teórico La Ecuación 2.5 puede ser transformada al dominio de Laplace, obteniéndose: U (s) = K p (bR(s) − Y (s)) + Ki ( R(s) − Y (s)) − sKd Y (s) s (2.6) Implementar un término puramente derivativo, no es una buena práctica, porque resulta en una gran amplificación del ruido en la medición de y(t). Este término puede ser aproximado, para limitar la ganancia de la transferencia en altas frecuencias: sKd ≈ sKd 1 + sKd /N (2.7) La Ecuación 2.7 aproxima bien el término derivativo puro en bajas frecuencias pero limita la ganancia a N en altas frecuencias. El valor de N y Kd se ajusta para obtener la transferencia deseada. Combinando la Ecuación 2.6 con la aproximación de la Ecuación 2.7, se obtiene la siguiente expresión en el dominio de Laplace: U (s) = K p (bR(s) − Y (s)) + Ki sKd Y (s) (2.8) ( R(s) − Y (s)) − s 1 + sKd /N A continuación se deriva la ecuación matemática del controlador PID digital[2]: La parte proporcional de la Ecuación 2.8 no requiere aproximación. Se define P(t) como la parte proporcional de la ecuación Ecuación 2.8. Entonces, tomando como período de muestreo a h, como tiempo discreto a n y evaluando a P(t) en los instantes de tiempo (nh)∀n ≥ 0 se obtiene: P(nh) = K p (br [nh] − y(nh)) n P[n] = P(nh) ∀n ≥ 0. (2.9a) (2.9b) Se define I (t) como la parte integral de la Ecuación 2.8. Utilizando una forward approximation se obtiene: I ((n + 1)h) = I (nh) + Ki h (r (nh) − y(nh)) n I [n] = I (nh) ∀n ≥ 0. (2.10a) (2.10b) Se define D (t) como la parte derivativa de la ecuación Ecuación 2.8. En el dominio del tiempo, D (t) resulta ser: D (t) + Kd d d ( D (t)) = − (y(t)) N dt dt [ 16 de abril de 2013 at 16:46 – version 1.0 ] (2.11) 2.2 desarrollo teórico de los algoritmos de control digitales La Ecuación 2.11 se aproxima utilizando una backward approximation: D (nh) K y(nh) − y((n − 1)h) N + Kd = d D ((n − 1)h) − Kd (2.12) N N h Reagrupando términos en la ecuación Ecuación 2.12 se obtiene: D (nh) = Kd D ((n − 1)h) Kd N (y(nh) − y((n − 1)h)) − Nh + Kd Nh + Kd (2.13) Entonces la señal D [n] resulta ser: D [n] = Kd Kd N D [ n − 1] − (y[n] − y[n − 1]) Nh + Kd Nh + Kd (2.14) A partir de utilizar las señales de la Ecuación 2.9b, Ecuación 2.10b y Ecuación 2.14 se obtiene la ecuación en diferencias que permite implementar el algoritmo de control PID en una computadora digital: u[n] = P[n] + I [n] + D [n] (2.15) El resultado obtenido en la ecuación Ecuación 2.15 permite implementar el controlador PID en una computadora digital. 2.2.1.1 Considereaciones prácticas En la práctica, hay algunas consideraciones adicionales que deben hacerse: Saturación de actuadores: Los actuadores físicos, que son los encargados de excitar a la planta o al proceso, pueden saturarse si el error integrado por el controlador se hace muy grande. Una vez saturado el actuador debido a los efectos del integrador, por más que luego de un tiempo el error se vea reducido, dicho integrador permanece con un valor muy elevado y puede tardar un tiempo considerable en regresar a los valores normales. Este efecto se conoce como integrator windup. Existen diferentes formar de evitar este efecto (técnicas anti-windup). Una forma es detener por completo la acción integral cuando el actuador se encuentra saturado. Esta técnica es fácil de implementar en una computadora digital. Offset en la integración: En la Ecuación 2.15, I [n] aproxima la parte integral del controlador PID mediante una sumatoria. Como los cálculos que se realizan en una computadora digital tienen precisión finita, se puede producir un offset en la aproximación de la integración. Si se asume que en un instante n se tiene [ 16 de abril de 2013 at 16:46 – version 1.0 ] 31 32 desarrollo teórico un error e[n], dicho error se ve incrementando en cada instante posterior de muestreo en (Ki h)e[k ]∀k ≥ (n + 1). Si el producto Ki h es lo suficientemente pequeño, el cambio en la salida puede ser menor que la resolución del DAC. Por ejemplo, si se utiliza un DAC de 12-bits, el mismo tiene una resolución de 1/4096. Si la ganancia Ki es pequeña (por ejemplo Ki = 1/3600) y se toma h = 1, cualquier error e[n] que se encuentre por debajo del 90 % de la amplitud del DAC resulta ser menor a la resolución de este último. Si el término I [n] es almacenado en una variable con la misma precisión que el DAC, entonces se produce un error de offset. Una manera de evitar este problema, es utilizar variables de mayor precisión que la del DAC para realizar las cuentas involucradas en el algoritmo PID. En la actualidad, dada la gran cantidad de recursos que tienen disponibles los microcontroladores de 32 bits, es posible utilizar el tipo de dato float o el tipo de dato double que son respectivamente de 32 bits y 64 bits. Con estos tipos de datos, se puede evitar los errores de offset. Estas consideraciones prácticas, son tenidas en cuenta en el Capítulo 3 donde se implementa y se diseña la biblioteca de algoritmos de control para sistemas embebidos. 2.2.2 Desarrollo teórico del controlador DMC 2.2.2.1 Introducción al control predictivo Los controladores MPC (Model Predictive Control por sus siglás en inglés) nacen hacia fines de la década del 70 y han sido ampliamente utilizados desde ese entonces hasta la actualidad en diferentes industrias. El término MPC engloba diversas estrategias de control, que en todos los casos, utilizan explícitamente el modelo matemático del sistema dinámico y optimizan una función objetivo de costos. Las estrategias se diferencian entre sí por el método utilizado para modelar el sistema, el modelo utilizado para simular el efecto del ruido en las mediciones y el tipo de función objetivo a optimizar. Existen muchas aplicaciones prácticas en las cuáles los controladores MPC obtuvieron resultados exitosos. Entre ellas podemos destacar diferentes aplicaciones en procesos industriales, en particular en la industria química, aplicaciones en el área de la robótica y en el área de clínica médica [3] [13]. Las principales ventajas que presentan los controladores MPC son: Son fáciles de operar por mano de obra no calificada en ambientes industriales. Son fáciles de adaptar a los requerimientos de las aplicaciones a partir de manipular los parámetros del controlador. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 2.2 desarrollo teórico de los algoritmos de control digitales Pueden ser utilizados para controlar una gran variedad de sistemas dinámicos, desde los más simples hasta los más complejos. Por ejemplo, se los puede utilizar para controlar sistemas con grandes retardos y sistemas de fase no mínima. Este tipo de controladores se adaptan fácilmente a sistemas MIMO. Utiliza técnicas de feedfoward para compensar el efecto que tienen las perturbaciones medibles sobre las salidas. Los algoritmos de control MPC puede manejar de manera muy efectiva restricciones en las diferentes variables del sistema. Son muy útiles en ambientes en los que las señales de referencia del sistemas son conocidas (por ejemplo en el control de un brazo robótico), pero también se obtinen muy bueno resultados estimando las referencias futuras. Las principales desventajas que presentan los controladores MPC son: Los algoritmos de control MPC necesitan un modelo matemático preciso del sistema dinámico. El origen del modelo matemático puede ser experimental a partir de realizar mediciones o matemático a partir de analizar la física del sistema dinámico. En el caso de implementar el algoritmo de control MPC con restricciones en las variables del sistema, el costo computacional suele ser elevado. La estrategia de control utilizada en MPC puede resumirse de la siguiente manera: 1. En cada instante de tiempo n, se predicen las futuras salidas sobre un horizonte P de muestras. La predicción de las salidas yb[n + k |n] para k = 1, 2, ..., P dependen de los valores pasados de las entradas y de las salidas así como también de las futuras acciones de control u[n + k |n] para k = 0, 2, ..., M − 1. El número P representa el horizonte de predicción de futuras salidas y el número M representa el horizonte de predicción de futuras acciones de control. Ambos son parámetros de diseño del controlador. La notación utilizada indica que para una señal determinada, por ejemplo yb[n + k|n], el valor de la misma en el instante n + k se predice en el instante n. 2. El conjunto de las futuras acciones de control se calculan a partir de optimizar una determinada función objetivo de costos. Esta optimización busca mantener la salida del proceso lo más [ 16 de abril de 2013 at 16:46 – version 1.0 ] 33 34 desarrollo teórico b [n] (puede ser la tracerca posible a la trayectoria de referencia w yectoria real de referencia en el caso de conocerla previamente o una estimación de la misma). La función objetivo de costos es, en general, una sumatoria cuadrática de los errores obtenidos al comparar la predicción de los valores de salida con la predicción de los valores de referencia sobre un horizonte P de muestras. 3. En cada instante de tiempo n, la señal de control u[n|n] es enviada al sistema. En el siguiente instante de tiempo n + 1, se repiten los pasos para obtener u[n + 1|n + 1]. Cabe destacar que u[n + 1|n + 1] difiere de u[n + 1|n] pues las predicciones fueron realizadas en diferentes instantes. 2.2.2.2 Modelo del sistema Dado un sistema SISO, discreto, LTI, con entrada u[n] y salida y[n], la respuesta del mismo ante una excitación de entrada puede ser expresada en términos de la respuesta al escalón. Se define la entrada escalón como: ( ustep [n] = 0 si n < 0; 1 si n ≥ 0. (2.16) La salida del sistema al excitarlo con la entrada escalón es: ( ystep [n] = 0 si n < 0; gn si n ≥ 0. (2.17) Donde gn representa los valores de la señal discreta ystep [n] obtenida al exitar al sistema con la entrada escalón. Cualquier entrada arbitraria u[n] puede ser escrita como una combinación lineal de escalones desplazados: ( u[n] = 0 si n < 0; un si n ≥ 0. u[n] = ustep [n]u0 + ustep [n − 1] (u1 − u0 ) + ustep [n − 2] (u2 − u1 ) + ... Como el sistema es LTI, la salida del mismo al excitarlo con una entrada arbitraria es: y[n] = ystep [n]u0 + ystep [n − 1] (u1 − u0 ) + ystep [n − 2] (u2 − u1 ) + ... [ 16 de abril de 2013 at 16:46 – version 1.0 ] 2.2 desarrollo teórico de los algoritmos de control digitales Reagrupando términos y asumiendo, sin perder generalidad, que g0 = 0 se obtiene la Ecuación 2.18: y[n] = ∞ ∞ i =1 i =1 ∑ gi (u[n − i] − u[n − i − 1]) = ∑ gi ∆u[n − i] (2.18) La Ecuación 2.18 muestra que la salida y[n] de un sistema SISO, discreto, LTI, puede expresarse en términos de la respuesta del mismo al escalón y de la señal de entrada. Cabe recordar que gn representa los valores de la señal de salida obtenida al exitar al sistema con la entrada escalón. Este resultado es el punto de partida del controlador DMC. 2.2.2.3 Controlador DMC SISO sin restricciones Se define naturalmente la predicción de salida en el instante (n + k ) calculada en el instante n a partir del modelo del sistema, utilizando la Ecuación 2.18 [3] [14] : ∞ yb[n + k |n] = ∑ gi ∆u[n + k − i] + nbnoise [n + k|n] (2.19) i =1 bnoise [n + k |n] es la predicción de la perturbación en el insDonde n tante n + k caclulada en el instante n. En el caso de la estrategia DMC, las perturbaciones son consideradas constantes a lo largo del horizonte de predicción y se pueden calcular a partir de la diferencia entre la medición de la salida y la predicción de la salida obtenida en la Ecuación 2.19: bnoise [n + k|n] = n bnoise [n|n] = ym [n] − yb[n|n] n (2.20) Donde ym [n] es la medición de la salida en el instante n y por otro lado yb[n|n] es la predicción de la salida en el instante n calculada en el mismo instante. Entonces, combinando la ecuación Ecuación 2.19 con la ecuación Ecuación 2.20, la predicción de la salida resulta ser: ∞ yb[n + k |n] = ∑ gi ∆u[n + k − i] + ym [n] − yb[n|n] i =1 [ 16 de abril de 2013 at 16:46 – version 1.0 ] (2.21) 35 36 desarrollo teórico Utilizando la expresión matemática de la predicción yb[n|n], la Ecuación 2.21 resulta ser: yb[n + k |n] = ∞ ∞ i =1 i =1 ∑ gi ∆u[n + k − i] + ym [n] − ∑ gi ∆u[n − i] k yb[n + k |n] = ∑ gi ∆u[n + k − i] + i =1 ∞ ∑ i = k +1 (2.22a) ∞ gi ∆u[n + k − i ] + ym [n] − ∑ gi ∆u[n − i ] i =1 (2.22b) yb[n + k |n] = k ∞ i =1 i =1 ∞ ∑ gi ∆u[n + k − i] + ∑ gk+i ∆u[n − i] + ym [n] − ∑ gi ∆u[n − i] i =1 (2.22c) El primer término de la Ecuación 2.22c depende de futuras acciones de control, las cuales son predichas en el instante n a partir de optimizar una función de costos. Para ser consistentes con la notación utilizada, se reescribe esta ecuación de la siguiente manera: k yb[n + k |n] = ∑ gi ∆u[n + k − i|n] + f [n + k] (2.23) i =1 Donde f [n + k ] es la respuesta libre del sistema, es decir, la parte de la predicción que no depende de las futuras acciones de control. ∞ f [n + k ] = ym [n] − ∑ gi ∆u[n − i ] (2.24) i =1 Si el sistema es asintóticamente estable, entonces la salida y[n] converge a un valor finito. Con esta condición, podemos asumir que para un N suficientemente grande: ( gi ≈ g n ) ∀ i ≥ N → ( g k + i − gi ≈ 0 ) ∀ i ≥ N (2.25) Entonces, la respuesta libre del sistema aproximada puede obtenerse combinando la Ecuación 2.24 con la Ecuación 2.25: n f [n + k ] = ym [n] − ∑ gi ∆u[n − i ] (2.26) i =1 La aproximación para el cálculo de la respuesta libre obtenida en la Ecuación 2.26, es fundamental para que el algoritmo de control DMC pueda ser implementado en una computadora digital ya que limita (con una aproximación válida) la cantidad de términos que tiene la sumatoria de la Ecuación 2.24. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 2.2 desarrollo teórico de los algoritmos de control digitales Finalmente se pueden obtener las predicciones de la salida sobre un horizonte P de muestras (considerando M acciones de control con M ≤ P): yb[n + 1|n] = g1 ∆u[n] + f [n + 1] (2.27a) yb[n + 2|n] = g2 ∆u[n] + g1 ∆u[n + 1] + f [n + 2] .. . (2.27b) (2.27c) m yb[n + p|n] = ∑ gi ∆u[n + p − i] + f [n + p] (2.27d) i =1 Se definen los vectores Y [n|n], ∆U [n|n] y F [n] de la siguiente manera: (2.28a) Y [n|n] = yb[n + 1|n]] yb[n + 2|n] · · · yb[n + p|n] T ∆U [n|n] = ∆u[n|n]] ∆u[n + 1|n] · · · ∆u[n + m − 1|n] T (2.28b) F [n] = f [ n + 1] f [ n + 2] · · · f [n + p] T (2.28c) A partir de la Ecuación 2.27 y de la Ecuación 2.28 se puede obtener la siguiente expresión matricial: Y [n|n] = G∆U [n|n] + F [n] g1 0 ··· g2 g1 ··· .. .. .. . . . G= g m g m −1 · · · . .. .. . . . . gp g p −1 (2.29a) 0 0 .. . g1 .. . (2.29b) · · · g p − m +1 Donde G es la matriz dinámica del sistema. Se puede observar que esta matriz posee tantas columnas como el horizonte M elegido para las futuras acciones de control y tantas filas como el horizonte P elegido para los futuros valores de la predicción de las salidas. El objetivo del controlador DCM es mantener la salida de un sistema lo más cercana posible a la referencias a partir de optimizar una función de costos que toma la forma de una sumatoria cuadrática. Dicha optimización puede estar sujeta a restricciones en los posibles valores de las variables involucradas. b [n|n] como la predicción de la referencia. Esta predicSe define w ción puede ser directamente la referencia real en el caso que la trayectoria a seguir sea conocida o puede ser una estimación de la misma en caso que la trayectoria no sea conocida a priori. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 37 38 desarrollo teórico En el caso más simple, cuando la optimización no está ligada a restricciones en las variables, la solución al problema de optimización es cerrada. Se define la función de costos de la siguiente manera: P J [n] = ∑ (yb[n + i|n] − wb[n + i|n]) 2 (2.30) i =1 En un caso más general, se puede añadir a la Ecuación 2.30 un término que mide el esfuerzo de control necesario para lograr acercar la salida a la referencia: J [n] = P m i =1 i =1 2 2 ∑ (yb[n + i|n] − wb[n + i|n]) + ∑ λ (∆u[n + i − 1|n]) (2.31) La Ecuación 2.31 puede ser escrita en formato vectorial de la siguiente manera: J [n] = Y [n|n] − R[n|n] T T Y [n|n] − R[n|n] + λ∆U ∆U (2.32) Al no haber restricciones en las variables, en cada instante n la solución a la Ecuación 2.32 se obtiene derivando J [n] respecto de ∆U y luego igualando a cero. Es decir: ∂J ∂∆u[n|n] ··· ∇ ( J [n]) = 0 ∂J =0 ∂∆u[n+m−1|n] (2.33a) (2.33b) Entonces la solución cerrada del problema de optimización es: −1 ∆U = G T G + λI GT R − F (2.34) La Ecuación 2.34 se utiliza para calcular instante a instante la acción de control que se debe enviar a la planta [15]. 2.3 algoritmos de control A partir de la teoría desarrollada en este capítulo se pudieron desarrollar en Matlab los algoritmos del controlador PID digital y del DMC SISO digital. Estos código se presentan en la Sección A.1 y en la Sección A.2 respectivamente. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 3 D I S E Ñ O E I M P L E M E N TA C I Ó N En este capítulo se presenta la estructura general de la biblioteca de algoritmos de control, detallando cuales son las funcionalidades que se desean implementar en la misma y poniendo especial énfasis en las decisiones de diseño realizadas para conseguir dichas funcionalidades. El diseño es realizado de manera tal que la biblioteca sea independiente del hardware y del RTOS utilizados en cada aplicación particular. Primero se realiza una presentación de la estructura general de la biblioteca, introduciendo los módulos que la componen y cómo estos interactúan entre sí para conseguir el funcionamiento deseado. Luego se expone la implementación de los diferentes módulos en el lenguaje de programación C, explicando cuales fueron las técnicas de programación utilizadas para lograr una estructura de código flexible y escalable. Por último se realiza un resumen de las principales características de la biblioteca de algoritmos de control. 3.1 diseño de la biblioteca de algoritmos de control La biblioteca de algoritmos de control, referenciada desde aquí en adelantebajo el nombre libRTCS 1 , está diseñada con el objetivo de que posea las siguientes características fundamentales: Flexibilidad: Disponer de una biblioteca de código estructurada de manera tal que sea flexible y pueda ser fácilmente ampliada. Escalabilidad: Tener la posibilidad de incorporar nuevos algoritmos de control digital a la libRTCS sin tener que modificar el código existente. Portabilidad: Poder portar fácilmente la biblioteca a diferentes microcontroladores y a diferentes RTOS. Usabilidad: Poder utilizar la biblioteca en diferentes escenarios de control, garantizando el cumplimiento de las restricciones temporales impuestas al sistema global. Por un lado, es fundamental que la característica de flexibilidad sea buscada desde los inicios del diseño de la libRTCS. Para conseguir esta característica se realiza un diseño modular, en el cual, cada 1 Nombre de la biblioteca de código diseñada e implementada en este trabajo. La misma está pensada para ser utilizada en sistemas de control de tiempo real, de aquí su nombre libRTCS por el significado en inglés de las siglas RTCS. 39 [ 16 de abril de 2013 at 16:46 – version 1.0 ] 40 diseño e implementación módulo implementa una funcionalidad específica y expone una interfaz pública de uso que permite independizar a los módulos entre sí. Por otro lado, la escalabilidad se consigue utilizando correctamente diferentes conceptos y técnicas de Object Oriented Programming - Programación Orientada a Objetos (OOP). Se pretende poder incorporar a la biblioteca nuevos algoritmos de control digital sin tener que modificar el código existente. Es decir, se busca que simplemente agregando el código correspondiente a un nuevo algoritmo de control digital (respetando las interfaces expuestas por la biblioteca), se pueda comenzar a instanciar objetos correspondientes al nuevo controlador incorporado. La portabilidad se consigue a partir de incorporar un módulo que permita abstraer el hardware específico, conocido bajo el nombre de Hardware Abstraction Layer - Capa de Abstracción de Hardware (HAL), y otro módulo que permita abstraer las llamadas al RTOS. Por último, para que la biblioteca disponga de buena usabilidad se añade un módulo que pueda administrar automáticamente las tareas que ejecutan los algoritmos de control. Este último módulo se encarga de hacer las correspondientes llamadas al RTOS para crear las tareas y asignar sus prioridades. Estas últimas, son asignadas automáticamente a partir de ejecutar un test de schedulability que permite determinar si todas las restricciones temporales impuestas pueden o no ser cumplidas. Figura 3.1: Esquema general de la libRTCS [ 16 de abril de 2013 at 16:46 – version 1.0 ] 3.1 diseño de la biblioteca de algoritmos de control En la Figura 3.1 se presenta el esquema general de la libRTCS. Se puede observar la estructura modular de la biblioteca, compuesta por un módulo principal y diferentes módulos secundarios que interactuan con el primero. A continuación se hace una breve introducción al diseño de cada módulo y luego en la Sección 3.2 se presenta la implementación de cada módulo en el lenguaje de programación estándar C. Módulo principal: Este módulo es el núcleo central de la libRTCS. Su función principal es almacenar y administrar una lista con la información de todos los controladores instanciados dinámicamente durante la ejecución del sistema. Como cada controlador incorporado en la libRTCS utiliza sus propios tipos de datos, ya que cada uno dispone de diferentes parámetros de configuración, es un requisito fundamental que la lista pueda almacenar instancias de diferentes tipos de controladores. Es decir, la lista debe ser un contenedor de información independiente del tipo de dato almacenado. En la Sección 3.2.1 se explica cómo se implementa una lista con estas características en el lenguaje de programación estándar C. Este módulo expone una interfaz tal que los módulos secundarios puedan agregar, modificar y eliminar los elementos de la lista. Cabe destacar también, que cada elemento de esta lista representa la instancia particular de un controlador y que la información almacenada en dicho elemento de la lista será utilizada por el módulo de administración de tareas para ejecutar el algoritmo de control. Módulo de interfaces: Este módulo es fundamental para lograr que la libRTCS pueda ser portada fácilmente a diferentes microcontroladores y a diferentes RTOS. Por un lado se incluye una capa de abstracción, que habitualmente recibe el nombre de HAL, que le permite a la biblioteca utilizar recursos del microcontrolador independiente de cuál sea este último (e.g. utilizar un timer para medir tiempos). Por otro lado se incluye también una capa de abstracción para que la biblioteca pueda independizarse del RTOS. Habitualmente los RTOS incluyen un módulo para administrar memoria dinámica y un módulo para administrar tareas. Mediante la capa de abstracción para el RTOS, la libRTCS puede utilizar estos recursos independientemente de cual sea el RTOS particular que se está utilizando en la aplicación. En la sección Sección 3.2.2 se explica detalladamente cuáles son las técnicas de programación utilizadas para implementar las capas de abstracción del microcontrolador y del RTOS. Módulo de administración de tareas: La principal función de este módulo es la de utilizar toda la información disponible en la lista de controladores del módulo principal para crear en [ 16 de abril de 2013 at 16:46 – version 1.0 ] 41 42 diseño e implementación el RTOS todas las tareas necesarias para ejecutar los correspondientes algoritmos de control. Para esto, la biblioteca utiliza las interfaces definidas en el módulo de interfaces que le permiten aplicar los diferentes recursos disponibles en el RTOS (e.g. creación de memoria dinámica, administración de tareas, · · · ). También incorpora la estructura necesaria para soportar diferentes esquemas de scheduling. Por último, dispone de los algoritmos que aplican los diferentes test de schedulability, los cuales permiten determinar si un conjunto de tareas puede cumplir o no con los requerimientos temporales impuestos. Cabe destacar que este trabajo, se pondrá especial énfasis en el esquema de scheduling RMS y sus correspondientes test de schedulability. En la Sección 3.2.3 se detalla la implementación de este módulo. Módulo de controladores: Por último, en este módulo se implementan concretamente los diferentes algoritmos de control digital. En particular, en el presente trabajo, se desarrollan exhaustivamente el controlador PID y el controlador DMC. La biblioteca libRTCS está estructurada de manera tal que fácilmente se puedan agregar nuevos algoritmos de control digital. Para lograr esta finalidad, se diseñó una interfaz y una estructura de datos básica común a todos los algoritmos de control. Esta interfaz es utilizada por la lista de controladores para lograr que esta última sea independiente del tipo particular de cada controlador. En la Sección 3.2.4 se detalla cómo se aplican técnicas propias de OOP en un lenguaje de programación estructurado, para lograr implementar toda la funcionalidad requerida en la libRTCS. 3.2 implementación de la biblioteca de algoritmos de control En esta sección se detalla la implementación de los módulos que componen a la libRTCS. La misma está implementada en el lenguaje de programación estándar C. Se decidió utilizar este lenguaje de programación por los siguientes motivos: El lenguaje de programación C es ampliamente utilizado en la industria de los sistemas embebidos. No requiere adquirir licencias para utilizarlo. Existe una gran variedad de Integrated Development Environment - Entornos Integrados de Desarrollo (IDEs) sobre los cuáles se puede desarrollar. Al tratarse de un estandar en la industria, la biblioteca libRTCS puede ser portada a la mayoría de los microcontroladores existentes. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 3.2 implementación de la biblioteca de algoritmos de control 3.2.1 Módulo principal El módulo principal es el encargado de almacenar, administrar y proveer a los módulos secundarios la información de todos los controladores instanciados durante la ejecución del RTCS. A partir de esta información se crean las tareas del RTOS, que en definitiva, son las encargadas de ejecutar los algoritmos de control y asegurar que se cumplan con las restricciones temporales impuestas. Como la biblioteca libRTCS incluye diferentes algoritmos de control, la información que este módulo almacena es variable en función del tipo de controlador instanciado. Por este motivo, se debe implementar un contenedor de información que se independiente del tipo de dato que el mismo almacena. Se decide implementar una lista simplemente enlazada, ya que a la misma se le pueden agregar y quitar elementos en tiempo de ejecución utilizando de manera eficiente la memoria dinámica. En el Código 6 se presentan las estructuras utilizadas para implementar la lista simplemente enlazada. Código 6: Estructuras utilizadas para implementar la lista simplemente enlazada struct RTCS_list_TypeNode { int32_t fileDescriptor; void* data; struct RTCS_list_TypeNode* next; }; typedef struct RTCS_list_TypeNode RTCS_list_TNode; struct RTCS_list_TypeList { RTCS_list_TNode* first; RTCS_list_TNode* last; uint16_t size; }; typedef struct RTCS_list_TypeList RTCS_list_TList; La estructura RTCS_list_TNode define la información básica que tiene cada elemento de la lista. Se puede observar que cada elemento tiene un descriptor de archivo utilizado como identificador único, un puntero genérico que se utiliza para almacenar la información de los controladores y un puntero al siguiente elemento que se utiliza para generar la lista simplemente enlazada. La estructura RTCS_list_TList es la que implementa la lista simplemente enlazada. Se puede observar que la lista tiene un puntero al primer elemento, un puntero al último elemento y una variable que indica la cantidad actual de elementos. En el Código 7 se presenta la interfaz pública que se utiliza para manejar la lista simplemente enlazada. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 43 44 diseño e implementación Código 7: Interfaz pública para manejar la lista simplemente enlazada void RTCS_list_Init (RTCS_list_TList* pList); int32_t RTCS_list_AddNode (RTCS_list_TList* pList, void* _data); RTCS_list_TNode* RTCS_list_SearchNode (RTCS_list_TList* pList , int32_t _fileDescriptor); En el Código 7 se puede observar que se dispone de un procedimiento para inicializar la lista, una función para agregar nuevos elementos a la lista y por último una función para buscar elementos en la misma. Utilizando las estructuras definidas en el Código 6 y la interfaz definida en el Código 7 se logra implementar la lista simplemente enlazada, de manera tal que resulta ser un contenedor independiente del tipo de dato a almacenar. Conceptualmente, esto se logra utilizando el puntero genérico void ∗ data en la estructura RTCS_list_TNode. En el lenguaje de programación C un puntero genérico es una variable que permite almacenar la dirección de memoria de otra variable independientemente del tipo de dato de la segunda. Mediante conversiones explícitas y seguras de tipos de datos, se logra recuperar la información direccionada por en el puntero genérico. En la Figura 3.2 se muestra un esquema representativo de una lista simplemente enlazada, en el cual se puede observar como se conectan los diferentes elementos que la misma contiene. Figura 3.2: Esquema de una lista simplemente enlazada Por otro lado, se había dicho anteriormente que se perseguía como objetivo generar una biblioteca de código que sea escalable, permitiendo agregar nuevos algoritmos de control sin necesidad de modificar el código existente. El módulo principal, es el encargado de crear y administrar todas las tareas que ejecutan los algoritmos de control. Para esto se necesita que todos los algoritmos de control tengan una interfaz pública común y genérica, pero que a su vez cada uno ejecute un algoritmo de control diferente. En un lenguaje de programación [ 16 de abril de 2013 at 16:46 – version 1.0 ] 3.2 implementación de la biblioteca de algoritmos de control orientado a objetos esta escalabilidad se consigue utilizando los conceptos de herencia y polimorfismo. Este tipo de lenguajes de programación incorporan mecanismos que permiten aplicar estos conceptos de manera nativa al lenguaje. En cambio, un lenguaje de programación estructurado (como lo es el lenguaje C), no incorpora este tipo de mecanismos de manera nativa. En la Sección 3.2.4 se explica como se logran implementar los conceptos de herencia y polimorfismo en el lenguaje de programación C a partir de utilizar la lista simplemente enlazada. Habiendo realizado la introducción a como se almacena la información de los diferentes controladores, se presenta en el Código 8 la interfaz pública del módulo principal. Código 8: Interfaz pública del módulo principal void RTCS_system_Init (void); int32_t RTCS_system_AddController ( RTCS_genericController_TController* pControllerData); RTCS_genericController_TController* RTCS_system_GetController (int32_t fileDescriptor); RTCS_list_TList* RTCS_system_GetControllersList (); void RTCS_system_RunControllersFirstTime (); Como se puede observar en el Código 8, el módulo principal dispone de un procedimiento para inicializar al sistema (define valores iniciales de variables privadas), una función para agregar controladores a la lista, funciones para administrar la lista y un procedimiento para ejecutar por primera vez a los controladores. La función para ejecutar por primera vez a los controladores es fundamental porque permite que se realicen todas las operaciones matemáticas que los diferentes algoritmos de control instanciados pueden hacer antes de iniciar la ejecución del scheduler del RTOS. De esta manera, se ahorra un considerable tiempo de ejecución en algunos de los algoritmos de control, haciendo que el sistema se optimice y soporte una mayor cantidad de tareas concurrentes. Por último, es importante destacar que la libRTCS aplica el concepto de descriptores de archivos que habitualmente se utiliza en los sistemas operativos Portable Operating System Interface (POSIX). A cada instancia particular de un controlador se le asigna un número de identificación único, con el cual se puede entre otras cosas: recuperar la información almacenada en la lista de controladores, modificar parámetros del controlador, etc. La biblioteca de código presentada en este trabajo, aplica diferentes conceptos utilizados en los sistemas operativos POSIX, con el objetivo de generar una estructura de código que respete los estándares utilizados en la actualidad. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 45 46 diseño e implementación 3.2.2 Módulo de interfaces El módulo de interfaces es fundamental en la libRTCS ya que le otorga a la misma la propiedad de portabilidad a diferentes microcontroladores y a diferentes RTOS. Por un lado se específica la interfaz pública que define como se utilizan los recursos de un microcontrolador genérico en la libRTCS, y por otro lado se especifica la interfaz pública que define como se utilizan los recursos de un RTCS genérico en la misma. En ambos casos, portar la biblioteca a un microcontrolador y un RTOS particulares implica implementar el código de ambas interfaces públicas para dichos sistemas. En el Capítulo 4 se muestra como es portada la libRTCS al microcontrolador LPC1769 con tecnología Cortex-M3 de ARM del fabricante NXP y el sistema operativo de tiempo real FreeRTOS. El recurso básico que la libRTCS necesita utilizar de un microcontrolador es un timer con resolución del orden del microsegundo. El mismo es utilizado para medir de manera precisa, durante la ejecución, el tiempo que consumen los algoritmos de control instanciados (Worst Case Execution Time (WCET)). Como se arumentó en la Sección 2.1.1.3, estas mediciones son fundamentales para que luego el módulo de administración de tareas pueda ejecutar los correspondientes test de schedulability. Sobre este punto, es pertinente aclarar nuevamente por qué se decide realizar las mediciones del tiempo de computo de los algoritmos de control en tiempo de ejecución. Es posible analizar en tiempo de compilación, y desde un punto de vista matemáticoteórico, la performance de los diferentes algoritmos obteniendo la complejidad temporal y espacial (memoria de stack) de los mismos. Ambos parámetros se obtienen como funciones matemáticas del volumen de entrada de datos que debe procesar cada algoritmo. En general, se busca determinar dichas funciones para el peor caso de ejecución exponiendo al algoritmo al conjunto de datos más perjudicial. En particular, en los algoritmos de control, el volumen de entrada de datos depende entre otras cosas de las dimensiones de la planta a controlar. Para especificar la complejidad temporal y espacial se utiliza la notación asintótica, la cual da una idea clara de como se comporta un algoritmo. A partir de esta notación, se obtiene un conjunto de funciones que acotan superiormente e inferiormente el orden de crecimiento de la complejidad temporal y espacial del algoritmo en términos del volumen de entrada de datos. El problema es que las cotas obtenidas son adimensionales, es decir, dan información asintótica sobre la cantidad de operaciones que realiza un algoritmo, pero no especifican ninguna unidad temporal ya que esta es dependiente del hardware en el cual se ejecuta dicho algoritmo. Como la libRTCS pretende ser una solución independiente de la arquitectura utilizada en cada aplicación, se decide calcular el tiempo de computo de los algoritmos de control durante la ejecución del sistema. Por otro lado, [ 16 de abril de 2013 at 16:46 – version 1.0 ] 3.2 implementación de la biblioteca de algoritmos de control esta decisión también es justificable argumentando que los sistemas de control del tiempo real deben cumplir con condiciones temporales muy rígidas para asegurar la integridad de cada lazo de control. En esta dirección, la primera medida que se debe tomar, es ejecutar un test de schedulability para determinar si el conjunto de controladores concurrentes puede cumplir con las restricciones temporales impuestas. Para esto último, es fundamental poder medir de forma precisa los tiempos de computo de los correspondientes algoritmos. En el Código 9 se presentan las funciones y procedimientos públicos que componen a la interfaz con los microcontroladores. Código 9: Interfaz pública del módulo de interfaces (microcontrolador) extern void (*RTCS_uCinterface_TimerStart) (uint32_t baseTimeInUS); extern uint32_t (*RTCS_uCinterface_TimerStop) (void); void RTCS_uCinterface_SetTimerStart (void (*pointerToFunction ) (uint32_t)); void RTCS_uCinterface_SetTimerStop (uint32_t (* pointerToFunction) (void)); Para lograr independizar a la biblioteca libRTCS de los microcontroladores, se utilizan los punteros a funciones disponibles en el lenguaje de programación C. Un puntero a función, es una variable que puede almacenar la dirección de memoria de una función o procedimiento que tiene el mismo encabezado que el especificado en la declaración del puntero. Entonces si se almacena en el puntero la dirección de memoria de una función o procedimiento, luego la invocación se puede realizar desde dicho puntero. Esta herramienta es fundamental para poder escribir código flexible y escalable. La interfaz con los microcontroladores declara dos punteros a funciones, RTCS_uCinterface_TimerStart para apuntar a la función que inicia la cuenta de un timer y RTCS_uCinterface_TimerStop para apuntar a la función que termina la cuenta del mismo y retorna el tiempo transcurrido en microsegundos. Ahora bien, ambos punteros deben apuntar a funciones y procedimientos ya declarados y definidos por el usuario de la biblioteca. Para esto, la interfaz incorpora dos procedimientos que permiten configurar la dirección de memoria a la que deben apuntar los punteros. El usuario de la biblioteca, por fuera de la misma, debe declarar y definir dos procedimientos dependientes del microcontrolador (que respeten el formato impuesto por los punteros a funciones) que se encarguen de iniciar y detener la cuenta del timer. Luego utilizando los procedimientos de configuración de los punteros, se informa a la libRTCS que funciones puede utilizar para manipular al timer. Como esta última puede utilizar los punteros a funciones públicos, se logra que la biblioteca utilice recursos de un microcontrolador particular sin modificar el código de la misma. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 47 48 diseño e implementación Por otro lado, los recursos básicos que necesita utilizar la libRTCS de un RTOS son: Administrador de memoria dinámica Administrador de tareas Administrador de tiempos El administrador de memoria dinámica del RTOS es fundamental para que los diferentes controladores puedan ser instanciados y eliminados en tiempo real. Los RTOS modernos incluyen la implementación de las funciones típicas de manejo de memoria dinámica: malloc y free. Estas funciones son ampliamente utilizadas por la libRTCS. Por otro lado, el administrador de tareas del RTOS se utiliza para crear, eliminar y coordinar las tareas que se encargan de ejecutar a los controladores instanciados. Por último, el administrador de tiempos permite que cada controlador instanciado se ejecute según la frecuencia de lazo especificada. En el Código 10 se presentan las funciones y los procedimientos públicos que componen a la interfaz con RTCS. Código 10: Interfaz pública del módulo de interfaces (RTOS) extern void* (*RTCS_RTOSinterface_Malloc) (size_t size); extern void (*RTCS_RTOSinterface_Free) (void* pointer); extern void (*RTCS_RTOSinterface_TaskCreate) (void (* taskHandler) (void*), void* taskParameters, uint32_t taskPriority, void* taskIdentifier); extern void (*RTCS_RTOSinterface_TaskDelete) (void* taskIdentifier); void RTCS_RTOSinterface_SetMallocFunction (void* (* pointerToFunction) (size_t)); void RTCS_RTOSinterface_SetFreeFunction (void (* poiterToFunction) (void*)); void RTCS_RTOSinterface_SetTaskCreateFunction (void (* pointerToFunction) (void (*taskHandler) (void*), void* taskParameters, uint32_t taskPriority, void* taskIdentifier)); void RTCS_RTOSinterface_SetTaskDeleteFunction (void (* pointerToFunction) (void* taskIdentifier)); Al igual que en la interfaz con los microcontroladores, mediante la configuración de los correspondientes punteros a funciones, el usuario de la biblioteca define los recursos que la misma requiere del RTOS. A modo de resumen, cabe aclarar que para portar la libRTCS a diferentes microcontroladores y a diferentes RTOS, el usuario de la biblioteca únicamente debe implementar funciones externas que respeten la declaración de los punteros a funciones públicos disponibles en el módulo de interfaces y configurarlos mediante los procedimientos [ 16 de abril de 2013 at 16:46 – version 1.0 ] 3.2 implementación de la biblioteca de algoritmos de control disponibles en el mismo módulo. De esta manera, siempre que la biblioteca necesite utilizar aglún recurso externo lo hace a través de los punteros a funciones, desacoplándose efectivamente del microcontrolador y del RTOS específicos. 3.2.3 Módulo de administración de tareas El módulo de administración de tareas utiliza intensivamente los recursos del RTOS a través del módulo de interfaces. Una vez instanciados todos los controladores que la aplicación requiere, este módulo se encarga de crear todas las tareas en el RTOS necesarias para ejecutar dichos controladores. Para esto, el módulo utiliza toda la información disponible en la lista de controladores invocando las correspondientes funciones y procedimientos del módulo principal. En el Código 11 se presenta la interfaz pública del módulo de administración de tareas: Código 11: Interfaz pública del módulo de administración de tareas enum RTCS_tasks_EnumSchedulingScheme { RTCS_tasks_EnumSchedulingScheme_RMS = 0, RTCS_tasks_EnumSchedulingScheme_EDF = 1, }; typedef enum RTCS_tasks_SchedulerScheme RTCS_tasks_ESchedulerScheme; enum RTCS_tasks_EnumSchedulabilityTests { RTCS_tasks_EnumSchedulabilityTests_RMSbasic = 0, RTCS_tasks_EnumSchedulabilityTests_EDFbasic = 1, }; typedef enum RTCS_tasks_EnumSchedulerTests RTCS_tasks_ESchedulerTests; int8_t RTCS_tasks_CreateAll (RTCS_tasks_ESchedulerScheme scheme); int8_t RTCS_tasks_DeleteAll (); void RTCS_tasks_AddExternalTask (uint32_t taskPeriodInMS, uint32_t taskProcessorTimeInUS); int8_t RTCS_tasks_RunSchedulerTest ( RTCS_tasks_ESchedulerTests schedulerTest); En el Código 11 se incluyen dos enumeraciones. Por un lado, la enumeración RTCS_tasks_ESchedulerScheme define los diferentes tipos de esquemas de scheduling que soporta la libRTCS. Esta enumeración está pensada para que la biblioteca pueda ser expandida con nuevos esquemas de scheduling. En particular, en este trabajo, solo se imple- [ 16 de abril de 2013 at 16:46 – version 1.0 ] 49 50 diseño e implementación menta el esquema RMS presentado en la Sección 2.1.1.3. Por otro lado, RTCS_tasks_ESchedulerTests define los tipos de test de schedulability que soporta la libRTCS. Esta enumeración también está pensada para que la biblioteca pueda ser expanidad con nuevos test de schedulability. En este trabajo se implementa el test de schedulability básico para el esquema RMS. En el Código 11 también se puede observar que existe una función que permite crear todas las tareas que son necesarias para ejecutar los controladores instanciados. La función RTCS_tasks_CreateAll crea las tareas en función del esquemas de scheduling seleccionado. En el caso del esquema RMS, esta función debe acceder a la lista de controladores disponible en el módulo principal para buscar la información necesaria de cada controlador. Por cada controlador instanciado, la función debe crear una tarea en el RTOS con una determinada prioridad. Para poder utilizar los recursos del RTOS se basa en el módulo de interfaces. En el caso del esquema RMS, las prioridades de las tareas son determinadas en función de la frecuencia de ejecución de cada controlador. Se deben ordenar los controladores en función de la frecuencia de ejecución, para luego asignarle la mayor prioridad a aquella tarea que maneje el controlador de mayor frecuencia. Finalmente, este módulo implementa los diferentes test de schedulability en la función RTCS_tasks_RunSchedulerTest. Antes de iniciar al sistema, el usuario de la libRTCS puede utilizar esta función para determinar si el conjunto de controladores que instanció puede o no cumplir con los requerimientos temporales impuestos. También puede utilizar la función RTCS_tasks_AddExternalTask para agregar al test información sobre otras tareas que desea ejecutar de manera concurrente con los controladores. En este trabajo, para implementar el test de schedulability se utiliza la Ecuación 2.2. En tiempo de ejecución, antes de que el sistema inicie, se miden los tiempos de computo de todas las tareas instanciadas utilizando el recurso timer del microcontrolador. Con dichas mediciones se puede determinar si el conjunto de tareas instanciadas puede o no cumplir con los requerimientos temporales impuestos. En caso de no poder cumplir con los requerimientos temporales, el sistema dispara una alarma y no inicia. 3.2.4 Módulo de controladores El módulo de controladores tiene una importancia fundamental en la libRTCS. Este módulo le permite a la biblioteca incluir nuevos algoritmos de control sin necesidad de modificar el código existente. Darle esta funcionalidad a la libRTCS no resulta trivial, ya que cada algoritmo de control implementa sus propios tipos de datos y sus propios algoritmos. Sin embargo, todos los algoritmos de control también tienen en común determinados parámetros. Entonces, se tiene un esquema en el cual existen distintos tipos de objetos con una interfaz [ 16 de abril de 2013 at 16:46 – version 1.0 ] 3.2 implementación de la biblioteca de algoritmos de control básica en común pero que a su vez el comportamiento particular de cada tipo de objeto es diferente. Como se mencionó anteriormente, en un lenguaje de programación orientado a objetos este tipo de esquema es fácil de implementar a partir de utilizar los mecanismos nativos de clases, herencia y polimorfismo. Como la libRTCS está implementada en el lenguaje de programación C, estos mecanismos no están disponibles de manera nativa. En esta sección se explica cómo se implementan dichos mecanismos en la biblioteca. En el Código 12 se presenta la estructura de dato que define a un controlador genérico. Código 12: Interfaz pública del controlador genérico struct RTCS_genericController_TypeController { void (*ControllerFirstRunFunction) (void*); void (*ControllerRunFunction) (void*); void (*ControllerSaveFunction) (void*); void (*ControllerSendFunction) (float*, uint32_t); void (*ControllerReceiveFunction) (float*, uint32_t); void (*ControllerWorstRun) (void*); void* taskIdentifier; uint32_t taskPriority; uint32_t periodInMS; uint32_t processorTimeInUS; void* data; }; typedef struct RTCS_genericController_TypeController RTCS_genericController_TController; Todos los algoritmos de control que se implementan en la biblioteca tienen en común la información que almacena la estructura de datos RTCS_genericController_TController. En esta estructura se declaran dos punteros a funciones. Por un lado, el puntero a función ControllerRunFunction almacena la dirección de memoria de la función que ejecuta el algoritmo de control. Por otro lado, el puntero a función ControllerFirstRunFunction almacena la dirección de memoria de la función que ejecuta el algoritmo que realiza todas las operaciones matemáticas del controlador que no requieren ser actualizadas en cada iteración. Cabe aclarar que esta última función es muy útil para reducir el tiempo de computo de los algoritmos de control. El puntero a función ControllerSaveFunction, almacena la dirección de memoria de la función que se encarga de actualizar el estado de las variables internas del algoritmo de control. Es importante destacar, que la actualización de las variables internas del algoritmo de control se realiza luego de enviar la acción de control al sistema dinámico para reducir el tiempo de computo. Las funciones mencionadas, reciben como parámetro un puntero genérico con los datos de la instancia particular de cada controlador. Cada controlador particular implementa sus [ 16 de abril de 2013 at 16:46 – version 1.0 ] 51 52 diseño e implementación propias funciones respetando la firma de los punteros a función del controlador genérico. Cuando un nuevo controlador es instanciado, se agrega dinámicamente a la lista de controladores del módulo principal una nueva estructura del tipo RTCS_genericController_TController. Los punteros a función de esta nueva estructura son cargados con las direcciones de memoria de las funciones propias del controlador instanciado. De esta manera, la estructura del controlador genérico logra abstraer completamente cuál es el tipo particular del controlador que se instanció. Cada elemento de la lista de controladores es representado por un controlador genérico y los punteros a funciones encapsulan el comportamiento particular de cada algoritmo de control. Cuando el módulo de administración de tareas es utilizado para crear las tareas del RTOS que ejecutan los algoritmos de control, la lista de controladores provee la información de que algoritmo debe ejecutar cada tarea. De esta manera, se logra implementar el polimorfismo en un lenguaje de programación estructurado que no implementa dicho mecanismo de manera nativa. Esto le permite a la biblioteca libRTCS obtener un elevado grado de escalabilidad. Nuevas estrategias de control pueden ser añadidas, ya que el comportamiento particular de cada estrategia es abstraído por la estructura del controlador genérico. Los nuevos controladores solo deben respetar dicha interfaz. En la Figura 3.3 se muestra un esquema de la lista de controladores, en la cual fueron agregados diferentes tipos de controaldores. En la misma, se puede observar como la lista almacena un puntero a cada controlador genérico y a su vez, como cada controlador genérico almacena un puntero a la estructura de datos específica de cada controlador. La estructura de datos del controlador genérico almacena las direcciones de memoria correspondientes a las funciones específicas de cada controlador. De esta manera el módulo principal puede abstraerse totalmente de la implementación específica de cada controlador. Por otro lado, la estructura RTCS_genericController_TController dispone de la variable taskPriority para almacenar la prioridad de la tarea, de la variable periodInMS para almacenar el período de ejecución del lazo de control en milisegundos y la variable processorTimeInUS para almacenar el tiempo de computo del algoritmo de control en microsegundos. La variable taskPriority es asignada automáticamente por el módulo administrador de tareas cuando se crean las tareas a partir de la lista de controladores. La prioridad asignada depende del tipo de esquema de scheduling seleccionado. La variable periodInMS es determinada por el usuario de la biblioteca cuando instancia el controlador particular. La misma se utiliza para definir la frecuencia del lazo de control de cada controlador. La variable processorTimeInUS es medida y almacenada cuando se ejecuta el test de schedulability. La misma es utiliza para hacer los cálculos matemáticos que requiere el test de schedulability seleccionado. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 3.2 implementación de la biblioteca de algoritmos de control Figura 3.3: Lista de controladores almacenando diferentes tipos de controladores Por último, la estructura del controlador genérico también incluye el puntero genérico data. Este puntero almacena la dirección de memoria de la estructura que dispone de la información específica de cada controlador instanciado. Cuando se implementa un controlador en la libRTCS, lo primero que se define es la estructura de datos del mismo. Dicha estructura es distinta para cada controlador, ya que los parámetros y la información que cada estrategia de control necesitan son diferentes. Anteriormente se explicó que cuando un nuevo controlador es instanciado, se agrega a la lista de controlador una nueva estructura del tipo controlador genérico. Cabe aclarar, que también se crea una nueva estructura con la información específica del controlador creado. La dirección de memoria de dicha estructura es almacenada en el puntero genérico data. Cuando una tarea del RTOS es ejecuta, la misma recibe como parámetro este puntero genérico. Como la tarea del RTOS ejecuta un algoritmo de control particular, dentro de dicho contexto se conoce el tipo exacto del puntero genérico data. Mediante una conversión de tipos explícita se logra recuperar la información disponible dentro de dicho puntero. Esta información es luego utilizada por la tarea para hacer los cálculos correspondientes y actualizar la acción de control. En este trabajo, en particular, se implementan los controladores PID y DMC. En el Código 13 se presenta la estructura de datos definida para el controlador PID. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 53 54 diseño e implementación Código 13: Interfaz pública del controlador PID enum RTCS_PID_EnumConfigCommands { RTCS_PID_ConfigData = 0, }; typedef enum RTCS_PID_EnumConfigCommands RTCS_PID_EConfigCommands; struct RTCS_PID_TypeData { // PID config parameters float RTCS_PID_Kp; float RTCS_PID_Ki; float RTCS_PID_Kd; float RTCS_PID_b; float RTCS_PID_N; float RTCS_PID_LowOutputLimit; float RTCS_PID_HighOutputLimit; uint32_t RTCS_PID_periodTimeInMS; void (*RTCS_PID_receiveData) (float*, uint32_t); void (*RTCS_PID_sendData) (float*, uint32_t); // PID internal data float RTCS_PID_Der; float RTCS_PID_Int; }; typedef struct RTCS_PID_TypeData RTCS_PID_TData; int32_t RTCS_PID_New (); void RTCS_PID_Config (int32_t fileDescriptor, RTCS_PID_EConfigCommands cmd, void* arg); void RTCS_PID_RunFirstTime (RTCS_PID_TData* pData); void RTCS_PID_Run (RTCS_PID_TData* pData); En esta estructura se pueden observar todos los parámetros del PID que están englobados en la Ecuación 2.15: RTCS_PID_Kp: Es la ganancia de la parte proporcional del controlador PID. RTCS_PID_b: Es un término que pondera la acción de la ganancia proporcional sobre la referencia. RTCS_PID_Ki: Es la ganancia de la parte integral del controlador PID. RTCS_PID_Kd: Es la ganancia de la parte derivativa del controlador PID. RTCS_PID_N: Es un término que limita la ganancia de la parte derivativa en altas frecuencias. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 3.2 implementación de la biblioteca de algoritmos de control RTCS_PID_periodTimeInMS: Es el período del lazo de control. En las ecuaciones del PID estaba representado por el término h. RTCS_PID_LowOutputLimit: Límite inferior del anti-windup. RTCS_PID_HighOutputLimit: Límite superior del anti-windup. También se pueden observar dos punteros a funciones. Por un lado RTCS_PID_receiveData almacena la dirección de memoria de la función que se utiliza para recibir las señales de entrada requeridas en cada instante n. En el caso del PID estás señales son la referencia r [n] y la salida y[n]. Por otro lado RTCS_PID_sendData almacena la dirección de memoria de la función que se utiliza para enviar las señales de salida del controlador en cada instante n. En el caso del PID esta señal es la acción de control u[n]. Las invocaciones a las funciones de recepción y envío de señales se realiza mediante punteros a funciones, para que estas funciones puedan ser implementadas por el usuario de la libRTCS. Esto representa otra característica de flexibilidad de la biblioteca, ya que la misma es independiente del hardware utilizado para realizar la adquisición de datos. El usuario de la biblioteca puede realizar dicha adquisición mediante el ADC y el DAC del microcontrolador o mediante un integrado dedicado que disponga de una comunicación digital con el microcontrolador. En cualquier caso, se deben implementar estas funciones por fuera de la biblioteca respetando la firma de los punteros a funciones. Por otro lado, en el Código 13, se encuentran disponibles las funciones para crear y configurar una nueva instancia de un controlador PID. La función RTCS_PID_New utiliza las funciones de memoria dinámica abstraída por el módulo de interfaces para crear un nuevo objeto PID. La misma devuelve un file descriptor que identifica unívocamente la instancia particular creada. Este file descriptor puede ser utilizado por el usuario de la libRTCS para modificar o eliminar el objeto instanciado. La función RTCS_PID_Config permite configurar los parámetros del PID instanciado. Las funciones RTCS_PID_RunFirstTime y RTCS_PID_Run son las encargadas de implementar el algoritmo de control. Estas funciones tienen la misma firma que los punteros disponibles en la estructura del controlador genérico. Por último, en la Sección A.4 se presenta el algoritmo de control PID en el lenguaje de programación C [16]. Para implemenar el algoritmo de control PID en este lenguaje de programación, se tomo como base el algoritmo diseñado en Matlab (Sección A.1) En el Código 14 se presenta la estructura de datos definida para el controlador DMC SISO. Al igual que en el caso del controlador PID, en esta estructura se pueden observar todos los parámetros del controlador DMC SISO y los punteros a funciones para enviar y recibir información del sistema dinámico. [ 16 de abril de 2013 at 16:46 - version 1.0 ] 55 56 diseño e implementación Código 14: Interfaz pública del controlador DMC enum RTCS_DMC_SISO_EnumConfigCommands { RTCS_DMC_SISO_ConfigData = 0, }; typedef enum RTCS_DMC_SISO_EnumConfigCommands RTCS_DMC_SISO_EConfigCommands; struct RTCS_DMC_SISO_TypeData { // DMC config parameters uint32_t RTCS_DMC_SISO_P; uint32_t RTCS_DMC_SISO_M; uint32_t RTCS_DMC_SISO_N; float* RTCS_DMC_SISO_step; float RTCS_DMC_SISO_a; float RTCS_DMC_SISO_lambda; float* RTCS_DMC_SISO_reference; void (*RTCS_DMC_SISO_receiveData) (float*, uint32_t); void (*RTCS_DMC_SISO_sendData) (float*, uint32_t); // DMC internal data float* RTCS_DMC_SISO_G; float* RTCS_DMC_SISO_F; uint32_t RTCS_DMC_SISO_periodTimeInMS; }; typedef struct RTCS_DMC_SISO_TypeData RTCS_DMC_SISO_TData; int32_t RTCS_DMC_SISO_New (); void RTCS_DMC_SISO_Config (int32_t fileDescriptor, RTCS_DMC_SISO_EConfigCommands cmd, void* arg); void RTCS_DMC_SISO_RunFirstTime (RTCS_DMC_SISO_TData* pData); void RTCS_DMC_SISO_Run (RTCS_DMC_SISO_TData* pData); RTCS_DMC_SISO_P: Es el horizonte de predicción del controlador DMC SISO. RTCS_DMC_SISO_M: Es el horizonte de control del controlador DMC SISO. RTCS_DMC_SISO_N: Es la cantidad de muestras que tiene la respuesta al escalón de la planta SISO. RTCS_DMC_SISO_step: Es la respuesta al escalón de la planta. RTCS_DMC_SISO_a: Es el factor utilizado en la predicción de la referencia. RTCS_DMC_SISO_reference: Para el caso en el cuál la referencia es conocida, este vector almacena sus valores. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 3.3 resumen de características de la biblioteca de algoritmos de control En la estructura RTCS_DMC_SISO_TData, al igual que en el caso del PID, se pueden observar los punteros a funciones que se utilizan para recibir y enviar las señales que iteración a iteración requiere el controlador. También se observan las funciones para crear y configurar una nueva instancia del controlador DMC SISO. Por último en la Sección A.5 se presenta el algoritmo DMC en el lenguaje de programación C. 3.3 resumen de características de la biblioteca de algoritmos de control A partir de la implemtación realizada de la biblioteca libRTCS, se logró que la misma tenga las siguientes características fundamentales: Es independiente del microcontrolador y del RTOS a utilizar en cada aplicación. Es flexible y escalable ya que nuevas estrategias de con trol pueden ser agregas sin tener que modificar el código existente. Está preparada para soportar diferentes esquemás de scheduling y diferentes test de schedulability. Es segura desde el punto de vista del cumplimiento temporal de las restricciones impuestas ya que ejecuta los test de schedulability antes de iniciar el sistema. Es simple de utilizar ya que todos los algoritmo de control exponen la misma interfaz para la creación y configuración de instancias. Las instancias se representan mediante file descriptors al igual que los drivers de los sistemas operativos POSIX. La recepción y envío de datos a los procesos físicos son independientes de la libRTCS y pueden ser definidos por el usuario de la misma. Para validar los algoritmos de control implementados en este trabajo y para poner a prueba el funcionamiento de la libRTCS, es necesario portar la misma a un hardware y a un RTOS específicos. En el Capítulo 4 se porta la libRTCS al al microcontrolador LPC1769 con tecnología Cortex-M3 de ARM del fabricante NXP y el sistema operativo de tiempo real FreeRTOS. Luego, en el Capítulo 5 se presentan los diferentes resultados obtenidos al utilizar la libRTCS y también se realiza la validación de los diferentes algoritmos de control implementados en este trabajo. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 57 [ 16 de abril de 2013 at 16:46 – version 1.0 ] 4 P L ATA F O R M A D E H A R D WA R E Y A P L I C A C I Ó N En este capítulo se hace la portación de la libRTCS a una plataforma concreta. Utilizando el microcontrolador LPC1769[17] del fabricante NXP [18] con tecnología Cortex-M3 [19] de ARM y el sistema operativo de tiempo real FreeRTOS [20]. La justificación en la elección del microcontrolador y del RTOS se presentan en la Sección 4.1 y en la Sección 4.2, respectivamente. En la Sección 4.1, se presenta la platafroma de desarrollo utilizada y se detalla el diseño de la plataforma de hardware implementada. Luego se explica cómo se hace la portación concreta de la libRTCS al microcontrolador LPC1769, detallando el diseño de firmware realizado. Este capítulo tiene una gran importancia, porque es necesario portar la biblioteca a una plataforma concreta para poder: Validar los algoritmos de control implementados. Validar el funcionamiento general de la libRTCS. Por otro lado, este capítulo también es importante desde el punto de vista de una aplicación de ingeniería, porque se trabajan simultáneamente y de forma articulada en los siguientes niveles, para lograr los objetivos mencionados: Hardware: Diseño e implementación de un circuito electrónico. En este nivel se decide que componentes electrónicos se van a utilizar, en función de los recursos que se requieren que tenga una determinada aplicación. Luego se realiza un esquemático donde se indica todas las conexiones eléctricas entre los diferentes componentes. Finalmente, se realiza un circuito impreso, a partir del cual, se construye una placa. Firmware: Diseño e implementación de los programas que ejecutan los microcontroladores. El nivel firmware involucra tanto la codificación del programa que utiliza bibliotecas de código como la portación de las mismas a la arquitectura particular de hardware utilizada. Luego en el Capítulo 5, a partir de utilizar la implementación realizada en este capítulo, se presentan los resultados que validan el trabajo realizado. 59 [ 16 de abril de 2013 at 16:46 – version 1.0 ] 60 plataforma de hardware y aplicación 4.1 4.1.1 hardware Presentación de la plataforma de hardware Como se mencionó anteriormente, la plataforma de hardware utilizada incluye al microcontrolador LPC1769 del fabricante NXP que incorpora la tecnología Cortex-M3 de ARM. Se decidió utilizar este microcontrolador, porque dentro de la gama de procesadores de 32 bits, se trata de una opción económica (se consigue por aproximadamente us $2), de gran poder de cálculo y bajo consumo de energía. Por otro lado, este microcontrolador puede ser programado en el lenguaje de programación estándar C (detalles sobre la programación del mismo y el compilador utilizado se encuentra en la Sección 4.2). También cabe aclarar que la libRTCS pretender ser una solución que pueda ser utilizada tanto en microcontroladores de gama mediabaja como en microcontroladores de gama alta. En comparación con los microcontroladores avanzados que actualmente existen en el mercado, el LPC1769 puede ser considerado de gama media-baja. De hecho, la tecnología Cortex-M3 del núcleo de este microcontrolador no incluye una FPU, lo cual hace que sea aún más interesante observar el funcionamiento de la libRTCS al tener que simular las operaciones en punto flotante por software. En este trabajo se pretende medir el desempeño de la libRTCS en un microcontrolador de relativos bajos recursos, ya que un funcionamiento aceptable de la biblioteca en esta plataforma asegura también un correcto funcionamiento en una plataforma de mayores recursos. Por último, otro de los motivos por los cuales fue elegida esta plataforma, es la disponibilidad de un sistema operativo de tiempo real como el FreeRTOS. Este RTOS incluye todos los recursos que la libRTCS requiere (el detalle de los mismos fueron discutidos en el Capítulo 3 y son repetidos a modo de resumen la Sección 4.2). En la Figura 4.1 se presenta un diagrama en bloques de un núcleo Cortex-M3. Figura 4.1: Diagrama en bloques de un núcleo Cortex-M3 [ 16 de abril de 2013 at 16:46 – version 1.0 ] 4.1 hardware En la Tabla 4.1 se realiza un breve resumen de las características fundamentales que poseen los núcleo basados en la tecnología CortexM3 de ARM [19]. característica valor típico Interrupciones no enmascarables 1 Vector de interrupciones anidadas Hasta 240 Niveles de prioridad de interrupciones 8 a 256 Regiones de memoria protegida Hasta 8 regiones Modos de bajo consumo Si Potencia estática y dinámica Ver en [19] Debugging Tracing JTAG ETM, DWT y ITM Tabla 4.1: Características principales del núcleo Cortex-M3. El núcleo Cortex-M3 presentado en la Figura 4.1 y descripto en la Tabla 4.1 es utilizado como procesador del microcontrolador LPC1769. En la Figura 4.2 se presenta un diagrama en bloques del microcontrolador LPC1769. Figura 4.2: Diagrama en bloques del microcontrolador LPC1769 [ 16 de abril de 2013 at 16:46 – version 1.0 ] 61 62 plataforma de hardware y aplicación En la Tabla 4.2 se detallan las características principales del mismo. característica Procesador valor típico Cortex-M3 de ARM Frecuencia máxima de reloj 120MHz 64KByte SRAM Memoria de variables Interconexión periféricos Multilayer AHB Matrix Direct Memory Access 8 canales Módulo Ethernet Si Módulo USB 2.0 Si (host y device) UART 4 canales con FIFOs internas Módulo I2C 3 interfaces Módulo SPI 1 interfaz Módulo SSP 2 controladores Módulo CAN 2 canales ADC 12bits, mux 8 canales y 200KHz DAC 10bits, DMA y 1MHz Timers Módulo RTC de bajo consumo Módulo PWM 4 timers / counters Si 6 salidas Tabla 4.2: Características principales del microcontrolador LPC1769. El microcontrolador LPC1769, es parte de la plataforma de desarrollo [LPCXpresso][21] del fabricante [NXP]. Se trata de una plataforma de desarrollo de bajo costo, que involucra a los procesadores basados en la tecnología Cortex de ARM. La misma está compuesta por un Integrated Development Environment - Entorno Integrados de Desarrollo (IDE) gratuito basado en Eclipse [22] y una placa de bajo costo que incluye un debugger JTAG. El IDE está desarrollado por la empresa Code Red[23] y la placa (conocida como LPCXpresso target board) es desarrollada en conjunto por NXP, Code Red y Embedded Artists[24]. Como se puede observar en la Figura 4.3, la placa target board está divida en dos partes. Por un lado, el LPC-Link implementa la interfaz de debugging JTAG y provee a la plataforma de desarrollo de una interfaz USB para comunicarse con el IDE. El LPC-link esta implementado [ 16 de abril de 2013 at 16:46 – version 1.0 ] 4.1 hardware a través del microcontrolador LPC3154 con tecnología ARM9. El IDE corre en una computadora con sistema operativo Windows o Linux. Por otro lado, la target board tiene un expansion board que incorpora el microcontrolador que puede ser programado utilizando el LPC-Link. Figura 4.3: Target board En la Figura 4.4 se presenta el target board particular del LPC1769. Se puede observar que esta placa puede cortarse a la mitad para separar al LPC-Link del expansion board. De esta manera, el LPC-Link puede ser reutilizado para programar microcontroladores de diferentes series (LPC1100, LPC1300, LPC1700, etc.). En la página web del fabricante del target board se pueden encontrar los circuitos esquemáticos del mismo [24]. Figura 4.4: Target board LPC1769 Por último, cabe mencionar que en la Sección 4.2 se describe con más detalles el IDE utilizado así como también el compilador que [ 16 de abril de 2013 at 16:46 – version 1.0 ] 63 64 plataforma de hardware y aplicación se utiliza para transformar el código desarrollado en el lenguaje de programación C al correspondiente código de máquina. 4.1.2 Diseño e implementación de la plataforma de hardware El objetivo principal de diseñar e implementar una plataforma de hardware en este trabajo, es poder validar el funcionamiento de la libRTCS. Para realizar dicha validación se utiliza la técnica hardware in the loop (HIL). La misma consiste en utilizar dos microcontroladores distintos para ejecutar en uno, modelos matemáticos de los sistemas dinámicos y en el otro los correspondientes algoritmos de control. Ambos procesadores se comunican entre sí para lograr de esta manera simular en tiempo real el comportamiento del conjunto sistema dinámico - sistema de control. Está técnica permite evaluar el desempeño de la libRTCS sin tener la necesidad de implementar un sistema dinámico real. De hecho, está forma de trabajo tiene un correlato con aplicaciones actuales, ya que muchos escenarios de control están constituidos por distintos microcontroladores que hacen de interfaz con diferentes procesos de un sistema dinámico y se comunican (mediante un protocolo de comunicación) con un microcontrolador central que implementa el RTCS. En la Sección 4.2 se explica en detalle como es utilizada la técnica HIL. Entonces, para validar el funcionamiento de la libRTCS, se diseña e implementa una placa que incluye dos microcontrolador LPC1769. En el primer microcontrolador se hace la portación de toda la biblioteca libRTCS (referenciado en adelante como microcontrolador RTCS). En el segundo microcontrolador se implementan los modelos matemáticos de diferentes sistemas dinámicos en términos de sus respectivas ecuaciones de recurrencia (referenciado en adelante como microcontrolador de sistemas dinámicos). Ambos microcontrolador están conectados entre sí mediante una interfaz UART. En la Figura 4.5, se presenta el circuito esquemático del hardware desarrollado. Por otro lado, en la Figura 4.6 se presenta el circuito impreso de dicho hardware. Por cuestiones de tiempo, el circuito impreso no fue fabricado. En su lugar, se construyó el circuito a partir de utilizar plaquetas universales. En la Figura 4.7 se presenta una fotografía de la placa terminada. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 4.1 hardware COMicrocontrolador de sistemas de dinámicos Microcontroladores sistemas dinámicos Microcontrolador RTCS COuC libRTCS 3V3_1 3V3_1 PILed10 PILed102 PIR402 PIR401 1 dinámicos01 PIMicrocontrolador de sistemas GND COLed1 Led1 2 PIMicrocontrolador de sistemas dinámicos02 3 dinámicos03 PIMicrocontrolador de sistemas 4 PIMicrocontrolador de sistemas dinámicos04 5 PIMicrocontrolador de sistemas dinámicos05 COR4 R4 6 PIMicrocontrolador de sistemas dinámicos06 330 7 PIMicrocontrolador de sistemas dinámicos07 8 PIMicrocontrolador de sistemas dinámicos08 NLUART010TX UART_1_TX 9 PIMicrocontrolador de sistemas dinámicos09 GND Conversor USB - Serie 5V NLUART010RX UART_1_RX 10 PIMicrocontrolador de sistemas dinámicos010 11 PIMicrocontrolador de sistemas dinámicos011 3V3_1 CO0* 3 PI003 4 PI004 3V3 8 PI008 TX PI007 RX PI006 GND PI005 5V D+ SERIE 2 PI002 12 PIMicrocontrolador de sistemas dinámicos012 USB 1 PI001 DGND 7 13 UART_1_RX 6 UART_1_TX 5 PIMicrocontrolador de sistemas dinámicos013 14 PIMicrocontrolador de sistemas dinámicos014 15 PIMicrocontrolador de sistemas dinámicos015 16 GND PIMicrocontrolador de sistemas dinámicos016 GND Usb-serie 17 PIMicrocontrolador de sistemas dinámicos017 18 PIMicrocontrolador de sistemas dinámicos018 Regulador 5v / 3.3v 19 PIMicrocontrolador de sistemas dinámicos019 3V3_2 5V 2 PIU102 IN 21 3 OUT PIU103 GND PIU10 COC1 C1 Capacitor 10uF HT7533 1 PIC101 PIC102 20 PIMicrocontrolador de sistemas dinámicos020 Regulador 5V-3V3 COU1 U1 PIMicrocontrolador de sistemas dinámicos021 PIC201 PIC202 22 PIMicrocontrolador de sistemas dinámicos022 COC2 C2 23 PIMicrocontrolador de sistemas dinámicos023 Capacitor 10uF 24 PIMicrocontrolador de sistemas dinámicos024 25 PIMicrocontrolador de sistemas dinámicos025 GND GND COLed2 Led2 GND 26 PIMicrocontrolador de sistemas dinámicos026 R3 COR3 PIR301 PIR302 27 PILed202 PILed201 PIMicrocontrolador de sistemas dinámicos027 GNDX 28 VIO_3V3X PIMicrocontrolador de sistemas dinámicos028 GND 65 1 PIuC libRTCS01 GNDX 3V3_2 28 VIO_3V3X PIuC libRTCS028 EXT_POWX 29 29 PIMicrocontrolador de sistemas dinámicos029 2 PIuC libRTCS02 EXT_POWX 29 VB 30 30 PIMicrocontrolador de sistemas dinámicos030 3 PIuC libRTCS03 VB 30 30 PIuC libRTCS030 RESET 31 PIMicrocontrolador de sistemas dinámicos031 RD- P0.8 MISO1 31 PIuC libRTCS04 31 PIuC libRTCS031 PIMicrocontrolador de sistemas dinámicos032 32 PIuC libRTCS05 P0.9 MOSI1 RD- PIuC libRTCS032 RD+ 33 PIMicrocontrolador de sistemas dinámicos033 6 PIuC libRTCS06 P0.8 MISO1 RD+ PIuC libRTCS033 P0.7 SCK1 TD- PIMicrocontrolador de sistemas dinámicos034 P0.7 SCK1 TD- PIuC libRTCS034 P0.6 SSEL1 TD+ PIMicrocontrolador de sistemas dinámicos035 P0.6 SSEL1 TD+ PIuC libRTCS035 USB-D- P0.9 MOSI1 4 29 PIuC libRTCS029 5 31 32 33 34 PIuC libRTCS07 35 PIuC libRTCS08 PIMicrocontrolador de sistemas dinámicos036 36 NLUART020TX UART_2_TX 9 PIuC libRTCS09 P0.0 TXD3/SDA1 USB-D- PIuC libRTCS036 USB-D+ 37 PIMicrocontrolador de sistemas dinámicos037 NLUART020RX UART_2_RX 10 PIuC libRTCS010 P0.1 RXD3/SCL1 USB-D+ PIuC libRTCS037 P0.18 MOSI0 P0.4 CAN_RX2 PIMicrocontrolador de sistemas dinámicos038 P0.18 MOSI0 P0.4 CAN_RX2 PIuC libRTCS038 P0.17 MISO0 P0.5 CAN_TX2 PIMicrocontrolador de sistemas dinámicos039 P0.17 MISO0 P0.5 CAN_TX2 PIuC libRTCS039 P0.10 TXD2/SDA2 PIMicrocontrolador de sistemas dinámicos040 PIuC libRTCS013 P0.15 TXD1/SCK0 P0.10 TXD2/SDA2 PIuC libRTCS040 P0.11 RXD2/SCLP 41 PIMicrocontrolador de sistemas dinámicos041 14 PIuC libRTCS014 P0.16 RXD1/SSEL P0.11 RXD2/SCLP PIuC libRTCS041 P0.23 AD0.0 P2.0 PWM1.1 PIMicrocontrolador de sistemas dinámicos042 P0.23 AD0.0 P2.0 PWM1.1 PIuC libRTCS042 P0.24 AD0.1 P2.1 PWM1.2 PIMicrocontrolador de sistemas dinámicos043 P0.24 AD0.1 P2.1 PWM1.2 PIuC libRTCS043 P0.25 AD0.2 P2.2 PWM1.3 P0.25 AD0.2 P2.2 PWM1.3 PIuC libRTCS044 P0.26 AD0.3/AOUT P2.3 PWM1.4 PIuC libRTCS045 P1.30 AD0.4 P2.4 PWM1.5 PIuC libRTCS046 P1.31 AD0.5 P2.5 PWM1.6 PIuC libRTCS047 P0.0 TXD3/SDA1 P0.1 RXD3/SCL1 P0.15 TXD1/SCK0 P0.16 RXD1/SSEL 7 RESET 8 38 UART_2_TX PIuC libRTCS011 39 UART_2_RX PIuC libRTCS012 40 11 12 13 42 PIuC libRTCS015 43 PIuC libRTCS016 PIMicrocontrolador de sistemas dinámicos044 44 PIuC libRTCS017 45 PIMicrocontrolador de sistemas dinámicos045 18 PIuC libRTCS018 P0.26 AD0.3/AOUT P2.3 PWM1.4 P1.30 AD0.4 P2.4 PWM1.5 PIMicrocontrolador de sistemas dinámicos046 P1.31 AD0.5 P2.5 PWM1.6 15 16 17 46 PIuC libRTCS019 PIMicrocontrolador de sistemas dinámicos047 47 PIuC libRTCS020 P0.2 48 P2.6 PIMicrocontrolador de sistemas dinámicos048 PIuC libRTCS021 P0.2 P0.3 49 PIMicrocontrolador de sistemas dinámicos049 22 PIuC libRTCS022 P0.3 P0.21 50 P2.8 PIMicrocontrolador de sistemas dinámicos050 PIuC libRTCS023 P0.22 51 P2.10 PIMicrocontrolador de sistemas dinámicos051 PIuC libRTCS024 P0.27 52 P2.11 PIMicrocontrolador de sistemas dinámicos052 PIuC libRTCS025 P2.7 53 P0.28 P2.12 PIMicrocontrolador de sistemas dinámicos053 P2.13 GND PIMicrocontrolador de sistemas dinámicos054 54 19 20 21 23 24 25 26 PIuC libRTCS026 27 PIuC libRTCS027 P0.21 34 35 36 37 38 39 40 41 42 43 44 45 46 47 COLed3 Led3 COR1 R1 48 PIR101 P2.6 PIuC libRTCS048PILed301 PILed302 PIR102 330 49 P2.7 PIuC libRTCS049 GND 50 P2.8 PIuC libRTCS050 P0.22 51 P2.10 PIuC libRTCS051 P0.27 52 P2.11 PIuC libRTCS052 P0.28 P2.12 PIuC libRTCS053 PILed401 PILed402 PIR202 P2.13 GND PIuC libRTCS054 COLed4 Led4 R2 COR2 53 GND Header hembra GND Header hembra PIR201 330 54 330 GND GND Figura 4.5: Esquemático de la plataforma de hardware COuC Sistemas Dinamicos PAuC Sistemas Dinamicos028 PAuC libRTCS01 PAuC libRTCS028 PAuC Sistemas Dinamicos02 PAuC Sistemas Dinamicos029 PAuC libRTCS02 PAuC libRTCS029 PAuC Sistemas Dinamicos03 PAuC Sistemas Dinamicos030 PAuC libRTCS03 PAuC libRTCS030 PAuC Sistemas Dinamicos04 PAuC Sistemas Dinamicos031 PAuC libRTCS04 PAuC libRTCS031 PAuC Sistemas Dinamicos05 PAuC Sistemas Dinamicos032 PAuC libRTCS05 PAuC libRTCS032 PAuC Sistemas Dinamicos06 PAuC Sistemas Dinamicos03 PAuC libRTCS06 PAuC libRTCS033 PAuC Sistemas Dinamicos07 PAuC Sistemas Dinamicos034 PAuC libRTCS07 PAuC libRTCS034 PAuC Sistemas Dinamicos08 PAuC Sistemas Dinamicos035 PAuC libRTCS08 PAuC libRTCS035 PAuC Sistemas Dinamicos09 PAuC Sistemas Dinamicos036 PAuC libRTCS09 PAuC libRTCS036 PAuC Sistemas Dinamicos010 PAuC Sistemas Dinamicos037 PAuC libRTCS010 PAuC libRTCS037 PALed102 PAuC Sistemas Dinamicos01 PAuC Sistemas Dinamicos038 PAuC libRTCS011 PAuC libRTCS038 PALed101 PAuC Sistemas Dinamicos012 PAuC Sistemas Dinamicos039 PAuC libRTCS012 PAuC libRTCS039 PAuC Sistemas Dinamicos013 PAuC Sistemas Dinamicos040 PAuC libRTCS013 PAuC libRTCS040 PAuC Sistemas Dinamicos014 PAuC Sistemas Dinamicos041 PAuC libRTCS014 PAuC libRTCS041 PAuC Sistemas Dinamicos015 PAuC Sistemas Dinamicos042 PAuC libRTCS015 PAuC libRTCS042 PAuC Sistemas Dinamicos016 PAuC Sistemas Dinamicos043 PAuC libRTCS016 PAuC libRTCS043 PAuC Sistemas Dinamicos017 PAuC Sistemas Dinamicos04 PAuC libRTCS017 PAuC libRTCS044 PAuC Sistemas Dinamicos018 PAuC Sistemas Dinamicos045 PAuC libRTCS018 PAuC libRTCS045 PAuC Sistemas Dinamicos019 PAuC Sistemas Dinamicos046 PAuC libRTCS019 PAuC libRTCS046 PAuC Sistemas Dinamicos020 PAuC Sistemas Dinamicos047 PAuC libRTCS020 PAuC libRTCS047 PAuC Sistemas Dinamicos021 PAuC Sistemas Dinamicos048 PAuC libRTCS021 PAuC libRTCS048 PAuC Sistemas Dinamicos02 PAuC Sistemas Dinamicos049 PAuC libRTCS022 PAuC libRTCS049 PAR301 COR3 PAuC Sistemas Dinamicos023 PAuC Sistemas Dinamicos050 PAuC libRTCS023 PAuC libRTCS050 PAuC Sistemas Dinamicos024 PAuC Sistemas Dinamicos051 PAuC libRTCS024 PAuC libRTCS051 PAR302 PAuC Sistemas Dinamicos025 PAuC Sistemas Dinamicos052 PAuC libRTCS025 PAuC libRTCS052 PAuC Sistemas Dinamicos026 PAuC Sistemas Dinamicos053 PAuC libRTCS026 PAuC libRTCS053 PALed401 PALed402 PAR202 PAuC Sistemas Dinamicos027 PAuC Sistemas Dinamicos054 PAuC libRTCS027 PAuC libRTCS054 COR2 COC2 PAC201 PAC202 PAC101 PAC102 COC1 PAU103 PAU102 PAU101 COU1 COLed1 PAR401 PA000 PAR402 COR4 CO0 PA004 PA001 PA003 PA002 COuC libRTCS PAuC Sistemas Dinamicos01 PA008 PA007 PA006 PA005 PALed202 PALed201 COLed2 Figura 4.6: Circuito impreso de la plataforma de hardware [ 16 de abril de 2013 at 16:46 – version 1.0 ] COLed3 PALed301 PALed302 PAR102 COR1 PAR101 COLed4 PAR201 66 plataforma de hardware y aplicación Figura 4.7: Fotografía de la plataforma de hardware utilizada En la Sección 4.2.3 se presenta una descripción del firmware del microcontrolador RTCS y en la Sección 4.2.4 se presenta una descripción del firmware del microcontrolador de sistemas dinámicos. 4.2 firmware En la Sección 4.2.1 se presenta el detalle sobre el IDE y el compilador utilizados para generar los archivos binarios que se ejecutan en los microcontroladores LPC1769. Luego, en la Sección 4.2.2, se presenta una explicación del esquema general de firmware para microcontroladores, basado en capas de abstracción, interfaces públicas y encapsulamiento en bibliotecas de código. Por último, en la Sección 4.2.3 se presenta como se aplica el esquema general de firmware al microcontrolador libRTCS y en la Sección 4.2.4 se presenta como se aplica el esquema general de firmware al microcontrolador de sistemas dinámicos. Los códigos de ambos microcontroladores, al igual que la libRTCS, están implementados en el lenguaje de programación estándar C. 4.2.1 IDE y compilador El IDE que se utiliza para programar los microcontroladores es el LPCXpresso del fabricante Code Red. Este IDE ya incluye todo el toolchain para generar el archivo binario que ejecuta el microcontrolador LPC1769. Cabe resaltar que este toolchain resulta ser un compilador cruzado que se ejecuta en una computadora y genera un binario para la plataforma ARM. El mismo, soporta dos bibliotecas de código C. Por un lado, soporta el uso de la Newlib, que es una biblioteca de código GNU para el lenguaje C preparada para ser utilizada en sistemas embebidos [25]. Por otro lado, soporta el uso de la Redlib, que es una biblioteca de código propietaria de Code Red para el lenguaje de programación C (compatible con el estándar ISO C90[26]). La biblioteca Newlib soporta todo el estándar ISO C99 a expensas de generar [ 16 de abril de 2013 at 16:46 – version 1.0 ] 4.2 firmware código que consume mayor cantidad de recursos del microcontrolador. La biblioteca Redlib, en cambio, solo soporta el estándar ISO C90 (con la inclusión de algunas funcionalidades extras) y genera código que consume menor cantidad de recursos del microcontrolador. En este trabajo, se utiliza la biblioteca Redlib. 4.2.2 Esquema general de firmware para microcontroladores modernos En la actualidad, gracias a la gran cantidad de recursos que tiene disponible un microcontrolador, es posible implementar una estructura de código basada en capas de abstracción, interfaces públicas y encapsulamiento en bibliotecas de código. Este tipo de estructura de código permite generar código reusable, flexible y escalable. Anteriormente, este tipo de estructura de código era únicamente utilizada en programación de alto nivel. Desde hace algunos años, muchos de los conceptos de diseño de software utilizados en programación de alto nivel, comenzaron a ser utilizados en el diseño de firmware para microcontroladores. Esto produjo la aparición en el mercado de bibliotecas de código para microcontroladores que abstraen completamente a la plataforma de hardware. Por ejemplo, es posible encontrar en el mercado bibliotecas de código que implementan: Sistemas Operativos de Tiempo Real (RTOS)[20], Stacks TCP/IP[27], bibliotecas de recursos matemáticos[28], etc. Este trabajo de tesis se tiene como objetivo aportar una biblioteca de código para implementar Sistemas de Control de Tiempo Real (RTCS). Por este motivo, en esta sección, se explica la estructura general de firmware que permite generar código reusable en diferentes plataformas de hardware, flexible y escalable. En la Figura 4.8 se presenta la estructura general de firmware que se utiliza tanto en el microcontrolador RTCS como en el microcontrolador de sistemas dinámico. En la Figura 4.8 se puede observar una estructura de código basada en niveles o capas de abstracción: Aplicación: En el nivel más alto, se ubica la aplicación final que debe cumplir con un requisito concreto. Se persigue como objetivo, que dicha aplicación sea independiente de la plataforma de hardware utilizada. Para lograr este objetivo, se necesitan utilizar diferentes capas de abstracción. Idealmente, la aplicación solo debería comunicarse con la capa API para mantener la portabilidad a diferentes plataformas. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 67 68 plataforma de hardware y aplicación Figura 4.8: Diseño general del firmware API: Por debajo del nivel aplicación, se ubica la capa API (Application Programming Interface). En este capa se ubican diferentes bibliotecas de código, que también buscan ser independientes de la plataforma de hardware utilizada. Estas bibliotecas de código, a diferencia de la aplicación, pueden ser utilizada en una gran variedad de proyectos. La biblioteca libRTCS desarrollada en este trabajo, se ubica en esta capa de abstracción. A modo de ejemplo, en la Figura 4.9 se pueden observar bibliotecas de código que podrían pertenecer a este nivel. Figura 4.9: Ejemplos de bibliotecas incluídas en el nivel API [ 16 de abril de 2013 at 16:46 – version 1.0 ] 4.2 firmware BSP: Por debajo del nivel API, se ubica la capa BSP (Board Support Package). En este nivel no se implementa código específico a ninguna plataforma, sino que solo se especifican cuáles son las interfaces públicas comunes a los periféricos que habitualmente incluye un microcontrolador. En el BSP, habitualmente se encuentran las interfaces públicas de periféricos como la UART, el ADC, el DAC, el timer, etc. En cada plataforma, el código específico de cada periférico cambia debido a que los registros de configuración disponibles en cada microcontrolador son diferentes. Lo que se mantiene invariante en todos los casos, son las interfaces públicas de uso de dichos periféricos. En la Figura 4.10 se pueden observar ejemplos de interfaces públicas de periféricos. Todas las capas de abstracción que se encuentran por arriba del nivel BSP, utilizan las interfaces públicas definidas en este último. De esta manera, se consigue que tanto el nivel aplicación como el nivel API sean portables a diferentes plataformas de hardware, ya que nunca acceden directamente a los registros de un microcontrolador en particular. Esta técnica de programación, conocida bajo el nombre Programación Orientada a Eventos se pudo comenzar a utilizar en la última década, debido al aumento de recursos disponibles en los microcontroladores modernos. La misma incluye la separación del código en capas de abstracción y el agregado de interfaces de comunicación entre las diferentes capas. Dentro de cada nivel, se ubican diferentes bibliotecas de código que funcionan de manera asincrónica y se comunican con capas superiores a partir de disparar eventos. En este paradigma de programación, el flujo de una aplicación no avanza de manera secuencial sino que avanza de manera concurrente a partir de disparar y procesar eventos. Cabe remarcar que, en el lenguaje de programación estándar C, la herramienta nativa al lenguaje que permite utilizar el paradigma de programación orientada a eventos son los punteros a funciones. Figura 4.10: Ejemplos de interfaces públicas de periféricos en el nivel BSP [ 16 de abril de 2013 at 16:46 – version 1.0 ] 69 70 plataforma de hardware y aplicación Target Boards: Por debajo del nivel BSP, se encuentra cada plataforma particular de hardware. Para cada plataforma particular es necesario implementar la interfaz pública definida en la capa de abstracción BSP. En la Figura 4.8 solo se muestra la plataforma del LPC1769 compuesta por los drivers de NXP y la CMSIS (ambos conceptos se explican en los siguientes párrafos). Si se desea cambiar de plataforma, solo es necesario volver a implementar la interfaz pública definida en el nivel BSP. Todo el código que se encuentre por encima del BSP podrá ser reutilizado automáticamente. Esta es una de las ventajas fundamentales de la estructura de código presentada en este trabajo, ya que permite ahorrar mucho tiempo y dinero, porque los microcontroladores con el paso del tiempo se van descontinuando, y al desarrollar aplicaciones y bibliotecas de código con los conceptos presentados, las mismas resultan ser independientes de la plataforma utilizada y por lo tanto se pueden reutilizar en futuros desarrollos. RTOS: Hoy en día, los RTOS se convirtieron en un componente fundamental en los sistemas embebidos. Cada vez son más las aplicaciones que requieren manejar restricciones temporales realmente duras. En ese tipo de aplicaciones, utilizar un RTOS es prácticamente obligatorio. También, son muchas las aplicaciones que no administran procesos críticos y las restricciones temporales son más suaves. En este tipo de aplicaciones, utilizar un RTOS puede no ser necesario. De todos modos, dada la gran cantidad de recursos que disponen actualmente los microcontroladores, los desarrollados en la práctica siempre utilizan un RTOS. Este último, permite desarrollar aplicaciones que ejecutan tareas concurrentes de manera mucho más fácil, escalable y flexible. Los RTOS disponibles en el mercado, son generalmente independientes de la plataforma de hardware utilizada (e.g. FreeRTOS). Este tipo de RTOS incluyen una capa de portabilidad, que le permiten independizarse del microcontrolador. Esta capa de portabilidad debe ser implementada para cada plataforma específica donde se desee utilizar el RTOS. Por lo general, la portación a las diferentes plataformas de hardware es impulsada por el mismo fabricante del RTOS y pueden ser directamente utilizados en una gran variedad de microcontroladores. En la Figura 4.8 el RTOS se encuentra en paralelo con el nivel BSP ya que, en general, los RTOS implementan su propio BSP para acceder a los recursos específicos que necesitan del microcontrolador. Antes de explicar en detalle el firmware del microcontrolador RTCS y el firmware del microcontrolador de sistemas dinámicos, es necesario hacer una breve introducción a la CMSIS y a los drivers de NXP. La [ 16 de abril de 2013 at 16:46 – version 1.0 ] 4.2 firmware Cortex Microcontroller Software Interface Standard (CMSIS) es otra capa de abstracción impulsada por ARM para sus microcontroladores Cortex[28]. Se trata de una capa de abstracción estándar, independiente de cada vendedor de microcontroladores particulares que utilizan núcleo Cortex Serie M. Este nivel le otorga al usuario del microcontrolador, una biblioteca de código que le permite acceder fácilmente y de manera estándar al núcleo y a los periféricos del mismo. La utilización de la CMSIS en microcontroladores Cortex permite aumentar la reutilización del código, reducir la curva de aprendizaje de desarrollo y acelerar el time-to-market de nuevos microcontroladores. La CMSIS a su vez está divida en la CMSIS de ARM y la CMSIS de NXP. La primera ofrece una interfaz de acceso a los registros y a la funcionalidad del núcleo Cortex ARM del microcontrolador, mientras que la segunda ofrece una interfaz de acceso a los registros y a la funcionalidad de los periféricos provistos por el fabricante NXP. Por otro lado, encima de la CMSIS, el fabricante NXP provee una capa de abstracción de los periféricos del microcontrolador (drivers de NXP). Esta capa de abstracción permite a los usuarios utilizar los periféricos del microcontrolador sin acceder directamente a los registros del mismo. Esto permite simplificar los desarrollos de firmware, acortando considerablemente el tiempo que se insume en la programación de las capas de más bajo nivel. Por último, antes de cerrar esta sección, cabe destacar que en la Figura 4.8 se puede observar un bloque llamado DSPlib. La DSPlib es una biblioteca de código de recursos matemáticos, desarrollada por ARM como parte de la CMSIS. Esta biblioteca de código de recursos matemáticos incluye, entre otras funcionalidades: operaciones entre vectores, operaciones entre matrices, funciones de filtrado y procesamiento de señales, etc. La misma, es utilizada en la libRTCS como se explica en la Sección 4.2.3. Una de las principales ventajas que tiene esta biblioteca matemática para plataformas ARM, es que si el núcleo del microprocesador es un Cortex-M3 las operaciones matemáticas entre variables del tipo float son simuladas por software pero si el núcleo del microprocesador en un Cortex-M4 dichas operaciones matemáticas son automáticamente realizadas por la FPU que este procesador incluye, sin que el programador deba ocuparse de los detalles. Esta es una ventaja muy importante, ya que en el caso de utilizar la libRTCS en un procesador Cortex-M4, todas las operaciones matemáticas que realizan los algoritmos de control son procesadas automáticamente por la FPU. Es decir, al utilizar la DSPlib, se logra reducir considerablemente los tiempos de ejecución de los algoritmos de control más pesados desde un punto de vista matemático y, los mismos, podrían ser utilizados en sistemas que requieren lazos de control de muy altas frecuencias. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 71 72 plataforma de hardware y aplicación 4.2.3 Firmware del microcontrolador RTCS En esta sección se presenta el firmware en particular del microcontrolador RTCS. Cabe resaltar, que el diseño y la implementación de la libRTCS ya fue discutida en el Capítulo 3. A continuación, se presenta la portación de la libRTCS al microcontrolador LPC1769. Como se explicó anteriormente, para validar el funcionamiento de la biblioteca implementada en este trabajo, se utiliza la técnica HIL. La utilización de esta técnica implica desarrollar el firmware de dos microcontroladores: el que ejecuta la biblioteca de algoritmo de control (microcontrolador RTCS) y el que ejecuta los modelos matemáticos de los sistemas dinámicos (microcontrolador de sistemas dinámicos). El desarrollo de dichos firmware están basados en el esquema de código presentado en la Figura 4.8. Para comenzar esta sección, yendo desde lo general hacia los detalles, primero se presenta en la Figura 4.11 el diagrama de flujo general del firmware del microcontrolador RTCS. Figura 4.11: Diagrama de flujo del firmware del microcontrolador RTCS [ 16 de abril de 2013 at 16:46 – version 1.0 ] 4.2 firmware A continuación, se explica en detalle el firmware del microcontrolador RTCS. Para esto se recorre la Figura 4.8 de manera down-top, resaltando las bibliotecas de código incluidas en cada nivel y las interfaces públicas de las mismas. Para estructurar la presentación del firmware, cada bloque de la Figura 4.8 es analizado en una sub-sección aparte. 4.2.3.1 Nivel target board Como se mencionó anteriormente, el fabricante del microcontrolador LPC1769 provee del entorno de desarrollo LPCXpresso. También provee a la CMSIS que es utilizada para acceder de manera simplificada a los registros de los periféricos del microcontrolador y del núcleo del mismo. Esta capa de abstracción, también incluye a la biblioteca de recursos matemáticos DSPlib. Como la libRTCS requiere de una biblioteca de recursos matemáticos, se decide utilizar la DSPlib. En este punto cabe hacer una aclaración relevante. La libRTCS requiere de tres componentes fundamentales para funcionar: El microcontrolador El sistema operativo de tiempo real La biblioteca de recursos matemáticos En el Capítulo 3 se explicó que la libRTCS incorpora el módulo de interfaces para independizarse de un microcontrolador y un RTOS particular. De igual modo, la libRTCS debería poder independizarse de la biblioteca de recursos matemáticos. En el mercado, existen diferentes bibliotecas de recursos matemáticos para el lenaguaje de programación C, que son libres y gratuitas. Estas soluciones se pueden utilizar en sistemas embebidos. Entre ellas podemos resaltar a: BLAS, LAPACK, DSPlib, etc. En este trabajo se decide utilizar la DSPlib porque el algoritmo de control DMC requiere realizar operaciones matriciales. En el Sección A.3 se muestra el detalle de como se utiliza la DSPlib. Es trabajo futuro, implementar una capa de abstracción de la biblioteca de recursos matemáticos, para que el usuario final de la libRTCS pueda elegir que biblioteca particular utilizar. 4.2.3.2 Nivel BSP La libRTCS requiere disponer de un timer del microcontrolador, para medir el tiempo de procesamiento de los algoritmos de control y ejecutar los correspondientes test de schedulability. Por este motivo, a nivel de BSP, se añade la interfaz pública para controlar un timer. Dicha interfaz se presenta en el Código 15 y la implementación de la misma se realiza en particular para el microcontrolador LPC1769 en el nivel target board. [ 16 de abril de 2013 at 16:46 - version 1.0 ] 73 74 plataforma de hardware y aplicación Código 15: Interfaz pública para controlar un timer void Timers_IntervalMeasure_Config (uint8_t timerId); inline void Timers_IntervalMeasure_Start (uint8_t timerId); inline uint32_t Timers_IntervalMeasure_Stop (uint8_t timerId) ; inline uint32_t Timers_IntervalMeasure_GetTime (uint8_t timerId); En el Código 15 se puede observar que la interfaz pública del timer incluye una función de configuración, una función de inicio de la cuenta, una función de fin de la cuenta y una función para obtener el tiempo que transcurrió desde el último inicio de la cuenta. En el LPC1769 se tienen disponibles 4 timers, como lo indica la Tabla 4.2. Por este motivo, todas las funciones definidas reciben como parámetro el id del timer que se desea configurar y utilizar. Por último, cabe aclarar que los timers son configurados para que midan tiempos con precisión del microsegundo. En la Sección 5.1 se muestran los resultados obtenidos al calibrar este módulo de medición de tiempos a partir de utilizar como patrón un osciloscopio digital. A partir de dicha calibración, se obtiene la incerteza absoluta en la medición de tiempos. Por otro lado, para poder validar a la libRTCS, se utiliza la técnica HIL. Esta técnica, como se explicó anteriormente, requiere que dos microcontroladores se comuniquen entre sí. Por este motivo, en el nivel BSP de ambos microcontroladores, también se incluye la interfaz pública pra controlar una UART. Dicha interfaz se presenta en el Código 16 y la implementación de la misma se realiza en particular para el microcontrolador LPC1769 en el nivel target board. Cabe aclarar, que la implementación realizada para el módulo UART soporta tanto el modo de funcionamiento sincrónico como el asincrónico. Código 16: Interfaz pública para controlar una UART int32_t int32_t int32_t int32_t int32_t UART_open (uint8_t* filepath, uint8_t mode); UART_close (int32_t fd); UART_ioctl (int32_t fd, int32_t cmd, void* args); UART_write(int32_t fd, void* buffer, int32_t size); UART_read(int32_t fd, void* buffer, int32_t size); En la Código 16 se puede observar que las funciones implementadas en esta tesis para manejar una UART, respetan el estándar POSIX de manejo de archivos I/O. De esta manera, se abstraen completamente los registros particulares del microcontrolador que hay que manipular para controlar una UART. Al utilizar el estándar POSIX de esta manera, la aplicación no sólo logra independizarse de la plataforma de hardware utilizada sino que también logra independizarse del RTOS utilizado (siempre y cuando este último disponga de una interfaz POSIX). [ 16 de abril de 2013 at 16:46 – version 1.0 ] 4.2 firmware 4.2.3.3 75 Nivel RTOS Como se mencionó anteriormente se utiliza el sistema operativo de tiempo real FreeRTOS. La libRTCS requiere que el RTOS utilizado disponga de un módulo de creación de memoria dinámica, de un módulo de administración de tareas y de un módulo de administración de tiempos. El FreeRTOS incluye todos estos módulos y sus respectivas interfaces públicas son presentadas en el Código 17. Código 17: Interfaz pública del RTOS \\ Dynamic memory interface void* pvPortMalloc (size_t xWantedSize); void vPortFree (void* pv); \\ Task scheduler interface portBASE_TYPE xTaskGenericCreate (pdTASK_CODE pxTaskCode, char* pcName, unsigned short usStackDepth, void* pvParameters, portBASE_TYPE uxPriority, xTaskHandle* pxCreatedTask, portSTACK_TYPE* puxStackBuffer, xMemoryRegion* xRegions); void vTaskDelete( xTaskHandle pxTaskToDelete); \\ Time manager interface void vTaskDelayUntil (portTickType* pxPreviousWakeTime, portTickType xTimeIncrement); 4.2.3.4 Nivel API En el nivel API, se ubican la libRTCS y la libProtocol. El diseño y la implementación de la libRTCS fue presentada en el Capítulo 3. Para utilizar la libRTCS, es necesario hacer la portación al microcontrolador y al RTOS específicos utilizados en la aplicación. Para esto la libRTCS incluye el módulo de interfaces. Dicho módulo está divido en dos interfaces públicas, una presentada en el Código 9 para abstraer al microcontrolador y otra presentada en la Código 10 para abstraer el RTOS. Los recursos básicos que necesita utilizar la libRTCS del microcontrolador y del RTOS están listados a continuación: Microcontrolador: • Timer. • Administrador de memoria dinámica. • Administrador de tareas. • Administrador de tiempos. Para hacer la portación de la libRTCS a una plataforma particular, es necesario que el usuario de la misma configure los punteros a funciones disponibles en el módulo de interfaces a partir de utilizar las [ 16 de abril de 2013 at 16:46 – version 1.0 ] 76 plataforma de hardware y aplicación correspondientes funciones de configuración. Por un lado, a nivel de BSP, se dispone de una interfaz pública que define el comportamiento general de un timer en modo de medición de tiempos. Por otro lado, el FreeRTOS define las interfaces públicas del administrador de memoria, del administrador de tareas y del administrador de tiempos. Tanto la interfaz pública definida en el BSP como las interfaces públicas definidas en el FreeRTOS pueden o no coincidir con el prototipo de los punteros a funciones disponibles en el módulo de interfaces de la libRTCS. Por este motivo, el usuario de la libRTCS debe incluir a nivel de aplicación la correspondiente transformación de prototipos de funciones. Esto se explica con mayor detalle en la Sección 4.2.3.5. La libProtocol es utilizada para abstraer el intercambio de datos entre los dos microcontroladores LPC1769 utilizados para implementar la técnica HIL. Este protocolo utiliza la interfaz pública para controlar una UART especificada en la Sección 4.2.3.2. El protocolo de comunicación implementado entre ambos microcontroladores es muy simple. El mismo cuenta únicamente con un campo de id y un campo de informacion. El campo id representa el número de sistema dinámico al cual se le está enviando información o del cual se está recibiendo información. En función de dicho campo, los microcontroladores ya saben qué cantidad de bytes de información deben enviar o recibir. En la Figura 4.12 se muestra como es una comunicación entre el microcontrolador libRTCS y el microcontrolador de sistemas dinámicos. Figura 4.12: Protocolo de comunicación implementado entre los microcontroladores [ 16 de abril de 2013 at 16:46 – version 1.0 ] 4.2 firmware 77 En el Código 18 se presenta la interfaz pública de la libProtocol implementada. Código 18: Interfaz pública del la libRTCS int32_t debUART_open (uint8_t* filepath, uint8_t mode); int32_t libProtocol_config (int32_t fd, int32_t cmd, void* args); int32_t debUART_write (int32_t fd, int32_t id, void* buffer, int32_t size); int32_t debUART_read (int32_t fd, int32_t id, void* buffer, int32_t size); Cabe resaltar, que la libProtocol desarrollada utiliza una UART configurada en modo sincrónico para realizar el intercambio de información. Se decidió utilizar una comunicación sincrónica, porque la misma es utilizada por el microcontrolador RTCS para enviar y recibir la información del microcontrolador de sistemas dinámicos, simulando de esta manera la acción del ADC y del DAC. 4.2.3.5 Nivel aplicación A nivel de aplicación, se utiliza la libRTCS para implementar un controlador PID y un controlador DMC SISO. En el Capítulo 3 se presentó el diseño y el desarrollo de la libRTCS, pero no se mostró como dicha biblioteca de código de utiliza en una aplicación concreta. Por este motivo, es oportuno presentar el Código 19 en donde se muestra de manera resumida como se utiliza la libRTCS para generar una aplicación concreta. Código 19: Aplicación de la libRTCS int main(void) { ... // RTCS Init int32_t fileDescriptor1; // PID identifier fileDescriptor1 = RTCS_PID_New (); if (fileDescriptor1 >= 0) { RTCS_PID_TData PID1; PID1.RTCS_PID_periodTimeInMS = 1; PID1.RTCS_PID_Kp = 1.5; PID1.RTCS_PID_Ki = 0.2 / (1 / 1000); PID1.RTCS_PID_Kd = 0.5 * (1 / 1000); PID1.RTCS_PID_receiveData = PID1_ReceiveData; PID1.RTCS_PID_sendData = PID1_SendData; ... // Others PID parameters RTCS_PID_Config (fileDescriptor1, RTCS_PID_ConfigData , &PID1); } int32_t fileDescriptor2; // DMC SISO identifier [ 16 de abril de 2013 at 16:46 - version 1.0 ] 78 plataforma de hardware y aplicación fileDescriptor2 = RTCS_DMC_SISO_New (); if (fileDescriptor3 >= 0) { RTCS_DMC_SISO_TData DMC1; DMC1->RTCS_DMC_SISO_step = DMC1_systemStepResponse; DMC1->RTCS_DMC_SISO_N = 80; DMC1->RTCS_DMC_SISO_P = 15; DMC1->RTCS_DMC_SISO_M = 5; PID1.RTCS_PID_receiveData = DMC1_ReceiveData; PID1.RTCS_PID_sendData = DMC1_SendData; ... // Others DMC parameters RTCS_DMC_SISO_Config (fileDescriptor2, RTCS_DMC_SISO_ConfigData, &DMC1); } // Create all RTOS task if (RTCS_tasks_CreateAll ( RTCS_tasks_EnumSchedulingScheme_RMS) == 1) { // Run schedulability test if (RTCS_tasks_RunSchedulerTest ( RTCS_tasks_EnumSchedulabilityTests_RMSbasic) == 1) { // Run controller’s first loop RTCS_system_RunControllersFirstTime (); // Start the RTOS’scheduler RTCS_system_StartRTOSScheduler (); } } } En el Código 19 se puede observar como primero se crean una instancia del controlador PID y una instancia del controlador controlador DMC. Luego, cuando se terminaron de instanciar los controladores, se utiliza la función RTCS_tasks_CreateAll para crear todas las tareas del RTOS necesarias para ejecutar dichos algoritmos de control. Las tareas son asignadas con las prioridades que corresponden según el esquema de scheduling RMS. Posteriormente, se ejecuta el test de schedulability que se corresponde con el esquema de scheduling seleccionado. En la Sección 5.3 se muestran los resultados de aplicar el test de scheduleability, definido por la Ecuación 2.2, en diferentes escenarios de control. Finalmente, se ejecutan las funciones de los controladores que efectuan todas las operaciones previas a que inicien los lazos de control y se da inicio al scheduler del RTOS. Es importante destacar, que a nivel de aplicación, no se accede directamente ni a los registros internos del microcontrolador ni al RTOS sino que se hace a través de la capa de abstracción API. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 4.2 firmware 79 Cabe aclarar, que los prototipos de los punteros a función definidos en la libRTCS puede o no coincidir con la interfaz pública del timer y con la interfaz pública del RTOS utilizados en cada aplicación concreta. Esto se debe a que no todos los programadores utilizan una interfaz pública estándar para las funciones del timer o del RTOS, entonces es necesario realizar una adaptación de funciones. A modo de ejemplo, por un lado en el Código 20 se muestra que el prototipo del puntero a función de la libRTCS que es utilizado para crear tareas no coincide con el prototipo de la correspondiente función del FreeRTOS. Por este motivo, el usuario de la libRTCS debe crear una función intermedia que adapte el prototipo de la función del FreeRTOS al prototipo del correspondiente puntero a función de la libRTCS. Código 20: Diferencias entre los prototipos de la funciones de la libRTCS con el timer y el FreeRTOS // FreeRTOS’s function portBASE_TYPE xTaskGenericCreate (pdTASK_CODE pxTaskCode, char* pcName, unsigned short usStackDepth, void* pvParameters, portBASE_TYPE uxPriority, xTaskHandle* pxCreatedTask, portSTACK_TYPE* puxStackBuffer, xMemoryRegion* xRegions); // libRTCS’s pointer to function extern void (*RTCS_RTOSinterface_TaskCreate) (void (* taskHandler) (void*), void* taskParameters, uint32_t taskPriority, void* taskIdentifier); Por otro lado, en el Código 21 se muestra que el prototipo del puntero a función de la libRTCS que es utilizado para crear memoria dinámica, coincide con el prototipo de la correspondiente función del FreeRTOS. En este caso, el usuario no necesita hacer ninguna adaptación y puede configurar el puntero a función de manera directa. Código 21: Similitudes entre los prototipos de la funciones de la libRTCS con el timer y el FreeRTOS // FreeRTOS’s function void* pvPortMalloc (size_t xWantedSize); // libRTCS’s pointer to function extern void* (*RTCS_RTOSinterface_Malloc) (size_t size); Para terminar de presentar el firmware del microcontrolador RTCS, es necesario explicar cómo se realiza la simulación de diferentes sistemas dinámicos en tiempo de ejecución utilizando la técnica HIL. En el Código 19 se mostró como se utiliza la libRTCS para instanciar un controlador PID y un controlador DMC. Durante la configuración de ambos controladores, se especificaron las funciones que el microcoontrolador RTCS utiliza para enviar y recibir información del microcontrolador de sistemas dinámicos: [ 16 de abril de 2013 at 16:46 – version 1.0 ] 80 plataforma de hardware y aplicación PID1_ReceiveData: Es la función que utiliza el microcontrolador RTCS para recibir datos del microcontrolador de sistemas dinámicos utilizando la libProtocol con id = 1. Como se trata de un PID float recibe 8bytes, 4bytes representan el número real de la referencia y 4bytes representan el número real de la salida en cada instante n de tiempo. PID1_SendData: Es la función que utiliza el microcontrolador RTCS para enviar datos al microcontrolador de sistemas dinámico utilizando la libProtocol con id = 1. Como se trata de un PID float envía 4bytes, que representan el número real de la acción de control en cada instante n de tiempo. DMC1_ReceiveData: Es la función que utiliza el microcontrolador RTCS para recibir datos del microcontrolador de sistema dinámicos utilizando la libProtocol con id = 2. Como se trata de un DMC SISO, al igual que el float PID, recibe 8bytes para la referencia y la salida en cada instante n de tiempo. DMC1_SendData: Es la función que utiliza el microcontrolador RTCS para enviar datos al microcontrolador de sistemas dinámicos utilizando la libProtocol con id = 2. Como se trata de un DMC SISO envía 4bytes, que representan el número real de la acción de control en cada instante n de tiempo. Todas las funciones enumeradas, tienen la misma firma y respetan al prototipo de los punteros a funciones ControllerSendFunction y ControllerReceiveFunction definidos en la estructura de datos del controlador genérico (Código 12). De esta manera, sin modificar el código particular de cada algoritmo de control, el usurio de la biblioteca puede especificar que funciones se encargan de enviar y obtener datos del sistema dinámico (mediante un protocolo de comunicación, mediante un ADC y un DAC, etc.). 4.2.4 Firmware del microcontrolador de sistemas dinámicos En esta sección se presenta el firmware en particular del microcontrolador de sistemas dinámicos. Cabe aclarar que este firmware es una herramienta auxiliar para validar a la libRTCS. Al igual que en el caso del firmware del microcontrolador RTCS, la presentación del firmware del microcontrolador de sistemas dinámicos se basa en el esquema de código de la Figura 4.8. Es importante resaltar, que los modelos matemáticos de los diferentes sistemas dinámicos están representados mediante ecuaciones de recurrencia que evolucionan en cada vuelta del correspondiente lazo de control. En la Figura 4.13 se presenta el diagrama de flujo del firmware del microcontrolador de sistemas dinámicos. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 4.3 conclusiones Figura 4.13: Diagrama de flujo del firmware del microcontrolador de sistemas dinámicos El firmware del microcontrolador de sistemas dinámicos es más simple que el firmware del microcontrolador RTCS. Para no repetir la explicación realizada en la Sección 4.2.3, se hace una breve mención de cómo está compuesto el firmware de este microcontrolador. En el nivel de BSP se incluye el driver para manejar la UART y en el nivel de API se incluye la libProtocol. En este caso la libProtocol se configura de manera asincrónica, ya que el que marca los tiempos y funciona como dispositivo maestro es el microcontrolador RTCS. Esto es así, porque el RTOS está ejecutandose en este último microcontrolador. Para que las simulaciones sean realizadas en tiempo real es necesario que todos los tiempos sean impuestos por el RTOS. De esta manera, el microcontrolador de sistemas dinámicos envía información, recibe información y avanza las ecuaciones de recurrencia solo cuando el microcontroaldor RTCS lo indica. 4.3 conclusiones En este capítulo, primero se presentó la plataforma de hardware que se utiliza en este trabajo. Luego, se presentó el diseño y la implementación de la plataforma de hardware que permite utilizar la técnica HIL para validar a la libRTCS. Finalmente, se presenta la estructura general de firmware para microcontroladores y la aplicación de la misma al caso concreto de esta tesis. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 81 [ 16 de abril de 2013 at 16:46 – version 1.0 ] 5 R E S U LTA D O S O B T E N I D O S En este capítulo, se realiza la validación de los diferentes algoritmos de control implementados y se analiza el desempeño general de la libRTCS. Para esto, se utiliza la portación realizada, en el Capítulo 4, de la libRTCS al microcontrolador LPC1769. Para validar los algoritmos de control implementados se utiliza la técnica HIL sobre la plataforma de hardware desarrollada, que también fue presentada en el Capítulo 4. La emulación de diferentes plantas se ejecutan sobre la plataforma de hardware desarrollada, en tiempo real. Para poder mostrar que realmente los puntos obtenidos para las señales son en tiempo real, se utiliza el módulo de medición de intervalos de tiempo desarrollado para el LPC1769 en la Sección 4.2.3.2. Todos los puntos de las señales procesadas son marcados con un valor de tiempo absoluto. De esta manera, el eje horizontal de los gráficos simulados en tiempo real no son en función del número de muestra sino que son realmente en función del tiempo. Para determinar la precisión con la cual se están realizados las mediciones temporales, se hace previamente una validación del módulo de medición de intervalos de tiempo. Para realizar dicha validación, se comparan los tiempos de diferentes eventos medidos con el LPC1769 con los tiempos medidos con un osciloscopio digital. Cabe resaltar, que las mediciones de tiempos también son útiles para medir el tiempo de procesamiento de los diferentes algoritmo de control. Luego de validar el módulo de medición de intervalos de tiempo, se validan los algoritmos de control que fueron implementados en este trabajo: PID con precisión float, PID con precisión double y DMC SISO con precisión float. Para realizar la validación, se comparan los resultados obtenidos al ejecutar los algoritmo de control en tiempo real sobre la plataforma de hardware desarrollada con los resultados obtenidos al simular los mismos algoritmos de control en Matlab. Por último, se presentan diferentes resultados que permiten analizar el desempeño general de la biblioteca libRTCS sobre un procesador Cortex-M3: Memoria de programa consumida por la libRTCS. Memoria de programa libre. Memoria dinámica consumida por los diferentes algoritmos de control de la libRTCS. Memoria de variables libre. 83 [ 16 de abril de 2013 at 16:46 – version 1.0 ] 84 resultados obtenidos Tiempo de procesamiento consumido por el algoritmo de control PID float. Máxima frecuencia posible en el lazo de control para el algoritmo PID float. Tiempo de procesamiento consumido por el algoritmo de control PID double. Máxima frecuencia posible en el lazo de control para el algoritmo PID double. Tiempo de procesamiento consumido por el algoritmo de control DMC SISO float. Máxima frecuencia posible en el lazo de control para el algoritmo DMC SISO float. Diferentes esquemas de control concurrentes que pasan el test de schedulability básico RMS. 5.1 validación del módulo de medición de intervalos de tiempo El módulo de medición de intervalos de tiempo desarrollado para el LPC1769 en la Sección 4.2.3.2, está diseñado para tener una resolución teórica en el orden del microsegundo. Para poder contrastar el diseño de este módulo con la realidad y poder determinar de esta manera la incerteza que tienen las mediciones de intervalos de tiempo, se realiza un experimento muy simple. Se hace que el LPC1769 cambie el estado de un pin de manera periódica. Dicho período es medido por el LPC1769 y mediante un osciloscopio digital de ancho de banda 25MHz. Este proceso de medición se repite para diferentes periodos y se confecciona la Tabla 5.1. n° lpc1769 osciloscopio diferencia 1 2us 2,5us 0,5us 2 10us 10,3us 0,3us 3 20us 20,7us 0,7us 4 220us 220us 0us 5 1100us 1100us 0us 6 2200us 2200us 0us Tabla 5.1: Medición de intervalo de tiempos . [ 16 de abril de 2013 at 16:46 – version 1.0 ] 5.2 validación de los algoritmos de control implementados A partir de la Tabla 5.1 se determina que el error absoluto en la medición de intervalos de tiempo es de ±1us. De esta manera queda definida la incerteza en las marcas temporales de las simulaciones en tiempo real. A partir de dichas marcas temporales, se realizan gráficos en función de un valor temporal absoluto. Por último, cabe resaltar, que el valor del tiempo obtenido en el LPC1769 es en microsegundos y es almacenado en un entero no signado de 32 bits. Utilizando únicamente dicha variable se logra obtener el máximo tiempo que podría durar un experimento antes de que se produzca un overflow en este indicador de tiempos: Tmax = (232 − 1)us = 71,6minutos (5.1) Como los tiempos de duración de las emulaciones realizadas en este trabajo son inferiores a 71,6minutos, este sistema de medición de intervalos de tiempos es suficiente para generar un eje absoluto de tiempo. 5.2 validación de los algoritmos de control implementados En esta sección se realiza la validación de los diferentes algoritmos de control implementados en la libRTCS. Primero, en la Sección 5.2.1 se presenta el esquema general de validación de los algoritmos de control. Luego, en la Sección 5.2.2 se presentan los sistemas dinámicos discretos que se utilizan para realizar las emulaciones. Finalmente, en la Sección 5.2.3 se presentan los resultados obtenidos al ejecutar los diferentes algoritmos de control tanto en Matlab como en el LPC1769 y se realiza una comparación de los mismos. 5.2.1 Esquema general de validación Para realizar la validación de los algoritmos de control implementados en este trabajo, se utiliza la técnica de validación Hardware In the Loop (HIL) y la plataforma de hardware desarrollada en la Sección 4.1. En la Figura 5.1 se presenta un esquema que resume el procedimiento utilizado. Luego se presenta el detalle de cada etapa de dicho procedimiento. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 85 86 resultados obtenidos Figura 5.1: Esquema del procedimiento de validación de los algoritmos de control 1. Primero se define una ecuación en recurrencias que representa a un sistema dinámico discreto. Sobre este punto conviene hacer una aclaración: el objetivo principal de este trabajo es implementar una biblioteca de algoritmos de control para sistemas embebidos, que permita implementar sistemas de control de tiempo real. Para cumplir con dicho objetivo, es necesario validar los diferentes algoritmos de control implementados. Pero para esto, no resulta relevante conocer el sistema dinámico continuo del cual proviene la ecuación de recurrencias, ni tampoco resulta relevante conocer el método de discretización utilizado. Asímismo, tampoco es importante realizar una comparación sobre el desempeño que diferentes algoritmos de control tienen sobre el mismo sistema dinámico discreto. Es decir, en este trabajo solo se pone énfasis en determinar si cada algoritmo de control tiene un correcto funcionamiento. La elección de que algoritmo de control utilizar para un determinado sistema dinámico será luego realizada por el usuario de la libRTCS. De todos modos, en la Sección 5.2.2 se presentan los sistemas dinámicos discretos utilizados para realizar las validaciones y se justifica la elección de los mismos. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 5.2 validación de los algoritmos de control implementados 2. Se selecciona una frecuencia para el lazo de control. Cabe destacar que durante el proceso de validación, se utilizan diferentes frecuencias para los lazos de control para analizar como responde en tiempo real la libRTCS. Las frecuencias de los lazos de control utilizadas en este trabajo son valores que habitualmente se aplican para controlar sistemas dinámicos físicos y están comprendidos en en rango que varía aproximadamente desde 10Hz hasta 1KHz. Algunos procesos industriales utilizan frecuencias para el lazo de control más bajas. Estos casos industriales no son criticos para los sistemas de control de tiempo real porque las restricciones temporales son más relajadas al utilizar frecuencias de lazo más bajas. Por otro lado, algunas aplicaciones particulares requieren frecuencias mayores para el lazo de control, pero no son analizadas en este trabajo. A modo de ejemplo, la aplicación particular del control automático de un quadrotor, utiliza lazos de control que van desde los 50Hz hasta los 400Hz. 3. Se realiza una simulación en tiempo no real en Matlab del conjunto sistema dinámico discreto - algoritmo de control. Esta simulación es utilizada como patrón para poder determinar posteriormente, si el algoritmo de control simulado en tiempo real en el LPC1769 funciona correctamente. Los algoritmos de control implementados en Matlab son obtenidos a partir de la teoría presentada en la Sección 2.2 y son presentados en la Sección A.1 y en la Sección A.2. Es importante aclarar que el término tiempo no real implica que la simulación en Matlab es ejecutada sin tener en cuenta la variable temporal, es decir, sin respetar la frecuencia del lazo de control. Por otro lado, el término tiempo real implica que la simulación en el LPC1769 es realizada teniendo en cuenta la variable tempora y respetando estrictamente la frecuencia del lazo de control. 4. Se realiza una validación en tiempo real del conjunto sistema dinámico discreto - algoritmo de control. Para realizar la validación en tiempo real se utiliza la plataforma de hardware desarrollada. Como se explicó en la Sección 4.1, en el microcontrolador de sistemas dinámicos se ejecuta la ecuación de recurrencias que define al sistema dinámico. Por otro lado, en el microcontrolador RTCS se ejecuta la libRTCS con una instancia del algoritmo de control que se quiere valida. Mediante una comunicación UART, entre los microcontroladores, se intercambian las señales de salida, de referencia y de control para cada instante de tiempo. El tiempo es controlado por el RTOS y los puntos de las señales obtenidas son marcadas con un valor absoluto de tiempo. Al finalizar la simulación, la señal de referencia, la señal de salida y la señal de control son extraídas del microcontrolador RTCS y llevadas a diferentes gráficos. Cabe aclarar, que en este caso se [ 16 de abril de 2013 at 16:46 – version 1.0 ] 87 88 resultados obtenidos utilizan los correspondientes algoritmos de control implementados en el lenguaje de programación C. Estos códigos son presentados en la Sección A.4 y en la Sección A.5. 5. Se realiza una comparación entre las señales obtenidas en tiempo no real en Matlab y en tiempo real en el LPC1769. Para hacer esta comparación se grafican las señales de referencia, de salida y de control obtenidas tanto en Matlab como en el LPC1769. 6. Se analiza el tiempo de procesamiento y el tiempo de computo del algoritmo de control que se ejecuta en la plataforma de tiempo real. En la Sección 5.2.1.1 se recuerda la definición del tiempo de procesamiento y del tiempo de computo. En la misma, se explica porque es importante medir y analizar estos tiempos. 5.2.1.1 Importancia del tiempo de procesamiento y del tiempo de computo Cabe resaltar, que a partir de analizar el tiempo de procesamiento del algoritmo de control, es posible determinar la máxima frecuencia a la cual puede ejecutarse el lazo de control. Según la bibliografía, por ejemplo [29], para que el desempeño de un algoritmo de control digital no se vea degrado es necesario que el tiempo de computo (también conocido como retardo de computo) sea por lo menos 20 veces menor que el período del lazo de control. El tiempo de computo está definido según la Ecuación 5.2. A partir de utilizar esta relación práctica, se puede encontrar para cada algoritmo de control una máxima frecuencia de ejecución:. τ = TADC + TAlgoritmo + TDAC (5.2) Para aclarar como este criterio práctico es utilizado, se presenta un ejemplo numérico. Suponiendo que el tiempo computo de un algoritmo de control resulta resulta ser 30us, entonces según la Ecuación 5.2 se obtiene: f lazo ≤ f max = 1 1 = = 1,67KHz 20τ 20 × 30 × 10−6 (5.3) La Ecuación 5.2 es utilizada en la Sección 5.3 para determinar la máxima frecuencia de ejecución de los diferentes algoritmos de control en el LPC1769. Es importante destacar, que en función de la plataforma de hardware utilizada estas frecuencias cambian. 5.2.2 Sistemas dinámicos discretos utilizados Cada algoritmo de control implementado en este trabajo es validado a partir de utilizar dos sistemas dinámicos discretos diferentes. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 5.2 validación de los algoritmos de control implementados 89 Por un lado, el primer sistema dinámico se define a partir de la ecuación de recurrencia presentada en la Ecuación 5.4 y su respectiva respuesta al escalón (a lazo abierto) se presenta en la Figura 5.2. Por otro lado, el segundo sistema dinámico se define a partir de la ecuación de recurrencia presentada en la Ecuación 5.5 y su respectiva respuesta al escalón (a lazo abierto) se presenta en la Figura 5.3. y[n] = 0,8351y[n − 1] + 0,2713x [n − 2] (5.4) Figura 5.2: Respuesta al escalón del primer sistema dinámico a lazo abierto y[n] = 1,9598 ∗ y[n − 1] − 0,9608 ∗ y[n − 2] + 0,0201 ∗ x [n − 1] − 0,0191 ∗ x [n − 2] (5.5) Figura 5.3: Respuesta al escalón del segundo sistema dinámico a lazo abierto [ 16 de abril de 2013 at 16:46 – version 1.0 ] 90 resultados obtenidos En la Ecuación 5.4 y en la Ecuación 5.5, y[n] es la salida del sistema, x [n] es la entrada del sistema y n es el tiempo discreto. Es importante destacar, que en todos los gráficos presentados en las siguientes secciones en los cuales se representen señales de salida, señales de referencia y señales de control, los ejes verticales de los mimos utilizan unidades adimensionales. El primer sistema dinámico es incluído en este trabajo, porque se encontró en la bibliografía [30], que otros trabajos también lo utilizan para analizar el desempeño del algoritmo de control DMC SISO. El segundo sistema dinámico fue seleccionado indistintamente, procurando que no incluya retardos entre la entrada y la salida para simplificar los análisis de los resultados. Ambos sistemas dinámicos son utilizados para realizar la validación de todos los algoritmos de control implementados en este trabajo. Cabe aclarar, que también hubiese sido útil cualquier otro sistemas dinámico para realizar la validación. 5.2.3 Resultados de la validación de los algoritmos de control En esta sección se presentan los resultados del proceso de validación de los diferentes algoritmos de control implementados en este trabajo para la libRTCS. Los mismos se enumeran a continuación: 1. PID de precisión float 2. PID de precisión double 3. DMC SISO de precisión float Cabe aclarar que en el lenguaje de programacion C, la precisión float implica utilizar 4bytes para representar números reales en punto flotante (precisión simple) mientras que la precisión double implica utilizar 8bytes para representar números reales en punto flotante (precisión doble). En este trabajo, se pretenden comparar los resultados obtenidos al implementar y ejecutar un mismo algoritmo de control primero con precisión float y luego con precisión double. Por este motivo, el algoritmo de control PID es implementado con ambas precisiones. En particular, se quiere comparar para el algoritmo de control PID las diferencias en los tiempos de procesamiento de los algoritmos ya que las diferencias en cuanto a consumo de memoria de variables no resultan significativas. Esto es así porque las operaciones matemáticas que realiza el algoritmo de control del PID son simples y no necesita almacenar ni matrices ni vectores de datos. En cambio, este proceso no es repetido para el algoritmo de control DMC SISO, ya que el mismo realiza cuentas matriciales que consumen considerablemente más tiempo y más recursos de memoria que el PID. Por este motivo, para el caso DMC SISO solo se hace la implementación para el caso de precisión float. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 5.2 validación de los algoritmos de control implementados Por último, es importante resaltar, que para todas las validaciones presentadas a continuación se utiliza el procedimiento presentado en la Figura 5.1. 5.2.3.1 Resultados de la validación del algoritmo de control PID de precisión float para el primer sistema dinámico Para realizar la validación de este algoritmo de control, se utiliza el primer sistema dinámico definido por la Ecuación 5.4. Para esto, dicho sistema dinámico es controlado, por un lado en Matlab mediante el algoritmo PID presentado en Sección A.1 y por otro lado en el LPC1769 mediante el algoritmo PID presentado en Sección A.4. La frecuencia seleccionada para el lazo de control es 1KHz. El tiempo de las simulaciones es de 0,5s, con lo que se obtiene un total de 500 muestras para cada señal involucrada. Los parámetros del PID utilizados para realizar las simulaciones son presentados en la Tabla 5.2. parámetro descripción valor Kp Constante proporcional 1,5 Ki Constante integrativa 200 Kd Constante derivativa 0 N Limitación acción derivativa 20 h Período de muestreo [s] 0,001 b Factor de referencia 1 LowOutputLimit Limitador inferior −10 HighOutputLimit Limitador superior 10 Tabla 5.2: Parámetros del PID float para el primer sistema dinámico utilizado. Los parámetros presentados en la Tabla 5.2 son elegidos de manera tal que el controlador mejore la respuesta del sistema dinámico, frente a una determinada referencia, en algún sentido. Por ejemplo, se busca que el conjunto sistema dinámico - controlador haga un correcto seguimiento de referencia, que el tiempo de establecimiento sea menor, que el sobrepico sea menor, etc. Cabe aclarar, que en esta sección no se pretende estudiar el ajuste de los parámetros de los controladores sino que se busca validar el funcionamiento de los diferentes algoritmos de control implementados. En la Figura 5.4 se presenta, a la izquierda los resultados obtenidos al realizar la simulación en tiempo no real en Matlab y a la derecha los resultados obtenidos al realizar la simulación en tiempo real en el LPC1769. En esta figura, se grafican en simultáneo la referencia, la sa- [ 16 de abril de 2013 at 16:46 – version 1.0 ] 91 92 resultados obtenidos lida obtenida sin controlador y la salida obtenida con controlador. En la misma, no se pueden observar diferencias apreciables en las formas de las señales. Cabe resaltar, que el eje horizontal del gráfico ubicado a la izquierda es en función del número de muestras, mientras que el eje horizontal del gráfico ubicado a la derecha es en función del tiempo. Esta es una diferencia fundamental entre los dos gráficos y para lograrla, cada muestra obtenida en el LPC1769 es marcada con un valor temporal absoluto. Para resaltar la diferencia entre los dos gráficos, se presenta la Tabla 5.3. En esta tabla se muestra, para 10 instantes de tiempo los valores de las salidas con su respectivos números de muestra obtenidos en Matlab y los valores de las salidas con su respectivos valores temporales obtenidos en el LPC1769. En la Tabla 5.3 se puede observar, en la columna Tiempo LPC1769, que la libRTCS está respetando el tiempo del lazo de control de 1ms pero con una incerteza de 1us en el último dígito. Esta incerteza es la obtenida en el Sección 5.1, para el módulo de medición de intervalos de tiempo. Figura 5.4: A la izquierda la salida simulada en Matlab y a la derecha la salida en tiempo real simulada en el LPC1769 para el primer sistema dinámico y el PID float [ 16 de abril de 2013 at 16:46 – version 1.0 ] 5.2 validación de los algoritmos de control implementados n° matlab salida matlab tiempo lpc1769 salida lpc1769 [U.A.] [ms] [U.A.] 7 1.332754 7.001 1.332755 8 1.148701 8.001 1.148701 9 0.954870 9.001 0.954870 10 0.812564 10.000 0.812564 11 0.750569 11.000 0.750570 12 0.769609 12.000 0.769610 13 0.845869 13.000 0.845870 14 0.944953 14.000 0.944953 15 1.033483 15.000 1.033484 16 1.088882 16.001 1.088883 [muestra] Tabla 5.3: Diferencias entre las señales obtenidas en Matlab y en el LPC1769 . En la Figura 5.5 se grafica las diferencias entre la salida obtenida en matlab y la salida obtenida en el LPC1769. En el mismo se observa que la máxima diferencia obtenida es del orden de 6 × 10−7 . Esta pequeña diferencia se debe a principalmente a dos factores, por un lado que en Matlab se utiliza por defecto el tipo de dato double y por otro lado las diferencias en la implementación de los tipos de datos en el Matlab y en el LPC1769. Figura 5.5: Comparación de la salida simulada y la salida en tiempo real para el primer sistema dinámico y el PID float [ 16 de abril de 2013 at 16:46 – version 1.0 ] 93 94 resultados obtenidos A partir de los resultados obtenidos en el gráfico de la Figura 5.4 y la Figura 5.5, se puede afirmar que las diferencias obtenidas son despreciables y que algoritmo implementado en el LPC1769 y ejecutado en tiempo real devuelve los mismos resultados que el algoritmo patrón desarrollado en Matlab. En la Figura 5.6 se grafica también la acción de control obtenida. A la izquierda se presenta la simulación atemporal realizada en Matlab y a la derecha se presenta la simulación en tiempo real realizada en el LPC1769. En este gráfico, tampoco se observar diferencias apreciables en la forma de las señales. Figura 5.6: A la izquierda la acción de control simulada en Matlab y a la derecha la acción de control en tiempo real simulada en el LPC1769 para el primer sistema dinámico del PID float En la Figura 5.7 se presentan las diferencias obtenidas entre la acción de control obtenida en Matlab y la acción de control obtenida en el LPC1769. También se observa que el máximo error obtenido es del orden de 6 × 10−7 . Este error resulta ser despreciable frente a los valores de las señales involucradas. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 5.2 validación de los algoritmos de control implementados Figura 5.7: Comparación de la acción de control simulada en Matlab y la acción de control simulada en tiempo real en el LPC1769 para el primer sistema dinámico y para el PID float Por último, en la Figura 5.8 se presenta a la izquierda el tiempo de computo del controlador PID float (definido por la Ecuación 5.2) y a la derecha el tiempo de procesamiento del mismo controlador. Ambos gráficos son obtenidos a partir de los datos de tiempo real en el LPC1769. Figura 5.8: A la izquierda el tiempo de computo y a la derecha el tiempo de procesamiento del algoritmo PID float para el primer sistema dinámico en el LPC1769 Los resultados obtenidos en los gráficos de la Figura 5.8 son los esperados. El tiempo de procesamiento del algoritmo de control PID se espera que sea constante, ya que la cantidad de operaciones que realizada el algoritmo en cada iteración son las mismas. Es decir, el tiempo de procesamiento es independiente de los parámetros de la planta a controlar y también es independiente de los datos procesados en cada iteración del algoritmo. La única bifurcación en el código que tiene [ 16 de abril de 2013 at 16:46 – version 1.0 ] 95 96 resultados obtenidos el algoritmo de control PID son los condicionales que implementan el anti-windup. Pero en caso de activarse el anti-windup solo se ejecuta una instrucción más, lo cual tampoco modifica considerablemente el tiempo de ejecución del algoritmo. Esta conclusión está corroborada por el gráfico a la derecha de la Figura 5.8. El peor tiempo de ejecución del algoritmo PID float es de 8us y en algunos puntos dicho tiempo baja a 7us. La pequeña variación observada está dentro de la incerteza en la medición de los tiempos obtenida en la Sección 5.1. Por otro lado, en el gráfico de la izquierda de la Figura 5.8 se puede observar el retardo de computo en cada iteración del algoritmo. El retardo de cómputo también es constante y resulta ser mayor que el tiempo de procesamiento del algoritmo. Este resultado también es esperado porque el retardo de computo incluye el tiempo de ADC y el tiempo de DAC. Dichos tiempos, en este trabajo, están simulados por el retardo que impone la comunicación UART entre ambos microcontroladores. Es decir, como ya se explicó, no hay ni DAC ni ADC. Los mismos son emulados mediante la comuniacción acUART. 5.2.3.2 Resultados de la validación del algoritmo de control PID de precisión float para el segundo sistema dinámico En la Sección 5.2.3.1 se utilizó el primer sistema dinámico definido por la Ecuación 5.4 para validar el PID de precisión float. En esta sección, se utiliza el segundo sistema dinámico definido por la Ecuación 5.5. Para realizar la validación, el segundo sistema dinámico es controlado, por un lado en Matlab mediante el algoritmo PID presentado en Sección A.1 y por otro lado en el LPC1769 mediante el algoritmo PID presentado en Sección A.4. La frecuencia seleccionada para el lazo de control es 100Hz. Como se mencionó en la Sección 5.2.1, para las diferentes validaciones se utilizan distintas frecuencias para los lazos de control, con el objetivo de cubrir el rango de frecuencias habitualmente utilizados en la práctica y observar como se comporta la libRTCS en dicho rango. El tiempo de las simulaciones es de 5s, con lo que se obtiene un total de 500 muestras por cada señal involucrada. Los parámetros del PID utilizados para realizar las simulaciones son presentados en la Tabla 5.4. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 5.2 validación de los algoritmos de control implementados parámetro descripción valor Kp Constante proporcional 2,6 Ki Constante integrativa 8 Kd Constante derivativa 0,1 N Limitación acción derivativa 20 h Período de muestreo 0,01 b Factor de referencia 1 LowOutputLimit Limitador inferior −10 HighOutputLimit Limitador superior 10 Tabla 5.4: Parámetros del PID float para el segundo sistema dinámico utilizado. En los parámetros presentados en la Tabla 5.4, también son elejidos de manera tal que el controlador mejore la respuesta del sistema dinámico, frente a una determinada referencia, en algún sentido. Es importante destacar nuevamente, que durante la validación de los diferentes algoritmos de control no se pretende estudiar el ajuste de los parámetros de los mismos. En la Figura 5.9 se presentan las señales obtenidas a partir de realizar la simulación en tiempo no real en Matlab y a partir de realizar la simulación en tiempo real en el LPC1769. En este gráfico tampoco se puede observar una diferencia apreciable en la forma de las señales obtenidas en Matlab y en el LPC1769. En la Figura 5.10, se puede observar, que la diferencia entre la señal de salida obtenida en matlab y la señal de salida obtenida en el LPC1769 representa un error despreciable frente los valores de las señales involucradas. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 97 98 resultados obtenidos Figura 5.9: A la izquierda la salida simulada en Matlab y a la derecha la salida en tiempo real simulada en el LPC1769 para el segundo sistema dinámico y el PID float Figura 5.10: Comparación de la salida simulada y la salida en tiempo real para el segundo sistema dinámico y el PID float En el gráfico de la Figura 5.12 se presenta la comparación de las acciones de control obtenidas al realizar la simulación en Matlab y al realizar la simulación en tiempo real en el LPC1769. En este gráfico tampoco se puede observar una diferencia apreciable en la forma de las señales involucradas. Por otro lado, en el gráfico de la Figura 5.12 se vuelve a obtener un error despreciable frente a los valores de las diferentes señales. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 5.2 validación de los algoritmos de control implementados Figura 5.11: A la izquierda la acción de control simulada en Matlab y a la derecha la acción de control en tiempo real simulada en el LPC1769 para el segundo sistema dinámico del PID float Figura 5.12: Comparación de la acción de control simulada en Matlab y la acción de control simulada en tiempo real en el LPC1769 para el segundo sistema dinámico y para el PID float Por último, en el gráfico de la Figura 5.13 se presenta a la izquierda el tiempo de computo del algoritmo de control y a la derecha el tiempo de procesamiento del mismo. Los resultados obtenidos son similares a los presentados en el gráfico de la Figura 5.8. De todos modos, si se compara el gráfico de la derecha de la Figura 5.8 con el gráfico de la derecha de la Figura 5.13, se puede observar que en el primero el tiempo de procesamiento varía entre 7us y 8us, mientras que en el segundo [ 16 de abril de 2013 at 16:46 – version 1.0 ] 99 100 resultados obtenidos varía entre 8us y 9us. Esto se debe a la incerteza que tiene el módulo de medición de intervalos de tiempo. A partir de estos resultados se puede concluir que el tiempo de procesamiento del algoritmo de control PID de precisión float es de (8 ± 1) us. Figura 5.13: A la izquierda el tiempo de computo y a la derecha el tiempo de procesamiento del algoritmo PID float para el segundo sistema dinámico en el LPC1769 A partir de los resultados obtenidos para el PID float, tanto utilizando el primer sistema dinámico como el segundo sistema dinámico, se puede concluir que el algoritmo implementado en la libRTCS y ejecutado en el LPC1769 queda validado respecto al algoritmo patrón desarrollado en Matlab. 5.2.3.3 Resultados de la validación del algoritmo de control PID de precisión double para el primer sistema dinámico y para el segundo sistema dinámico En esta sección, se repiten las simulaciones realizadas tanto para el primer sistema dinámico definido por la Ecuación 5.4 como para el segundo sistema dinámico definido por la Ecuación 5.5, pero utilizando el tipo de dato double en el LPC1769. Cabe recordar, que el tipo de dato float utiliza 4bytes para representar números reales en punto flotante (precisión simple) y que el tipo de dato double utiliza 8bytes para representar números reales en punto flotante (precisión double). El objetivo de esta sección es analizar las diferencias que existen en cuanto a precisión y tiempo de ejecución al utilizar el tipo de dato double en lugar del tipo de dato float. Se espera que, para el tipo de dato dou- [ 16 de abril de 2013 at 16:46 – version 1.0 ] 5.2 validación de los algoritmos de control implementados ble, las diferencias entre las señales obtenidas mediante simulación en tiempo no real en Matlab y las señales obtenidas mediante simulación en tiempo real en el LPC1769 sean menores respecto de los resultados obtenidos para el tipo de dato float. También se espera que el tiempo de procesamiento en el LPC1769 aumente, porque en el caso de precisión double las operaciones matemáticas consumen más tiempo. Por último, también se espera que el tiempo de computo también aumente en el LPC1769, porque en este caso el intercambio de señales entre el microcontrolador RTCS y el microcontrolador de sistemas dinámicos implica el doble de bytes. Para el primer sistema dinámico, se realiza la validación del PID de precisión doble, utilizando nuevamente una frecuencia del lazo de control de 1KHz, un tiempo de simulación de 0,5s, 500 muestras para las señales involucradas y los mismos parámetros para el controlador PID que los presentados en la Tabla 5.2. Para no repetir todas las figuras presentadas en la Sección 5.2.3.1 se presentan los resultados más relevantes en la Tabla 5.5. parámetro valor Diferencia máxima entre la salida en Matlab y en el LPC1769 5 × 10−7 Diferencia máxima entre la acción de control en Matlab y en el LPC1769 5 × 10−7 Tiempo de procesamiento máximo (13 ± 1) us Tiempo de computo máximo (50 ± 1) us Tabla 5.5: Resultados obtenidos al realizar la validación del algoritmo de control PID double en el LPC1769 para el primer sistema dinámico. Comparados los resultados obtenidos en la Sección 5.2.3.1 con la tabla Tabla 5.5, se puede observar que la diferencia entre los valores de las señales en Matlab y los valores de las señales en el LPC1769 prácticamente no disminuyó. La misma paso de ser 6 × 10−7 en el PID float a ser 5 × 10−7 en el PID double. Por otro lado, lo que si aumento de manera más apreciable es el tiempo de procesamiento y como consecuencia el tiempo de compunto. Para el mismo sistema dinámico, el tiempo de procesamiento para el PID float es en el peor caso de funcionamiento (8 ± 1) us mientras que el tiempo de procesamiento para el PID double es en el peor caso (13 ± 1) us. Por otro lado, el tiempo de computo para el PID float es en el peor caso de funcionamiento (26 ± 1) us mientras que en PID double es en el peor caso de funcionamiento (50 ± 1) us. Se puede observar que el aumento en el tiempo de computo para el PID double es mayor que el aumento en el tiempo de procesamiento para el mismo algoritmo. Esto se debe a que la cantidad de bytes que se in- [ 16 de abril de 2013 at 16:46 – version 1.0 ] 101 102 resultados obtenidos tercambian mediante la simulación HIL entre el microcontrolador RTCS y el microcontrolador de sistemas dinámicos aumenta al doble, ya que el tipo de dato double consume el doble de memoria. También para el segundo sistema dinámico, se realiza la validación del PID de precisión doble, utilizando nuevamente una frecuencia del lazo de control de 100Hz, un tiempo de simulación de 5s, 500 muestras para las señales involucradas. Para no repetir todas las figuras presentadas en la Sección 5.2.3.2 se presentan los resultados más relevantes en la Tabla 5.6. parámetro valor Diferencia máxima entre la salida en Matlab y en el LPC1769 5 × 10−7 Diferencia máxima entre la acción de control en Matlab y en el LPC1769 5 × 10−7 Tiempo de procesamiento máximo (15 ± 1) us Tiempo de computo máximo (54 ± 1) us Tabla 5.6: Resultados obtenidos al realizar la validación del algoritmo de control PID double en el LPC1769 para el segundo sistema dinámico. Comparados, en este caso, los resultados obtenidos en la Sección 5.2.3.2 con la tabla Tabla 5.6, se puede observar que la diferencia entre los valores de las señales en Matlab y los valores de las señales en el LPC1769 disminuyó de manera más notoria. La misma paso de ser 2 × 10−6 en el PID float a ser 5 × 10−7 en el PID double. Por otro lado, también se observa que aumentó el tiempo de procesamiento y como consecuencia el tiempo de compunto. En conclusión, los resultados obtenidos en esta sección son los esperados. Al aumentar la precisión del tipo de dato utilizado para realizar las operaciones matemáticas, la diferencia entre las señales obtenidas en tiempo no real en Matlab y las señales obtenidas en tiempo real en el LPC1769 disminuyó a expensas de aumentar el tiempo de computo y el tiempo de procesamiento. Se observa que la pequeña disminución en la diferencia entre las señales presentadas en la tab:resultadosPIDdouble1 y en la tab:resultadosPIDdouble1 no justifica el aumento más representativo que se produce en el tiempo de computo. Por este motivo, para el algoritmo de control DMC SISO solo se utiliza el tipo de dato float. 5.2.3.4 Resultados de la validación del algoritmo de control DMC SISO de precisión float para el primer sistema dinámico Para realizar la validación de este algoritmo de control, se utiliza el primer sistema dinámico definido por la Ecuación 5.4. Para esto, di- [ 16 de abril de 2013 at 16:46 – version 1.0 ] 5.2 validación de los algoritmos de control implementados cho sistema dinámico es controlado, por un lado en Matlab mediante el algoritmo DMC presentado en Sección A.2 y por otro lado en el LPC1769 mediante el algoritmo DMC presentado en Sección A.5. La frecuencia seleccionada para el lazo de control es 50Hz. El tiempo de las simulaciones es de 4s, con lo que se obtiene un total de 200 muestras para cada señal involucrada. Los parámetros del DMC utilizados para realizar las simulaciones son presentados en la Tabla 5.7. parámetro descripción valor N cantidad de muestras rta. escalón 50 P horizonte de predicción 10 M horizonte de control 5 λ peso del esfuerzo de control 1 a factor de predicción de la referencia 0,5 Tabla 5.7: Parámetros del DMC SISO float para el primer sistema dinámico utilizado. Los parámetros presentados en la Tabla 5.7 son nuevamente elegidos de manera tal que el controlador mejore la respuesta del sistema dinámico, frente a una determinada referencia, en algún sentido. Para no repetir nuevamente los mismos tipos de gráficos que en la Sección 5.2.3.4 y que en la Sección 5.2.3.5, en esta sección solo se grafica las señales de las salidas y las señales de las acciones de control obtenidas mediante simulación en tiempo no real en Matlab y en tiempo real en en LPC1769. Se deciden dejar de lado los gráficos que muestran las diferencias entre las señales y se exponen los resultados relevantes en la Tabla 5.8 al final de la sección. En la Figura 5.14 se presentan, a la izquierda los resultados obtenidos al realizar la simulación en tiempo no real en Matlab y a la derecha los resultados obtenidos al realizar la simulación en tiempo real en el LPC1769. En esta figura, se grafican en simultáneo la referencia, la salida obtenida sin controlador y la salida obtenida con controlador. En la misma, no se pueden observar diferencias apreciables en las formas de las señales. Cabe resaltar, que el eje horizontal del gráfico ubicado a la izquierda es en función del número de muestras, mientras que el eje horizontal del gráfico ubicado a la derecha es en función del tiempo. Esta es una diferencia fundamental entre los dos gráficos. Para lograr esta diferencia, cada muestra obtenida en el LPC1769 es marcada con un valor temporal absoluto. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 103 104 resultados obtenidos Figura 5.14: A la izquierda la salida simulada en Matlab y a la derecha la salida en tiempo real simulada en el LPC1769 para el primer sistema dinámico del DMC float En la Figura 5.15 se grafica también la acción de control obtenida. A la izquierda se presenta la simulación atemporal realizada en matlab y a la derecha se presenta la simulación en tiempo real realizada en el LPC1769. En este gráfico, tampoco se observar diferencias apreciables en la forma de las señales. Figura 5.15: A la izquierda la acción de control simulada y a la derecha la acción de control en tiempo real para el primer sistema dinámico del DMC float [ 16 de abril de 2013 at 16:46 – version 1.0 ] 5.2 validación de los algoritmos de control implementados El gráfico que si resulta relevante incluir es el presentado en la Figura 5.16. En el mismo se presenta a la izquierda el tiempo de computo del controlador DMC float (definido por la Ecuación 5.2) y a la derecha el tiempo de procesamiento del mismo controlador. Ambos gráficos son obtenidos en tiempo real en el LPC1769. Este gráfico resulta relevante por las grandes diferencias que marca entre el comportamiento del algoritmo de control DMC y el algoritmo de control PID. Figura 5.16: A la izquierda el tiempo de cómputo y a la derecha el tiempo de procesamiento del algoritmo para la primera planta del sistema dinámico del DMC float A diferencia de lo que ocurría con el controlador PID, se puede observar en el Figura 5.16 que el tiempo de procesamiento del algoritmo de control DMC y en concecuencia su respectivo tiempo de computo, no son constantes a lo largo del tiempo. Se puede observar que desde la primera muestra hasta la muestra 50 el tiempo de procesamiento aumenta linealmente. Este comportamiento es esperado y se justifica observando que el algoritmo de control DMC SISO implementado en Sección A.5 multiplica, en cada iteración del lazo de control, la matriz de respuesta libre F por el vector de esfuerzos de control pasados. La matriz de respuesta libre F ∈ RPxN y el vector de esfuerzos de control pasados pastU ∈ R Nx1 . Inicialmente el vector de esfuerzos de control pasados tiene todas sus posiciones en el valor 0. En cada iteración, dicho vector acumula un esfuerzo de control no nulo y la multiplicación matricial F ∗ pastU cada vez requiere más tiempo de procesamiento. Esta operación matricial adquiere su máximo tiempo de procesamiento cuando el vector pastU acumuló N acciones de control. Como en el Figura 5.16 N = 50, el tiempo de procesamiento continua incrementándose hasta [ 16 de abril de 2013 at 16:46 – version 1.0 ] 105 106 resultados obtenidos dicho valor. Por otro lado, en el mismo gráfico, se puede observar picos en el tiempo de procesamiento alrededor de las muestra 50, 100, 150 y 200. Estos instantes de tiempo coinciden con los cambios en la referencia. Se puede concluir que el peor tiempo de procesamiento del algoritmo de control DMC SISO float, para este caso, es aproximadamente 850us. Como es esperado, el tiempo de computo es superior porque incluye los efectos del ADC y del DAC, los cuales están simulados por el retardo que impone la comunicación UART entre ambos microcontroladores. También hay otra diferencia fundamental con el controlador PID. El tiempo de procesamiento del controlador PID es independiente del sistema dinámico a controlar y también es independiente de los datos que el algoritmo procesa en cada iteración del controlador. Por otro lado, el tiempo de procesamiento del controlador DMC no es ni independiente del sistema dinámico a controlar ni es independiente de los datos que el algoritmo procesa en cada iteración. Por un lado, no es independiente del sistema dinámico a controlar porque el tiempo de procesamiento de las operaciones matriciales que el controlador realizada dependen del tamaño de las matrices y estos tamaños dependen de los parámetros del controlador (N, P y M). Por otro lado, queda corroborado por la Figura 5.16 que tampoco es independiente de los datos que el algoritmo procesa en cada iteración ya que el tiempo de procesamiento varía en cada instante de tiempo. La diferencia descripta en el párrafo anterior genera dos problemas. A diferencia del controlador PID, para el algoritmo DMC SISO no puede definirse una máxima frecuencia de ejección absoluta para el LPC1769. La máxima frecuencia de ejecución debe ser especificada en función de los parámetros del controlador. Por otro lado, y también a diferencia del controlador PID, no alcanza con ejecutar una vez el algoritmo DMC SISO para determinar durante la ejecución de la libRTCS el tiempo de procesamiento. Esto resulta ser un problema, ya que el test de schedulability necesita conocer el peor caso del tiempo de procesamiento de cada controlador instanciado, para luego poder determinar si el conjunto de controladores instanciados pueden o no cumplir con las restricciones temporales impuestas. De todos modos, este problema fue resuelto en la libRTCS incluyendo (para cada controlador) una función que ejecuta el peor caso de funcionamiento de los algoritmos. Se puede observar en el Código 12 del Capítulo 3 que la estructura de datos del controlador genérico incluye un puntero a función llamado ControllerWorstRun. Dicho puntero a función le permite a la libRTCS ejecutar el peor caso de cada controlador instanciado en el momento de la ejecución del test de schedulability. El peor caso de funcionamiento (WCET) se determina analizando en particular cada algoritmo de control. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 5.2 validación de los algoritmos de control implementados En la Tabla 5.8 se presenta un resumen de los resultados obtenidos al validar el algoritmo de control DMC SISO con el primer sistema dinámico. parámetro valor Diferencia máxima entre la salida en Matlab y en el LPC1769 6 × 10−7 Diferencia máxima entre la acción de control en Matlab y en el LPC1769 6 × 10−7 Tiempo de procesamiento máximo 880us Tiempo de computo máximo 900us Tabla 5.8: Resultados obtenidos al realizar la validación del algoritmo de control DMC SISO float en el LPC1769 para el primer sistema dinámico. 5.2.3.5 Resultados de la validación del algoritmo de control DMC SISO de precisión float para el segundo sistema dinámico En la Sección 5.2.3.4 se utilizó el primer sistema dinámico definido por la Ecuación 5.4 para validar el PID de precisión float. En esta sección, se utiliza el segundo sistema dinámico definido por la Ecuación 5.5. Para realizar la validación, el segundo sistema dinámico es controlado, por un lado en Matlab mediante el algoritmo PID presentado en Sección A.2 y por otro lado en el LPC1769 mediante el algoritmo PID presentado en Sección A.5. La frecuencia seleccionada para el lazo de control es 10Hz debido a que se quiere probar el desempeño del algoritmo de control DMC SISO en el LPC1769 con un volumen mayor de datos como lo indica la Tabla 5.9. El tiempo de las simulaciones es de 10s, con lo que se obtiene un total de 100 muestras por cada señal involucrada. Los parámetros del DMC utilizados para realizar las simulaciones son presentados en la Tabla 5.9. parámetro descripción valor N cantidad de muestras rta. escalón 80 P horizonte de predicción 15 M horizonte de control 5 λ peso del esfuerzo de control 0,8 a factor de predicción de la referencia 0,5 Tabla 5.9: Parámetros del DMC SISO float para el segundo sistema dinámico utilizado. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 107 108 resultados obtenidos Para no repetir gráficos y no hacer repetitiva la lectura de esta sección, se presentan los resultados más relevante en la Tabla 5.10. parámetro valor Diferencia máxima entre la salida en Matlab y en el LPC1769 6 × 10−7 Diferencia máxima entre la acción de control en Matlab y en el LPC1769 6 × 10−7 Tiempo de procesamiento máximo 1880us Tiempo de computo máximo 1900us Tabla 5.10: Resultados obtenidos al realizar la validación del algoritmo de control DMC SISO float en el LPC1769 para el primer sistema dinámico. En la Tabla 5.10, se puede observar que para el segundo controlador DMC SISO simulado el tiempo de computo para el peor caso vale aproximadamente 1900us, mientras que para el primer controlador DMC SISO este tiempo vale 850. Esto se debe a la diferencia en los parámetros de los controladores. Para el controlador utilizado en el sistema dinámico definido por la Ecuación 5.4 los parámetros del controlador son: N = 50, P = 10 y M = 50. Por otro lado, para el controlador utilizado en el sistema dinámico definido por la Ecuación 5.5 los parámetros del controlador son: N = 80, P = 15 y M = 50 A partir de los resultados obtenidos para el DMC SISO de precisión float, tanto utilizando el primer sistema dinámico como el segundo sistema dinámico, se puede concluir que el algoritmo implementado en la libRTCS y ejecutado en el LPC1769 queda validado respecto al algoritmo patrón desarrollado en Matlab. 5.3 análisis de desempeño de la librtcs Finalmente, el presente trabajo concluye presentando esta sección, donde se incluyen los diferente resultados que permiten analizar el desempeño general de la libRTCS. En la Tabla 5.11 se presentan los diferentes consumos de memoria de la libRTCS utilizando el microcontrolador Cortex-M3 LPC1769. En la misma se muestra el consumo total de memoria de programa utilizando el IDE y el compilador detalladas en el Capítulo 4. Estos parámetros son entregados por el mismo compilador. También se muestra el consumo de memoria dinámica de las estructuras de datos de los diferentes controladores de la libRTCS. La memoria consumida por las diferentes estructuras de datos de los controladores es obtenida mediante el operador sizeof disponible en el lenguaje de programación [ 16 de abril de 2013 at 16:46 – version 1.0 ] 5.3 análisis de desempeño de la librtcs C. Cabe aclarar que la memoria dinámica consumida por la estructura de datos del algoritmo DMC SISO está desglosada en dos partes. Por un lado, la cantidad de bytes que ocupa la estructura de datos propiamente dicha y por otro lado la cantidad de bytes que ocupan los buffers internos utilizados para almacenar las matrices utilizadas por el algoritmo. Dichos buffers también son creados dinámicamente, motivo por el cual, dicha memoria también debe ser computada. La Ecuación 5.6 determina el tamaño total de los buffers internos que crea dinámicamente el controlador DMC SISO por cada instancia, en función de los parámetros del controlador. Esta ecuación se determina a partir de analizar la estructura de datos del controlador y las matrices que el mismo utiliza. Memoria Bu f f ers = 4 ∗ (2 ∗ N + P + P ∗ N + 3 ∗ P ∗ M + 4 ∗ M ∗ M + 6 ∗ P) (5.6) parámetro valor Memoria de programa 4476bytes Memoria de programa libre 480Kbytes En uso: libRTCS + FreeRTOS + CMSIS Memoria de variables libre 37Kbytes En uso: libRTCS + FreeRTOS + CMSIS Memoria dinámica PID float 120bytes Memoria dinámica PID double 188bytes Memoria dinámica DMC SISO float 284bytes Memoria dinámica buffers internos 3680bytes ( N = 50, P = 10, N = 5) Memoria dinámica DMC SISO float 284bytes Memoria dinámica buffers internos 7160bytes ( N = 80, P = 15, N = 5) Tabla 5.11: Consumos de memoria de la libRTCS utilizando el microcontrolador Cortex-M3 LPC1769. En la Tabla 5.12 se presentan las máximas frecuencias de ejecución de los diferentes algoritmos de control de la libRTCS en el microcon- [ 16 de abril de 2013 at 16:46 – version 1.0 ] 109 110 resultados obtenidos trolador Cortex-M3 LPC1769. Estas máximas frecuencias de ejecución se obtienen a partir de utilizar la relación empírica [29]: f max = 1 20τ (5.7) procesamiento computo f max PID float 9us 28us 1,8KHz PID double 16us 55us 910Hz DMC SISO 880us 900us 56Hz 1980us 2000us 25Hz controlador N = 50 P = 10 M=5 DMC SISO N = 80 P = 15 M=5 Tabla 5.12: Máximas frecuencias de ejecución de los algoritmos de control de la libRTCS en el microcontrolador Cortex-M3 LPC1769. Cabe recordar que el tiempo de procesamiento es el intervalo de tiempo que le lleva al procesador ejecutar un determinado algoritmo de control, mientras que el tiempo de computo es el intervalo de tiempo desde el inicio de la utilización del ADC hasta la finalización de la utilización del DAC. Por último, se analiza el desempeño de la libRTCS en diferentes escenarios de control concurrentes (muchos controladores ejecutándose a la vez). Para todos dichos escenarios de control, se ejecuta el test de schedulability RMS básico definido por la Ecuación 2.2. Los resultados obtenidos son presentados en la Tabla 5.13. Cabe resaltar, que en todos los casos analizados, el test de schedulability es verificado ampliamente. Eso se debe a que los períodos de los lazos de los controladores instanciados son mucho más grandes que los tiempos de procesamiento de los algoritmos. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 5.4 conclusiones escenario de control resultado del test PID float 1: f rec = 100Hz τPID1 = 28us PID float 2: f rec = 10Hz τPID2 = 28us PID float 3: f rec = 2Hz τPID3 = 28us Test RMS básico Ecuación 2.2 DMC float 1: f rec = 2Hz U = 3,14 × 10−3 ≤ 0,78 τDMC1 = 900us ( N = 50, P = 10, M = 5) PID double 2: f rec = 100Hz τPID2 = 55us PID double 3: f rec = 50Hz τPID3 = 55us PID float 4: f rec = 33,34Hz τPID4 = 28us PID float 5: f rec = 25Hz τPID5 = 28us Test RMS básico Ecuación 2.2 DMC float 1: f rec = 10Hz U = 11,7 × 10−3 ≤ 0,74 τDMC1 = 900us ( N = 50, P = 10, M = 5) DMC float 2: f rec = 5Hz τDMC2 = 2000us ( N = 80, P = 15, M = 5) PID float 3: f rec = 1KHz τPID3 = 28us PID float 4: f rec = 1KHz τPID4 = 28us PID float 5: f rec = 1KHz τPID5 = 28us PID float 6: f rec = 1KHz τPID6 = 28us PID float 7: f rec = 1KHz τPID7 = 28us Test RMS básico Ecuación 2.2 U = 0,16 ≤ 0,73 Tabla 5.13: Resultados de utilizar la libRTCS en diferentes escenarios de control concurrentes en el microcontrolador Cortex-M3 LPC1769. 5.4 conclusiones En este capítulo primero se presentó la validación del módulo de medición de intervalos de tiempo. A partir de dicha validación se obtuvo que la precisión en la medición de tiempos es de ±1us. Luego se realizó la validación de los diferentes algoritmos de control implementados en este trabajo. Para esto, se tomo como patrón los resultados obtenidos al realizar las simulaciones en tiempo no real en Matlab y se los comparó con los resultados obtenidos al realizar las simulaciones en tiempo real en el LPC1769. Los resultados obtenidos fueron exitosos, ya que las diferentecias entre las señales fueron del orden de 10−7 . También se analizó en detalle el tiempo de procesamiento y el tiempo de computo de los diferentes algoritmos de control para el LPC1769. Pese a que el procesador utilizado no incluye una FPU, los resultados [ 16 de abril de 2013 at 16:46 – version 1.0 ] 111 112 resultados obtenidos obtenidos fueron ampliamente satifactorios. Por un lado, para el controlador PID de precisión float y para el controlador PID de precisión double los tiempos de computo resultaron ser del orden de 10us y por otro lado, para el controlador DMC SISO float los tiempos de computo resultador ser del orden de 1ms. Por último, se presentaron diferentes parámetros que permiten medir el desempeño general de la libRTCS. Es importante destacar, que la frecuencias máximas de ejecución del algoritmo PID y del algoritmo DMC resultaron ser del orden de 1KHz y 100Hz respectivamente para el microcontrolador LPC1769. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 6 CONCLUSIONES 6.1 principales aportes del trabajo realizado En el presente trabajo se diseñó, se implementó y se validó una biblioteca de algoritmos de control para sistemas embebidos. Dentro de la investigación bibliográfica y de mercado realizadas en este trabajo, no se encontró una biblioteca de código que tenga características similares a la implementada en esta tesis. La libRTCS resulta ser una solución innovadora, que permite implementar sistemas de control de tiempo real independientemente de cuál sea el microcontrolador y el RTOS que se utilizan en cada aplicación particular. Para cumplir con el objetivo de diseñar, implementar y validar la biblioteca de algoritmos para sistemas embebidos libRTCS, se tuvo que realizar la lista de tareas presentada a continuación: 1. Se realizó una investigación bibliográfica para conocer el estado del arte de los sistemas de control de tiempo real (RTCS). 2. Se realizó una investigación de mercado para buscar soluciones existentes que permitan implementar sistemas de control de tiempo real (RTCS). 3. Se encontró que tanto a nivel académico como a nivel industrial existe la necesidad de una solución para implementar RTCS en sistemas embebidos. 4. Se estudió y se desarrolló el marco teórico necesario para poder implementar los algoritmos de control PID y DMC en Matlab. 5. Se diseñó y se implementó la libRTCS en el lenguaje de programación C. 6. Se utilizaron técnicas de programación orientadas a objetos en un lenguaje de programación estructurado para lograr que la libRTCS sea independiente del microcontrolador y del RTOS, para que sea una biblioteca flexible y que pueda ser fácilmente expandida con nuevos algoritmos de control. 7. Se implementaron los algoritmos de control PID y DMC en el lenaguaje de programación C. Para esto se tomaron como base los algoritmos desarrollados en Matlab. 8. Se utilizó la biblioteca de recursos matemáticos libDSP del fabricante ARM para resolver operaciones matriciales en el lenguaje 113 [ 16 de abril de 2013 at 16:46 – version 1.0 ] 114 conclusiones de programación C. Estas operaciones eran requeridas por el algoritmo de control DMC. 9. Se diseñó y se implementó una plataforma de hardware que incluye a dos microcontroladores LPC1769 con procesadores Cortex-M3 del fabricante ARM. Esta plataforma de hardware se utilizó para validar el funcionamiento de los algoritmos de control utilizando la técnica Hardware In the Loop. 10. Se realizó la portación de la libRTCS al microcontrolador LPC1769 y al sistema operativo de tiempo real FreeRTOS. 11. Se validaron los algoritmos de control incluidos en la libRTCS a partir de utilizar la técnica HIL, con resultados exitosos. 12. Se analizó el desempeño general de la libRTCS en el microcontrolador LPC1769, con resultados exitosos. El trabajo realizado generó como resultado una biblioteca de algoritmos de control para sistemas embebidos que puede ser utilizada tanto a nivel académico como a nivel industrial. Su principal aporte fue el de cubrir una necesidad existente en el área de los sistemas embebidos y los sistemas de control digitales, a partir de generar una biblioteca de código que permite implementar sistemas de control de tiempo real independientemente de cual sea la plataforma de hardware y el sistemas operativo de tiempo real utilizados. Por otro lado, desde un punto de vista académico, se logró articular áreas de la ingeniería que no son habitualmente encontradas juntas en la bibliografía. Estas áreas son sistemas de control y sistemas embebidos. A su vez, dentro del área de los sistemas embebidos, se incluyó en este trabajo una fuerte componente de uso de Sistemas Operativos de Tiempo Real (RTOS) y de técnicas avanzadas de programación. El trabajo presentado tiene una gran componente práctica y de implementación a diferencia de muchos otros trabajos existentes que abordan la temáticamente desde un punto de vista meramente teórico. En resumen, los principales aportes de este trabajo son: 1. Diseñar, implementar y validar una biblioteca de algoritmos de control para sistemas embebidos que puede ser utilizada tanto en el ámbito académico como en el ámbito industrial. 2. Portar la biblioteca de algoritmos de control al microcontrolador LPC1769 con procesador Cortex-M3. Esta tecnología es utilizada en muchos sistemas embebidos actuales. Poner a disposición de los desarrolladores de sistemas embebidos una biblioteca como la libRTCS es un aporte importante. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 6.2 resumen de los capítulos del trabajo realizado 6.2 resumen de los capítulos del trabajo realizado En el Capítulo 1 se presentaron las motivaciones tanto académicas como industriales que impulsaron el desarrollo de esta tesis. También se hizo una presentación del estado del arte en el área de los sistemas de control digitales para sistemas embebidos. Por último, se investigaron las diferentes soluciones que existen en la industria y se tomó la decisión de desarrollar una biblioteca de algoritmos de control para sistemas embebidos que sea portable a diferentes microcontroladores y a diferentes Sistemas Operativos de Tiempo Real (RTOS). En el Capítulo 2 se presentó la teoría necesaria para diseñar e implementar la biblioteca de algoritmos de control para sistemas embebidos. Se comenzó haciendo una breve introducción teórica a los Sistemas Operativos de Tiempo Real (RTOS) y a los esquemas de scheduling. Luego, se decidió incluir en la biblioteca el algoritmo de control clásico PID y el algoritmo de control predictivo DMC. Se desarrolló en detalle la teoría de ambos controladores y a partir de la misma se diseñaron los correspondientes algoritmos de control. Dichos algoritmos de control fueron implementados en Matlab para utilizarlos como patrón. En el Capítulo 3 se realizó el diseño y la implementación de la biblioteca de algoritmos de control. La biblioteca fue denominada libRTCS. El diseño y la implementación fueron realizados de manera tal que la libRTCS sea independiente del microcontrolador y del RTOS utilizados en cada apliacción particular. Para lograr estas características, se tuvieron que utilizar conceptos propios de la programación orientada a objetos como la herencia y el polimorfismo en el lenguaje de programación estructurado C. Esto último representó un gran desafío de diseño e implementación pero se logró diseñar una biblioteca para sistemas embebidos flexible y escalable. La misma, soporta que nuevos algoritmos de control sean agregados sin tener que modificar el código existente. También soporta la creación de diferentes algoritmos de control concurrentes, soporta la utilización de diferentes esquemas de scheduling e incluye la posibilidad de ejecutar diferentes test de schedulability para determinar si un conjunto de controladores puede o no cumplir con las restricciones temporales impuestas. Por último, en este capítulo, se pasaron los algoritmos de control implementados en Matlab al lenguaje de programación C. Se decidió utilizar como librería de recursos matemáticos a la libDSP del fabricante ARM. En el Capítulo 4 se hizo la portación de la libRTCS a una plataforma de hardware y a un RTOS concretos. Se decidió utilizar el microcontrolador LPC1769 que incluye el procesador ARM Cortex-M3 y el sistema operativo de tiempo real FreeRTOS. En este capítulo, se realiza una introducción a la plataforma de desarrollo y al RTOS utilizados. Para poder validar el funcionamiento de los algoritmos de control implementados en el Capítulo 3 y analizar el desempeño general de [ 16 de abril de 2013 at 16:46 – version 1.0 ] 115 116 conclusiones la libRTCS, fue necesario realizar la portación de la libRTCS a una plataforma concreta. La validación de la libRTCS se hace utilizando la técnica Hardware In the Loop (HIL). Para poder utilizar esta técnica de simulación, se diseñó y se implementó un hardware que incluye dos microcontroladores LPC1769. En un microcontrolador se hizo la portación de la libRTCS y en el otro se realizó la simulación de diferentes sistemas dinámicos discretos a partir de definir sus ecuaciones de recurrencia. Finalmente, se hizo una presentación detallada del firmware de ambos microcontroladores. Por último, en el Capítulo 5 se presentaron todos los resultados obtenidos. Inicialmente se realizó la validación del algoritmo de controlo PID y del algoritmo de control DMC. Para esto, se simularon para diferentes sistemas dinámicos discretos los algoritmos de control implementados en Matlab. Los resultados obtenidos en Matlab fueron utilizados como patrón para validar el funcionamiento de los algoritmos de control implementados en el lenguaje de programación C. Posteriormente se presentaron diferentes resultados e indicadores relevantes que permiten analizar el desempeño general de la libRTCS en un microcontroaldor basado en el procesador Cortex-M3. Finalmente, se simularon diferentes escenarios de control concurrentes y se presentaron los resultados obtenidos al aplicar el test de schedulability básico RMS. Los resultados obtenidos fueron satisfactorios en términos de funcionamiento de los algoritmos, consumos de memoria, frecuencia de los lazos de control y tiempos de procesamiento. La libRTCS quedó terminada y lista para ser utilizada en diferentes aplicaciones prácticas que requieran utilizar sistemas de control de tiempo real. 6.3 trabajo futuro El trabajo realizado deja abiertas las puertas a continuar desarrollando una solución completa que permita implementar sistemas de control de tiempo real en sistemas embebidos. Los trabajos a futuros pueden derivar en temas de otras tesis de ingeniería como así también en un tema de doctorado concreto. Por un lado, los trabajos a futuro que pueden incluirse en otras tesis de ingeniería son: Portar la libRTCS a un procesador con FPU, como el Cortex-M4, y comprar los resultados obtenidos con los de este trabajo. Implementar en la libRTCS el módulo de abstracción de la biblioteca de recursos matemáticos. Incluir en la libRTCS nuevos algoritmos de control, como por ejemplo: LQR, LQG, LPV etc. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 6.3 trabajo futuro Aplicar la libRTCS a plataformas reales, como puede ser un quadrotor. Ampliar los esquemas de scheduling y los test de schedulability que incluye la libRTCS. Por otro lado, este trabajo deja preparado el camino para iniciar un posible doctorado. En la actualidad, los sistemas de control de tiempo real representan un área de estudio e investigación muy activa. Los RTOS comerciales, no están completamente preparados para implementar RTCS que requieren cumplir restricciones temporales realmente duras en aplicaciones de control críticas. Por otro lado, los jitters en el periódo de muestreo y en el tiempo de computo de los algoritmos de control, pueden ocasionar que los controladores no cumplan con las especificaciones de diseño y fallen de manera crítica. Por estos motivos, en el área de los RTCS se comenzó a estudiar la posibilidad de realizar un co-diseño del scheduler en conjunto con los controladores. En este co-diseño, el mismo scheduler utiliza un lazo de control para poder adaptar los parámetros de los algoritmos de control de manera dinámica y en función del estado global del sistema en cada instante de tiempo para optimizar al sistema [9] [31] [32]. Dentro de la búsqueda bibliográfica realizada en este trabajo, no se encontró ningún sistema operativo de tiempo real comercial que esté completamente orientado a los RTCS y que utilice algoritmos de scheduling realimentados. El diseño y la implementación de un RTOS con estas características, que a su vez incluya a la libRTCS, podría ser un posible trabajo de doctorado. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 117 [ 16 de abril de 2013 at 16:46 – version 1.0 ] A APÉNDICE a.1 algoritmo pid desarrollado en matlab En el Código 22 se presenta el algoritmo del controlador PID desarrollado en Matlab. Código 22: PID desarrollado en Matlab % PID parameters: % PIDdata.Kp (proportional constant) % PIDdata.Ki (integrative constant) % PIDdata.Kd (derivative constant) % PIDdata.N (derivative effect attenuation) % PIDdata.h (sampling period) % PIDdata.b (proportional effect attenuation) % PIDdata.highOutputLimit (high anti-windup) % PIDdata.lowOutputLimit (low anti-windup) % Inputs: % PIDdata.reference (actual setpoint) % PIDdata.mOutput (actual measure output) % Outputs: % PIDdata.u (actual control action) % Auxiliar data % PIDdata.futureI % PIDdata.pastD % PIDdata.pastmOutput function PIDdata = Controller_PID (PIDdata) % Variables definitions Kp = PIDdata.Kp; Ki = PIDdata.Ki; Kd = PIDdata.Kd; b = PIDdata.b; N = PIDdata.N; h = PIDdata.h; ref = PIDdata.reference; pastD = PIDdata.pastD; mOutput = PIDdata.mOutput; pastmOutput = PIDdata.pastmOutput; highOutputLimit = PIDdata.highOutputLimit; lowOutputLimit = PIDdata.lowOutputLimit; % Initial setup (first run) if ( isempty (PIDdata.Kp_b) == 1) PIDdata.Kp_b = Kp * b; PIDdata.Der_K1 = Kd / (N * h + Kd); PIDdata.Der_K2 = PIDdata.Der_K1 * N; PIDdata.Int_K1 = Ki * h; 119 [ 16 de abril de 2013 at 16:46 - version 1.0 ] 120 apéndice end % PID iteration algorithm actualP = PIDdata.Kp_b * ref - PIDdata.Kp * mOutput; actualD = PIDdata.Der_K1 * pastD - PIDdata.Der_K2 * (mOutput - pastmOutput); actualI = PIDdata.futureI; PIDdata.u = actualP + actualD + actualI; % High Anti-windup if (PIDdata.u > highOutputLimit) PIDdata.u = highOutputLimit; end % Low Anti-windup if (PIDdata.u < highOutputLimit) PIDdata.u = lowOutputLimit; end % PID variables actualization PIDdata.futureI = actualI + PIDdata.Int_K1 * (ref - mOutput); PIDdata.pastD = actualD; PIDdata.pastmOutput = mOutput; end a.2 algoritmo dmc siso desarrollado en matlab En el Código 23 se presenta el algoritmo del controlador DMC desarrollado en el Matlab. Código 23: DMC desarrollado en Matlab % DMC parameters: % DMCdata.step (step response) % DMCdata.P (prediction horizon) % DMCdata.M (control action horizon) % DMCdata.lambda (control effort weight) % DMCdata.a (smooth factor) % Inputs: % DMCdata.reference (actual reference) % DMCdata.mOutput (actual measure output) % Outputs: % DMCdata.u (actual control action) % Auxiliar data % DMCdata.N (size of the step response) % DMCdata.G (dynamic matrix) % DMCdata.pastU (past control effort) % DMCdata.freeResponseM (free response matrix) % DMCdata.expandedStep (input step expanded) % DMCdata.K (DMC gain) function DMCdata = Controller_DMC_SISO (DMCdata) [ 16 de abril de 2013 at 16:46 - version 1.0 ] A.2 algoritmo dmc siso desarrollado en matlab % Definition of the size of the step response DMCdata.N = size (DMCdata.step,1); % P N M Variables definitions = DMCdata.P; = DMCdata.N; = DMCdata.M; % Initial setup (first run) if ( isempty (DMCdata.G) == 1) DMCdata.expandedStep = [DMCdata.step; ones(P,1) * DMCdata .step(N,1)]; DMCdata.pastU = zeros (DMCdata.N, 1); DMCdata.freeResponseM = zeros (P, N); for i = 1:1:N DMCdata.freeResponseM(:,i) = flipud ( DMCdata. expandedStep (i+1:P+i,1) ) - DMCdata.expandedStep (i,1) * ones(P,1); end DMCdata.G = zeros (P, M); for i = 1:1:M DMCdata.G(:,i) = [zeros(i-1,1); DMCdata.expandedStep (1:P-i+1,1)]; end K = inv(DMCdata.G ’ * DMCdata.G + DMCdata.lambda * eye(M) ) * DMCdata.G’ ; DMCdata.K = K(1,:) DMCdata.u = 0; end % DMC iteration algorithm % Actual free response calculation actual_freeResponse = DMCdata.mOutput + DMCdata.freeResponseM * DMCdata.pastU; % Reference prediction actual_reference = zeros (P, 1); actual_referenceSize = size(DMCdata.reference, 1); if (actual_referenceSize >= P) actual_reference = DMCdata.reference(1:P,1); else actual_reference = [DMCdata.reference(:,1); DMCdata. reference(end,1) * ones(P-actual_referenceSize, 1)]; end actual_referenceEstimation = zeros (P, 1); actual_referenceEstimation(1,1) = DMCdata.mOutput; a = DMCdata.a; for i = 2:1:P [ 16 de abril de 2013 at 16:46 - version 1.0 ] 121 122 apéndice actual_referenceEstimation(i,1) = a * actual_referenceEstimation(i-1,1) + (1 - a) * actual_reference(i,1); end % Control effort calculation actual_deltaU = DMCdata.K * (actual_referenceEstimation actual_freeResponse); % Actualization of the past control efforts DMCdata.pastU = [actual_deltaU; DMCdata.pastU(1:end-1)]; % Return the next control action that must be applied to the dynamic system DMCdata.u = DMCdata.u + actual_deltaU(1,1); end a.3 biblioteca de recursos matemático dsplib En esa sección se muestra como se utiliza a la DSPlib para realizar las siguientes operaciones: suma de matrices, resta de matrices, multiplicación de matrices, transposición de matrices e inversión de matrices. En el Código 24 se presenta la interfaz pública de las operaciones matriciales de la libRTCS. También, en el Código 24, se presenta la estructua de datos que la libRTCS utiliza para representar matrices. Código 24: Operaciones matriciales utilizando la libDSP typedef struct { uint16_t numRows; uint16_t numCols; float32_t *pData; } arm_matrix_instance_f32; void arm_mat_init_f32 (arm_matrix_instance_f32* S, uint16_t nRows, uint16_t nColumns, float32_t* pData); arm_status arm_mat_sub_f32 (const arm_matrix_instance_f32 * pSrcA, const arm_matrix_instance_f32 * pSrcB, arm_matrix_instance_f32 * pDst); arm_status arm_mat_add_f32 (arm_matrix_instance_f32* pSrcA, arm_matrix_instance_f32* pSrcB, arm_matrix_instance_f32* pDst); _ arm status arm_mat_mult_f32 (const arm_matrix_instance_f32* pSrcA, arm_matrix_instance_f32* pSrcB, arm_matrix_instance_f32* pDst); arm_status arm_mat_trans_f32 (arm_matrix_instance_f32* pSrc, arm_matrix_instance_f32* pDst); [ 16 de abril de 2013 at 16:46 - version 1.0 ] A.4 algoritmo pid implementado en el lenguaje de programación c arm_status arm_mat_inverse_f32 (arm_matrix_instance_f32* src, arm_matrix_instance_f32* dst); Como se puede observar en el Código 24, la estructura de datos que define a la matrices incluye el número de filas, en número de columnas y el puntero al arreglo de floats que contiene la información de la matriz. Cabe destacar que en dicho arreglo la matriz está cargada por filas, es decir, primero los numCols floats que representan a la fila 1, luego los numCols floats que represesntan a la fila 2, hasta los numCols floats que representan a la fila (numRows − 1). También se puede observar, que los prototitpos de las funciones son muy representativos de cómo trabajan. Las operaciones binarias (suma, resta y multiplicación) que requieren dos matrices de origen y entregan una nueva matriz como resultado, toman como parámetros los punteros a las matrices de origen y destino, dejando el resultado en el arreglo de floats correspondientes a la matriz de destino. Las operaciones unarias (transposición e inversión) funcionan de la misma manera, solo que toman como parámetros únicamente a los punteros de la matriz origen y destino. Cabe aclarar que para utilizar estas funciones todas las matrices deben estar inicializadas mediante la función arm_mat_init_f32 y los arreglos de floats deben ya estar creados con el tamaño de memoria compatible con las matrices que se van a almacenar (las funciones no crean ni destruyen memoria dinámica). a.4 algoritmo pid implementado en el lenguaje de programación c En el Código 25 se presenta el algoritmo del controlador PID implementado en el lenguaje de programación C Código 25: PID implementado en C void RTCS_PID_Run (void* pData) { float actualP; float actualD; float actualI; float ADCvalues [2]; float* pActualReference; float* pActualOutput; RTCS_PID_TData* pPIDdata = (RTCS_PID_TData*) pData; pPIDdata->RTCS_PID_receiveData (ADCvalues, 2); pActualReference = ADCvalues; pActualOutput = ADCvalues + 1; actualP = pPIDdata->RTCS_PID_Kp_b * (*pActualReference) pPIDdata->RTCS_PID_Kp * (*pActualOutput); [ 16 de abril de 2013 at 16:46 - version 1.0 ] 123 124 apéndice actualD = pPIDdata->RTCS_PID_Der_K1 * pPIDdata-> RTCS_PID_pastDer - pPIDdata->RTCS_PID_Der_K2 * ( (* pActualOutput) - pPIDdata->RTCS_PID_pastOutputMeasure); actualI = pPIDdata->RTCS_PID_futureI; pPIDdata->RTCS_PID_u = actualP + actualD + actualI; if (pPIDdata->RTCS_PID_u > pPIDdata->RTCS_PID_HighOutputLimit ) pPIDdata->RTCS_PID_u = pPIDdata->RTCS_PID_HighOutputLimit ; if (pPIDdata->RTCS_PID_u < pPIDdata->RTCS_PID_LowOutputLimit) pPIDdata->RTCS_PID_u = pPIDdata->RTCS_PID_LowOutputLimit; pPIDdata->RTCS_PID_sendData ( &(pPIDdata->RTCS_PID_u), 1); pPIDdata->RTCS_PID_futureI = actualI + pPIDdata-> RTCS_PID_Int_K1 * ( (*pActualReference) - (*pActualOutput ) ); pPIDdata->RTCS_PID_pastDer = actualD; pPIDdata->RTCS_PID_pastOutputMeasure = (*pActualOutput); } a.5 algoritmo dmc siso implementado en el lenguaje de programación c En el Código 26 se presenta el algoritmo del controlador DMC implementado en el lenguaje de programación C Código 26: DMC implementado en C void RTCS_DMC_SISO_Run (void* pData) { float ADCvalues [2]; float* pActualReference; float* pActualOutput; uint16_t i; uint16_t j; arm_status operationStatus; RTCS_DMC_SISO_TData* pDMCdata = (RTCS_DMC_SISO_TData*) pData; if (pDMCdata->RTCS_DMC_SISO_knownReference == 0) { pDMCdata->RTCS_DMC_SISO_receiveData (ADCvalues, 2); pActualReference = ADCvalues; pActualOutput = ADCvalues + 1; // Actual free response calculation [ 16 de abril de 2013 at 16:46 - version 1.0 ] A.5 algoritmo dmc siso implementado en el lenguaje de programación c operationStatus = arm_mat_mult_f32 ( &(pDMCdata-> RTCS_DMC_SISO_F_matrix), &(pDMCdata-> RCTS_DMC_SISO_pastU_matrix), &(pDMCdata-> RTCS_DMC_SISO_actualFR_AUX_matrix) ); for (i = 0; i < pDMCdata->RTCS_DMC_SISO_P; i++) { pDMCdata->RTCS_DMC_SISO_actualFR_buffer[i] = pDMCdata->RTCS_DMC_SISO_actualFR_AUX_buffer[i ] + (*pActualOutput); } // Only the actual reference is known for (i = 0; i < pDMCdata->RTCS_DMC_SISO_P; i++) { pDMCdata->RTCS_DMC_SISO_actualReference_buffer[i] = (*pActualReference); } // Smooth approximation from the current output to the known reference pDMCdata->RTCS_DMC_SISO_actualRefEstimation_buffer[0] = *(pActualOutput); for (i = 1; i < pDMCdata->RTCS_DMC_SISO_P; i++) { pDMCdata->RTCS_DMC_SISO_actualRefEstimation_buffer[i] = pDMCdata->RTCS_DMC_SISO_a * pDMCdata-> RTCS_DMC_SISO_actualRefEstimation_buffer [i - 1] + (1 - pDMCdata-> RTCS_DMC_SISO_a) * pDMCdata-> RTCS_DMC_SISO_actualReference_buffer[i ]; } // Control effort calculation operationStatus = arm_mat_sub_f32 ( &(pDMCdata-> RTCS_DMC_SISO_actualRefEstimation_matrix), &(pDMCdata ->RTCS_DMC_SISO_actualFR_matrix), &(pDMCdata-> RTCS_DMC_SISO_RElessFR_matrix) ); operationStatus = arm_mat_mult_f32 ( &(pDMCdata-> RTCS_DMC_SISO_finalK_matrix), &(pDMCdata-> RTCS_DMC_SISO_RElessFR_matrix), &(pDMCdata-> RTCS_DMC_SISO_deltaU_matrix) ); // Control action calculation pDMCdata->RTCS_DMC_SISO_u = pDMCdata->RTCS_DMC_SISO_u + pDMCdata->RTCS_DMC_SISO_deltaU; pDMCdata->RTCS_DMC_SISO_sendData (&(pDMCdata-> RTCS_DMC_SISO_u), 1); // Actualization of the pastU buffer int16_t k; [ 16 de abril de 2013 at 16:46 - version 1.0 ] 125 126 apéndice for (k = pDMCdata->RTCS_DMC_SISO_N; k >= 0; k--) { pDMCdata->RCTS_DMC_SISO_pastU_buffer[k + 1] = pDMCdata->RCTS_DMC_SISO_pastU_buffer[k]; } pDMCdata->RCTS_DMC_SISO_pastU_buffer[0] = pDMCdata-> RTCS_DMC_SISO_deltaU; } } [ 16 de abril de 2013 at 16:46 – version 1.0 ] BIBLIOGRAFÍA [1] C. Bissell, A History of Automatic Control. Springer, 2009. [2] B. W. Karl J. Astrom, Computer Controlled Systems. Theory and Design. Prentice Hall, 3rd ed., 1997. [3] C. B. Eduardo F. Camacho, Model Predictive Control. Springer, 1999. [4] K. E. A. B. Wittenmark, Karl J. Aström, “Computer control: An overview,” IFAC PROFESSIONAL BRIEF. Department of Automatic Control, Lund Institute of Technology. [5] R. J. Patton, “Fault-tolerant control systems: The 1997 situation,” 1997. [6] S. G. S. Baruah, G. Buttazzo, “Scheduling periodic task systems to minimize output jitter,” International Conference on RealTime and Embedded Computing Systems and Applications, December 1999. [7] G. F. Pau Marti, Josep M Fuertes, “Sampling jitter compensation in real-time control systems,” [8] J. E. A. Cervin, Bo Lincoln, “The jitter margin and its application in the design of real-time control systems,” 10th International Conference on Real-Time and Embedded Computing Systems and Applications, August 2004. [9] B. B. Karl-Erik Arzén, “Integrated control and scheduling,” Department of Automatic Control, Lund Institute of Technology, August 1999. [10] R. M. Ph.D., “Real time systems - computer science and engineering,” Indian Institute of Technology Kharagpur. http://www.nptel.iitm.ac.in/, 2013. [11] J. W. L. C. L. Liu, “Schedulability analysis for real-time systems with edf scheduling,” Journal of the Associations for Computing Machinery, Vol. 20, No. 1, January 1972. [12] A. B. Fengxiang Zhang, “Scheduling algorithms for multiprogramming in a hard-real-time environment,” IEEE Transactions on Computers, Vol. 58, 2009. [13] T. A. B. S. J. Qin, “A survey of industrial model predictive control technology,” Control Engineering Practice 11, 2003. 127 [ 16 de abril de 2013 at 16:46 – version 1.0 ] 128 bibliografía [14] P. L. S. Adam Besenyei, “Asymptotic output controllability via dynamic matrix control,” Differential Equations and Applications, V4, 2012, April 2012. [15] S. B. Y. Wang, “Fast model predictive control using online optimization,” 17th World Congress The International Federation of Automatic Control (IFAC), July 2008. [16] J. Ledin, Embedded Control Systems in C/C++: An Introduction for Software Developers Using MATLAB. CMP Books, 2004. [17] N. Semiconductors http://www.nxp.com/, 2013. [18] NXP, “Microcontrolador LPC1769,” http://ics.nxp.com/lpcxpresso/, 2013. [19] ARM, “Tecnología cortex-m3 para microcontroladores del fabricante ARM,” http://www.arm.com/, 2013. [20] R. Barry, “Sistema operativo de tiempo real FreeRTOS,” http://www.freertos.org/, 2013. [21] N. Semiconductors, “LPCXpresso - Plataforma de desarrollo de NXP,” http://ics.nxp.com/lpcxpresso/, 2013. [22] Eclipse, “Entorno de http://www.eclipse.org/, 2013. Integrado [23] CodeRed, “Fabricante del http://ics.nxp.com/lpcxpresso/, 2013. de IDE Desarrollo,” LPCXpresso,” [24] E. Artist, “Fabricante del target board que incluye al LPC1769,” http://www.embeddedartists.com/, 2013. [25] C. Support, “Newlib - Biblioteca del lenguaje de programación C para sistemas embebidos,” http://en.wikipedia.org/wiki/Newlib, 2013. [26] ANSI, “Estandar del lenguaje de programación C,” [27] lwIP, “A lightweight TCP/IP http://savannah.nongnu.org/projects/lwip/, 2013. stack.,” [28] ARM, “CMSIS - Cortex Microcontroller Software Interface Standard,” http://www.arm.com/, 2013. [29] C. C. Tsai, “Digital control systems. implementation of digital controllers.,” National Chung-Hsing University. http://aecl.ee.nchu.edu.tw/, 2013. [30] Y. Cao, “MPC Tutorial I: Dynamic Matrix Control.,” Mathworks. Matlab Central. http://www.mathworks.com/, 2013. [ 16 de abril de 2013 at 16:46 – version 1.0 ] bibliografía [31] A. Cervin and J. Eker, “Feedback scheduling of control tasks,” 39th IEEE Conference on Decision and Control, December 2000. [32] C. L. J. A. Stankovic, “The case for feedback control real-time scheduling,” International Conference on Real-Time and Embedded Computing Systems and Applications. [ 16 de abril de 2013 at 16:46 – version 1.0 ] 129 [ 16 de abril de 2013 at 16:46 – version 1.0 ] colophon This document was typeset using the typographical look-and-feel classicthesis developed by André Miede. The style was inspired by Robert Bringhurst’s seminal book on typography “The Elements of Typographic Style”. classicthesis is available for both LATEX and LYX: http://code.google.com/p/classicthesis/ Happy users of classicthesis usually send a real postcard to the author, a collection of postcards received so far is featured here: http://postcards.miede.de/ [ 16 de abril de 2013 at 16:46 – version 1.0 ]