Animación de sistemas dinámicos en tiempo real

De ISAwiki

Tabla de contenidos

Introducción

Esta práctica consiste en desarrollar un programa que realice la animación gráfica de un sistema físico. Para realizar la animación son necesarios dos elementos básicos:

  • La simulación numérica de las ecuaciones que modelan el sistema, para obtener su estado en cada instante.
  • La representación gráfica del sistema, dado su estado.

Además, dichos elementos tienen que funcionar en tiempo real. Es decir, se trata de que en el programa se calcule en pequeños intervalos de tiempo el nuevo estado del sistema para cada instante actual y que se redibuje el sistema para dicho estado.

Para realizar esta práctica se proporciona código de ejemplo para un péndulo, que se tomará de punto de partida y en el que, como mínimo, habrá que sustituir el código de las ecuaciones del sistema y el código del dibujado, cuyas localizaciones se describen exactamente más adelante.

La simulación numérica se encuentra implementada en el código proporcionado usando el método Runge-Kutta de cuarto orden. Para la representación gráfica se usa la biblioteca gtkmm (software libre), que permite una implementación compatible tanto para Windows como para Linux.

Como ejemplo, un video de la ejecución en Linux del programa cuyo código fuente se proporciona como punto de partida, con la simulación de un péndulo.


Instalación del entorno de desarrollo (Microsoft Windows)

  1. Instalar Dev-C++ versión 5 beta (4.9.9.2 o superior) con Mingw/GCC en la carpeta C:\Dev-Cpp (descarga)
  2. Instalar paquete de desarrollo de gtk, gtk+-win32-devel versión 2.8.20, en la misma carpeta C:\Dev-Cpp (descarga directa, y si falla la descarga, se puede intentar buscándolo aquí)
  3. Instalar paquete de desarrollo de gtkmm versión 2.8 en la misma carpeta C:\Dev-Cpp (descarga)
  4. El entorno de desarrollo ya está preparado para compilar y ejecutar el ejemplo (descarga)

Instalación del entorno de desarrollo (Linux)

Las instrucciones para preparar el entorno de desarrollo en Linux no son muy precisas por las diferencia entre distintas distribuciones o incluso versiones dentro de la misma distribución y por eso deben de tomarse sólo como una orientación. Los siguientes puntos corresponden a Debian GNU/Linux 4.0 "Etch":

  1. Compilador GNU para C++: g++ (versión 4.1; pero téngase en cuenta que el entorno recomendado en el apartado anterior para Windows viene con la versión 3.4.2 del mismo, así que no debe considerarse importante).
  2. GNU make (versión 3.81). Puede haberse instalado automáticamente por dependencias del g++. Si falla el comando "make" del punto 5, puede ser porque falta.
  3. Paquete de desarrollo de gtk: libgtk2.0-dev (versión 2.8.20). En Debian y otras distribuciones con un buen sistema de gestión de paquetes no es necesario pedir directamente su instalación porque se instalará automáticamente al instalar el de gtkmm; en ese caso se puede saltar este punto e ir directamente al siguiente.
  4. Paquete de desarrollo de gtkmm: libgtkmm-2.4-dev (versión 2.8.8).
  5. El entorno de desarrollo ya está preparado para compilar y ejecutar el ejemplo (descarga). Basta cambiar al directorio que contiene el código fuente una vez descomprimido y ejecutar el comando "make" para crear el ejecutable.

Descripción del código fuente de ejemplo

Las clases que se definen en el código fuente son las siguientes:

Auxiliares:

  • Timer: clase temporizador

Simulación de ecuaciones diferenciales en espacio de estados:

  • ModelSimulation: clase interfaz para simulación de modelos
  • RKModelSimulation: clase implementación de simulación de modelos con Runge-Kutta de cuarto orden
  • Model: clase interfaz de modelo en espacio de estados
  • BaseModel: clase implementación básica de modelo en espacio de estados

Animación:

  • RTGSimulation: clase implementación base para simulaciones gráficas en tiempo real (animaciones)

