INGENIER´ IA T´ ECNICA EN INFORM ´ ATICA DE SISTEMAS
Escuela T´ ecnica Superior en Ingenier´ıa Inform´ atica Curso acad´ emico 2009-2010
Proyecto Fin de Carrera
JDE DS:
Plataforma de desarrollo de esquemas
Tutor: Jos´e Mar´ıa Ca˜nas Plaza.
Autor: Carlos Iv´an Mart´ın Amor.
Aqu´ı escribo una frase introductoria
carlos 123 [email protected] [email protected]
Agradecimientos.
Aqu´ı escribo mis agradecimientos
Enhorabuena a todos.
´ Indice general
1. Introducci´on 1
1.1. Contexto . . . 1
1.2. Motivaci´on . . . 6
2. Infraestructura 8 2.1. Jderobot . . . 8
2.2. Gtk . . . 9
2.2.1. libGlade y GtkBuilder . . . 10
2.2.2. GLib . . . 12
2.2.3. Pango . . . 13
2.2.4. Gdk . . . 14
2.2.5. GdkPixbuf . . . 14
2.2.6. Cairo . . . 15
2.3. LibXml . . . 15
3. Descripci´on Inform´atica 17 3.1. Organizaci´on del c´odigo . . . 17
3.1.1. Interfaces gr´aficas . . . 17
3.1.2. Ficheros en C . . . 29
3.2. Arquitectura . . . 43
3.3. Implementaci´on . . . 43
4. Pruebas 44 4.1. Bup and Go . . . 44
4.2. Circuito Cheste . . . 44
4.3. Sigue Linea con Gazebo . . . 44
5. Manual de uso 45 5.1. Creaci´on de un aut´omata . . . 45
i
´INDICE GENERAL ii
6. Conclusiones y trabajos futuros 46
6.1. Conclusion . . . 46 6.2. Trabajos futuros . . . 46
Bibliograf´ıa 47
´ Indice de figuras
1.1. Ejemplos de robots. . . 2
1.2. Esquema perceptivo. . . 2
1.3. Esquema de actuaci´on. . . 4
1.4. Aut´omata finito determinista. . . 5
1.5. Funci´on del middleware Jderobot . . . 6
2.1. Esquema de acci´on de jderobot. . . 8
2.2. Aplicaci´on Glade con la interfaz gr´afica de JDE DS . . . 12
2.3. Editor con multitud de idiomas con pango . . . 14
2.4. Dibujo realizado con Cairo . . . 15
3.1. Explicaci´on de la interfaz JDE DS. . . 18
3.2. Contenido del widget GtkMenuBar. . . 18
3.3. Contenido del menu Archivo. . . 19
3.4. Contenido del menu Editar. . . 20
3.5. Contenido del menu Ver. . . 20
3.6. Contenido del menu Ayuda. . . 20
3.7. Botones de la aplicaci´on. . . 20
3.8. Marco de selecci´on de acci´on. . . 21
3.9. Widgets de la selecci´on del estado inicial. . . 22
3.10. Configuraci´on de la velocidad del esquema. . . 22
3.11. Zona de creaci´on del aut´omata . . . 23
3.12. Activaci´on de sensores . . . 23
3.13. Partes de la interfaz del Editor . . . 24
3.14. Men´u archivo del editor. . . 25
3.15. Men´u Editar del editor de c´odigo. . . 25
3.16. Men´u Buscar del editor de c´odigo. . . 26
3.17. Botones que forman parte del editor de c´odigo. . . 26
3.18. GtkNotebook perteneciente al editor de c´odigo. . . 27
iii
´INDICE DE FIGURAS iv
3.19. Interfaz gr´afica del fichero Acerca De.glade. . . 28 3.20. Interfaz gr´afica del fichero VentanaSeleccion.glade. . . 29 3.21. Interfaz gr´afica para la b´usqueda de una cadena de texto. . . 42
Cap´ıtulo 1
Introducci´ on
En este primer cap´ıtulo nos adentraremos en el mundo de la rob´otica, hasta llegar a encontrar la motivaci´on por la que se ha llevado a cabo este PFC.
1.1. Contexto
El origen del termino robot proviene de la novela RUR”(Rossum’s Universal Robots) del autor checo Karel Capek, publicada en 1920. Este drama trata sobre un brillante cient´ıfico, Rossum, y su hijo, quienes desarrollan humanos artificiales sumisos.
El protagonista sigue trabajando hasta alcanzar el perfeccionamiento de dichos seres, pero al final el argumento da un giro inesperado y todos acaban rebel´andose contra los humanos. Capek se dirige a estos seres artificiales mediante la palabra robot, derivaci´on del vocablo checo robota que significa trabajo obligatorio o forzoso.
Posteriormente Isaac Asimov, escritor y bioqu´ımico, fuen quien acu˜no la palabra rob´otica con el sentido de disciplina cient´ıfica encargada de construir y programar robots.
En la actualidad, se sigue manteniendo el enfoque de la definici´on. La Real Academia Espa˜nola define la rob´otica como t´ecnica que aplica la inform´atica al dise˜no y empleo de aparatos que, en sustituci´on de personas, realizan operaciones o trabajos, por lo general en instalaciones industriales. Dichos aparatos se les denomina robots, que define as´ı: m´aquina o ingenio electr´onico programable, capaz de manipular objeto y realizar operaciones antes reservadas solo a las personas.
1
CAP´ITULO 1. INTRODUCCI ´ON 2
(a) Perrito Aibo de Sony (b) Brazo transportador
Figura 1.1: Ejemplos de robots.
Una de las caracter´ısticas intr´ınsecas y axiom´aticas de los robots es el comportamiento aut´onomo. Este atributo se denomina a la habilidad para tomar decisiones por uno mismo y llevarlas a cabo, concretamente en el ´ambito de la rob´otica a la capacidad para percibir la situaci´on y actuar apropiadamente. Llevar a cabo la percepci´on e interacci´on de la realidad no es tarea f´acil, y por ello se dotan de una serie de herramientas llmadas sensores y actuadores.
Los sensores son los dispositivos encargados de detectar un determinado est´ımulo del exterior y transmitirlo de forma eficiente. Constituyen el sistema de percepci´on del robot, gracias a ellos podemos captar la realidad, las cantidades f´ısicas de atributos del entorno en el que esta inmerso el robot (temperatura, velocidad, inclinaci´on, distancias, sonido, etc.). Son dispositivos inexactos, ruidosos y limitados, y por ello se emplean varios sensores para una misma propiedad f´ısica.
Figura 1.2: Esquema perceptivo.
CAP´ITULO 1. INTRODUCCI ´ON 3
Un sensor por s´ı solo no proporciona s´ımbolos, puede hacer falta mucha capacidad de proceso para convertir se˜nales en s´ımbolos. La sensorizaci´on de un robot implica diversas disciplinas como la electr´onica, la inform´atica y el procesamiento de se˜nales.
Los sensores se pueden caracterizar mediante las siguientes propiedades:
Sensibilidad: ratio de cambio de la salida a los cambios de las entradas.
Linealidad: medida de la constancia del ratio entrada/salida.
Rango: diferencia entre el m´aximo y el m´ınimo valor medible.
Tiempo de respuesta: tiempo requerido para que un cambio de la entrada sea observable.
Exactitud: diferencia entre el valor real y el valor medido.
Resoluci´on: el incremento m´ınimo observable en la entrada.
Repetitividad: diferencia entre sucesivas medidas de la misma entrada.
Tipo de salida: entero, real, matriz, ...
Estas cualidades son de gran utilidad, nos proporcionan la informaci´on adecuada para optar un sensor u otro, dependiendo necesidades propias. Tambi´en existen caracter´ısticas en las que podemos agrupar a dichos dispositivos. Las clasificaciones m´as conocidas son las siguientes:
Internos/Externos
• Internos: son los encargados de dar informaci´on sobre el propio robot, como la posici´on, la velocidad, la aceleraci´on.
• Externos: nso proporcionan informaci´on sobre el entorno, por ejemplo la proximidad, el tacto, la fuerza, la visi´on.
Sencillos/Complejos
• Sencillos: no necesitan mucha capacidad de c´alculo.
Necesitan cierta electr´onica como los conectores a los puertos, y los convertidores anal´ogicos digitales.
• Complejos: requieren de cierta programaci´on. Necesitan interpretaci´on de la informaci´on, ya que por si sola se hace insuficiente.
CAP´ITULO 1. INTRODUCCI ´ON 4
Activos/Pasivos
• Activos: son aquellos que producen un est´ımulo y miden su interacci´on con el entorno, para ello necesitan m´as energ´ıa, m´as procesamiento. Como por ejemplo el ultrasonido, el l´aser, los infrarrojos, etc.
• Pasivos: simplemente miden se˜nales del entorno, como verbigracia interruptores, luz, botones, etc.
Los actuadores son dispositivos capaces de provocar un efecto sobre un proceso automatizado. Son los encargados de generar movimiento de los elementos del robot permitiendo interaccionar con el entorno. Una propiedad que cabe destacar dentro de los actuadores son los grados de libertad, cada uno de los movimientos independientes que pueden realizar. La mayor´ıa de los actuadores controlan un grado de libertad.
Podemos distinguir dos tipos de robots dependiendo de los grados de libertad, los holon´omicos o no holon´omicos. Se dice que un robot es holon´omico cuando la cantidad de grados de libertad totales y controlables son los mismos. Por otro lado los robots no holon´omicos son aquellos que los grados de libertad controlables son menor que la cantidad de grados de libertado totales, cuanto mayor sea la diferencia mayor es la complejidad para controlarlo. Los tipos de actuadores m´as comunes que nos podemos encontrar son los neum´aticos, hidr´aulicos y el´ectricos.
Figura 1.3: Esquema de actuaci´on.
Gracias a sensores y actuadores, los robots tienen las herramientas necesarias para poder interaccionar con el entorno, ofreciendo respuestas a determinados est´ımulos. Son partes de gran peso en el robot, pero por s´ı solos no hacen del robot un ser aut´arquico,
CAP´ITULO 1. INTRODUCCI ´ON 5
por ello no carece de importancia el computador y la programaci´on que se lleva a cabo.
Estos cuatro ingredientes indiscutibles dotan al robot de autonom´ıa, tal vez por ello se habla de robot como aut´omata.
La definici´on de aut´omata seg´un la Real Academia Espa˜nola es la siguiente:
[1]instrumento o aparato que encierra dentro de s´ı el mecanismo que le imprime determinados movimientos,[1]m´aquina que imita la figura y los movimientos de un ser animado. Ambas definiciones corresponden a las caracter´ısticas de los robots, pero podemos obtener una explicaci´on m´as t´ecnica de lo que es un aut´omata. En el campo de la rob´otica, nos encontramos con aut´omatas finitos deterministas. Un Aut´omata Finito Determinista(AFD) es un m´aquina de estados que tiene acceso a una secuencia de s´ımbolos de entrada, se encuentra en cada momento en un estado determinado y puede llegar a transitar a otro estado, y para ello se realizan lo siguientes pasos: 1)Se lee de la cinta y se avanza la cabeza lectora, 2)En funci´on del s´ımbolo le´ıdo y del estado actual el aut´omata transita a otro estado. Un AFD es una qu´ıntupla A = (Q, Σ, f, q0, F ), donde: Q es el conjunto de estados; Σ es el alfabeto de entrada; f : Q × Σ ⇒ Q es la funci´on de transici´on; q0 3 Q es el estado inicial; y F ⊆ Q es el conjunto de estados finales.
Figura 1.4: Aut´omata finito determinista.
La relaci´on de un Aut´omata Finito Determinista con los robots es clara, los sensores corresponden con los s´ımbolos de entrada (s´ımbolos le´ıdos), los estados corresponden con los movimientos o acciones que se desenvuelven en circunstancias concretas, el alfabeto concuerda con los posibles valores que nos ofrecen los sensores, no obstante el conjunto de estado finales no tiene porque existir debido a que un robot siempre se encuentra activo, detectando est´ımulos del exterior e intentado actuar en su entorno, preservando la caracter´ıstica de autonom´ıa.
CAP´ITULO 1. INTRODUCCI ´ON 6
Una vez ubicados y comprendiendo que un robot es equivalente a un aut´omata, podemos sacar en conclusi´on que a partir de un aut´omata podemos programar un robot con comportamiento aut´onomo. El objetivo de este proyecto es crear una aplicaci´on capaz de crear aut´omatas de forma gr´afica e intuitiva al que se le pueda programar cada estado y transici´on de aut´omata. El resultado final debe ser un esquema compatible con la aplicaci´on JDE.
Las aplicaciones rob´oticas que se ejecutan bajo JDE, se les denominan esquemas concurrentes. Un esquema no es m´as que una hebra con cierto objetivo, que se ejecuta iterativamente a un ritmo controlado. Dicha hebra contiene el c´odigo del comportamiento programado, las variables perceptivas y de actuaci´on necesarias para llevar a cabo el comportamiento. Estas variables nos la proporciona JDE, middleware rob´otico cuyo objetivo es simplificar el desarrollo, proporcionando contextos n´ıtidos, estructuras de datos predefinidos, bloques depurados de c´odigo de uso frecuente, protocolos est´andar de comunicaciones, etc..
Figura 1.5: Funci´on del middleware Jderobot
1.2. Motivaci´ on
La gran afluencia de proyectos, pr´acticas, e investigaciones del grupo Gsyc ligados al ´ambito de la rob´otica obliga a trabajar de forma continua con JDE. Esta plataforma como se comento con anterioridad, trabaja de forma axiom´atica con los esquemas, los cuales permiten englobar con gran capacidad las caracter´ısticas b´asicas de un robot.
La programaci´on de estas estructuras de forma manual se hace tediosa, debido a la configuraci´on de variables globales provenientes de otros esquemas aportandonos datos
´
utiles. El hecho de tener que estar configurando cada esquema nos perjudica de forma sustancial con p´erdidas de tiempo, con un trabajo repetitivo en muchos casos, y que nos puede llevar a confunsiones en la programaci´on. Sin ninguna duda nos dispersa de
CAP´ITULO 1. INTRODUCCI ´ON 7
nuestro objetivo, que es programar nuestro propio comportamiento.
A parte de la carga que nos puede suponer realizarlo de forma manual, la programaci´on directa en el fichero del esquema es poco intuitiva y engorrosa, nada parecido a un aut´omata. Todo esto dificulta nuestra tarea en la elaboraci´on de comportamientos compatibles con JDE.
La motivaci´on para el desarrollo de este proyecto, sin ning´un lugar de dudas, es establecer un primer contacto involucrado en mejorar la creaci´on de esquemas de forma simple e intuitiva, definiendo un comportamiento, un aut´omata.
Habiendo ya recalcado las motivaciones de este proyecto, procedemos a enumerar los objetivos perseguidos.
El principal objetivo, cuyo fin del proyecto, es desarrollar una aplicaci´on capaz de dibujar de forma gr´afica e intuitiva cualquier comportamiento y transformarlo posteriormente en un esquema preparado para JDE. La primera parte del objetivo, tiene varias metas a cumplir. Debe ser un programa capaz de dibujar un Aut´omata Finito Determinista al completo, de dise˜no manejable y c´omodo, permitiendo ver la programaci´on del comportamiento de forma abstracta, eliminando los detalles superfluos. Esto nos ayuda a tener una idea general de como estamos desarrollando la estructura del comportamiento, facilitando en la tarea de depuraci´on en caso de mala elecci´on, y favoreciendo su modificaci´on.
La segunda parte del objetivo trata de la creaci´on de un esquema compatible con JDE, calcando la estructura del aut´omata y la programaci´on de cada nodo o transici´on.
Siempre sin descuidar las propiedades fundamentales que componen los esquemas, como a˜nadiendo si es preciso las variables relacionadas con cada sensor o actuador.
Cap´ıtulo 2
Infraestructura
En este cap´ıtulo se tratar´an los pilares en que se basa JDE DS. Se describir´an cada unas de las bibliotecas utilizadas en el desarrollo de la aplicaci´on.
2.1. Jderobot
JDE es un entorno de desarrollo de software, escrito en C, para aplicaciones rob´oticas. Proporciona un entorno de programaci´on donde el programa de control del robot se abastece de una colecci´on de procesos simult´aneos as´ıncronos con el nombre de esquemas. Se basa en la arquitectura cognitiva JDE para robots aut´onomos.
La arquitectura de un robot es la organizaci´on de sus capacidades sensoriales, de procesamiento y de acci´on para conseguir un repertorio de comportamientos inteligentes interactuando con cierto entorno. Este espacio de desarrollo simplifica el acceso al hardware rob´otico del programa que lleva el control. Obtener las mediciones de un sensor es tan simple como leer una variable local, y ordenar movimientos a los motores es tan f´acil como escribir en una variable local. La aplicaci´on del robot lee y escribe en dichas variables con el objetivo de desplegar su comportamiento.
Figura 2.1: Esquema de acci´on de jderobot.
8
CAP´ITULO 2. INFRAESTRUCTURA 9
El esquema es la unidad b´asica de JDE, nos permite encapsular una determinada funcionalidad, con el objetivo de formar comportamientos mediante la agrupaci´on de varios esquemas. Definimos esquema como un flujo de ejecuci´on independiente con un objetivo; un flujo que es modulable, iterativo, y que puede ser activado o desactivado a voluntad. Podemos distinguir dos tipos de esquemas, esquemas perceptivos y esquemas motores o de actuaci´on. Los esquemas perceptivos se encargan de elaborar los est´ımulos, que pueden ser le´ıdos por otros esquemas. Las entradas de estos esquemas pueden ser los sensores del sistema, o la percepci´on de otros esquemas. Por otro lado los esquemas de actuaci´on, utilizan los datos obtenidos por otros esquemas perceptivos, para generar sus salidas, que pueden ser comandos directos hacia los actuadores del sistema o simplemente env´ıan se˜nales de activaci´on y/o modulaci´on a otros esquemas.
Todos los esquemas est´an definidos por tres ficheros: schema.c, schema.h y Makefile.
El schema.c contiene el c´odigo de las funciones que permite administrar el esquema. El fichero schema.h tiene las funciones de administraci´on del esquema m´as importantes.
Las funciones son las siguientes: schema cycle, establece la velocidad de ejecuci´on del esquema; schema iteration, se encuentra el c´odigo que se ejecuta concurrentemente cuando el esquema se encuentra en modo ejecutado; schema init, se encarga de cargar el esquema en un nuevo hilo para el JDE; schema terminate, destruye el hilo del esquema dentro del JDE; schema stop, pone el esquema en modo espera; schema run, coloca el esquema en ejecuci´on; schema show, muestra la interfaz gr´afica del esquema si lo tiene;
schema hide, se encarga de cerrar el GUI del esquema si lo tiene. Por ´ultimo el fichero Makefile se encarga de definir las directrices del compilado del esquema para generar el c´odigo schema.so que se ejecutar´a dentro del entorno JDE.
2.2. Gtk
GTK+ es una biblioteca gr´afica (toolkit) sobre la que se sustenta todo el interfaz gr´afico de Gnome. Es una biblioteca que contiene todo lo necesario para el desarrollo de interfaces gr´aficas. Los elementos, con el que el usuario puede interactuar, se denominan widgets, que son los artifices del aspecto final de la aplicaci´on. Nos permiten la posibilidad de crear todo tipo de widgets, desde los m´as b´asicos como botones, etiquetas, hasta widgets m´as complejos como selectores de ficheros, cajas de texto multil´ınea, etc.
Un widget es un componente software visible y personalizable.
Visible porque est´a pensado para ser usado en los interfaces gr´aficos de los programas y personalizable porque el programador puede cambiar sus propiedades. La biblioteca
CAP´ITULO 2. INFRAESTRUCTURA 10
Gtk+ est´a escrita en C, pero la implementaci´on de los widgets utiliza conceptos propios de la programaci´on orientada a objetos, como la herencia; cada widget hereda todas las funciones y variables de su predecesor.
La jerarqu´ıa de objetos comienza en GObject de la librer´ıa Glib del que hereda GtkObject. Todos los widgets heredan de la clase de objetos GtkWidget, que a su vez hereda directamente de GtkObject. La clase GtkWidget contiene las propiedades comunes a todos los widget; cada widget particular le a˜nade sus propios atributos.
Los widgets se definen mediante punteros a una estructura GtkWidget. Todos estos objetos tienen una relaci´on padre/hijo entre s´ı. Todo widget debe de tener un padre, llamado contenedor.
En GTK+ se usa el modelo de programaci´on por eventos. Este modelo consiste en la asociaci´on de determinadas acciones (“eventos”) a determinadas operaciones (“funciones”). Dichos eventos marcan un cambio de estado del determinado objeto.
Los eventos en GTK se refieren a se˜nales especificadas en la definici´on de las clases de los distintos widgets.
El programador es el encargado de decidir c´omo se debe reaccionar ante una determinada acci´on. Debe enlazar una funci´on (callback) a una determinada se˜nal.
As´ı, en cuanto se reciba dicha se˜nal, se llamar´a automaticamente al callback.
Para que este tipo de sistemas sea fructuoso se usa el bucle de eventos. Este no es m´as que un bucle interno de GTK+, en el que se van comprobando, una y otra vez, los estados de cada uno de los elementos de la aplicaci´on.Este concepto se traduce b´asicamente en dos funciones, gtk main(void) y gtk main quit(void).
Estas dos funciones representan el interfaz que tienen las aplicaciones para usar el bucle de eventos. La funci´on gtk main(void) ejecuta dicho bucle, esto significa que, una vez que se haya realizado la llamada se cede todo el control de la aplicaci´o a GTK. No retorna hasta que dentro de alg´un manejador se haga una llamada a gtk main quit(void), y termina el bucle de eventos de GTK+.
Dentro de GTK+ podemos encontrar unas seria de bibliotecas de las que depende, por antonomasia nos encontramos: GLib, Pango, Atk, GdkPixbuf, Gdk, Cairo.
2.2.1. libGlade y GtkBuilder
Crear una interfaz gr´afica es sencillo, pero muy costoso en cuanto a codificaci´on se refiere. Para hacer m´as eficiente este trabajo existen herramientas que automatizan muchas tareas y nos permiten un dise˜no visual de layout de la aplicaci´on, nos aporta un entorno WYSIWYG (What You See Is What You Get).
CAP´ITULO 2. INFRAESTRUCTURA 11
Para definir interfaces GTK+ existe Glade (, que nos permite:
Crear ventanas y cuadros de di´alogo.
A˜nadir widgets a la ventanas.
Definir las propiedades de cada widget.
Relacionar funciones a eventos determinados de cada widget.
Para enlazar la interfaz gr´afica creada por Glade con una aplicaci´on en C existen dos formas. Exportar el dise˜no creado en un fichero con c´odigo C, para enlazarlo posteriormente en tiempo de compilaci´on. Esta v´ıa permite tiempos de carga ligeros, sin embargo nos permite un menor control sobre el c´odigo generado autom´aticamente, ya que no debemos manipular el c´odigo generado por Glade. La segunda v´ıa guarda el dise˜no en un fichero en formato XML, y se carga en la aplicaci´on en tiempos de ejecuci´on. Las bibliotecas que nos permiten cargar la interfaz en tiempo de ejecuci´on son dos: libGlade y GtkBuilder.
La utilidad es la misma para ambas bibliotecas, nos aportan un conjunto de primitivas para cargar el fichero, iniciarlo, obtener widgets a partir de un nombre, o enlazar de forma autom´atica cada se˜nal con su funci´on callback correspondiente.
La diferencia entre las dos bibliotecas es que libGlade no forma parte de GTK, sino que sigue un desarrollo completamente independiente. Eso limita en muchos aspectos el mantenimiento de aplicaciones que desarrollemos en referencia a GTK por ejemplo, velocidad a la hora de soportar nuevos widgets y propiedades. Aunque libGlade siempre funciono bien no tiene sentido que una biblioteca tan fundamental fuese un elemento externo.
Por todo esto los desarrolladores de GTK optaron por crear una biblioteca integrada en GTK y que fuese lo m´as parecida a libGlade, con el objetivo de reemplazarla se desarroll´o GtkBuilder. La forma de comportarse GtkBuilder es muy similar a libGlade, la principal diferencia es que en GtkBuilder no es posible generar s´olo una parte del ´arbol.
Esto significa que es m´as eficiente poner cada ventana en un fichero XML independiente.
CAP´ITULO 2. INFRAESTRUCTURA 12
Figura 2.2: Aplicaci´on Glade con la interfaz gr´afica de JDE DS
2.2.2. GLib
GLib proporciona los bloques b´asicos para construir aplicaciones y bibliotecas escritas en C. Proporciona el sistema de objetos b´asicos usado en GNOME, la implementaci´on del bucle principal, y un gran conjunto de utilidades para cadenas y estructuras de datos comunes. Tiene la propiedad de mejorar la portabilidad de nuestros programas.
Debido a las diferencias entre sistemas operativos/arquitecturas en cuanto a los tama˜nos de tipos de datos se refiere, se vuelve a veces complejo el hacer que los programas funcionen sin cambios de S.O. o hardware. Por ello ofrece una serie de tipos de datos propios, sin embargo no son muy diferentes de los que se usa en le est´andar de C.
Podemos ver algunas diferencias en la nomeclatura de los tipos de datos Tipos GLib Tipos est´andar C
gchar char
gint int
gshort short
glong long
gfloat float gdouble double
Cuadro 2.1: Tipos de GLib equiparando al est´andar C.
CAP´ITULO 2. INFRAESTRUCTURA 13
Esta biblioteca tambi´en alberga otros tipos de datos o funciones de gran interes, caben destacar:
Conversi´on de tipos.
Cadenas de texto: GLib tiene sus propios string, del tipo GString. Adem´as vienen acompa˜nadas de un gran n´umero de funciones de gran aceptaci´on.
Control de la memoria: con funciones como g malloc(), g malloc0(), g free(), que nos ayudan en la reserva y liberaci´on de memoria.
Hilos: tiene a su disposici´on un repertorio de funciones destinadas al control de threads.
Estructura de datos complejas: listas simplemente y doblemente enlazadas; tablas Hash.
2.2.3. Pango
Pango es una biblioteca para la composici´on y renderizado de texto, con ´enfasis en la internacionalizaci´on. Pango se usa all´a donde el emplazado de texto sea necesario, sin embargo, la mayor´ıa del trabajo en Pango se hizo usando el conjunto de herramientas para elementos de GTK+ como plataforma de prueba. Pango conforma el n´ucleo del manejo de texto y tipograf´ıas en GTK+-2.0.
Tiene un soporte extensivo para los variados sistemas de escritura en todo el mundo. Muchos sistemas de escritura usados en los idiomas tienen complejas reglas de dibujado de glifos y composici´on de caracteres. Con Pango, casi todos los idiomas pueden escribirse y mostrarse correctamente, permitiendo a los usuarios de cualquier parte ver texto en sus idiomas maternos. El soporte de Pango para m´ultiples sistemas de escritura es autom´atico.
Soporta el estilo de texto usado en los t´ıpicos documentos e interfaces, incluyendo cursivas, tama˜nos de tipograf´ıa y subrayado. Esta biblioteca usa un vocabulario parecido a XML llamado PangoMarkup que le permite establecer el tama˜no de la tipograf´ıa, el color, los estilos y otros atributos del texto.
Podemos definirla como una biblioteca para la salida de texto internacionalizado.
Se encarga de todo lo relacionado al manejo de fuentes, internacionalizaci´on y afines, es la biblioteca que se encarga de la impresi´on del texto en pantalla.
Mediante Pango, se ha realiazado la parte de editor de texto que viene intr´ınseca con
CAP´ITULO 2. INFRAESTRUCTURA 14
la aplicaci´on, JDE DS. Se ha reconocido el idioma del sistema, y establecido el tipo de fuente para dicho editor.
Figura 2.3: Editor con multitud de idiomas con pango
2.2.4. Gdk
Se trata de la biblioteca de bajo nivel que usa GTK+ para interactuar con el sistema para los dispositivos gr´aficos y de entrada. GDK contiene toda la funcionalidad necesaria para dibujar objetos y texto en la pantalla e interactuar con el usaurio con varios dispositivos de entrada.
Posee caracter´ısticas de contexto gr´afico y primitivas de dibujado que son adecuadas para dibujar objetos simples y renderizar im´agenes en la pantalla. Nos sirve de gran utilidad para la representaci´on de los nodos y transiciones en la aplicaci´on desarrollada.
A trav´es de GDK podemos acceder a eventos del teclado, ratones y otros dispositivos de entrada. Tambi´en nos proporciona rutinas de bajo nivel para acceder a los datos de arrastrar y soltar y del portapapeles del sistema.
2.2.5. GdkPixbuf
GdkPixbuf es una biblioteca para la carga, manipulaci´on y visualizaci´on de imagenes en distintos formatos (png, gif, jpeg, etc). En la versi´on 1.x, esta librer´ıa no forma parte de GTK+, aunque, al ser la sustituta de imlib, se ha procedido a la distribuci´on junto con GTK+.
Esta biblioteca nos ofrece funciones para el dibujo de imagenes en diversos widgets, el escalado de las mismas, informaci´on de bajo nivel de las im´agenes, etc. El tipo de dato con el que trabaja se denomina GdkPixbuf, es la estructura con la que representa la
CAP´ITULO 2. INFRAESTRUCTURA 15
imagen, y guarda toda su informaci´on.
Con el conjunto de funciones que lleva consigo la librer´ıa, se ha desarrollado el zoom de la vista prev´ıa y la impresi´on del aut´omata.
2.2.6. Cairo
Es una biblioteca gr´afica 2D que cuenta cun una API sofisticada para dibujar vectores gr´aficos, im´agenes compuestas y renderizar texto con antialias.Cairo proporciona soporte para muchos dispositivos de salida, incluyendo el sistema X Window, Microsoft Windows y b´uferesd de imagen, permiti´endole escribir c´odigo para dibujar gr´aficos en diferentes medios independiente de la plataforma.
El modelo de dibujado de Cairo es similar al que proporcionan PostScript y PDF.
La API de Cairo proporciona operaciones de dibujado tales como pincelar y rellenar splines c´ubicos de B´ezier, componer im´agenes y realizar transformaciones afines. Estas operaciones con vectores permiten altos gr´aficos con antialias sin tener que usar el caro dibujo basado en p´ıxeles en el c´odigo de la aplicaci´on.
Tambi´en permite renderizado de alta calidad en m´ultiples dispositivos, como verbigracia la creaci´on de salidas modificadas adecuadas para una impresi´on.
Figura 2.4: Dibujo realizado con Cairo
2.3. LibXml
Es una biblioteca, desarrollada por el proyecto Gnome, de funciones en C cuyo objetivo es tratar archivos XML. Se caracteriza por su gran portabilidad, pues depende s´olo de la biblioteca est´andar de ANSI C. Adem´as de la interfaz nativa en C, provee interfaces para otros lenguajes de programaci´on como: C++, C#, Perl, Python, Ruby y otros. Aunque pertenezca al proyecto Gnome puede usarse de forma independiente.
CAP´ITULO 2. INFRAESTRUCTURA 16
Provee todas las funciones necesarias para trabajar archivos xml, abrir documentos, recorrer, crear y modificar ´arboles (xml), validar contra DTDs y manejar diferentes juegos de caracteres como ISOxxxx, UTF8 o UTF16, entre otras.
Cap´ıtulo 3
Descripci´ on Inform´ atica
En el cap´ıtulo 3 comentaremos como esta desarrollada la aplicaci´on JDE DS de forma minuciosa, su implementaci´on y arquitectura.
3.1. Organizaci´ on del c´ odigo
La aplicaci´on se compone de 23 ficheros con c´odigo c, un directorio llamado /gui con 4 ficheros XML almacenando interfaces gr´aficas y otro directorio /schema albergando ficheros en “.c”, “.h” y Makefile destinados a la creaci´on del esquema final.
3.1.1. Interfaces gr´ aficas
Adentrando en el directorio /gui nos encontramos cuatro fichero XML creados por la aplicaci´on Glade: JDE DS.glade, Editor.glade, Acerca De.glade y VentanaSeleccion.glade.
En este apartado s´olo comentar´e las interfaces que se encuentran en dichos ficheros XML, ya que las ventanas o cuadros de di´alogo de menor importancia se encuentran en c´odigo “.c”, realizadas de forma manual, es decir sin Glade.
JDE DS.glade
El primer fichero respectivamente corresponde con la interfaz general de la aplicaci´on. Dicha interfaz gr´afica conlleva los siguientes widgets de tipo Gtk+: GtkMenuBar, GtkImageMenuItem, GtkButton, GtkImage, GtkLabel, GtkFrame, GtkRadioButton, GtkCheckButton, GtkEntry, GtkHScale, GtkDrawingArea, GtkScrolledWindow, etc..
17
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 18
Figura 3.1: Explicaci´on de la interfaz JDE DS.
El men´u desplegable de la aplicaci´on est´a desarrollado por unGtkMenuBar, cuya funcionalidad es representar un menu en una barra de herramientas. Dicho men´u (figura 3.2) contiene los desplegables de Archivo, Editar, Ver y Ayuda.
Figura 3.2: Contenido del widget GtkMenuBar.
Desplegando el menu Archivo (figura 3.3), contiene ocho items de tipo GtkImageMenuItem: Nuevo, Abrir, Guardar, Propiedades, Convertir, Guardar Imagen, Imprimir, y Salir.
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 19
Figura 3.3: Contenido del menu Archivo.
La opci´on Nuevo, accionable con la secuencia “CTRL + N”, permite crear un proyecto vac´ıo dentro de la aplicaci´on. En caso de aceptar su di´alogo posterior se eliminar´a de la aplicaci´on el proyecto anterior. El item Abrir, accionable con la secuencia “CTRL + O”, es la encargada de abrir una ventana de di´alogo d´onde se deber´a elegir el proyecto a cargar. El tercer item es Guardar, accionable con la combinaci´on “CTRL + S”, cuya acci´on predeterminada es guardar nuestro proyecto.
El cuarto GtkImageMenuItem que nos encontramos es Propiedades, ejecutable con las teclas “CTRL + C”, permite configurar las propiedades del proyecto actual. Le sigue la opci´on Convertir, cuyo acceso directo es mediante las teclas “CTRL + M”, se encarga de crear el resultado final de nuestro aut´omata generado, construye el esquema.
Posteriormente nos encontramos con Guardar Imagen, accesible mediante “CTRL + I”, permite abrir una ventana de di´alogo para guardar el aut´omata generado en forma de im´agen en el directorio que el usuario dese´e. La s´eptima opci´on es Imprimir, ejecutable mediante “CTRL + P”, como su nombre indica nos permite imprimir s´olamente la parte gr´afica del aut´omata. Y para concluir se encuentra Salir, accionable mediante
“CTRL + Q”, nos proporciona la salida de la aplicaci´on.
El segundo menu que nos encontramos es el deEditar (figura 3.4), el cu´al s´olo tiene dos GtkImageMenuItem: Deshacer y Rehacer.
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 20
Figura 3.4: Contenido del menu Editar.
Como su nombren indican los dos se usan para deshacer y rehacer cambios ocasionados en el proyecto. Los accesos directos de cada una son “CTRL + Z” para deshacer los cambios y “CTRL + MYS + Z” para rehacerlos.
El tercer item que nos encontramos en el men´u desplegable de la aplicaci´on es Ver (figura 3.5), conteniendo el bot´on de Visualizar. Dicho bot´on nos permite lanzar una ventan con el aut´omata actual, mostrando una vista m´as general. Las teclas de acceso directo son “CTRL + V”.
Figura 3.5: Contenido del menu Ver.
Por ´ultimo item del men´u nos encontramos la opci´on de Ayuda (figura 3.6. Esta contiene solamente un item, denominado Acerca De, en el que podemos ver ciertas caracter´ısticas de la aplicaci´on.
Figura 3.6: Contenido del menu Ayuda.
Los botones de la aplicaci´on son widgets de tipo GtkButton, cada uno tiene asociada un tipo evento a una determinada operaci´on. Por la circunstancia de organizar el c´odigo, todas las operaciones se encuentran dentro del fichero callbacks.
Figura 3.7: Botones de la aplicaci´on.
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 21
Todos estos botones tienen su item correspondiente en el men´u de la aplicaci´on, ya visto anteriormente, por lo que tambi´en dichos items poseen la misma funci´on de operaci´on que su bot´ones paralelos.
Bot´on Item del Men´u Funci´on
Propiedades Propiedades on BtnPropiedades pressed
Nuevo Nuevo on BtnNuevo pressed
Abrir Abrir on BtnAbrir activate
Guardar Guardar on BtnGuardar pressed Deshacer DesHacer on BtnUndo pressed Rehacer Rehacer on BtnRedo pressed Visualizar Visualizar on BtnVisualizar pressed
Imagen Imagen on BtnImagen clicked
Imprimir Imprimir on BtnImprimir pressed Convertir Convertir on BtnConvertir pressed
Codigo – on BtnCodigo pressed
– Salir on window1 destroy
– Ayuda on MenuAyudaAcercaDe activate
Cuadro 3.1: Relaci´on de cada bot´on o item del men´u con su funci´on de operaci´on.
Todos los botones como he comentado anteriormente tienen las mismas funciones que los items que se encuentran en el men´u desplegable. Salvo el bot´on de Codigo, que no se encuentra en el men´u. Este bot´on nos permite abrir el c´odigo global de nuestro esquema, mediante un editor de la plataforma.
La selecci´on de acci´on es un conjunto de botones de tipo GtkRadioButton englobados por un marco cuyo widget es un GtkFrame. Dentro del marco tambi´en encontramos un bot´on de tipo GtkCheckButton, ver figura 3.8.
Figura 3.8: Marco de selecci´on de acci´on.
Todos los GtkRadioButton que se encuentran en la interfaz est´an agrupados en un mismo conjunto, este hecho hace que s´olo y solamente uno sea el seleccionado. Estos botones nos ofrencen la posibilidad de crear estados, transiciones o permitir la selecci´on de los objetos que hay en la zona de creaci´on del aut´omata.
Dentro de este frame tambi´en tenemos un bot´on de tipo GtkCheckButton, con la etiqueta de Mover todo. Este bot´on nos da la posibilidad de elegir si queremos la opci´on de mover las transiciones cuando se muevan los estados.
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 22
Las funciones de operaci´on ubicada en el fichero callbacks relacionadas con el evento pressed de cada uno de los botones, son las siguientes:
Bot´on Funci´on
Estados on RdBtnEstados pressed Transiciones on RdBtnTransiciones pressed Selecci´on on RdBtnSeleccion pressed
Cuadro 3.2: Relaci´on de cada bot´on con su funci´on en el fichero callbacks.
El indicador del estado inicial est´a formado por dos widgets. Uno de ellos es un GtkLabel, el cu´al muestra el texo de “Estado Inicial:”; el otro widget es un GtkEntry con la propiedad de no modificable, s´olo nos muestra el nombre del estado inicial. Ver figura 3.9.
Figura 3.9: Widgets de la selecci´on del estado inicial.
Los dos widgets que forman parte de la indicaci´on del estado inicial, no producen ninguna acci´on, por lo que no hay que recoger ning´un tipo de evento y no necesitan estar relacionados con ninguna funci´on.
El editor de velocidad est´a formado por un GtkLabel y un GtkHScale. Este
´
ultimo widget es el encargado de modificar la velocidad del esquema, por lo que debe ser sensible tras su cambio de valor. La funci´on que recoge esa se˜nal que nos indica el cambio de valor es: on HscaleVelocidad value changed. El GtkHScale se encuentra ajustado mediante un objeto de tipo GtkAdjustment, este se encarga de establecer los rangos de valores, el valor inicial y el incremento de valores por cada movimiento. Ver en la figura 3.10.
Figura 3.10: Configuraci´on de la velocidad del esquema.
La zona de creaci´on del aut´omata est´a dise˜nada por varios widgets: un GtkFrame,
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 23
un GtkScrolledWindow, un GtkViewPort, dos GtkAdjustment y el m´as importante un GtkDrawingArea denominada en el fichero XML como ZonaDibujo, ver figura 3.11.
Figura 3.11: Zona de creaci´on del aut´omata
Es la parte m´as importante de la aplicaci´on, porque es d´onde se centra el mayor nivel de interactividad con el usuario. En est´a zona es donde se dibujan los estados, transiciones dando la posibilidad de eliminarlos, moverlos, programarlos, cambiarlos de nombre, etc..
El n´umero de funci´ones para albergar los eventos que produce el GtkDrawingArea son considerables. A continuaci´on las muestro distinguiendo las se˜nales que proceden a cada funci´on, ver en la tabla 3.4.
Evento Desencadenante Funci´on
button press event Presionar con el rat´on on ZonaDibujo button press event button release event Soltar el rat´on on ZonaDibujo button release event configure event Reconfigura el widget on ZonaDibujo configure event expose event Mostrar el widget on ZonaDibujo expose event motion notify event Movimiento del rat´on on ZonaDibujo notify event
Cuadro 3.3: Relaci´on de cada funci´on con su se˜nal de GtkDrawingArea.
Otros widgets que tambi´en tienen funciones recogiendo sus se˜nales son los dos GtkAdjustment, los cuales tienen la misma funci´on on adjustmentDibujo value changed.
Esta funci´on se ejecuta cuando cambian de valor estos widgets que funcionan al un´ısono con los scrolls de la zona de creaci´on del aut´omata.
La parte de activaci´on de sensores (figura 3.12). Esta parte est´a organizada por 5 GtkCheckButton, correspondientes por cada sensor que se puede insertar en el esquema.
Nos encontramos con los Motors, Sonars, el Laser, los Encoders y la Camara.
Figura 3.12: Activaci´on de sensores
Las funciones que captan el evento de “clicked“ en los widgets son las siguientes:
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 24
Widget Funci´on
Motors on ChckBtnMotors clicked Sonars on ChckBtnSonars clicked Laser on ChckBtnLaser clicked Encoders on ChckBtnEncoders clicked Camara on ChckBtnCamara clicked
Cuadro 3.4: Relaci´on de cada funci´on con su se˜nal y widget.
Para concluir con la descripci´on de esta interfaz, acabaremos por definir las se˜nas y las funciones de operaci´on que se encuentran enlazadas a la ventana de la interfaz, denominada dentro del fichero XML como window1. S´olamente tenemos una se˜nal que recoger, es delete event, la cu´al se acciona en el momento de cerrar la ventana.
La funci´on que recoge dicha se˜nal es on window1 destroy ubicada dentro del fichero callbacks.
Editor.glade
En esta secci´on comentar´e al detalle con que componentes est´a elaborado el editor de programaci´on de JDE DS.
Nos encontramos tres partes diferenciadas dentro del Editor: el men´u desplegable, los botones del editor, y el editor de texto. Ver figura 3.14.
Figura 3.13: Partes de la interfaz del Editor
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 25
Dentro del men´u desplegable creado gracias a un GtkMenuBar, nos encontramos cuatro tipos de men´us: Archivo, Editar y B´uscar. En el primero nos encontramos las funciones comunes de cualquier aplicaci´on, que son Guardar, Cerrar y Salir.
Figura 3.14: Men´u archivo del editor.
Todos estos items son creados mediante el objeto GtkMenuImageItem, y todos ellos provocan la activaci´on de la se˜nal activate. Las funciones que captan dicha se˜nal para cada item son las siguientes (tabla 3.5):
Widget Funci´on Guardar GuardarBloc Cerrar BorrarPaginasBloc Salir SalirBloc
Cuadro 3.5: Relaci´on de cada item de Archivo del editor, con su funci´on correspondiente.
La funci´on de Guardar nos permite almacenar cada pesta˜na abierta del editor, nunca se guardar´an todas las pesta˜nas a la vez. Con Cerrar podemos cerrar las pesta˜nas abiertas del editor. Y por ´ultimo el item Salir, que como su nombre indica nos permite salir de la aplicaci´on.
Entramos en el segundo men´u del editor, denominado Editar. Este men´u lo componen tres items: Cortar, Copiar y Pegar (figura 3.15). Estos componentes son del tipo GtkImageMenuItem. Cada bot´on que compone dicho men´u est´a ligado a una funci´on perteneciente al fichero callbackbloc.
Figura 3.15: Men´u Editar del editor de c´odigo.
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 26
En la tabla 3.6 muestro la relaci´on de cada bot´on con su funci´on de operaci´on.
Todas estas funciones trabaja bajo la se˜nal activate.
Widget Funci´on Cortar TextCut Copiar TextCopy Pegar TextPaste
Cuadro 3.6: Correspondencia de cada items del men´u Editar con su funci´on de operaci´on.
El bot´on Cortar nos permite cortar una cadena de texto del editor, almacen´andola en el portapapeles. Copiar nos permite duplicar una cadena de texto seleccionada previamente para pegarla mediante el bot´on Pegar en cualquier posici´on del cursor.
Como ´utlimo men´u nos encontramos el de Buscar, el cu´al est´a constituido por un items llamado Buscar (figura 3.16). La funci´on que recoge la se˜nal activate de este bot´on es menu Find perteneciente al fichero callbackbloc.
Este bot´´ on nos permite mostrar una ventana emergente con los recursos necesarios para encontrar cualquier cadena dentro de la pesta˜na activa del editor.
Figura 3.16: Men´u Buscar del editor de c´odigo.
Una vez explicado los men´us deplegables del editor de c´odigo, paso a detallar los botones de esta interfaz. Los botones del editor est´an compuestos por seis objetos de tipo GtkButton. Los nombres adquiridos son los siguiente: Guardar, Atr´as, Adelante, Deshacer, Rehacer y Cerrar.
Figura 3.17: Botones que forman parte del editor de c´odigo.
Cada bot´on tiene activado el evento pressed, por lo que son sensibles al pulsarlos.
En la tabla 3.7 muestro la funci´on predefinida que se encargar´a de recoger dicha se˜nal.
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 27
Widget Funci´on Guardar GuardarBloc Atr´as PrevPage Adelante NextPage Deshacer onUndoPressed Rehacer onRedoPressed Cerrar BorrarPaginasBloc
Cuadro 3.7: Correspondencia de cada bot´on del editor de c´odigo con su funci´on de operaci´on.
El bot´on de Guardar nos permite guardar la pesta˜na que se encuentra activa.
Los botones de Atr´as y Adelante nos desplazan de pesta˜na. Deshacer y Rehacer nos permiten hacer y deshacer cambios ocasionados dentro del editor de texto y son comunes a todas las pesta˜nas. Y por ´ultimo el bot´on Cerrar nos da la posibilidad de cerrar la pesta˜na actual.
La zona de edici´on de c´odigo no se encuentra definida al completo en el fichero XML. S´olo define la parte de las pesta˜nas, realizado mediante el widget GtkNotebook que nos permite a˜nadir pesta˜nas y movernos sobre ellas. El evento que es recogido por la funci´on PageSwitch es el de switch page, que se activa al cambiar de pesta˜na.
Como he resaltado antes, se muestra incompleta la definici´on de esta parte de la interfaz en el c´odigo XML. Ya que los contenidos de las pesta˜nas se encuentran definido en el fichero callbackbloc. La raz´on por la que se define mediante c´odigo ”C“ es al desconocimiento del n´umero de pesta˜nas y por tanto de editores de texto que podemos tener abiertos, por ello hay que hacerlo de forma din´amica y asignar a cada nueva pesta˜na un nuevo widget que nos permita escribir y editar el texto correspondiente.
Figura 3.18: GtkNotebook perteneciente al editor de c´odigo.
Para concluir con esta interfaz, definir´e laventana principal. Esta ventana tiene solamente un evento activo, se trata del delete event. La funci´on que recoge esta se˜nal es la misma que la del bot´on Salir del men´u Archivo, se trata de la funci´on: SalirBloc.
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 28
Acerca De.glade
Esta interfaz es meramente informativa (figura 3.19. S´olo tiene un widget que emita alguna se˜nal, se trata de un bot´on de tipo GtkButton, cuya se˜nal es la de pressed recogida por la funci´on gtk widget destroy, al que se le pasa como par´ametro el widget de la ventana.
Esta funci´on no se encuentra en ning´un fichero, es propia de la biblioteca de gtk+, y nos permite cerrar la ventana sin escribir nada de c´odigo.
Figura 3.19: Interfaz gr´afica del fichero Acerca De.glade.
VentanaSeleccion.glade
Este ´´ ultimo fichero con extensi´on ”.glade“, est´a destinado a la creaci´on de una ventana de di´alogo con selector de archivos. El objetivo es desarrollar una ventana con la que sea capaz de elegir la ruta donde guardar la imagen del aut´omata en formato png.
Esta intefaz est´a formado por GtkFileChooserDialog al que se le a˜nade un GtkLabel, GtkEntry, y dos botones de tipo GtkButton, ver figura 3.20.
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 29
Figura 3.20: Interfaz gr´afica del fichero VentanaSeleccion.glade.
Los dos widgets que contienen una se˜nal que es recogida por una funci´on de operaci´on pertenecen a los botones. En la tabla 3.8 se muestran las funciones correspondientes a cada widget. El bot´on Aceptar da pie al guardado de la imagen del aut´omata en la ruta seleccionada por el usuario, no obstante, el bot´on Cancelar cierra le ventana y no procede al guardado de la imagen.
Widget Funci´on
Aceptar on ventanaSeleccion BtnAceptar clicked Cancelar gtk widget destroy
Cuadro 3.8: Correspondencia de cada bot´on del fichero VentanaSeleccion.glade con su funci´on de operaci´on.
3.1.2. Ficheros en C
En esta secci´on, comentar´e de forma detallada el contenido que hay en cada fichero programado. Tanto como las estructuras que albergan como las funciones m´as principales dejando las m´as sup´erfluas.
Cuento con 23 ficheros en ”C“ con sus respectivos ”.h“.
main.c
Este fichero es el encargado de iniciar la aplicaci´on, ya que alberga la funci´on principal de JDE DS.
La ´unica funci´on que contiene es:
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 30
main: Es la encargada de crear la carpeta temporal donde se ubicar´an los ficheros de dichas caracter´ısticas. Adem´as inicializa todo lo necesario para utiliar las herramientas de GTK mediante la funci´on gtk init() e inicia el bucle principal de GTK con la llamada a gtk main(). A lo largo de la funci´on carga la interfaz gr´afica principal.
interface.c / interface.h
El objetivo de estos dos ficheros es el de levantar la interfaz gr´afica principal, es decir la contenida en el archivo JDE DS.glade. Este par de ficheros s´olo contienen una
´
unica funci´on:
create window1: Esta funci´on se encarga de inicializar una de las estructuras m´as importantes de la aplicaci´on, inicializa el contenido, los sensores y algunas variables relacionadas con el ”Undo/Redo“ de la aplicaci´on.
Su funci´on m´as importante es la de cargar el fichero XML de la interfaz principal mediante la librer´ıa GtkBuilder ya mencionada anteriormente. Una vez cargado el fichero obtendr´a los widgets m´as importantes o necesarios para posteriores operaciones.
Debido a problemas en cuanto a la insercci´on de accesos directos en algunos items del men´u desplegable de la interfaz JDE DS, se establecen de forma manual dichas accesibilidades. Se encarga de conectar todas las se˜nales predefinidas en el fichero XML con sus respectivas funciones.
callbacks.c / callbacks.h
Este par de ficheros son los encargados de soportar las funciones que la interfaz principal tiene como ”callbacks“.
Las funciones que alberga son las siguientes:
on window1 destroy: Es la funci´on encargada de destruir la interfaz principal, sin embargo, preguntando siempre que no se haya guardado el proyecto actual.
on ZonaDibujo configure event: El objetivo es dibujar el pixmap en el GtkDrawingArea siempre que se reconfigure la zona de creaci´on del aut´omata. A parte inicializa la variable global dibujo de tipo TypDibujo que la comentaremos posteriormente.
on ZonaDibujo expose event: Funci´on que nos permite refrescar la zona del aut´omata cuando se muestre la ventana principal. A parte de dicha funci´on resetea los sensores gr´aficos para que no este ninguno dado.
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 31
on ZonaDibujo motion notify event: Esta funci´on es llamada cuando detecta movimiento del rat´on encima de la zona de creaci´on. El objetivo que tiene es comprobar si se quiere arrastrar un estado/transici´on mediante la variable moviendo, en caso afirmativo comprueba si el rat´on se encuentra en los bordes de la zona de creaci´on para hacer o no scroll.
on adjustmentDibujo value changed: Tiene como objetivo actualizar el GtkDrawingArea con el pixmap que no contiene los sensores. Esta funci´on se ejecuta cuando se mueven los scrolls de la zona del aut´omata.
on ZonaDibujo button press event: Esta funci´on viene activada, cuando se presiona un bot´on del rat´on sobre la zona del aut´omata. Tiene como objetivo determinar la acci´on que desea realizar el usuario. En primer lugar realiza una copia del pixmap del aut´omata, a otro pixmap que ser´a el encargado de mostrar las l´ıneas de los sensores de cada estado, todo esto se ver´a posteriormente en el fichero de Dibujo.
La segunda acci´on que realiza es recoger la posici´on donde se hizo ”click“ y el tipo de bot´on. A continuaci´on comprueba si se ha realizado con el bot´on derecho, por lo que mostrar´a un men´u desplegable con varias opciones; en caso contrario dependiendo de una serie de variables globales detectar´a si el usuario quiere mover el origen o el destino de una transici´on, crear o mover un estado o transici´on.
Cuando el usuario decida mover uno de los dos objetos, actualizar´a variables para posteriormente realizar dicha operaci´on.
Tambi´en se encarga de evaluar si debe mostrar los sensores ligados a cada estado, todo depender´a de la opci´on elegida dentro de la zona de selecci´on de acci´on.
on ZonaDibujo button release event: La funci´on se activa cuando se suelta el bot´on del rat´on dentro de la zona de creaci´on del aut´omata. El objetivo es determinar la acci´on que desea realizar el usuario.
En esta funci´on comprobar´a d´onde desea el usuario cambiar el destino o el origen de la transici´on, d´onde desea mover los estados o transiciones. Todo esto es posible gracias a las variables globales de la aplicaci´on que almacenan el seguimiento del usuario sobre el GtkDrawingArea.
on BtnNuevo pressed: Se encargar´a de mostrar una ventana de di´alogo para confirmar si el usuario desea un nuevo proyecto.
on BtnPropiedades pressed: Muestra una ventana para configurar los detalles del proyecto actual.
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 32
on BtnGuardar pressed: Comprueba si se puede realizar el guardado del proyecto actual, en caso contrario manda un mensaje informativo al usuario.
on BtnAbrir activate: La funci´on principal es mostrar una ventana de selecci´on de ficheros, para cargar un proyecto. En primer lugar crea una ventana de selecci´on de ficheros con las opciones de abrir y cancelar, la selecci´on viene dada con un filtro, apareciendo s´olo los ficheros con extensi´on ”.xml“.
En caso de aceptar la carga del fichero elegido, configurar´a las variables y las propiedades del proyecto, eliminar´a el proyecto actual de la aplicaci´on para a continuaci´on cargar el nuevo proyecto. Tambi´en inicializar´a ”Undo/Redo“ de la aplicaci´on y cerrar´a el editor de c´odigo en caso de estar abierto.
on BtnUndo pressed: Es el encargado de cargar una versi´on del proyecto anterior al cambio ocasionado en el mismo. Y posteriormente comprobar´a si deben de ser visibles los botones Deshacer y Rehacer.
on BtnRedo pressed: Esta funci´on trabaja de forma sim´etrica que la anterior, salvo que cargar´a una acci´on siguiente.
on RdBtnTransiciones pressed: Se ejecuta cuando se presiona el bot´on transiciones, dentro de la zona de selecci´on de acci´on. Se encarga de modificar las variables oportunas como cambio de acci´on, y adem´as desactiva la zona de activaci´on de sensores.
on RdBtnEstados pressed: Se ejecuta al activar el bot´on Estados. Se encarga de cambiar las variables oportunas y de activar la zona de los sensores.
on RdBtnSeleccion pressed: Se ejecuta al presionar el bot´on Selecci´on. Al igual que las funciones anteriores cambia las variables correspondientes y activa la zona de los sensores.
on BtnConvertir pressed: Esta funci´on se encarga de convertir el aut´omata en esquema, en caso de ser factible. Si no se encuentra configurado el proyecto o falta alguna propiedad del mismo muestra un mensaje al usuario.
on HScaleVelocidad value changed: Se encarga de actualizar la variable que lleva la velocidad de ejecuci´on del esquema.
on BtnCodigo pressed: Abre el editor de c´odigo para mostrar y editar el c´odigo global del esquema.
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 33
on BtnImprimir pressed: Abre el di´alogo de impresi´on para imprimir el dibujo del aut´omata.
on BtnVisualiar pressed: Abre la visualizaci´on de la estructura del aut´omata en una nueva ventana que tiene soportado la acci´on de zoom.
on ChckBtnMotors pressed: Su funci´on es la de encargar el dibujado de los sensores en caso de tenerlos activos y de modificar los sensores en el estado seleccionado.
Esta funci´on es sim´etrica a las relacionadas con los sensores de Sonars, Laser, Encoders y Camara.
on MenuAyudaAcercaDe activate: Lanza la interfaz del fichero Acerca De.glade.
on BtnImagen clicked: Lanza la interfaz del fichero VentanaSeleccion.glade.
Dibujo.c / Dibujo.h
Este conjunto de ficheros define la estructura TypDibujo, encargada de almacenar los widgets relacionados con el dibujo del aut´omata; y adem´as contiene los m´etodos tanto para dibujar transiciones como nodos y sensores.
El TypDibujo es una estructura definida de la siguiente manera:
typedef s tr u c t {
GdkDrawable ∗ pixmap ; // Pixmap para e l aut´omata
GdkDrawable ∗ backPixmap ; // Copia para d i b u j a r l o s s e n s o r e s GtkWidget ∗ z o n a D i b u j o ; // Almacena GtkDrawingArea
GtkWidget ∗ s c r o l l ; // Almacena e l S c r o l l e d W i n d o w i n t l o n g i t u d X ; // L o n g i t u d d e l GtkDrawingArea i n t l o n g i t u d Y ; // A l t r u a d e l GtkDrawingArea GdkGC ∗ penWhite ; // C o l o r e s Blanco
} TypDibujo ;
En el pixmap s´olo se dibuja la estructura del aut´omata, es decir nodos y transiciones.
BackPixmap es el pixmap en el que se representan los nodos y transiciones con los sensores. La elecci´on de un doble pixmap se realiza para evitar tener que redibujar todos los objetos del pixmap, a la hora de mostrar los sensores. La zonaDibujo almacena el widget de la zona de creaci´on del aut´omata. Las dos variables de tipo ”int“ almacenan el tama˜no del GtkDrawingArea para aplicarselo a los diferentes pixmap. Y por ´ultimo el tipo GdkGC almacena el color blanco para postrarlo como fondo de la zona de creaci´on.
Para el dibujo de estados, transicones y sensores se emplea las herramientas de la biblioteca de Cairo, ya mencionada en el cap´ıtulo anterior.
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 34
Las funciones m´as importantes en este fichero son las siguientes:
En primer lugar posee las funciones b´asicas para tratar un tipo de estructura TypDibujo, como son: construirTypDibujo, getPixmapTypDibujo, setPixmapTypDibujo, etc.. Es decir contiene las funciones constructoras y las selectoras.
dibujarPunta: Esta funci´on dado dos puntos y un color, dibuja en el pixmap la punta de una flecha en la direcci´on correcta.
Dibujar: Es la funci´on encargada de borrar un pixmap, colocando el fondo en blanco.
Dibujar Pixmap Estado / Borrar Pixmap Estado: estas dos funciones estan destinadas en dibujar un estado en el pixmap. Lo que diferencia entre una y otra funci´on es el color que se aplica en el dibujado.
Posicion Transicion: Es la encargada de establecer la posici´on d´onde se va a representar la transici´on, debido a que se desconoce el n´umero de transiciones entre nodos, o entre un mismo nodo. Antes de decidir la posici´on concreta determina si es factible dicha posici´on, en caso contrario elige otra con mayor factibilidad.
Dibujar Pixmap Transicion / Borrar Pixmap Transicion: Al igual que ocurre con los estados, la diferencia entre ellas son los colores aplicados en el dibujo. Las dos funciones distinguen dos tipos de representaciones de una transici´on, dependiendo si es un bucle o una simple uni´on de nodos.
Dibujar Pixmap Bucle / Borrar Pixmap Bucle: Las dos son encargadas de dibujar las transiciones finales de tipo bucle de un nodo. La diferencia entre ellas es el color que se aplica para el dibujado.
Insertar Nombre Transicion / Borrar Nombre Transicion:
Son encargadas de dibujar un nombre pasado como argumento como nombre de la transici´on. La primera funci´on la dibuja en color negro y la segunda en blanco (realizando la funci´on de borrado).
dibujarConexionesSensores / dibujarBorradoConexionesSensores:
Ambas funciones dibujan los sensores estimados de un nodo. El dibujo de los sensores es de una l´ınea cuyo origen se encuentra en el estado seleccionado hasta
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 35
donde se encuentra el GtkCheckButton del sensor correspondiente. Cada sensor tiene un color predeterminado.
dibujarDibujoSensores: Esta funci´on es la encargada de determinar si se debe dibujar o no un sensor en el backPixmap.
borrarDibujoSensores: El objetivo es sim´etrico que el anterior, establece si se debe borrar los sensores.
copiarPixmapAreaDibujo: Devuelve un pixmap id´entico al pixmap de la estructura TypDibujo cuya variable global es la de dibujo.
volcarPixmapAreaDibujo: Guarda en el pixmap de la variable dibujo, el gr´afico mostrado por el GtkDrawingArea de la aplicaci´on.
CalcularRangoUtilizadoPixmap: Se encarga de establecer los valores m´aximos y m´ınimos tanto de altura como de longitud, que se encuentran dibujados dentro del pixmap.
guardarPixmapImagenPng: Dada una ruta, almacena el pixmap de la estructura TypDibujo en formato imagen ”.png“.
actualizarPixmap / actualizarPixmapSensores: Este par de funciones actualizan la zona de creaci´on del aut´omata con la imagen que contiene el pixmap o el backpixmap respectivamente.
Nodos.c / Nodos.h
Los ficheros Nodos.c y Nodos.h almacenan las funciones constructoras y selectoras del tipo TypNodo. Este tipo es el que da pie a cada nodos construido.
Las caracter´ısticas de TypNodo son las siguientes:
typedef s tr u c t {
i n t s u p i z q [ 2 ] ; // E s q u i n a s u p e r i o r i z q u i e r d a i n t s u p d e r [ 2 ] ; // E s q u i n a s u p e r i o r d e r e c h a i n t i n f i z q [ 2 ] ; // E s q u i n a i n f e r i o r i z q u i e r d a i n t i n f d e r [ 2 ] ; // E s q u i n a i n f e r i o r d e r e c h a i n t c e n t r o [ 2 ] ; // Centro d e l nodo
i n t i d ; // I d e n t i f i c a d o r ´u n i c o
G S t r i n g ∗ nombre ; //Nombre d e l nodo
i n t m o d i f i c a d o ; // V a r i a b l e de m o d i f i c a d o t e x t o GSList ∗ L i s t a ; // L i s t a de t r a n s i c i o n e s
T y p S e n s o r e s ∗ s e n s o r e s ; // V a l o r de l o s s e n s o r e s G S t r i n g ∗ c o d i g o ; // Codigo d e l esquema en e l nodo } TypNodo ;
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 36
Los array bidimensionales de dos enteros, almacenan la posici´on del nodo. Aunque se encuentren los nodos representados mediante circunferencias, internamente su tama˜no esta representado por un cuadrado. El id de nodo es ´unico, es lo que distingue a los nodos. La variable modificado nos se˜nala si se a tenido intenci´on de modificar el nodo, es decir, si se encuentra abierto en el editor de c´odigo. Lista representa una lista simple de punteros a las transiciones que se encuentran relacionadas con dicho nodo. La variable de tipo TypSensores representa el valor de los sensores que el nodo, y por ´ultmo tanto el c´odigo como el nombre son dos variables de caracter GString que almacenan su texto correspondiente.
Como ya he comentado antes, las funciones que albergan estos ficheros son las b´asicas para operar con una estructura de estas caracter´ısticas. Se encuentran las constuctoras para poder crear este tipo de estructuras, la funciones de tipo ”setter“ y
”getter“, para modificar los variables y extraerlas. Las ´unicas funciones que merecen una atenci´on especial son:
Nodo factible: Pas´andole la posici´on donde se ubicar´a el centro del nodo, esta funci´on determinar´a si es posible ubicarla ah´ı. Se encargar´a de mirar dentro de la variable global Indice (array de tipo TypPos) si no se encuentra ning´un nodo o transici´on y tambi´en de que el nodo se pueda representar de forma completa en el widget GtkDrawingArea devolviendo si es factible o no su representaci´on.
ReplicarNodo: Esta funci´on devuelve una copia exacta del nodo en cuesti´on salvo en los par´ametros que se pasan a la funci´on. Dichos par´ametros son el identificador ´unico, y la posici´on del nodo dentro del pixmap.
Transiciones.c / Transiciones.h
Este par de ficheros, al igual que el de Nodos, se encargan de soportar a un tipo de estructura propia. La estructura que se encuentra en este par de ficheros es TypTran, aportando las caracter´ısticas esenciales para soportar la construci´on de transiciones en la aplicaci´on. La estructura es la siguiente:
typedef s tr u c t {
i n t IdentNodoA ; // I d e n t i f i c a d o r NodoA i n t IdentNodoB ; // I d e n t i f i c a d o r NodoB i n t I d e n t ; // I d e n t i f i c a d o r t r a n s i c i ´o n i n t PosA [ 2 ] ; // P o s i c i ´o n NodoA
i n t PosB [ 2 ] ; // P o s i c i ´o n NodoB
i n t PosTrans [ 2 ] ; // P o s i c i ´o n t r a n s i c i ´o n
i n t PosTransL [ 2 ] ; // P o s i c i ´o n en c a s o de b u c l e i n t PosTransR [ 2 ] ; // P o s i c i ´o n en c a s o de b u c l e
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 37
i n t m o d i f i c a d o ; // V a r i a b l e m o d i f i c a d o i n t t e m p o r a l ; // T r a n s i c i ´o n t e m p o r a l long msec ; // M i l i s e g u n d o s
G S t r i n g ∗ nombre ; //Nombre t r a n s i c i ´o n G S t r i n g ∗ c o d i g o ; // C´odigo t r a n s i c i ´o n }TypTran ;
Las variables IdentNodoA y IdentNodoB, almacenan el identificador del los nodos que se encuentran en la transici´on, origen y destino respectivamente. El Ident contiene el identificador ´unico para cada transici´on (es independiente a los nodos). PosA y PosB albergan la posici´on de los nodos. Las variables PosTrans, PosTransL y PosTransR llevan la posici´on del nodo, la primera el la posici´on donde se ubica la transici´on y las dos ´ultimas posiciones son auxiliares para representar una transici´on de tipo bucle. La variable modificado, al igual que en los nodos, sirve para verificar si la transici´on se encuentra abierta en el editor de c´odigo. temporal y msec nos indican si es una transici´on temporal y en caso de serlo guardar los milisegundos. Y por ´ultimo nos encontramos con los tipos GString de las variables nombre y codigo que almacenan el texo para el nombre de la transici´on y para el c´odigo programado dentro de la transici´on.
La ´unica transici´on que merece un poco de atenci´on, debido a que las dem´as son las necesarias para construir y soportar este tipo de dato, es la siguiente:
transici´on factible: esta funci´on nos devuelve el nivel de factibilidad que tiene una transici´on para ubicarse en una posici´on concreta. Se encarga de revisar si se encuentran nodos u otras transiciones dentro de la variable global Indice (se explicar´a posteriormente) en esa misma posici´on, adem´as de comprobar si la posici´on se encuentra fuera del rango de dibujo del aut´omata.
Objeto.c / Objeto.h
Estos ficheros se basan en respaldar la estructura definida en los mismos. El tipo de dato definido es el de TypObjeto. La construcci´on de dicho tipo viene dado por la inserci´on dentro de la zona del aut´omata por un elemento externo a los nodos o transiciones ya vistos con anterioridad, por ello surgi´o. El tipo es el siguiente:
typedef s tr u c t { i n t i d ;
i n t c o n t ;
G S t r i n g ∗ nombre ; G S t r i n g ∗ c o d i g o ; i n t m o d i f i c a d o ; } TypObjeto ;
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 38
Esta estructura debe tener similitudes con los nodos y transiciones, sobre todo en el
´
ambito del identificador ´unico, el nombre, el c´odigo programado y la variable modificado controlando si se encuentra abierto en el editor de c´odigo.
Las funciones que ofrecen este par de ficheros est´an dedicadas a la estructura comentada. Por lo que carecen de importancia en cuento a la explicaci´on. Se tratan de las funciones generadoras, y las funciones ”setter“ y ”getter“ de la estructura.
Sensores.c / Sensores.h
El objetivo de los dos ficheros es almacenar una estructura capaz de albergar los sensores de cada nodo, con la caracter´ıstica de poseer una f´acil relaci´on con la zona de los sensores dentro de la interfaz general.
El tipo de dato construido se denomina TypSensores formado por un array de cinco celdas de booleanos, cada una est´a otorgada a un sensor en particular.
typedef s tr u c t {
g b o o l e a n s e n s o r e s [ 5 ] ; } TypSensores ;
Debido a que la mayor´ıa de las funciones se encuentran enfocadas en el abastecimiento de dicha estructura, proceder´e a explicar aquellas funciones m´as interesantes:
actualizarSensoresGUI: Dado un tipo TypSensores actualiza la zona de los sensores de la interfaz con el contenido de dichos sensores.
resetearSensoreGUI: Dentro de la interfaz vac´ıa la zona de los sensores, es decir, deja los botones sin activar.
activarSensoresGUI: Esta funci´on se encarga de habilitar o deshabilitar la zona de los sensores de la parte de la interfaz gr´afica.
recopilarSensores: El objetivo de esta funci´on es recoger de forma global qu´e sensores hay que activar o no para la elaboraci´on del esquema, por tanto deber recorrer todos los nodos construidos por el usuario.
Contenido.c / Contenido.h
Estos dos fichero tienen como objetivo albergar y controlar los datos de la aplicaci´on.
Para ello contienen 3 tipos de datos importantes, con su m´etodos correspondientes para poder construir los tipos de datos, extraer e importar los nodos y transiciones.
CAP´ITULO 3. DESCRIPCI ´ON INFORM ´ATICA 39
En primer lugar proceder´e a explicar el tipo de dato que nos permite identificar la transici´on o el nodo con la posici´on del GtkDrawingArea.
typedef s tr u c t { i n t num ; i n t nodo ; } TypPos ;
TypPos I n d i c e [ 2 5 0 0 ] [ 2 5 0 0 ] ;
La variable Indice es un array del tama˜no de la zona de creaci´on del aut´omata, compuesto en cada celda por un registro de dos enteros. El num nos almacenar´a el identificador del objeto (Objeto/Nodo/Transici´on). Y la variable nodo nos almacenar´a los siguiente valores dependiendo del tipo de objeto contenido en esa posici´on. Tomar´a valor -1 en caso de que est´e vac´ıo, 1 si es un nodo, 2 si es una transici´on, y 3 si es un tipo objeto.
Por tanto Indice nos permite la habilidad de saber si el usuario hace ”click“ en un objeto o no, y en caso haberlos saber con exactitud el objeto en cuesti´on. La creaci´on de esta variable fu´e fruto de una gran reflexi´on, ya que ganamos en velocidad perdiendo en memoria. Otra de las opciones que le hizo frente fu´e comparar todos los objetos construidos para saber si estaban en el rango del puntero, sin embargo la velocidad disminuye considerablemente con el n´umero de objetos que el usuario puede construir.
Tras la meditaci´on me decid´ı por la primera opci´on debido a que actualmente el tema de memor´ıa no resulta un gran problema.
Los tipos de datos en los que se almacenan los nodos o transiciones, son en tablas de tipo Hash concretamente del tipo GHashTable pertenecientes a Gtk+. Decid´ı esta opci´on por la mejor´ıa que ofrece en las b´usquedas frente a las listas. Como clave decid´ı el identificador de los objetos.
A continuaci´on explicar´e las funciones m´as importantes de este par de ficheros:
Inicializar Contenido: El objetivo de esta funci´on es inicializar la estructura del Indice colocando cada num y nodo con valor -1.
borrarContenido: Se encarga de eliminar la tabla Hash de nodos y la de transiciones, liberando tambi´en la memor´ıa de todos los objetos que la componen.
Adem´as inicializa la zona del aut´omata.
Marcar Nodo Contenido / Marca Transicion Contenido: Marca en la variable Indice la ubicaci´on del nodo/transici´on pasado como par´ametro.