scieee AI-readable full text Open interactive document viewer

Control de misión de UAV para transporte de vehículo

Mesta Guisasola, Diego

Abstract

El sector de los vehículos no tripulados ha tenido un gran desarrollo en los últimos años, permitiendo la automatización de tareas que no son adecuadas para el uso de la robótica tradicional y que además permiten evitar el riesgo que presentan estas tareas a los operarios encargados de realizarlas, tareas que pueden englobar desde la inspección visual de tejados evitando la necesidad de que un operario ascienda utilizando una grúa, hasta la toma y análisis de muestras en Marte sin necesidad de enviar tripulación. Para el correcto funcionamiento de estos vehículos no tripulados es necesario un extenso desarrollo de diversas tecnologías de hardware y software que aseguren que el vehículo es capaz de realizar todas las tareas para las que fue diseñado y es capaz de soportar y superar los imprevistos que ocurran durante su despliegue. Dentro de las tareas de las que se encarga el software se encuentra el control de misión, una tarea fundamental que se encarga desde el alto nivel que las tareas se realizan de forma ordenada y lógica. Este documento se encuentra enmarcado dentro del projecto SIMAR y presenta el desarrollo del control de misión de un UAV multirrotor que tiene como tarea el despliegue sobre una tubería de un instrumento motorizado controlado de forma remota por un operario que sea capaz de realizar la inspección del estado de tubería utilizando un sistema de rayos X embarcado. La metodología utilizada para el desarrollo del controlador de misión son los árboles de comportamiento, los cuales presentan una alternativa a las máquinas de estado que tiene como objetivo el permitir el desarrollo de forma más visual y jerárquica. Este tipo de enfoque es muy popular en el sector de los videojuegos para el desarrollo de las inteligencias artificiales de los personajes controlados por la consola y está ganando tracción en el sector de la robótica más tradicional debido a sus ventajas frente al enfoque más tradicional de máquinas de estado. El objetivo principal de este documento es presentar de forma clara los árboles de comportamiento que se han desarrollado para la realización de la misión y la explicación de su funcionamiento y del funcionamiento de los distintos bloques que lo componen, presentado gráficas con el comportamiento previsto del UAV durante el funcionamiento.

Full text