Ejemplo particular:

  • MiModelo: clase ejemplo de modelo en espacio de estados de un péndulo
  • MiAnimacion: clase ejemplo de animación del péndulo

Para la realización de la práctica, no es necesario (ni recomendable) alterar más que los ficheros MiModelo.h y MiModelo.cpp. El proyecto de ejemplo es completamente funcional y su código fuente se distribuye en varios ficheros. Dentro de estos ficheros, los cambios precisos para realizar la animación de un sistema diferente al del ejemplo se localizan en los siguientes puntos:

  1. Declaración de los parámetros del sistema dentro de la declaración de la clase MiModelo (en el fichero MiModelo.h). En el ejemplo esto corresponde a la aceleración de la gravedad (g), la longitud del péndulo (L), etc.
  2. Dar valor a dichos parámetros del sistema en el constructor MiModelo::MiModelo (en el fichero MiModelo.cpp). Además se define ahí el orden del sistema (por medio de BaseModel(n), donde n es el orden y vale 2 en el ejemplo) y los valores iniciales de cada una de las variables de estado.
  3. Declaración en la clase MiAnimacion (en el fichero MiModelo.h) de las variables de salida del sistema (ángulo de posición theta en el ejemplo), el instante de tiempo (t) y demás variables auxiliares para el dibujado.
  4. Dar valor inicial a las variables auxiliares de dibujado en la función MiAnimacion::InitDrawing (en el fichero MiModelo.cpp). NOTA: el valor inicial de las variables de salida del sistema no se hace aquí, sino que se hace automáticamente a partir del valor inicial de las variables de estado por medio de la función descrita en el siguiente punto.
  5. La función MiAnimacion::Output (en el fichero MiModelo.cpp) es usada para obtener las variables de salida del sistema (las que sean necesarias para realizar el dibujado) a partir de las variables de estado del modelo. Equivale a la ecuación de salida de espacio de estados.
  6. La función MiModelo::Evaluate (en el fichero MiModelo.cpp) evalúa las ecuaciones de estado para obtener las derivadas de las variables de estado (vector dot_state) en función de las propias variables de estado (vector state) y el instante de tiempo t.
  7. En la función MiAnimacion::Draw (en el fichero MiModelo.cpp) se realiza el dibujado. NOTA IMPORTANTE: nunca se debe acceder aquí directamente a las variables de estado del modelo, sino solamente a las variables de salida que se calculan en la función MiAnimacion::Output. La razón es que el dibujado se realiza concurrentemente con el cálculo del siguiente paso de la simulación y por lo tanto las variables de estado pueden haber cambiado. Véase que en el ejemplo la variable de salida (el ángulo de posición theta) es directamente el valor de la primera variable de estado y sin embargo se hace una copia.
  8. En la función CrearAnimacion (en el fichero MiModelo.cpp), es posible cambiar el parámetro delta_t (paso o step size) de la simulación, que es la diferencia de tiempo entre dos instantes consecutivos de la simulación. En el ejemplo vale 0,01 (10 milisegundos). Cuanto más pequeño, más precisa es la simulación, pero más potencia de cálculo necesita el ordenador. Si no tiene disponible esa potencia de cálculo, no puede hacer la simulación en tiempo real.

En la parte a modificar, sólo se hace uso de C++ estándar, salvo para la parte gráfica, que hace uso de la biblioteca gtkmm. Se proporciona documentación para su uso aquí. Dentro de ella, el capítulo relacionado con el dibujado es el 14. The Drawing Area Widget.

En Linux, esa misma documentación estaría disponible en el paquete libgtkmm-2.4-doc, que la instala en el directorio /usr/share/doc/libgtkmm-2.4-doc, pero es importante que sea una versión 2.8 y no una 2.10 o superior que es la disponible en la web de gtkmm, pero que difiere de forma importante en el uso de la clase DrawingArea.

Enlaces

Los siguientes enlaces se pueden usar como fuente de información extra, pero no son necesarios para la realización de la práctica:

Herramientas personales
Espacios de nombres

Variantes
Acciones
Navegación
Tipos de páginas
Bloques temáticos
Herramientas