Proyecto Fin de Carrera Ingeniería de Telecomunicación Formato de Publicación de la Escuela Técnica Superior de Ingeniería Autor: F. Javier Payán Somet Tutor: Juan José Murillo Fuentes Dep. Teoría de la Señal y Comunicaciones Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2013 Trabajo Fin de Máster Ingeniería Aeronáutica Control de Misión de UAV para Transporte de Vehículo Autor: Diego Mesta Guisasola Tutor: Francisco Rodriguez Rubio Dpto. Ingeniería de Sistemas y Automática Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2024 Trabajo Fin de Máster Ingeniería Aeronáutica Control de Misión de UAV para Transporte de Vehículo Autor: Diego Mesta Guisasola Tutor: Francisco Rodriguez Rubio Catedrático de la Universidad Dpto. Ingeniería de Sistemas y Automática Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2024 Trabajo Fin de Máster: Control de Misión de UAV para Transporte de Vehículo Autor: Diego Mesta Guisasola Tutor: Francisco Rodriguez Rubio El tribunal nombrado para juzgar el trabajo arriba indicado, compuesto por los siguientes profesores: Presidente: Vocal/es: Secretario: acuerdan otorgarle la calificación de: El Secretario del Tribunal Fecha: Resumen El sector de los vehículos no tripulados ha tenido un gran desarrollo en los últimos años, permitiendo la automatización de tareas que no son adecuadas para el uso de la robótica tradicional y que además permiten evitar el riesgo que presentan estas tareas a los operarios encargados de realizarlas, tareas que pueden englobar desde la inspección visual de tejados evitando la necesidad de que un operario ascienda utilizando una grúa, hasta la toma y análisis de muestras en Marte sin necesidad de enviar tripulación. Para el correcto funcionamiento de estos vehículos no tripulados es necesario un extenso desarrollo de diversas tecnologías de hardware y software que aseguren que el vehículo es capaz de realizar todas las tareas para las que fue diseñado y es capaz de soportar y superar los imprevistos que ocurran durante su despliegue. Dentro de las tareas de las que se encarga el software se encuentra el control de misión, una tarea fundamental que se encarga desde el alto nivel que las tareas se realizan de forma ordenada y lógica. Este documento se encuentra enmarcado dentro del projecto SIMAR y presenta el desarrollo del control de misión de un UAV multirrotor que tiene como tarea el despliegue sobre una tubería de un instrumento motorizado controlado de forma remota por un operario que sea capaz de realizar la inspección del estado de tubería utilizando un sistema de rayos X embarcado. La metodología utilizada para el desarrollo del controlador de misión son los árboles de comportamiento, los cuales presentan una alternativa a las máquinas de estado que tiene como objetivo el permitir el desarrollo de forma más visual y jerárquica. Este tipo de enfoque es muy popular en el sector de los videojuegos para el desarrollo de las inteligencias artificiales de los personajes controlados por la consola y está ganando tracción en el sector de la robótica más tradicional debido a sus ventajas frente al enfoque más tradicional de máquinas de estado. El objetivo principal de este documento es presentar de forma clara los árboles de comportamiento que se han desarrollado para la realización de la misión y la explicación de su funcionamiento y del funcionamiento de los distintos bloques que lo componen, presentado gráficas con el comportamiento previsto del UAV durante el funcionamiento. I Abstract The unmanned vehicles’sector has achieved a great development in the recent years, allowing the automation of tasks unfit for the use of the more traditional robots and removing the risk for the operatives said tasks inherently have. These task are very varied and range from the visual inspection of roofs without the need of anyone of lifting a person to big heights, to the sampling and analysis of said samples in Martian missions without a crew having to be physically present there. In order for any unmanned vehicle to work propperly, an extensive development of hardware and software technologies is required as the need to make sure the vehicle is capable of carrying out all the tasks it was designed to do while resisting and overcoming any unplanned setbacks that may happen during its deployment. One of the duties of the set the software is in charge of is the mission control, a fundamental high level functionality tasked with making sure everything is done in an orderly and logical manner. This documment is part of the SIMAR project and presents the development of the mission control system of an UAV multirottor tasked with carrying to and deploying on a pipe a radio controlled motorized instrument capable of inspeccting the state of the pipes using an onboard X-ray system. The methodology used in the development of the mission control system is the use of behavior trees, these are an alternative to the finite state machines with the objective of making the development of functionalities more visual and inherently hierarchical. This methodology is popular in the development of the AI of nonplayable characters in videogames and are gaining traction within the field of robotics due to their advantages against the more traditional finite state machines. The main objective of this document is to present in a clear manner the behavior trees developed for carrying out the mission and propperly explaining them and the different blocks used to make them, with the help of graphs showing the expected behavior of the UAV during their execution. III 4Capítulo 1. Introducción implementa el funcionamiento de los árboles de comportamiento en C++ y XML, permitiendo realizar la programación de los nodos forma eficiente con C++ mientras que los propios árboles de comportamiento se definen utilizando XML, que es más visual para el desarrollador. Adicionalemente, la librería permite detener la ejecución del árbol de comportamiento en cualquier momento y el cambiar el XML que se está ejecutando mientras el programa está en funcionamiento, lo que en la práctica se traduce en poder ejecutar distintos árboles de comportamiento con el mismo programa sin tener que recompilar o incluso detener la ejecución del programa. Antes de entrar en componentes específicos, es necesario entender como funciona desde un punto de ejecución el árbol de comportamiento. El árbol de comportamiento funciona mediante los denominados ticks, que se corresponden con una llamada a su ejecución. Una vez se le envía un tick al árbol de comportamiento su comportamiento puede visualizarse como agua descendiendo por el mismo, de un nodo superior hacia otro inferior, el cual se denomina como nodo hijo del nodo directamente superior, en el que los nodos intermedios de control actúan como vávulas, direccionando el flujo, una vez el tick llega un nodo de acción (también denominado como hoja en alguna literatura), este se ejecuta y el flujo se invierte, el nodo de acción puede devolver una de tres respuestas: SUCCESS (éxito) si el nodo ha completado su acción de forma correcta, FAILURE (fallo) si ha ocurrido algún problema y el nodo no ha podido realizar su acción o RUNNING (en ejecución) si no ha ocurrido ningún problema pero no se ha completado su ejecución. Esta señal viaja aguas arriba en el árbol de comportamiento y se modifica según los nodos intermedios que atraviese hasta llegar al origen del tick, el nodo superior del árbol de comportamiento, el cual devuelve al programa el estado que haya recibido, de forma que el programa que se encargue de ejecutar el árbol de comportamiento sea capaz de conocer si el tick que se ha enviado a finalizado el funcionamiento del árbol de forma correcta o incorrecta o sigue ejecutándose y por tanto, necesita enviar más ticks. El primer componente a mencionar son los nodos de acción que, como su nombre indica, son aquellos nodos que implementan las tareas a realizar, un ejemplo de estas tareas sería llamar a los servicios de despegue o aterrizaje de la capa de abstracción. Estos nodos toman control del hilo donde se está ejecutando el árbol de comportamiento hasta que terminan de ejecutar todo el código dentro de su método de ejecución, esto se traduce en que el árbol no puede llamar a ningún otro nodo hasta que se termine su ejecución, lo cual debe de tenerse en cuenta a la hora de desarrollar estos nodos. La librería utilizada permite implementar la funcionalidad de los nodos en otro hilo, sin embargo, este tipo de implementaciones no es nada recomendada ya que no existe forma de conocer mientras se desarrolla el código si la tarea que se comenzó en un nodo ha terminado cuando se llama a otro a no ser que se implementen medidas adicionales, dando lugar a un código no lineal, propenso a errores y difícil de depurar. Estos nodos de acción se dividen a su vez en nodos síncronos o asíncronos según el tipo de tarea que implementen: • Los nodos síncronos se utilizan para implementar tareas de corta duración, presentan un método tick el cual se llama cuando se ejecuta el nodo y puede devolver ÉXITO o FALLO según lo ocurrido dentro de su método. • Los nodos asíncronos por su parte se utilizan para implementar tareas con una duración elevada y tienen como objetivo evitar el bloqueo del árbol de comportamiento mientras estas se realizan, pudiendo devolver ÉXITO, FALLO o EN EJECUCIÓN presentan dos métodos onStart yonRunning que implementan el comportamiento del nodo al recibir el primer tick o sucesivos ticks respectivamente. En el caso de acabar la ejecución con ÉXITO o FALLO, se reiniciarán y el próximo tick ejecutará nuevamente el método onStart. De esta forma, si se quiere implementar una tarea como leer temperatura, podría utilizarse un nodo síncrono debido a su corta duración, sin embargo, si se quisiese implementar una tarea de mayor duración como girar barra hasta 45ºsería recomendable implementar un nodo síncrono que en onStart enviase el comando al motor y en su método onRunning leyese las medidas del motor (asumiendo que es un motor con control en bucle cerrado) para comprobar se se ha alcanzado la posición deseada. Es importante tener en cuenta que dentro de un mismo nivel de la jerarquía dos un nodo no puede devolver EN EJECUCIÓN si otro nodo lo ha devuelto anteriormente y no ha devuelto ÉXITO o FALLO, dando lugar a un error lógico si ocurre, por tanto, hay que tomar precauciones cuando se utilizan nodos asíncronos. La librería utilizada permite anular este fallo si el desarrollador piensa que es demasiado restrictivo, sin embargo, en el desarrollo realizado en este documento se ha dejado en su valor por defecto. 1.3 Introducción a los árboles de comportamiento 5 Figura 1.4 Ejemplo de secuencia en el que las acciones se ejecutan en el orden que están numeradas. Otra tipología de nodo incluye los nodos decoradores que, tal y como se mencionaba anteriormente, son aquellos que modifican la respuesta que viaja aguas arriba (o a veces, aguas abajo) y son muy variados. Este tipo de nodos solo puede tener un nodo en el nivel directamente inferior, es decir, un solo nodo hijo. Algunos de los ejemplos de nodos decoradores incluidos se incluyen a continuación: • Inverter: Invierte la respuesta recibida del nodo hijo, devolviendo FALLO si el hijo devuelve ÉXITO y viceversa. Si el hijo devuelve EN EJECUCIÓN, este nodo también devuelve EN EJECUCIÓN. • Repeat: Envía ticks al hijo hasta N veces (N es una entrada del nodo), parando de forma temprana si el hijo devuelve ÉXITO. Si el hijo devuelve ÉXITO en algún momento, este nodo devuelve ÉXITO y si el hijo devuelve FALLO todas las veces, este nodo devuelve FALLO. Si el hijo devuelve EN EJECUCIÓN este nodo devuelve EN EJECUCIÓN y no aumenta el contador de cuantos ticks ha enviado al hijo hasta que este devuelva otra respuesta. • ForceFailure,ForceSuccess: Si el hijo devuelve algo que no sea EN EJECUCIÓN, estos nodos devuelven siempre FALLO o ÉXITO respectivamente. El siguiente tipo de nodo a explicar son los nodos de control, estos nodos, como su nombre indica, se encargan de controlar la ejecución del árbol de comportamiento y son los nodos más importantes a la hora de determinar la lógica detrás del orden de ejecución de las acciones. Aunque existen diversos tipos de nodos de control, los más importantes son Sequence yFallback. • Sequence: Ejecuta los nodos hijo de izquierda a derecha, devolviendo EN EJECUCIÓN hasta que todos ellos devuelvan ÉXITO, en caso de que algún hijo devuelva FALLO, Sequence también devuelve FALLO. Cuando recibe un tick, se lo envía al primer hijo de la secuencia, si este devuelve ÉXITO, en el siguiente tick, se lo enviará al siguiente hijo. Si por el contrario, el hijo devuelve EN EJECUCIÓN, seguirá enviándole los ticks a dicho hijo hasta que devuelva otra respuesta. • Fallback: Ejecuta el hijo más a la izquierda, si este devuelve ÉXITO o EN EJECUCIÓN, Fallback devuelve también ÉXITO o EN EJECUCIÓN. Si por el contrario, el hijo devuelve FALLO, Fallback devuelve EN EJECUCIÓN y el siguiente tick se lo envía al siguiente hijo. Si todos los hijos devuelven FALLO, Fallback devuelve también FALLO. De esta forma los nodos del tipo Sequence se pueden utilizar para ordenar las acciones acciones a realizar según el orden lógico, por ejemplo, para regresar a base antes de intentar aterrizar, mientras que los nodos del tipo Fallback pueden utilizarse cuando se requiere realizar una acción solo si la anterior ha fallado, siguiendo el mismo ejemplo, para abortar el aterrizaje solo si este ha fallado. Los nodos anteriormente definidos se encuentran separados unos de otros y se definen cada uno como clases, las cuales, en el momento de su definición pueden cargar ciertos parámetros en memoria, sin embargo, esta no es la forma correcta para realizar comunicaciones entre los distintos nodos del árbol de comportamiento. Para comunicar los distintos nodos del árbol de comportamiento y que puedan transferirse variables se define una memoria compartida del árbol de comportamiento, llamada como Blackboard en la documentación 6Capítulo 1. Introducción Figura 1.5 Ejemplo de Fallback en el que se ejecuta una acción y si esta falla se ejecuta la primera contramedida, si una contramedida falla, se ejecuta la siguiente. de la librería. Los distintos nodos pueden acceder a esta memoria compartida mediante la definición de puertos de lectura y/o escritura de forma explícita en el nodo. La definición de esta memoria compartida da lugar a un cuarto tipo de nodo, el Script, el cual no es más que un nodo sencillo que altera el valor de una o varias variables de la memoria compartida sin la necesidad de implementar un nodo completo, su uso por ejemplo puede utilizarse para actualizar un booleano que finalice un bucle en caso de que se cumplan dos condiciones. Adicionalmente, los nodos pueden tener condiciones preliminares que dependan de variables de la memoria compartida, como, por ejemplo, saltarse la acción de aterrizar si el estado ya es aterrizado y también pueden definirse acciones de postprocesado, como devolver fallo si al final de la acción de aterrizaje el estado no es aterrizado. Como se mencionaba al principio de la sección, uno de los principios básicos de los árboles de comportamiento es la modularidad, una forma en la que esta se consigue es mediante la definición de árboles de comportamiento completos como ramas de otro árbol, estas ramas o Subtrees, como se denomina en la documentación, permiten componer comportamientos complejos mediante la unión de acciones más simples y presentan la ventaja adicional de ser independientes entre llamadas, teniendo memorias compartidas independientes por cada rama y otra para el árbol principal, pero pudiendo comunicar dichas memorias mediante la definición explícita de puertos, esto permite, por ejemplo, llamar un Subtree de ir al punto introduciendo en cada caso un punto distinto sin la necesidad de implementar nuevamente las acciones requeridas para ejecutar dicha tarea. 2 Diseño del Controlador El objetivo de esta sección es entrar en mayor detalle sobre el diseño que se ha realizado de los distintos componentes del controlador de misión así como la lógica que sigue cada Subtree para cumplir su función, para ello se hará uso de diagramas que muestren el comportamiento esperado de cada Subtree. Los diagramas completos de cada rama se encontrarán en el apéndice A. Antes de comenzar con el diseño de los árboles de comportamiento, es importante explicar el programa que se ha desarrollado para ejecutarlos. Como se comentaba en la introducción, el programa se ha desarrollado en C++ utilizando la librería BehaviorTree.CPP, el funcionamiento básico de la misma gira en torno a una clase llamada BehaviorTreeFactory, la cual se denominará como fábrica en el resto del texto, sobre la cual se ejecutan todos los comandos hasta generar el propio árbol de comportamiento. El primer paso del programa consiste en cargar dentro de la fábrica los distintos nodos que se han construido para ejecutar el árbol de comportamiento, para lo cual se ha aprovechado la posibilidad de de definir valores de inicialización para reducir el número de clases generadas utilizando clases más genéricas, por ejemplo, una sola clase RequestAction implementa todos los nodos del tipo Request X, es decir, se encarga de utilizar los clientes de los servicios que solicitan el cambio de estado, esto permite reducir la cantidad de ficheros que es necesario generar y hace más fácil implementar nuevas transiciones. Una vez se han definido cuales son los distintos nodos (que no se encuentran dentro de la librería de partida) se van a utilizar, el siguiente paso es definir cuales árboles de comportamiento se van a cargar durante la ejecución y cual de ellos se va a ejecutar como principal, la posibilidad de cargar varios árboles de comportamiento en varios archivos permite tener el árbol principal y cada uno de los Subtrees definidos por separado, facilitando el cambio de definición de un Subtree simplemente cargando otro archivo donde se encuentra la nueva definición. Para la carga de estos archivos, se ha desarrollado una interfaz simple que se ejecuta en el terminal y permite cargar uno o varios árboles de comportamiento desde la carpeta que los contiene o, navegar a subcarpetas dependiendo de donde se hayan almacenado los archivos. Una vez definida la ejecución se comienzan a enviar ticks para ejecutar el árbol de comportamiento cargado y se da la opción de cargar otro una vez este termina su ejecución. Figura 2.1 Interfaz que se muestra por pantalla al ejecutar el nodo principal, introducir un número ejecuta el comando o el árbol de comportamiento nombrado, el comando [0] de recarga permite al programa detectar nuevos archivos que se han introducido en la carpeta cuando esta ya se ha cargado. 7 8Capítulo 2. Diseño del Controlador Figura 2.2 Ejecutar el comando de cambio de carpeta muestra por pantalla las carpetas dentro de la localización actual y da la posibilidad de entrar en una de ellas, volver a la carpeta predeterminada o ir a la carpeta contenedora. Figura 2.3 Una vez se selecciona una de las carpetas, el programa detecta todos los ficheros que pueden contener árboles de comportamiento (ficheros XML). Figura 2.4 Si se escoge uno de los ficheros, se muestran cuales árboles de comportamiento contiene y da la opción de ejecutar uno de ellos o volver a la visualización de carpeta. 9 Figura 2.5 Si se escoge el comando de cargar todo el fichero se mostrarán por pantalla todos los árboles de comportamiento que se han encontrado y los ficheros que lo contienen, permitiendo ejecutar cualquiera de ellos y que el programa sea capaz de tomar Subtrees definidos dentro de cualquiera de los otros ficheros. Para el diseño de los árboles de comportamiento como tales, las principales ideas que se han tenido en cuenta son la modularidad y la simplicidad. Para cumplir con la idea de modularidad se ha comenzado con la separación de las distintas tareas en diversos Subtrees con el objetivo de permitir cambiar la implementación de tareas simples como despegar, ir a o aterrizar de forma sencilla, permitiendo así reutilizar parte de los árboles en otro proyecto si fuese necesario; además, con el mismo objetivo se han reutilizado algunos esquemas de forma que si estos dan buenos resultados para una de las funcionalidades y otra funcionalidad puede implementarse de forma análoga se reduzca el tiempo de diseño y de realización de pruebas, algunos ejemplos de esto es como los árboles de despegue (Figura A.2), aterrizaje (Figura A.3) y ir a (Figura A.7) tienen estructuras análogas como la que se muestra en la Figura ?? . Otro ejemplo puede verse en como el abortar se ha implementado de la misma forma en todos los árboles en los que es posible. Para cumplir con la idea de simplicidad, se ha reducido al mínimo el uso de nodos de control complejos, utilizando en la medida de lo posible Sequence,Fallback yLoopUntil X para facilitar la comprensión de los 10 Capítulo 2. Diseño del Controlador árboles de forma visual. Este último nodo de control se ha desarrollado para este programa y actúa como un bucle del tipo While, permitiendo repetir una sección mientras se espera a una condición, su implementación tiene como objetivo evitar el uso de soluciones más complejas utilizando los bloques base de la librería, para lo cual se requeriría utilizar un nodo que ejecute la rama hasta fallar (KeepRunningUntilFailure), un inversor para que la ejecución del árbol completo no finalice al terminar el bucle y alguna metodología adicional para detectar si el fallo que ha detenido el bucle es intencionado o no, es decir, si se ha detenido porque se ha completado el objetivo o porque alguna parte de la ejecución ha fallado. Figura 2.6 Estructura que se utiliza para implementar cambios de estado sencillos. Con todo lo anterior y diversos ensayos simulados, se ha llegado a los árboles de comportamiento que se muestran en el Apéndice A y cuyos funcionamientos se explican en la siguientes secciones. 2.1 Desarrollo de la misión De forma previa al desarrollo de los árboles de comportamiento individuales, es necesario explicar cual es el objetivo conjunto y cuales son los comportamientos que deberá de llevar a cabo la plataforma para cumplir la misión. La misión completa puede dividirse en varios comportamientos individuales gobernados por un árbol de 2.2 Cambios de estado sencillos 11 comportamiento de mayor nivel que, ejecutados de forma secuencial implementarán la misión completa, estos son: despegue, desplazamiento hacia la zona cercana a la tubería, búsqueda de la tubería, desplazamiento hasta sobrevolar la tubería, apoyo sobre la tubería, despliegue de la carga de pago, retorno a base y aterrizaje, en ese orden. Estos comportamientos se han combinado para formar las acciones que se van a implementar en los árboles de comportamiento que se desarrollan en los siguientes apartados: • Protocolo de despegue: implementa el despegue de la plataforma así como una espera en caso de que se aborte. • Maniobra de acercamiento: aquí se implementan los comportamientos de desplazamiento hacia la tubería y la búsqueda de la misma. • Maniobra de despliegue: será el encargado de implementar el desplazamiento hasta colocarse sobre la tubería una vez detectada, apoyando el crawler y controlando su despliegue. • Retorno a base: como su nombre implica, implementa el retorno de la plataforma desde su posición actual hasta sobrevolar la base. • Protocolo de aterrizaje: implementa el aterrizaje de la plataforma y una espera en caso de que este se aborte. El orden en el cual se ejecutan los distintos comportamientos se discutirá con mayor detalle en la sección donde se desarrolla el árbol de comportamiento de la misión completa (sección 2.6) y puede entenderse de forma visual con el diagrama de funcionamiento del mismo, que se muestra en la Figura 2.15. 2.2 Cambios de estado sencillos En primer lugar, se explicará el funcionamiento de los árboles que presentan la estructura que se muestra en la Figura 2.6, estos son los árboles de comportamiento más sencillos dentro del programa y la base que se utiliza para el diseño de comportamientos más complejos. Su comportamiento normal se muestra en la Figura 2.7. El funcionamiento de estos árboles de comportamiento comienza con una llamada al servicio de cambio de estado para realizar la acción, por ejemplo, el servicio de despegue. Una vez llamado el servicio se le da un valor a la variable FINISHED y se entra en un bucle hasta que esta cambia a VERDADERO. El bucle solamente presenta un par de comprobaciones, en primer lugar, se comprueba si se ha solicitado abortar la misión, llamando al servicio de abortaje del autopiloto y finalizando el bucle de forma temprana en caso afirmativo, adicionalmente, hace que el árbol devuelva FALLO (esto permitirá que otro árbol de mayor nivel implemente las acciones de contramedida pertinentes). En el caso en que no se ha solicitado el abortaje, se comprueba si el estado que devuelve el autopiloto se corresponde con el estado de final solicitado, finalizando el bucle y el árbol con ÉXITO en caso de que se encuentre en dicho estado, al significar esto que se ha finalizado la transición. Estos árboles también presentan un par de casos extremos que se detallan a continuación: • En caso de que falle la llamada al servicio de cambio de estado, por ejemplo, el servicio de aterrizaje, el árbol finaliza de forma inmediata y devuelve FALLO. Este caso solo debería de ocurrir si no se puede alcanzar el estado solicitado del actual, lo que significaría que el árbol de mayor nivel está mal planteado. Un ejemplo en el que se daría esto es en el caso de que el árbol de mayor nivel solicitase dos despegues uno detrás de otro. • Existe una posibilidad (menor cuanta mayor sea la frecuencia de los ticks) de que la llamada al servicio de abortaje falle. Esto ocurre cuando el autopiloto se encuentra en un estado que no es de transición y sucede cuando este transiciona hacia el estado objetivo en el lapso de tiempo entre la llamada al servicio de abortaje de misión y la llamada al servicio de abortaje del autopiloto. Si esto ocurre, el árbol, de comportamiento actúa como si no se hubiese solicitado el abortaje de misión y comprueba si el estado es el final, devolviendo ÉXITO al cumplirse. Entre estos árboles de comportamiento, se encuentran los árboles de comportamiento que implementan las funciones de tipo ir a, estos árboles requieren de un nodo adicional para enviar la ruta a seguir al autopiloto, de forma que la implementación completa de estos árboles de comportamiento es la que se encuentra en 12 Capítulo 2. Diseño del Controlador Figura 2.7 Diagrama de comportamiento normal de los árboles de cambio de estado sencillos. la Figura A.7 y su diagrama de comportamiento normal es el que se muestra en la Figura 2.8. Este tipo de diagrama se utiliza en varias partes de la maniobra de despliegue que se muestra en la Figura A.8 y es el tipo de árbol al que pertenece la maniobra de retorno de la Figura A.9. 2.2 Cambios de estado sencillos 13 Figura 2.8 Diagrama de comportamiento normal de un árbol que implementa la función de ir a. 20 Capítulo 2. Diseño del Controlador Por último, se desarrollado un tercer árbol de comportamiento para la maniobra de acercamiento, este se muestra en la Figura A.6 y se basa en el anterior. Como también puede visualizar en su diagrama de comportamiento nominal, que se muestra en la Figura 2.13, la principal adición es una rama que se ejecuta en el caso de que se desplace el objetivo, ya sea porque este sea móvil o porque se tenga una nueva estimación de la posición de la tubería requiera corregir la trayectoria, siendo este segundo caso el relevante dentro del marco del proyecto. La ejecución de dicha rama implica un cambio en la ruta del autopiloto, modificándose para avanzar hacia el nuevo punto de forma correcta, aunque en esta etapa del proyecto se ha dejado como un avance lineal. Para adaptarse a este posible cambio de trayectoria se ha dividido la rama de detección de tubería en dos partes, sin embargo, desde un punto de funcionamiento normal el comportamiento es el mismo. Este último árbol es el más complejo de los tres, sin embargo también presenta la gran ventaja de permitir ciertas correcciones en las trayectorias durante la ejecución, lo que lo convierte en el más adecuado desde un punto de vista de seguridad para implementar en la misión final. 2.5 Maniobra de despliegue El último comportamiento por implementar dentro de un árbol es el correspondiente a la maniobra de despliegue del UAV. Este árbol es el más complejo de los Subtrees que implementa la misión completa, sin embargo, gracias al uso de árboles ir a para la implementación de los movimientos, su visualización en las Figuras A.8 y 2.14, correspondientes a su árbol de comportamiento y diagrama de funcionamiento normal respectivamente, y su implementación se realizan de forma más sencilla. Su implementación comienza con una serie de árboles del tipo ir a, los cuales implementan un movimiento desde el punto cercano a la tubería donde debe encontrarse el UAV hasta apoyar el crawler sobre la tubería, realizando este movimiento en tres tramos diferenciados, un primer ascenso hasta una altitud en la que el punto más bajo del inspector se encuentre a una altura algo mayor que la tubería, un avance a nivel para alinear el inspector con la tubería y un descenso para que la tubería quede situada entre las ruedas del inspector para poder realizar el agarre. Una vez el inspector está en la posición correcta, se llama al servicio de despliegue del mismo y espera a que este termine. Una vez el despliegue a finalizado, se llama al servicio del UAV encargado de desconectar el crawler y se realiza un ascenso para evitar colisiones con este durante el resto de la ejecución, finalizando el árbol con ÉXITO. Si en cualquier momento del despliegue se solicita el abortaje de la misión, se ejecuta la otra rama. Esta comprueba si se ha terminado el despliegue, desconectando el crawler en caso afirmativo. En caso de que no se haya terminado el despliegue, aborta el despliegue mediante una llamada al servicio y espera hasta que se haya replegado por completo. Ambas posibilidades acaban con un ascenso para evitar posibles colisiones futuras y finalizan el árbol con FALLO. El motivo de separar el abortaje en dos casos es doble, en caso de que se haya terminado el despliegue el servicio de abortar el despliegue del inspector fallaría, pudiendo generar comportamientos inesperados en la misión, como esperar a que termine un pliegue que ni siquiera ha comenzado, por otro lado, desconectar el inspector si está desplegado permite continuar con el resto de la misión del proyecto, incluso si por seguridad se ha tenido que abortar la del UAV, además, es más seguro, ya que no se tiene un tiempo de espera adicional en el que UAV tiene que esperar a que se finalice por completo el pliegue. Adicionalmente, se ha añadido una comprobación al principio de la ejecución del árbol, devolviendo ÉXITO y no realizando ninguna acción en caso de que el UAV se encuentre aterrizado, el motivo de esta adición es asegurar que si se hubiese abortado el despegue, no se intenta realizar ninguna maniobra inesperada si se despega de forma manual y después se cambia el control a automático. Cabe mencionar la existencia de un caso que no se incluye en el diagrama de comportamiento normal, en el caso de que alguno de los árboles de desplazamiento fallen, ya sea por algún problema o porque se haya abortado la misión, el árbol devuelve FALLO, de forma que en el nivel superior la respuesta será la misma que si se hubiese abortado el despliegue. 2.5 Maniobra de despliegue 21 Figura 2.14 Diagrama de comportamiento nominal del árbol de comportamiento correspondiente a la maniobra de despliegue del inspector. 22 Capítulo 2. Diseño del Controlador 2.6 Misión completa Para finalizar el diseño de los árboles de comportamiento, se construye el árbol que implementa la misión completa y se muestra en la Figura A.10. El árbol está construido casi por completo utilizando los distintos árboles desarrollados en las secciones anteriores de este capítulo, de forma que no se entrará en detalle en su comportamiento interno en esta sección. Esta composición permite además hacer el árbol mucho más legible, al final del apéndice donde se incluyen los árboles de comportamiento, en la Figura A.11 se encuentra una imagen del árbol completo completamente desplegado, con el objetivo de ilustrar la complejidad del comportamiento final. Figura 2.15 Diagrama de funcionamiento del árbol que implementa la misión completa. 2.7 Nodos desarrollados 23 La ejecución de la misión comienza con un protocolo de despegue, el cual, en caso de FALLO hace que el árbol completo de misión completa devuelva FALLO. El siguiente paso, una vez el UAV se encuentra en el aire es la realización de la maniobra de acercamiento, seguida de la maniobra de despliegue una vez se encuentra cerca de la tubería. Tanto si ambos árboles devuelven ÉXITO como si alguno de ellos devuelve FALLO, la misión continúa con un retorno a base seguido de un protocolo de aterrizaje, finalizando el árbol con FALLO en caso de que alguno de estos retorne FALLO. En el caso de que un protocolo de aterrizaje devuelva ÉXITO y ningún árbol interno devuelva FALLO, el árbol completo devuelve ÉXITO. La lógica detrás de las respuestas del árbol principal se basan en si el UAV ha conseguido regresar con éxito a la base y aterrizar completando con éxito la misión. Si ocurre que este retorno se hace de forma prematura por un abortaje de misión, se considera que la misma ha fallado. En caso de que falle el despegue, el árbol también devuelve FALLO ya que no se ha finalizado la misión. Desde un punto de vista técnico la respuesta final del árbol completo de misión es irrelevante al no influenciar de forma alguna a la ejecución de la misión del UAV. Por ello, la respuesta del mismo puede ser un valor arbitrario, centrándose en este caso en si se ha cumplido con el objetivo de la misión o no, esto incluye el devolver FALLO en el caso de que se aborte la misión pero se deje el crawler sobre la tubería debido a que, a pesar de técnicamente haber cumplido con el objetivo de la misión, no se considera que se haya cumplido con éxito ya que el abortaje implica algún problema durante su ejecución. Es relevante recalcar nuevamente que aunque este árbol de misión completa sea el último en desarrollarse al depender de todos los demás, tal y como se explica en la sección 2.1, es también el punto de partida del diseño, siendo el proceso de diseño en V. Este tipo de diseño quiere decir que se parte de un nivel superior, diseñando un árbol completo preliminar y a partir de él cuales son necesarios para su implementación, repitiendo el desarrollo preliminar hasta llegar a los árboles que no dependan de ningún otro. Una vez se tienen todos los diseños preliminares se empieza un diseño en detalle desde el más bajo nivel hacia arriba, pudiendo fraccionar algunos árboles que sean al final más complejos de lo esperado en el diseño preliminar y, en la medida de lo posible, manteniendo estructuras similares en el diseño final para facilitar el proceso de comprobación de depuración de errores. Es importante comprobar que funcionan de forma correcta todos los árboles de los que depende antes de empezar el desarrollo en detalle del mismo, de lo contrario es posible que sea necesario descartar algunos después de haber invertido mucho tiempo en el mismo. Con todo esto, se llegaría a un árbol final completo y funcional como el que se presenta en esta sección. 2.7 Nodos desarrollados Una vez se ha explicado el desarrollo realizado de los árboles de comportamiento resulta interesante explorar los nodos que se han desarrollado para su implementación software. Estos nodos son principalmente nodos de acción, aunque también se ha desarrollado un nodo de control. Antes de explicar el funcionamiento interno de los nodos que se han desarrollado para el funcionamiento de los distintos árboles de comportamiento que se han desarrollado, es necesario explicar las conexiones ROS existentes entre el controlador de misión, el operador y la capa de abstracción intermedia. En primer lugar, se han definido cinco NodeHandle, estas actúan como etiquetas para conectarse a dicho nodo y permiten separar los servicios y conexiones a tópicos en distintas colas para poder procesar la información de forma más granulada, estas etiquetas son las siguientes: • Abortaje. Tiene la cola limitada a un solo elemento y se encarga de recibir las solicitudes de abortaje del operador. El límite en la cola impide que se aborte alguna acción de forma involuntaria debido a que se haya recibido más de una solicitud de forma errónea. –Esta cola es utilizada por el servidor del servicio de abortaje. • Estado. Se encarga de recibir en cada momento el estado actual de la máquina de estados del UAV, esto le permite al árbol conocer cuando terminan los estados de transición, incluyendo los estados de despliegue de la carga de pago. –En esta cola se implementa el subscriptor de estado del UAV. • Estado del Inspector. Se encarga de actualizar el estado actual de la máquina de estados que controla el inspector que se despliega sobre la tubería, el cual se utiliza el la lógica de la maniobra de despliegue. –En esta cola se implementa el subscriptor del estado del crawler. 24 Capítulo 2. Diseño del Controlador • Localización. Recibe información sobre la posición actual de la plataforma, esta se utiliza para generar algunas de las trayectorias cuando es necesario y para conocer en que momento se ha de activar el algoritmo de detección de la tubería. –Aquí se implementa el subscriptor de localización del UAV. • Localización del objetivo. Recibe la posición de la tubería desde el algoritmo de detección de tubería para poder construir las trayectorias de forma precisa. –Implementa el subscriptor de localización de la tubería. • Acción. Esta última cola es la encargada de enviar las solicitudes a la máquina de estados intermedia para poder controlar la plataforma. – Esta cola es contiene los clientes de los servicios de despegue, aterrizaje, abortaje (de la máquina de estados), ir a y definir plan de vuelo. Con todo lo anterior, se puede comenzar a explicar el funcionamiento de los nodos, empezando por el nodo de control desarrollado, Loop Until Flag. Este nodo es muy sencillo, se trata de un decorador que cada vez que recibe un tick lee de la memoria compartida Flag y continúa enviándo ticks hacia abajo, devolviendo ÉXITO solamente si recibe ÉXITO del hijo y se cumple la condición, de lo contrario, sigue devolviendo EN EJECUCIÓN. Si el hijo devuelve FALLO, este nodo también devuelve FALLO. El siguiente tipo de nodo a analizar es el nodo Request Action, también denominado como Start Action en los árboles de comportamiento. Este nodo consiste de una comprobación interna de cual acción es la que se quiere realizar y llama al servicio correspondiente de la capa de abstracción utilizando la cola de Acción definida anteriormente. Otro nodo que también utiliza la misma cola de ROS es el nodo de Request Abort, el cual llama al servicio de abortaje utilizando dicha cola. El conjunto de nodos que complementa al anterior corresponde a los nodos Check State yCheck Abort. El primero de ellos lee el siguiente elemento de la cola de Estado y actualiza la variable interna de estado si hay algún elemento en cola. Una vez hecho esto, si el estado no está desactualizado (si la última actualización se realizo dentro del marco de tiempo predefinido, el cual se comprueba mediante un temporizador de ros al cual se refresca cada vez que se lee la cola y se recibe un elemento correctamente) y en caso afirmativo comprueba si el último estado recibido coincide con el estado que se ha indicado en el nodo. El nodo presenta dos variantes, ambas devuelven Éxito si el estado que se comprueba y el actual coinciden, pero en caso de que no coincidan, la variante asíncrona devuelve EN EJECUCIÓN, mientras que la variante síncrona devuelve FALLO. Adicionalmente, si el estado recibido es MANUAL, ambas variantes devuelven FALLO, esto se hace para finalizar el árbol de comportamiento de forma ágil si se cambia a modo manual en emergencias. Por su parte el nodo Check Abort posee un funcionamiento análogo al nodo Check State en lo que se refiere a la lectura de la cola y actualización del estado, utilizando en su lugar la cola de Abortaje. Si se ha solicitado un abortaje, entonces el nodo devuelve ÉXITO y reinicia la cola para evitar que se acumulen solicitudes. En caso de no haberse solicitado, el nodo simplemente devuelve FALLO. Con estos nodos ya podrían construirse los árboles de comportamiento de protocolo de despegue y aterrizaje y los árboles de cambio de estado sencillos. El siguiente tipo de nodo a desarrollar es el nodo Set Flight Plan este nodo utiliza la cola de Acción para enviar un nuevo plan de vuelo a la capa de abstracción intermedia para seguirlo a continuación. Dicho plan de vuelo es definido por otros nodos u otros componentes (como el planificador de vuelo) y el nodo recibe cuando se construye un puntero a la variable en memoria en la cual se almacenarán dichos planes de vuelo, así como un identificador de cual de los planes de vuelo debe enviar. El otro componente de los planes de vuelo son los nodos del tipo Create X Flight Plan, estos nodos de vuelo son los encargados de construir los planes de vuelo que sean necesarios de forma auxiliar para cumplir la misión, entre los cuales se incluye el plan de búsqueda de la tubería y los planes de ascenso, descenso, etc que aparecen durante la fase de despliegue de la misión. No se va entrar en detalle sobre la forma en la que se construyen dichos planes de vuelo, pero un esquema del plan de vuelo de búsqueda (close_to_pipe) se muestra en la Figura 2.16. Los siguiente nodo necesario es el nodo Check close_to_pipe, el cual detecta cuando se encuentra cerca de la tubería. Este nodo toma al construirse un puntero a la estimación actual de la posición de la tubería, que generalmente proviene de la planificación inicial. El nodo comprueba si la plataforma se encuentra dentro de la esfera con centro dicho punto y un radio definido durante la construcción del nodo, devolviendo ÉXITO 2.7 Nodos desarrollados 25 Figura 2.16 Plan de búsqueda cuando la plataforma se acerca a la tubería. en caso afirmativo y FALLO en caso contrario, esto permite decir que se encuentra en las proximidades de donde se cree que se encuentra la tubería para poder cambiar al plan de búsqueda. Para poder terminar de definir los árboles de comportamiento de acercamiento, es necesario desarrollar el nodo Check pipe_detected. Este nodo comprueba si se ha recibido información recientemente (utilizando un temporizador de ROS) sobre la localización de la tubería mediante la cola de Localización del objetivo, devolviendo ÉXITO en caso afirmativo o FALLO en caso contrario, permitiendo detectar si es posible pasar a la fase de despliegue. Con lo anterior sería posible construir los dos primeros árboles que se han desarrollado para la maniobra de acercamiento, sin embargo, el tercero de ellos posee un nodo adicional, el nodo denominado como Has Target Moved BB? en la definición de dicho árbol de comportamineto, este nodo es similar al al nodo Check pipe_detected, con la diferencia de lo que comprueba es si ha ocurrido un cambio en el valor de la estimación de la posición de la tubería, permitiendo cambiar durante el vuelo la estimación antes de que se detecte la misma. Este nodo siempre devuelve ÉXITO y el estado de la comprobación se envía a la memoria compartida a través de un booleano. Para el funcionamiento del árbol de comportamiento de despliegue, se ha desarrollado un nodo de comprobación adicional, el nodo Check Crawler_State, el cual actualiza el estado actual del crawler leyendo la cola de Estado del Inspector y escribe si este se corresponde con el estado a comprobar, escribiendo en un booleano de la memoria compartida el resultado. Este nodo siempre devuelve ÉXITO. El último nodo a desarrollar es el nodo Disconnect Inspector, el cual hace una llamada a los controladores de los pistones que se encargan de sujetar la carga de pago para que se replieguen y la liberen, dejandola situada encima de la tubería. Con todos estos nodos, quedarían completamente definidos los árboles de comportamiento que componen la misión desarrollada en este documento. 3 Resultados de Simulación Para poder verificar el funcionamiento los árboles de comportamiento que se han diseñado en el documento y poder realizar las correcciones necesarias durante el desarrollo, es necesario realizar pruebas de los mismos, inicialmente, estas pruebas se realizarán en simulación ya que es un entorno seguro sin poner en peligro la plataforma, cuya construcción tampoco se encuentra finalizada. Debido a que en el proyecto no se tiene un modelo funcional del UAV para simulación, y como la función de los árboles de comportamiento es puramente desde el enfoque de organización de tareas y el funcionamiento a bajo nivel no afecta al diseño de los mismos, las simulaciones se realizarán con un programa simple realizado en Python que implementa los mismos servicios, publicadores y subscriptores que el autopiloto, pero en vez de utilizar el modelo del dinámico del UAV, solo implementa un modelo dinámico simple con movimientos puramente lineales y giros solo en guiñada y se utilizará en exclusiva para verificar que los árboles de comportamiento cumplen con su función de monitorización y organización de acciones. Figura 3.1 Interfaz del simulador de Python desarrollado para comprobar las funcionalidades de los árboles de comportamiento. En la Figura 3.1 se pueden apreciar las gráficas de posición, guiñada, altitud y una gráfica de Status, esta última gráfica representa el estado del autopiloto de forma numérica, esto es debido a que el estado se representa con un enumerate para poder utilizar como mensajes números enteros de 8 bits (Int8) para reducir 27 28 Capítulo 3. Resultados de Simulación el tamaño del mensaje. Los estados son los siguientes: •0- DESARMADO •1- MANUAL •2- ATERRIZADO •3- DESPEGANDO •4- HOVER •5- ATERRIZANDO •6- IR A Los primeros árboles de comportamiento de los que se mostrarán los resultados son los árboles correspondientes a los protocolos de despegue y de aterrizaje, mostrados en las Figuras 3.2 y 3.3 respectivamente, se puede comprobar que ambos estados implementan de forma correcta sus correspondientes funciones y que su abortaje de forma correcta envía al autopiloto al otro de los estados. Figura 3.2 Capturas de pantalla de la respuesta en simulación al despegue y a su abortaje. 29 Figura 3.3 Capturas de la respuesta en simulación al aterrizaje y a su abortaje. Centrándose en el protocolo de aterrizaje, puede visualizarse que su abortaje llama a la maniobra de despegue, pero que esta no lleva a la misma altura que en la gráfica del protocolo de aterrizaje. Esto es una respuesta intencionada ya que el despegue es una maniobra que aumenta la altitud desde el punto en el que se llame a su servicio, por tanto, al llamarse desde una altura mayor cuando se cancela un aterrizaje, la altitud objetivo del despegue es mayor. El siguiente árbol a estudiar es el que implementa la función de retorno, al ser este más sencillo que el resto de árboles y, por tanto, fácil de comprobar. Su respuesta se muestra en las Figuras 3.4 y 3.5, en las cuales puede verse como el UAV sigue la trayectoria que se le ha indicado, en este caso un movimiento lineal hasta el punto de despegue y después un descenso hasta una altura baja para poder aterrizar después. En cuanto al abortaje, se puede visualizar como el UAV queda detenido en HOVER en el punto en que se encuentra, este es el motivo por el cual su abortaje responde con FALLO en el árbol principal, ya que el UAV no se encuentra en un punto seguro, tal y como se comentaba en la seccion 2.6. 36 Capítulo 3. Resultados de Simulación Figura 3.12 Captura de la finalización de la maniobra de despliegue del crawler. Figura 3.13 Capturas de la maniobra de despliegue abortada mientras el crawler se encuentra desplegándose. 37 Figura 3.14 Capturas de la maniobra de despliegue abortada cuando el crawler se encuentra completamente desplegado. 38 Capítulo 3. Resultados de Simulación En lo referido a los abortajes de la maniobra de despliegue, las pruebas se han centrado en los casos de que dicho abortaje se solicite durante el despliegue del crawler, ya que, como se ha comentado en la sección 2.5, abortar en otro momento simplemente deja el UAV en HOVER en el punto en el que se encuentre en ese momento. Puede verse como se pausa la ejecución del árbol con un nodo DummyInput, esto simplemente se hace para dar tiempo a modificar los parámetros antes de continuar con la simulación de la prueba. En el caso de que se aborte cuando el inspector se encuentra en medio del despliegue, puede verse en la Figura 3.13 que el árbol envía una orden de abortar el despliegue del mismo, esperando hasta que este cambie de estado a almacenado antes de continuar con un movimiento vertical y finalizar con FALLO. Por otro lado, en el caso de que el abortaje se solicite cuando el inspector se encuentra completamente desplegado, tal y como ocurre en la Figura 3.14, simplemente se continua con la desconexión del mismo y el movimiento vertical, finalizando con FALLO. Por último, se realiza la prueba de la misión completa, mostrándose en las Figuras 3.15 y 3.16 los resultados obtenidos en el caso de que esta se ejecute por completo de forma exitosa, con todos los movimientos necesarios para ir hasta la tubería, localizarla, desplegar el crawler, regresar a base y aterrizar. Figura 3.15 Captura de la misión completa ejecutada de forma exitosa, incluyendo las consolas utilizadas durante la ejecución. En el caso de que este aborte durante las fases de acercamiento o despliegue, se puede comprobar en las Figuras 3.18 y 3.20, que el UAV realiza las maniobra de retorno y aterrizaje de forma correcta, devolviendo en ambos casos FALLO al no haber finalizado de forma correcta la misión. Si la misión se aborta durante el retorno, ya sea este el que ocurre tras haber colocado el inspector sobre la tubería o el que ocurre si se aborta otra fase, ocurre una respuesta como la que se muestra en la Figura 3.22, en la cual el UAV queda en HOVER en el punto actual para poder realizar maniobras manuales y el árbol devuelve FALLO, tal y como se había diseñado. Para finalizar, se estudia el caso en que se solicite el abortaje durante la maniobra de aterrizaje. Observando los resultados de la Figura 3.24, puede comprobarse que cuando ocurre esto, el árbol de comportamiento, como se había diseñado, solicita el servicio de abortaje, el cual cambia el modo del autopiloto a despegue y el UAV asciende la distancia de despegue y queda en HOVER en ese punto, finalizando el árbol con FALLO. 39 Figura 3.16 Captura de la misión completa ejecutada de forma exitosa, centrándose en los gráficos de los resultados de la simulación. Figura 3.17 Gráfica 3D de la misión completa. 40 Capítulo 3. Resultados de Simulación Figura 3.18 Captura de la misión completa abortada durante la fase de acercamiento a la tubería. Figura 3.19 Gráfica 3D de la misión completa abortada durante la fase de acercamiento. 41 Figura 3.20 Captura de la misión completa abortada durante la fase de despliegue del crawler. Figura 3.21 Gráfica 3D de la misión completa abortada durante la fase de despliegue. 42 Capítulo 3. Resultados de Simulación Figura 3.22 Captura de la misión completa abortada durante la fase de retorno. Figura 3.23 Gráfica 3D de la misión completa abortada durante la fase de retorno. 43 Figura 3.24 Captura de la misión completa abortada durante el aterrizaje. Figura 3.25 Gráfica 3D de la misión completa abortada durante el aterrizaje. 4 Conclusiones En el documento se ha presentado el desarrollo de un controlador de misión utilizando árboles de comportamiento para controlar el multirrotor y el despliegue del inspector dentro del proyector SIMAR. Teniendo en cuenta los resultados obtenidos se puede afirmar que el uso de los árboles de comportamiento es un método adecuado para poder implementar este tipo de controlador de alto nivel de una forma más intuitiva y que permite modificaciones y adaptaciones de forma más visual, así como el cambio de función completa mediante el cambio o adición de ramas a una función ya desarrollada. Comentar también que los desarrollos realizados parten de la existencia de una máquina de estados que se encargue de realizar los procesos de menor nivel, por lo tanto, no es correcto extender los resultados aquí obtenidos a un controlador que implemente el todas las funciones de la misión. En lo referido a desarrollos futuros, cabe mencionar la realización de pruebas sobre la plataforma real utilizando el modelo final de la misma cuando se encuentre finalizada, así como, el desarrollo de un nuevo árbol de comportamiento que implemente la función opuesta, recoger el crawler de la tubería, la cual podría partir de los desarrollos aquí realizados cambiando la rama correspondiente al despliegue por una de recogida. A modo de conclusión, se puede decir que el controlador desarrollado cumple con los objetivos que se habían planteado para su diseño y por tanto, se puede utilizar de forma segura en el proyecto SIMAR. 45 52 Apéndice A. Árboles de Comportamiento Figura A.6 Árbol de comportamiento implementando la maniobra de acercamiento, análogo a la Figura A.5, pero permitiendo cambiar la posición del blanco para poder realizar el acercamiento a un blanco móvil. 53 Figura A.7 Árbol de comportamiento implementando la lógica para seguir una trayectoria. 54 Apéndice A. Árboles de Comportamiento Figura A.8 Árbol de comportamiento implementando la maniobra de despliegue del crawler. 55 Figura A.9 Árbol de comportamiento implementando la maniobra de retorno a la base. 56 Apéndice A. Árboles de Comportamiento Figura A.10 Árbol de comportamiento que implementa la misión completa haciendo uso del resto de árboles de comportamientos definidos. 57 Figura A.11 Árbol de comportamiento de la misión completa, desplegando para mostrar todos los nodos que lo componen. Su inclusión es meramente ilustrativa al ser poco legible debido a su tamaño. Índice de Figuras 1.1 Ejemplo de tópico en el que dos publicadores envían mensajes y estos son recibidos por dos suscriptores distintos 2 1.2 Ejemplo de servicio en el que un servidor provee dicho servicio a dos clientes distintos, enviando a cada uno la respuesta que le corresponde 3 1.3 Ejemplo de árbol de comportamiento que implementaría una misión de acercamiento a un punto, despliegue de equipamiento y posterior aterrizaje 3 1.4 Ejemplo de secuencia en el que las acciones se ejecutan en el orden que están numeradas 5 1.5 Ejemplo de Fallback en el que se ejecuta una acción y si esta falla se ejecuta la primera contramedida, si una contramedida falla, se ejecuta la siguiente 6 2.1 Interfaz que se muestra por pantalla al ejecutar el nodo principal, introducir un número ejecuta el comando o el árbol de comportamiento nombrado, el comando [0] de recarga permite al programa detectar nuevos archivos que se han introducido en la carpeta cuando esta ya se ha cargado 7 2.2 Ejecutar el comando de cambio de carpeta muestra por pantalla las carpetas dentro de la localización actual y da la posibilidad de entrar en una de ellas, volver a la carpeta predeterminada o ir a la carpeta contenedora 8 2.3 Una vez se selecciona una de las carpetas, el programa detecta todos los ficheros que pueden contener árboles de comportamiento (ficheros XML) 8 2.4 Si se escoge uno de los ficheros, se muestran cuales árboles de comportamiento contiene y da la opción de ejecutar uno de ellos o volver a la visualización de carpeta 8 2.5 Si se escoge el comando de cargar todo el fichero se mostrarán por pantalla todos los árboles de comportamiento que se han encontrado y los ficheros que lo contienen, permitiendo ejecutar cualquiera de ellos y que el programa sea capaz de tomar Subtrees definidos dentro de cualquiera de los otros ficheros 9 2.6 Estructura que se utiliza para implementar cambios de estado sencillos 10 2.7 Diagrama de comportamiento normal de los árboles de cambio de estado sencillos 12 2.8 Diagrama de comportamiento normal de un árbol que implementa la función de ir a 13 2.9 Estructura de árbol de comportamiento que implementa un protocolo 14 2.10 Diagrama de comportamiento normal de los árboles de de estado de protocolo 15 2.11 Diagrama de comportamiento normal del árbol de estado que implementa la variante más sencilla de la maniobra de acercamiento 17 2.12 Diagrama de comportamiento normal del árbol de estado que implementa la maniobra de acercamiento con el cambio a ruta de búsqueda 18 2.13 Diagrama de comportamiento normal del árbol de estado que implementa la maniobra de acercamiento a un objetivo móvil 19 2.14 Diagrama de comportamiento nominal del árbol de comportamiento correspondiente a la maniobra de despliegue del inspector 21 2.15 Diagrama de funcionamiento del árbol que implementa la misión completa 22 2.16 Plan de búsqueda cuando la plataforma se acerca a la tubería 25 59 60 Índice de Figuras 3.1 Interfaz del simulador de Python desarrollado para comprobar las funcionalidades de los árboles de comportamiento 27 3.2 Capturas de pantalla de la respuesta en simulación al despegue y a su abortaje 28 3.3 Capturas de la respuesta en simulación al aterrizaje y a su abortaje 29 3.4 Capturas de la maniobra de retorno en simulación 30 3.5 Captura de una maniobra de retorno en simulación abortada 31 3.6 Captura del inicio de la maniobra de acercamiento 31 3.7 Capturas de la maniobra de acercamiento con barridos laterales para buscar la tubería 32 3.8 Captura de la finalización de la maniobra de acercamiento a la tubería con barridos laterales 33 3.9 Capturas del inicio de la maniobra de acercamiento con correcciones dinámicas 33 3.10 Capturas de la finalización de la maniobra de acercamiento con correcciones dinámicas 34 3.11 Capturas de la maniobra de despliegue del crawler 35 3.12 Captura de la finalización de la maniobra de despliegue del crawler 36 3.13 Capturas de la maniobra de despliegue abortada mientras el crawler se encuentra desplegándose 36 3.14 Capturas de la maniobra de despliegue abortada cuando el crawler se encuentra completamente desplegado 37 3.15 Captura de la misión completa ejecutada de forma exitosa, incluyendo las consolas utilizadas durante la ejecución 38 3.16 Captura de la misión completa ejecutada de forma exitosa, centrándose en los gráficos de los resultados de la simulación 39 3.17 Gráfica 3D de la misión completa 39 3.18 Captura de la misión completa abortada durante la fase de acercamiento a la tubería 40 3.19 Gráfica 3D de la misión completa abortada durante la fase de acercamiento 40 3.20 Captura de la misión completa abortada durante la fase de despliegue del crawler 41 3.21 Gráfica 3D de la misión completa abortada durante la fase de despliegue 41 3.22 Captura de la misión completa abortada durante la fase de retorno 42 3.23 Gráfica 3D de la misión completa abortada durante la fase de retorno 42 3.24 Captura de la misión completa abortada durante el aterrizaje 43 3.25 Gráfica 3D de la misión completa abortada durante el aterrizaje 43 A.1 Leyenda para los árboles de comportamiento 47 A.2 Árbol de comportamiento implementando el despegue 48 A.3 Árbol de comportamiento implementando el aterrizaje 49 A.4 Árbol de comportamiento implementando la maniobra de acercamiento, con la maniobra totalmente preprogramada 50 A.5 Árbol de comportamiento implementando la maniobra de acercamiento, en él la maniobra cerca de la tubería se define una vez el UAV se encuentra cerca de la misma 51 A.6 Árbol de comportamiento implementando la maniobra de acercamiento, análogo a la Figura A.5, pero permitiendo cambiar la posición del blanco para poder realizar el acercamiento a un blanco móvil 52 A.7 Árbol de comportamiento implementando la lógica para seguir una trayectoria 53 A.8 Árbol de comportamiento implementando la maniobra de despliegue del crawler 54 A.9 Árbol de comportamiento implementando la maniobra de retorno a la base 55 A.10 Árbol de comportamiento que implementa la misión completa haciendo uso del resto de árboles de comportamientos definidos 56 A.11 Árbol de comportamiento de la misión completa, desplegando para mostrar todos los nodos que lo componen. Su inclusión es meramente ilustrativa al ser poco legible debido a su tamaño 57 Bibliografía •Auryn Robotics (2024). BehaviorTree.CPP, en https://www.behaviortree.dev •Open Robotics (2022). ROS Wiki, en https://wiki.ros.org •Open Robotics (2024). ROS 2 Documentation: Rolling, en https://docs.ros.org/en/rolling/index.html 61