Visualização de Dados para Redes de Veículos Autónomos
Full text
Faculdade de Engenharia da Universidade do Porto Visualização de Dados para Redes de Veículos Autónomos Carlos José Rangel Vieira Ribeiro VERSÃO FINAL Dissertação realizada no âmbito do Mestrado Integrado em Engenharia Eletrotécnica e de Computadores Major Automação Orientador: Prof. João Tasso de Figueiredo Borges de Sousa 30 de julho de 2012
ii © Carlos Ribeiro, 2012
iii Resumo Vários desenvolvimentos tecnológicos recentes levaram ao aparecimento e proliferação de sistemas baseados em redes de veículos. Estes sistemas são caracterizados por estabelecerem uma colaboração entre operadores humanos e nós móveis da rede (veículos robóticos), nós esses que estabelecem caminhos de comunicação dinâmicos e, em simultâneo, dependem dos caminhos de comunicação criados para desempenhar os seus objetivos. Este trabalho visa estender o software Neptus, desenvolvido pelo Laboratório de Sistemas e Tecnologia Subaquática (LSTS) da Faculdade de Engenharia da Universidade do Porto (FEUP), dotando-o de novas visualizações que permitam compreender de que forma estão ligados vários sistemas e subsistemas numa rede de veículos e como evoluem essas ligações ao longo do tempo. Numa primeira fase, foi necessário fundir dados provenientes de vários veículos, transformando registos de dados individuais num log multi-sistema que permite posteriormente perceber as interações da rede. Na segunda fase do trabalho, procedeu-se à visualização das interações através da criação de grafos de comunicações. Os grafos são gerados usando a linguagem dot (GraphViz) que permite a utilização de várias ferramentas para layout, manuseamento e exportação dos grafos como o yEd Graph Editor ou o Microsoft Automatic Graph Layout. Por fim, estendeu-se o software Neptus com plugins que permitem gerar rapidamente grafos de comunicações a partir de logs de missão. As ferramentas criadas foram testadas em laboratório com dados reais e foram já utilizadas no terreno, durante missões reais de veículos autónomos.
iv
v Abstract Recent technological advances have led to the appearance and proliferation of networked vehicle systems. These systems are characterized by allowing collaboration between human operators and mobile nodes (robotic vehicles). These mobile nodes are used as routers of information creating dynamic communication networks. This work aims to extend the Neptus software, developed at the Underwater Systems and Technology Laboratory from Faculty of Engineering of the University of Porto, by creating new visualizations that allow the user to understand how the various nodes are connected to each other in a networked vehicle system and how existing connections evolve through execution time. In a first phase data generated from multiple vehicles was merged, transforming the individual log files into a multi-vehicle log that can be used to study the network interactions. On a second phase new data visualizations were created to generate different communication graphs. The generated graphs use a dot language (GraphViz) and associated tools like yEd Graph Editor or the Microsoft Automatic Graph Layout, which allow automatic graph layout, user-interactions (zooming, pan, node movement) and exporting graphs to other formats. Finally, plugins were added to allow rapid generation of communication graphs from mission log files in the Neptus Software. The created tools have been tested in the lab with real-world data acquired at the field while operating the LSTS autonomous vehicles.
vi
vii Agradecimentos Com os melhores agradecimentos para o meu orientador João Tasso de Figueiredo Borges de Sousa por me ter dado a oportunidade de desenvolver este trabalho sob a sua supervisão Também gostaria de agradecer ao doutor José Carlos de Queirós Pinto pelo tempo despendido, por todas as discussões que tivemos e pelos conselhos fornecidos, que me ajudaram a realizar um trabalho melhor. Também gostaria de agradecer ao Daniel Filipe de Azeredo Silva pela sua contribuição e principalmente por disponibilizar o laboratório I004 e I005 sempre que possível. Por último, mas não menos importante, gostaria de agradecer aos meus pais, ao meu irmão e amigos por todo seu apoio.
xiv
Abreviaturas API Application Programming Interface ASV Autonomous Surface Vehicle AUV Autonomous Underwater Vehicle BSD Berkeley Software Distribution CCL Compact Control Language CCU Command and Control Unit CORBA Common Object Request Broker Architecture CPU Central Processing Unit CRAN Comprehensive R Archive Network DCOM Distributed Component Object Model DEEC Departamento de Engenharia Eletrotécnica e de Computadores DUNE Unified Navigational Environment ETH Swiss Federal Institute of Technology Zurich FEUP Faculdade de Engenharia da Universidade do Porto GAM Generalized additive model GPL General Public License GUI Graphical User Interface HIL Hardware-in-the-loop IDE Integrated Development Environment IDL Interface Definition Language IEEE Institute of Electrical and Electronics Engineers IMC Inter-Module Communication Protocol JAUS Joint Architecture for Unmanned Systems JSIDL JAUS Service Interface Definition Language JSON JavaScript Object Notation JSS Core JAUS Core Service Set JVM Java Virtual Machine KML Keyhole Markup Language LLF LSTS Log Format
ii LSTS Laboratório de Sistemas e Tecnologia Subaquática LVQ Learning Vector Quantization MRA Mission Review and Analysis NATO North Atlantic Treaty Organization netCDF network Common Data Form PDF Portable Document Format ROS Robot Operating System ROV Remotely Operated Vehicle RPC Remote Procedure Call SAE Society of Automotive Engineers SDK Software Development Kit SNAME Society of Naval Architects and Marine Engineers SOA Service Oriented Architecture STAIR STanford AI Robot SVN Subversion TCP Transmission Control Protocol UAV Unmanned Air Vehicle UDT User Datagram Protocol URL Uniform Resource Locator USTL Underwater Systems and Technology Laboratory XML Extensible Markup Language XSD XML schema XSLT Extensible Stylesheet Language Transformations
1 Capítulo 1 Introdução Este trabalho desenvolve uma aplicação a integrar no software de controlo neptus, o qual foi desenvolvido pelo LSTS da FEUP. Com esta aplicação torna-se possível visualizar, através de grafos, todas as comunicações realizadas por uma rede de veículos ou, em alternativa, apenas aquelas pretendidas pelo operador. Como tal, permite ao leitor uma melhor compreensão dos problemas e das soluções encontradas para esses veículos, bem como fornece alguns conhecimentos acerca da implementação e do controlo da rede de veículos desenvolvida pelo LSTS. Por esta razão, nesta introdução seguirei de perto o artigo “Implementation of a Control Architecture for Networked Vehicle Systems” [1]. O LSTS visa a criação e o desenvolvimento de veículos autónomos e assistidos por operadores humanos e de redes de sensores [2] (figura 1). As redes formadas por estes sistemas são dinâmicas e como os veículos têm alcance de comunicação limitado e estão constantemente a mover-se, são criados ou eliminados links de comunicação e de controlo em tempo de execução. Os nós da rede podem funcionar como sensores, dispositivos móveis de comunicação ou mesmo trabalhar como mulas de informação (transportando dados) e recuperação de redes de comunicação [1]. O LSTS já construiu vários veículos autónomos diferentes, nomeadamente: Veículos Operados Remotamente (ROV) em 2005 [3], veículos autónomos de superfície (ASV) em 2007 [4], veículos submarinos autónomos [5] desde 2005 e vários veículos aéreos não tripulados [6] desde 2007. Para controlar estes veículos, a equipa do LSTS criou software e protocolos de comunicação que podem ser reutilizados para vários tipos de veículos, de acordo com necessidades específicas a cada veículo, e que podem realizar comportamentos simples ou cooperativos. Para suportar redes deste tipo, foi necessário gerir sensores e atuadores a bordo dos veículos e a sua utilização para controlo e navegação autónoma e para comunicação entre veículos, gateways e consolas de operadores. Foram desenvolvidas normas de comunicação para planeamento, seguimento e análise das missões, bem como interfaces adaptativas. Todo o software foi desenvolvido tendo em vista a sua extensibilidade de forma a oferecer flexibilidade para adicionar novos dispositivos, controladores, visualizações e eventuais soluções de problemas futuros [1]. Numa tentativa de satisfazer essas necessidades foram criadas varias ferramentas de software que juntas são denominadas como a LSTS Toolchain
Introdução 2 (ferramentas que, unidas, implementam uma arquitetura de controlo para múltiplos veículos). A LSTS Toolchain compreende o DUNE Unified Navigational Environment (DUNE), que é o software de bordo, o Neptus, que é o software de comando e controlo, e o protocolo de comunicações Inter-Module Communication (IMC) [2]. Todas estas ferramentas vão permitir a criação de logs que são posteriormente analisados. Existem vários projetos de protocolos de comando e controlo similares ao IMC que permitem controlo e comandos de baixo nível, como é o caso do JAUS/SAE AS-4 [7] e da Compact Control Language (CCL) [8] que utilizam mensagens para controlar o veículo. O IMC possui um conjunto de mensagens de alto nível que fornecem características idênticas às do NATO STANAG 4586 [9] e Common Control Language (common CL), os quais permitem o envio de mensagens genéricas e a monitorização do veículo em tempo real. O CCL e common CL [10] são projetados para submarinos autónomos (Autonomous Underwater Vehicles ou, simplesmente AUVs) tendo em consideração as comunicações subaquáticas acústicas, pelo que neste protocolo todas as mensagens são projetadas para caber em pacotes altamente compactos e assim otimizar as comunicações. O IMC, por sua vez, fornece vários formatos de serialização, o que viabiliza a comunicação para larguras de banda reduzidas, sendo comum usar um formato binário eficiente. O NATO STANAG 4586 é utilizado para definir padrões que podem ser usados para controlar veículos aéreos não tripulados (Unmanned Air Vehicles ou, simplesmente UAVs) com características distintas e, dada a possibilidade de operarem em conjunto, foram desenvolvidos protocolos para comandar qualquer UAV. O IMC também foi desenvolvido com o objetivo de obter interoperabilidade e abstração de hardware. O Joint Architecture for Unmanned Systems (JAUS) é semelhante ao IMC, permitindo a existência de uma vasta gama de veículos em que é utilizada uma vista hierárquica de veículos, como sistemas com subsistemas, nódulos, componentes e instâncias de componentes [11]. Quando Figura 1 - Conceito da rede do LSTS para sistemas de veículos [1].
Introdução 3 interrogados sobre o porquê de desenvolver um novo protocolo, os investigadores do LSTS indicam que o seu objetivo é desenvolver um novo protocolo não para um tipo de veículo específico mas sim para redes de veículos heterogéneos, tendo também interesse em adaptar o protocolo de acordo com as necessidades que vão sendo encontradas. 1.1 - Arquitetura Na arquitetura de controlo do sistema dos veículos em rede é utilizada uma abordagem de controlo por camadas, uma vez que existem vários nós diferentes na rede. Estes são compostos por vários componentes, como por exemplo veículos (figura 2), sensores, controladores (figura 3), operadores humanos, consolas de operação, dispositivos de comunicação, etc., de modo a estabelecer interfaces comuns para a comunicação e coordenação entre os componentes. Cada camada encapsula detalhes do nível inferior e fornece interfaces para leitura de estado e receção de comandos. Figura 2 - Diferentes camadas da arquitetura do controlo dos veículos [12].
Introdução 4 Figura 3 - Implementação da arquitetura e possível troca entre controladores ativos/inativos [1]. Todos os veículos têm uma plataforma de baixo nível com sensores e atuadores que são utilizados pela camada Guidance/Navigation, à qual compete a leitura e o comando dos atuadores. Na camada seguinte temos a Maneuver interface, que vai ler a informação do estado do veículo e vai enviar comandos para a camada de Guidance/Navigation. Em cima da camada Guidance/Navigation temos a Vehicle Interface que vai supervisionar o veículo, isto é, vai verificar se o sistema está a funcionar corretamente e inicia ou termina os controladores de manobra de acordo com as especificações solicitadas pela camada superior. O Vehicle Supervisor (integrado na camada Vehicle Interface), por sua vez, verifica se a manobra é possível fisicamente e se é seguro executá-la, de acordo com a informação recebida das camadas inferiores (níveis de bateria, falhas de hardware, etc.) e também pode terminar a execução da manobra em caso de falha de hardware ou qualquer violação de segurança. A camada superior envia comandos de especificação de manobras para o Vehicle Supervisor. Estes comandos podem provir do Team Supervisor, o qual comanda a execução de manobras em vários veículos, ou do Plan Supervisor, o qual se encontra a bordo dos veículos e, de acordo com uma especificação da missão, dispara a execução de manobras no veículo. Exceto para a camada da plataforma de hardware, todas as outras camadas seguem interfaces comuns; este fato permite ter várias instâncias de controladores na camada superior, o que por sua vez proporciona uma maior flexibilidade. As camadas vehicle, maneuver, guidance, navigation e Platform Interface foram implementadas pela framework do DUNE. 1.2 - DUNE O DUNE é o software de bordo usado nos veículos e é responsável pelas comunicações, supervisão de navegação, controlo, sensores e atuadores. É escrito em C++ e tem uma arquitetura multiplataforma que permite diferentes arquiteturas de CPUs (Intel x86 ou compatível, Sun SPARC, ARM, PowerPC e MIPS) e sistemas operativos (Linux, Solaris, Mac OS X, FreeBSD, NetBSD, OpenBSD, eCos, RTEM, Microsoft Windows ou superior e QNX Neutrino).
Introdução 5 Este fato permite a utilização do DUNE em barcos autónomos (Autonomous Surface Vehicles ou, simplesmente ASVs), ROVs, AUVs e UAVs e nas gateways de comunicação [13]. A sua adaptação a diferentes sistemas é feita através da alteração de perfis de execução e configurações, podendo existir tarefas comuns aos vários veículos, mudando apenas as suas configurações. Os conjuntos de parâmetros de configuração de uma tarefa são determinados pelo esquema de configuração que permite a ativação e desativação de tarefas sem haver necessidade de recompilar o software. O DUNE também pode ser configurado com perfis diferentes, que permitem ativar e desativar conjuntos de tarefas predefinidos no perfil. A versatilidade e modularidade do DUNE vai permitir um nível de abstração em que, para instalar um novo sensor ou um novo controlador, apenas é necessário habilitar ou desabilitar algumas tarefas, o que permite criar facilmente novo software para um módulo. O DUNE pode ser executado num perfil de simulação, o qual simula todos os sensores e atuadores, ou no perfil Hardware-in-the-loop (HIL) Simulation, o que permite ativar alguns sensores e atuadores bem como a simulação de tarefas, possibilitando testar e validar novas tarefas e funcionalidades. O DUNE funciona como um mecanismo de passagem de mensagens onde tarefas independentes são executadas em diferentes threads e onde as tarefas são ligadas a um canal de mensagens (bus) que permite publicar e assinar mensagens e através da qual podem ser consumidas ou publicadas por outras tarefas. As mensagens passadas para o bus são especificadas no protocolo de comunicações do LSTS, o IMC [11], sendo que o DUNE procede à criação de logs de todas as mensagens recebidas por uma tarefa especial de registo de dados (Transports.Logging) que concatena todas as mensagens recebidas num ficheiro em disco. 1.3 - Neptus Neptus é o software de comando e controlo usado por operadores humanos para interagir com sistemas de redes de veículos e suporta diferentes fases do ciclo de vida de uma missão: planeamento, simulação, execução, revisão e disseminação [14–18]. Este fornece uma interface que permite o controlo individual ou em simultâneo de vários veículos, como AUVs, UAVs, ASVs e ROVs. No Neptus, uma missão é visualizada graficamente e especificada a partir de um conjunto de manobras e transições entre manobras. Uma manobra pode ser realizada por um veículo específico ou uma classe de veículos resultando na instanciação de um controlador a bordo do veículo que potencialmente altera o seu estado físico. As transições usam uma expressão booleana que pode ser desencadeada por eventos assíncronos ou avaliando o estado (interno) do veículo. O Neptus tem uma Application Programming Interface (API) que fornece um mecanismo de modelos (templates) que gera planos de missão com base em parâmetros introduzidos pelo utilizador, sendo possível adicionar novos templates através de plugins em javascript (figura 4). Este software também permite efetuar o planeamento da missão visualmente, possuindo para o efeito um editor gráfico que fornece uma visualização do mapa do local da missão, e as manobras podem ser adicionadas e editadas a este mapa, também permite editar as ligações entre manobras e os parâmetros das manobras. Para verificar um plano de missão, geralmente os operadores pré-visualizam a sua execução usando um simulador.
Introdução 6 O neptus oferece três níveis diferentes de simulação: • Previsão rude do comportamento. • Simulação de software. • Simulação de HIL Para efetuar a simulação é necessário simular um ou mais veículos no DUNE em modo de simulação para que seja possível comunicar com o Neptus, não nos podemos esquecer também podem ser executados no interior dos veículos reais para testar sensores e atuadores. A simulação de Software HIL é utilizada para testar as especificações da missão, e para treinar os elementos da equipa antes das missões reais; a simulação HIL também pode ser usada para testar hardware em dry-run. O Neptus também fornece simulações de comportamento numa missão, quando os veículos perdem a ligação à base, para prever o estado dos veículos e os locais onde estes se possam encontrar, de forma a facilitar a vida ao operador em missões com múltiplos veículos. Figura 4 – Ambiente de trabalho do neptus. Em missões são utilizadas as consolas operacionais do Neptus (figura 5), as quais permitem monitorizar a execução do veículo, alterar ou criar novos planos, enviar planos de execução, operar remotamente os veículos, etc. Estas consolas operacionais suportam o controlo de múltiplos veículos em simultâneo, mostrando dados recebidos de todos os veículos, e permitem ao utilizador alternar entre veículos controlados. Como os veículos estão maioritariamente num modo de funcionamento autónomo, torna-se possível planear missões futuras enquanto outras estão a ser executadas. Para proporcionar uma operação mais segura, o Neptus fornece uma framework de alarmes composta por vários daemons que monitorizam os dados a serem recebidos pelos veículos, notificando o utilizador de eventos de interesse como avarias, o início e a conclusão das missões.
Introdução 7 Os veículos do LSTS armazenam os dados das mensagens geradas e recebidas nas missões em serialized streams. Para que seja possível inspecionar e analisar esses dados posteriormente, o Neptus fornece uma aplicação que descompacta os dados em arquivos de texto, bem como várias visualizações e utilitários para processar os dados e plugins de revisão logs e mapas de cores; os arquivos de texto podem ser exportados para ferramentas como Excel e o Matlab. Todas as mensagens têm uma tag com o tempo em que foram geradas pelo sistema. O neptus Mission Review and Analysis (MRA) permite a reprodução dos dados da missão (figura 6), recriando uma visualização da execução dos veículos em missões passadas e enviando os dados para as consolas operacionais. Os plugins do Neptus MRA vão viabilizar a exportação dos dados das missões para vários formatos, como PDF, NetCDF e KML. O Neptus tem algumas semelhanças com o conjunto de ferramentas do ROS [20]. Enquanto tentam satisfazer requisitos semelhantes, cada um segue a sua filosofia, o Neptus fornece interfaces configuráveis que podem ser adaptadas para cada tipo de veículo autónomo, enquanto que o ROS tem uma única interface. O Neptus foi testado várias vezes no campo, tendo feedback da comunidade académica, industrial e militar. O DUNE é executado num espaço muito pequeno (16 MB) e foi desenvolvido para processadores embutidos, de capacidade limitada, podendo ser executado em sistemas operacionais que não possuam processos, tais como o RTEMS ou ECOS. Por outro lado, o ROS é open-source e tem uma comunidade que contribui, ajudando a expandir o conjunto de ferramentas. Figura 5 - Consola operacional do NEPTUS [19].
Estado da Arte 14 Figura 10 - Screanshot do R project num MacOS X RAqua desktop [32]. A linguagem R tem funções que permitem a programação modular, branching e looping. As funções em R são escritas em R e permitem efetuar a interface com os procedimentos escritos em C, C++ e Fortran, de forma a obter uma maior eficiência. A distribuição R contém várias funcionalidades, tais como modelos lineares generalizados, modelos de regressão não linear, análise de séries cronológicas, testes paramétricos clássicos e não paramétricos, clustering e smoothing. Não obstante, verifica-se ainda a existência de funções para o ambiente gráfico, o que o torna flexível, bem como de módulos adicionais (add-on packages). A linguagem R é fácil e para além de originar publicações de qualidade também cria gráficos bem concebidos, incluindo símbolos e fórmulas matemáticas, em que o utilizador tem controlo total. O ambiente R tem um conjunto de software que inclui [32]: • Um manuseio eficiente de dados e facilidade de armazenamento. • Um conjunto de operadores para cálculos sobre cálculorrays, em algumas matrizes. • Uma grande coleção, coerente e integrada, de ferramentas para análise de dados. • Facilidade gráfica para análise e display de dados. • Uma linguagem de programação simples e eficaz que inclui condicionais, loops, funções recursivos definidas pelo utilizador, e input e output facilities. O código fonte, as distribuições binárias e a documentação para R podem ser obtidos através da Comprehensive R Archive Network (CRAN). O código fonte também está disponível através do repositório SVN (Subversion) do R-project [33]; Tarballs com snapshots diários da r-devel e r-patched e versões de desenvolvimento do R podem ser encontrados no ftp do ETH [34]. A distribuição R trás os seguintes Add-on packages: • base: Funções de base R. • compiler: compilador código R. • datasets: Base de dados para suporte R.
Estado da Arte 15 • grDevices: Dispositivos gráficos para gráficos base e grid. • graphics: Funções R para gráficos de base. • grid: A reescrita dos recursos de layout gráficos, além de algum apoio para interação. • methods: Métodos formalmente definidos e classes para os objetos R, além de ferramentas de programação, como descrito no Green Book. • parallel: Suporte para computação paralela, incluindo por bifurcação e soquetes, e geração de números aleatórios. • Splines: Regressão spline, funções e classes. • stats: Funções R estatísticas. • stats4: Funções estatísticas usando classes S4. • tcltk: Interface e ligações de linguagem a elementos Tcl/Tk do GUI. • tools: Ferramentas para o desenvolvimento de pacotes e administração. • utils: Utilitários para funções R. Os Add-on packages para o R disponíveis no repositório do CRAN são: • KernSmooth: Funções para a suavização do kernel correspondentes ao livro "Smoothing Kernel" [35]. • MASS: Funções e conjuntos de dados do pacote principal de Venables e Ripley, "Modern Applied Statistics with S" [36]. • Matrix: Um pacote de Matrizes. • boot: Funções e conjuntos de dados de inicialização do livro "Bootstrap Methods and Their Applications" [37]. • class: Funções de classificação (k-vizinho mais próximo e LVQ). • cluster: Funções para análise de cluster. • codetools: Ferramentas de análise de código. • foreign: Funções para ler e gravar dados armazenados pelo software estatístico como o Minitab, S, SAS, SPSS, Stata, Systat, etc. • lattice: Gráficos lattice, uma implementação de funções gráficas Trellis. • mgcv: Rotinas para GAMs e outros problemas generalizados de regressão de ridge com seleção múltipla, alisamento, e parâmetros por GCV ou UBRE. • nlme: Ajusta e compara modelos lineares Gaussianos e não-lineares de efeitos mistos. • nnet: Software para feed-forward neural networks. • rpart: Particionamento recursivo e árvores de regressão. • spatial: Funções para kriging e análise de padrões de pontos de W. Venables e Ripley B. [36]. • survivel: Funções para análise de sobrevivência, incluindo a probabilidade penalizada. As ligações mais utilizadas são ligações por ficheiros criadas pela função file. Estas ligações podem ser abertas para leitura, escrita ou anexar, em texto ou no modo binário; existe ainda a possibilidade de leitura e escrita simultânea. Por norma, uma ligação não se encontra aberta quando o ficheiro é criado, pelo que é necessário abrir uma e fechar a ligação após o uso; existem funções genéricas open e close com métodos para abrir e fechar as ligações. As ligações também podem ser efetuadas a partir de ficheiros comprimidos ou através do algoritmo gzip [38] (pela função gzfile), enquanto que os ficheiros compactados por bzip2 [39] são através da função bzfile [32].
Estado da Arte 16 Também é possível efetuar ligações de texto, as quais permitem que os vetores de caracteres possam ser lidos como se as linhas fossem ficheiros de texto. Uma ligação de texto é aberta, designando-se por textConnection, e copia o conteúdo atual do vetor de caracteres para um buffer interno no momento da criação. As pipes [40] são uma forma especial de arquivo que se ligam a outro processo, e são criadas pela função pipe. A abertura de uma ligação pipe para entrada executa um comando do sistema operativo que torna a saída padrão, disponível para a entrada da ligação R. Também é possível utilizar URLs de tipos de "http://", "ftp://" e "file://" que podem ser lidas usando a função url; a função file também aceita as URLs como especificação de ficheiro e chamada a url. Os sockets [41] também podem ser usados nas ligações socketConnection, podem ser escritas ou lidas a partir de ficheiros e podem ser usados sockets de cliente ou servidor. Uma das desvantagens dos sockets é que a instalação pode ser bloqueada por razões de segurança ou para forçar o uso de caches. O interface sockets de baixo nível é dado pelas funções make.socket, read.socket, write.socket e close.socket. A linguagem XML é utilizada para fornecer estruturas de dados padrão e está a tornar-se o padrão de dados de marcação e troca. O XML fornece uma maneira de especificar a codificação dos ficheiros. A função download.file é fornecida para ler um ficheiro Web via FTP ou HTTP e gravá-lo num ficheiro; Isto também pode ser feito com as funções read.table e scan, que podem ler diretamente a partir de uma URL, usando url para abrir a ligação. O Common Object Request Broker Architecture (CORBA) é semelhante ao Distributed Component Object Model (DCOM), que permite os aplicativos chamarem métodos ou operações, em objetos de servidores que correm noutras aplicações, e podem ser programados em linguagens diferentes e executados em máquinas diferentes. O pacote CORBA disponível no site da Omegahat [42] permite que comandos R possam ser usados para localizar servidores CORBA, consultar métodos e invocar métodos dinamicamente nesses objetos. Valores de R dados como argumentos a essas chamadas são exportados na chamada e disponibilizados para a invocação da operação. Podem-se também criar servidores CORBA em R, que permitem outras aplicações chamar esses métodos e é ainda possível usar o pacote CORBA para obter computação distribuída, e paralela em R. 2.3 - OpenJAUS O JAUS é um standard da SAE International para comunicação, comando e controlo de sistemas não-tripulados. Ele especifica como o software deve enviar e receber dados, a fim de interagir numa rede, o que permite que, quando o software está em conformidade com o JAUS, facilmente se pode integrar o sistema com outros sistemas baseados em JAUS (figura 11). Isto permitiu a criação do OpenJAUS, que consiste numa biblioteca de software escrito em C++ e possui um Kit de desenvolvimento que fornece exemplos de projetos diversos e utilitários[43].
Estado da Arte 17 Figura 11 - Sistema JAUS feito de subsistemas ligados em rede [43]. O JAUS define o protocolo de comunicação para os sistemas de veículos não tripulados, alguns dos seus componentes internos e a sua interação com estações de controlo, o que possibilita a formatação de mensagens para o transporte entre os serviços do sistema, bem como conjuntos de serviços standard[44], que descrevem componentes específicos. Este emprega uma Arquitetura Service Oriented Architecture (SOA) [45] o que lhe permite um comando e controlo distribuído. O standard JAUS foi desenvolvido pela Society of Automotive Engineers (SAE) no âmbito do Aerospace Standards Unmanned Systems Steering Committee (AS-4), e trata-se de um standard proprietário, em que os documentos que definem o JAUS podem ser comprados. O objetivo do JAUS é tornar os produtos de diferentes fabricantes uniformes e consistentes, a fim de permitir a interoperabilidade, a permutabilidade e modularidade o que, por sua vez, levará à redução do custo de aquisição e esforço humano em integração de sistemas. O OpenJAUS foi desenhado com o intuito de ter uma interface simples e robusta para o utilizador, clareza e integralidade da API, e o cumprimento das normas publicadas[46]. O principal objetivo do JAUS é a comunicação e a interação dos sistemas em rede. A rede é subdividida em camadas hierárquicas, sendo que a camada mais alta é constituída por subsistemas; um subsistema é uma entidade física, como um veículo ou uma unidade de controlo. No nível seguinte, os subsistemas são divididos em nós, que representam uma computação física no sistema; um nó pode ser um computador ou microcontrolador dentro de um subsistema e os nós podem conter vários componentes, os quais podem ser aplicações ou threads em execução no nó. Na última camada, os componentes são feitos de um ou mais serviços, sendo que um serviço é uma abstração lógica que fornece alguma função útil para o sistema e que tem uma interface de mensagens e protocolos bem definida. A SAE publica a norma JAUS em conjuntos de documentos relacionados mas separados, tal como se encontra exemplificado no site do OpenJAUS[43]: • JAUS Transport Specification (AS5669A) - Especificações para o UDP, TCP e da transmissão de dados baseada em série das mensagens JAUS, com o objetivo de padronizar o formato das mensagens JAUS que serão transportadas por comunicações Ethernet ou série. • JAUS Service Interface Definition Language (AS5684) - Define as estruturas de dados de serviços, mensagens e protocolo, como um esquema XML, para eliminar a ambiguidade
Estado da Arte 18 em serviço e interpretação da mensagem, e faz a validação/geração automática de código para os possíveis serviços. • JAUS Core Service Set (AS5710A) - Define com JSIDL os serviços de baixo nível de descoberta e transporte. Estes incluem definições de formato de mensagem e protocolo escrito em tabelas e diagramas, para especificar um conjunto base de serviços comuns que podem ser implementadas por todos os componentes JAUS. • JAUS Mobility Service Set (AS6009) – Define os serviços comuns de mobilidade, tais como posicionamento global e a plataforma de controlo de veículos definida em JSIDL e também inclui definições de formato de mensagem e protocolo escrito em tabelas e diagramas, o que permite ativar o comando e controlo de muitas plataformas de veículos definindo serviços abstratos que são agnósticos aos tipos específicos de mobilidade de veículos. • JAUS Human Machine Interface Service Set (AS6040) – Definição de serviços em JSIDL para interação HMI e inclui o desenho, entrada de teclado, entrada de dispositivo apontador, e controlos analógicos e digitais, para fornecer um meio standard para a interação humana com componentes duma rede JAUS. • JAUS Manipulation Service Set (AS6057) - Definições de serviço em JSIDL para controlar manipuladores robóticos. As mensagens são definidas genericamente, de modo que possam ser aplicadas a muitos tipos diferentes de manipuladores, pelo que padroniza o comando e o controlo de manipuladores robóticos que podem ser parte de uma plataforma de sistemas não-tripulados. O JAUS Service Interface Definition Language (JSIDL) do JAUS, para satisfazer a arquitetura SOA, fornece um esquema XML preciso, o qual é utilizado para conceber serviços JAUS. Um serviço é definido por um conjunto específico de entrada e saída de mensagens JAUS e por protocolo numa máquina de estado que controla como as mensagens devem ser recebidos, processadas e enviadas pelo serviço. O objetivo do JSIDL é reduzir erros humanos na interpretação de serviços standard do JAUS. O XML permite a especificação dum serviço para ser automaticamente validado e para gerar software de implementação de stubs de serviços e das mensagens, o que permite eliminar erros humanos. A sintaxe XML é usada para a especificação de serviços quando eles são concebidos e publicados na norma; o OpenJAUS usa a sintaxe da máquina validada para o design e para gerar código automaticamente. O JSIDL é utilizado para especificar como as mensagens devem ser estruturadas, pois define o formato dos campos de dados nas mensagens JAUS e também fornece a sintaxe de como designar esses campos. A definição de protocolo de serviço sob a forma de máquinas de estado do JSIDL é um serviço que responde às mensagens de entrada de forma diferente, dependendo do estado em que ele se encontra. O JSIDL vai fornecer a sintaxe XML para descrever a estrutura de serviço de uma máquina de estado que respeita a documentação standard JAUS. O JAUS Core Service Set (JSS Core) permite a interoperabilidade on-line de sistemas nãotripulados e dos seus componentes, através de um conjunto de serviços que permitem: trocas de informação entre os componentes, configuração de eventos baseados em mensagens, descoberta dos serviços on-line, etc. O JSS Core define os serviços básicos que são necessários pelos componentes de nível superior, o que o torna numa ferramenta crítica quando é necessário evitar que um serviço receba múltiplos sinais de controlo que entrem em conflito a partir de fontes diferentes. Os detalhes de implementação desses serviços em
Estado da Arte 19 OpenJAUS são fornecidos no Guia de utilizador do OpenJAUS. Alguns dos serviços definidos no JSS Core e para que são usados encontram-se definidos na tabela 1. Tabela 1 - Alguns serviços do JSS Core [43]. Serviço Propósito Mensagens Transport Atua como uma gateway para todas as mensagens que entram e saem de um componente. None Events Permite que outros componentes possam solicitar mensagens de serviços que herdam dos eventos de serviço de forma periódica fixa. Isso é o equivalente JAUS de um mecanismo de publicação e assinatura. CreateEvent, UpdateEvent, CancelEvent, QueryEvents, RejectEventRequest, Event Access Control Permite que os serviços que herdam do serviço de controlo de acesso a ser exclusivamente controlado por uma única fonte. Por sua vez, os serviços controlados só aceita comandos a partir de seus componentes de controlo. Isto é como os componentes JAUS implementam exclusão mútua. RequestControl, ReleaseControl, QueryControl, QueryAuthority, ReportControl, ConfirmControl Management Permite que os componentes do cliente para controlar e aceder a informação sobre o estado interno de outra função de componentes. Por exemplo, isso permite que os componentes do cliente para redefinir ou desligar um componente de servidor. Shutdown, Standby, Resume, Reset, SetEmergency, ClearEmergency, QueryStatus, ReportStatus Time Fornece uma interface para reportar o tempo de um componente do sistema interno para outros componentes. QueryTime, ReportTime Liveness Permite que os componentes do cliente para determinar se outra componente está online e responde há comunicação de mensagens. Similar ao conceito de um ping rede. QueryHeartbeatPulse, ReportHeartbeatPulse Discovery Permite aos componentes descobrir a presença uns dos outros e também permite trocar informações sobre os serviços que implementa e apoia. RegisterServices, QueryIdentification, QueryConfiguration, ReportIdentification, ReportConfiguration, ReportServiceList Podemos concluir que o OpenJAUS ajudar a implementar as normas JAUS, de uma forma simplificada e bem planeada, e a sua implementação pode ser efetuada pelas ferramentas Eclipse, Visual Studio e linguagem de programação C, C++, e Java e oferece mecanismos simples para melhor timing, compressão de dados, configuração do sistema, etc. 2.4 - IMC O IMC é um protocolo orientado a mensagens, projetado e implementado no Laboratório de sistemas e Tecnologia subaquática (LSTS), para construir sistemas interligados de veículos, sensores e operadores humanos que são capazes de cooperar entre si, abstraindo-se do hardware e heterogeneidade das comunicação e fornecendo um conjunto compartilhado de mensagens que podem ser serializadas [12] e transferidas através de diferentes meios. O objetivo principal é construir sistemas interligados de veículos (figura 12), sensores e operadores humanos que são capazes de perseguir objetivos comuns de forma cooperativa, trocando informações em tempo real sobre o meio ambiente e objetivos atualizados, com o intuito de permitir aos operadores poderem responder a situações imprevistas onde a sua contribuição é fundamental, como amostragem adaptativa[47], patrulhamento da fronteira
Estado da Arte 20 ou guerra cooperativa[48], em que o IMC permite uma rápida integração de novo hardware e facilita o desenvolvimento de novos algoritmos de cooperação. Figura 12 - Alguns veículos que usam IMC [11]. O protocolo IMC define uma infraestrutura que é modular e fornece camadas diferentes de controlo e de detecção nos ASVs, ROVs, AUVs e UAVs. O fluxo de mensagens que corresponde ao controlo e várias camadas de deteção dentro IMC[11]: • Mensagens de Mission control definem a especificação de uma missão e do ciclo de vida, para a interface entre um comando CCU e um módulo supervisor da missão. A missão é uma sequência ou um gráfico de manobras. • Mensagens de Vehicle control são utilizados para interligar o veículo a partir de uma fonte externa. • Mensagens de Maneuver são usadas para definir manobras e associam-se a comandos e a estados de execução. • Mensagens de Guidance estão relacionadas com a orientação usada nas manobras autónomas. • Mensagens de Navegation definem a interface para a comunicação do estado de um veículo de navegação. As mensagens Estimated State definem o estado de navegação de um veículo pela convenção SNAME[49]. • Mensagens dos sensores são usadas para comunicar as leituras dos sensores pelos respetivos controladores de hardware. • Mensagens dos atuadores vão especificar a interface com os controladores de hardware.
Estado da Arte 21 Os grupos de mensagem citados são apenas alguns exemplos, sendo que a lista completa pode ser consultada na tabela 6. Esta estrutura (figura 13) vai-nos permitir o desenvolvimento modular de aplicações que podem ser executadas em isolamento lógico, interagindo com outros módulos através da troca de mensagens IMC. Figura 13 - Mensagens IMC no AUV Seascout Light[11]. O DUNE[49] é o software implementado nos veículos autónomos que permite a abstração de mensagens, e fornece mecanismos de transporte para comunicação externa (figura 14). Os veículos podem ser monitorizados e controlados externamente, através de consolas neptus [49], [50]. A Rede de veículos e consolas é baseada em mecanismos de comunicação IP, tais como sockets TCP e UDP, o protocolo Real-Time Publish-Subscribe[51] ou modems acústicos subaquáticos [52]. Figura 14 - Conceito de transferência de mensagens e implementação de tasks do DUNE [1]. As mensagens IMC definem entidades que contêm um número de identificação exclusivo e que consistem numa sequência de campos de dados capazes de representar inteiros de largura fixa, números de vírgula flutuante e sequências de bytes de comprimento variável. Os Inteiros podem ser atribuídos ou não atribuídos, com tamanhos que variam dos 8 aos 64 bits;
Estado da Arte 22 os números de vírgula flutuante têm dois tamanhos, que podem ser de 32 ou 64 bits, como podemos verificar na seguinte tabela 2. Tabela 2 - Lista de tipos de campos válidos [53]. Tipo ID Nome Largura (bytes) Descrição 0 int8_t 1 8 bit signed integer. 1 uint8_t 1 8 bit unsigned integer. 2 int16_t 2 16 bit signed integer. 3 uint16_t 2 16 bit unsigned integer. 4 int32_t 4 32 bit signed integer. 5 uint32_t 4 32 bit unsigned integer. 6 int64_t 8 A 64 bit signed integer 7 fp32_t 4 32 bit single precision floating point number in IEEE 754 format. 8 fp64_t 8 64 bit double precision floating point number in IEEE 754 format. 9 rawdata - Variable length byte stream. 10 plaintext - Variable length ASCII character stream. 11 message - An inline message. Useful for encapsulating other messages. Para garantir o transporte ou armazenamento das mensagens na transmissão e receção é necessário encapsular as mensagens num pacote ou utilizar a serialization. A serialization é realizada a fim de traduzir os dados dos pacotes para um fluxo binário na mesma ordem em que foram definidos. Por inspeção do número de sincronização o recetor é capaz de deduzir a ordem de bytes dos restantes campos de dados e realizar as conversões necessárias para a interpretação correta, o que é denominado por deserialization. Isto permite que a comunicação entre nós com as mesmas ordens de bytes não sofra nenhuma sobrecarga na conversão. Não é necessário utilizar uma deserialization especial para os campos descritos na tabela 3. Tabela 3 - Tipo de serialization [53]. Nome Serialization rawdata A sequence of type rawdata is serialized by prepending a value of type uint16_t, representing the length of the sequence, to the stream of bytes. On deserialization the prepended value is used to retrieve the correct size of data bytes. The rawdata type length is limited only by the communication protocol in use. plaintext A sequence of type plaintext is serialized by prepending a value of type uint16_t, representing the length of the sequence, to the stream of ASCII characters. On deserialization the prepended value is used to retrieve the correct ASCII character sequence size. The plaintext type length is limited only by the communication protocol in use. message A field of type message is serialized by prepending a value of type uint16_t, representing the identification number of the message, to the serialized message payload. The special identification number 65535 must be used when no message is present. On deserialization the prepended value is used to retrieve the correct message identification number. The message type length is limited only by the communication protocol in use. Existem três formatos de serialization diferentes. Um deles é o formato LSTS Log Format (LLF), tratando-se de um formato de texto utilizado para criar logs IMC; este formato é de fácil compreensão e pode ser analisado diretamente por muitos aplicativos, como o Excel e o Matlab, e software personalizado de análise e revisão das missões[54]. Como o protocolo IMC
Estado da Arte 23 está constantemente em evolução o formato LLF tinha que ser independente da versão do protocolo IMC para permitir a revisão de dados de missões passadas, pelo que se definiu que o formato do log usa tabulações. Para cada coluna há um cabeçalho descrevendo o tipo de dados, o nome e as unidades a ser usadas, quando representados os dados. Um segundo formato é o LSTS Serialization Format (LSF) que consiste na concatenação das mensagens (binárias) num único ficheiro. Para a correcta interpretação desse ficheiro é necessário ter conhecimento da definição IMC correspondente e, por isso, os ficheiros LSF são normalmente acompanhados do ficheiro de definição IMC (IMC.xml). O último formato é o IMC-XML (figura 15) que consiste na tradução da definição da mensagem e conteúdos para XML. Este formato permite a integração de componentes webbased e web-enabled e sensores third-party em aplicações de larga escala de disseminação de dados[55]. Figura 15 - Exemplo de serialization IMC-XML [12]. Todas as mensagens IMC são divididas em header, payload e footer. O header e o footer têm a mesma estrutura para todos os pacotes e são definidos por uma sequência de campos de dados de tamanho fixo. O payload varia de mensagem para mensagem e tem um tamanho variável, podendo ser vazio, como mostra a figura 16. Figura 16 - Formato do pacote [53]. O header é sempre colocado no índice do pacote e contém o número de sincronização, que nos permite detetar diferentes ordens de bytes das serializations e diferentes versões de protocolo; possui ainda um identificador de mensagem, uma origem e um destino, como podemos ver na tabela 4
Estado da Arte 30 557 EmergencyControl Emergency Control 558 EmergencyControlState Emergency Control State 559 PlanDB Plan DB 560 PlanDBState Plan DB State 561 PlanDBInformation Plan DB Information 562 PlanControl Plan Control 563 PlanControlState Plan Control State 650 ReportedState Reported State 600 RestartSystem Restart System 651 RemoteSensorInfo Remote Sensor Info 652 Map Map 653 MapFeature Map Feature 654 MapPoint MapPoint 655 AcousticSystems Acoustic Systems Listing 700 VideoData Video Data 701 RawImage Raw Image 702 CompressedImage Compressed Image 703 ImageTxSettings Image Transmission Settings 704 NavigationState Navigation State 705 BrainsState BRAINS State 706 GpsNavData GPS Navigation Data 707 LblEstLog LBL Estimator Log 708 LblEstimate LBL Beacon Position Estimate 709 LblConfigEstimate LBL Configuration Estimate 710 RemoteState Remote State 711 PiccoloWaypoint Piccolo Waypoint 712 ListPiccoloWaypoints List Piccolo Waypoints 713 PiccoloWaypointDeleted Piccolo Waypoint Deleted 714 PiccoloTrackingState Piccolo Tracking State 715 PiccoloPacket Piccolo Packet 716 GotoPiccoloWaypoint Goto Piccolo Waypoint 717 PiccoloControlConfiguration Piccolo Control Configuration 718 GetPiccoloControlConfiguration Get Piccolo Control Configuration
Capítulo 3 Descrição do Problema O LSTS tem desenvolvido várias tecnologias no sentido de criar uma rede de veículos autónomos. Uma rede de veículos é uma rede constituída por nós de vários tipos: consolas de operação, sensores, gateways de comunicação e veículos autónomos. Uma das questões mais importantes nestas redes é a comunicação efetiva de dados entre nós da rede, sendo que cada nó pode ser um sistema físico ou um sistema lógico (processo a correr dentro de um veículo). Neste momento, apesar de muitas tecnologias que possibilitam a criação de redes de veículos autónomos terem já sido desenvolvidas pelo LSTS, o suporte para visualização de dados provenientes de uma rede deste tipo é ainda limitado: • Cada nó da rede regista um conjunto de dados (ficheiro de log) e é necessário agrupar todos os logs da rede de forma correta à posteriori. A este problema chamamos "intercalar logs de vários veículos". • Não existe forma simples de perceber que nó na rede originou informação e que outros nós receberam informação. Para isso devem ser criadas novas visualizações de dados multi-veículo que permitam perceber eficazmente as ligações que ocorreram na rede. 3.1 - Intercalar dados A necessidade de intercalar dados ocorreu aquando da análise dos logs, na qual se pretendia verificar quem comunicou com quem e quais foram as mensagens trocadas entre os vários sistemas. Esta verificação torna-se muito difícil de efetuar analisando os logs individualmente, o que gerou a necessidade de intercalar os dados de vários logs num único log. Para intercalar os dados provenientes de vários veículos, é necessário perceber o funcionamento da rede, principalmente o protocolo IMC, e também compreender as classes existentes no projeto, a fim de ser possível desenvolver um programa que seja eficiente e que cumpra os objetivos propostos; o mesmo deve identificar quantos nós existem na rede, identificar o seu id e concatenar todos os logs num único para ser possível mostrar as
Descrição do Problema 32 mensagens de todos eles. As ferramentas sugeridas pelo LSTS foram o Eclipse com acesso a SVN do LSTS[53] que contém o código fonte do IMC em java. O Java[58–62] é uma linguagem de programação desenvolvida por James Gosling na Sun Microsystems em 1995. Esta é de uso geral, concorrente, baseada em classes, e orientada a objetos, foi projetado para ter o mínimo de dependências de execução possível e permitir criar programas capazes de serem executados em qualquer arquitetura que tenha instalada uma Java Virtual Machine (JVM). O Java foi criado com o objetivo de ser simples, orientado a objetos e familiar, robusto e seguro, de ter arquitetura neutra e portável, ser executável em alta performance, ser interpretado e ser dinâmico. Ele tem vindo a evoluir de uma forma que é totalmente compatível com as aplicações existentes, sendo que os compiladores e sistemas são capazes de suportar as várias versões simultaneamente, com compatibilidade completa. O Eclipse[63] é um ambiente multilinguagem de desenvolvimento de software que inclui um IDE e um sistema plug-in extensível e é escrito em Java. Ele é utilizado para desenvolver aplicações em Java e tem plug-ins para incluir Ada, C, C++, COBOL, Haskell, Perl, PHP, Python, R, Ruby, Scala, Clojure, Groovy e Scheme, entre outros. O Eclipse é distribuído sob a Licença Pública Eclipse[64]. O Eclipse SDK é um software livre e open source, que permite escrever e contribuir com módulos plug-in para a plataforma Eclipse[65–67]. A Subversion (SVN)[68–70] é uma aplicação open source de controlo de versões, criada em 2000 pela CollabNet Inc. e atualmente faz parte do projeto Apache. A SVN gere as mudanças feitas em arquivos e diretórios ao longo do tempo, e permite recuperar versões antigas dos dados ou examinar o histórico de como os dados foram alterados. Esta pode funcionar em rede e apresenta a vantagem de permitir que várias pessoas sejam capazes de modificar e gerir o mesmo conjunto de dados a partir de vários locais, propiciando a colaboração entre os elementos de uma equipa. 3.2 - Criar grafo de comunicações A criação de grafos de comunicações é feita utilizando a linguagem DOT e os campos src, src_ent, dst e dst_ent das mensagens. Para a visualização do grafo pode ser usado o graphviz ou ferramentas semelhantes, como o yEd Graph Editor e o Microsoft Automatic Graph Layout, as quais permitem visualizar e editar os mesmos. Esta tem por objetivo a fácil analise das comunicações ocorridas numa missão, recorrendo para o efeito a ferramentas gráficas, de preferência open source. Além disso, permite efetuar a sua inspeção a qualquer altura e em qualquer lugar, por investigadores ou engenheiros que não estejam ligados ao LSTS e elimina a necessidade de utilizar o NEPTUS MRA, tornando-se numa mais-valia. O campo src corresponde ao sistema que cria a mensagem, ao passo que o src_ent é a entidade do sistema que cria a mensagem; do mesmo modo, o dst é o sistema de destino enquanto o dst_ent consiste na entidade de destino. Neste momento, as mensagens não são ainda endereçadas a tarefas específicas, sendo que o campo dst_ent está sempre preenchido com o valor 255, endereçando todas as tarefas que ouçam o tipo de mensagem enviado. A linguagem DOT foi sugerida pelo LSTS, e consiste na descrição de um grafo num texto simples, convertendo-se numa forma simples de descrever um grafo e fácil de usar, na qual os ficheiros usam a extensão .gv ou .dot. Um grafo é um objeto abstrato, definido por dois tipos de entidades, nós (nodes) ou vértices e ramos ou arestas (edges), em que os vértices representam entidades como, cidades, números, etc, e as arestas representam, existência das ligações entre nós, o valor da ligação entre nós, etc.
Descrição do Problema 33 Existem vários programas que leem ficheiros do tipo DOT e transformam-nos na forma gráfica, bem como alguns que realizam cálculos sobre o grafo representado e fornecem uma interface interativa. O Dot permite fazer layouts que distribuem os nós do grafo de forma automática e apelativa (nós espaçados corretamente e transições com nenhuns ou poucos cruzamentos). e fornece uma variedade de formas, estilos e cores adequadas para os diagramas. Esta linguagem pode descrever grafos dirigidos e não dirigidos. As principais ferramentas de layout utilizadas pelo graphviz são o Dot, para grafos dirigidos, e o Neato, para grafos não dirigidos. Estas leem os grafos, calculam os layouts e escrevem-nos nos formatos Dot, Gv, PostScript, GIF, etc., com o objetivo de criar bons diagramas, com tamanho razoável e bem dimensionado, e isto com etiquetas legíveis em grafos até 100 nós; quando estas forem maiores, é necessário interações adicionais ou técnicas de layout perante uma complexidade visual elevada. O Neato é compatível com o Dot pois aceita os mesmos ficheiros de entrada e as opções da linha de comandos. 3.3 - Criar ferramentas de visualização As ferramentas de visualização[71] a implementar no NEPTUS MRA permitirão o replay das comunicações com highlight das ligações e a visualização de informações provenientes dos logs processados. A visualização gráfica é uma forma útil e fácil de representar modelos, tendo encontrado muitas aplicações no projeto e análise de redes de comunicação, documentos, e permite estruturá-los de forma estática e dinâmica, levando à necessidade de ferramentas para exibir e manipular grafos. O replay das comunicações deverá possibilitar a visualização de qual o tipo de mensagens trocadas pelos vários sistemas. Em contra partida o highlight deverá permitir diferenciar a frequência com que estas foram trocadas, de forma a facilitar a diferenciação do número de mensagens trocadas pelos vários sistemas.
Descrição do Problema 34
Capítulo 4 Abordagem do Problema Neste capítulo descreve-se a abordagem efetuada ao problema relatado no capítulo 3, na qual explicarei como foi efetuado o tratamento dos dados provenientes dos vários veículos, a criação de grafos de comunicações e a criação de ferramentas de visualização. Finalmente irei abordar os problemas individualmente e obter soluções para os mesmos, as quais irão ser validadas no capítulo seguinte. As ferramentas utilizadas foram as sugeridas pelo LSTS, porque me davam uma resposta rápida e eficaz aos problemas e porque apesar de já saber trabalhar com elas teria uma equipa que me poderia prestar apoio caso se revelasse necessário. 4.1 - Intercalar dados Os dados provenientes dos veículos são recolhidos no final das missões, usando wi-fi e posteriormente enviados para um servidor Web, onde existe um repositório SVN com todos os dados de missões executadas previamente pelos vários veículos do LSTS. Para receção, envio e processamento de dados IMC, o Neptus usa uma biblioteca Java chamada IMCJava. Esta biblioteca permite, por exemplo, o carregamento de um log de mensagens através da classe LSFIndex. Essa classe permite ler as mensagens dos logs, e tem de utilizar um método LsfIndex, o qual procede à deserialization; este método converte os logs do formato .lsf para .index e usa como argumentos o caminho do ficheiro lsfile e o ficheiro xml com as definições de serialization, sendo utilizado da seguinte forma: “LsfIndex(File lsfile, IMCDefinition defs)”. Algumas das mensagens mais importantes do sistema utilizadas neste trabalho são: Announce, TransportBindings, EntityInfo e Heartbeat, de forma a perceber o funcionamento da rede vai ser necessário compreender que as mensagens de Announce permitem identificar os sistemas existentes, sendo enviada a descrição do veículo no modo broadcast para os outros sistemas; as mensagens EntityInfo descrevem as entidades locais existentes; as de TransportBindings são criadas quando as tasks se ligam às mensagens e permitem às entidades saberem quais as que devem ouvir; por fim, as mensagens Heartbeat permitem saber se os sistemas estão visíveis na rede e se estão a comunicar.
Abordagem do Problema 36 Para melhor perceber o funcionamento desta biblioteca, foram feitos vários testes iniciais de introdução à ferramenta. O primeiro desses testes (tarefa desempenhada) foi imprimir todas as mensagens de um certo tipo indicando a hora em que foram registadas. O teste consistia na criação de um método para ler as mensagens do tipo LogBookEntry, para o qual se criou um vetor com todas as mensagens deste tipo e depois utilizou um ciclo para correr esse vetor, onde se leram os campos htime (Timestamp) com o método “getTimestampMillis()” que retorna um long e text (texto da mensagem) e com o método “getString (String)” que retorna uma string, obtendo o código java da lista 2. 1 Vector<Integer> msgs = index.getMessagesOfType("LogBookEntry"); 2 for (int i = 0; i < msgs.size();i++) { 3 IMCMessage m = index.getMessage(msgs.get(i)); 4 System.out.println(new Date(m.getTimestampMillis())+": "+m.getString("text")); 5 } 6 System.out.println(msgs); Lista 2 – Método para mensagens do tipo LogBookEntry. Nas mensagens ControlLoops utilizou-se o mesmo raciocínio mas leu-se o campo mask (Control loop mask) com o método “getRawData(String)” que retorna byte[], o resultando encontra-se na lista 3. 1 Vector<Integer> msgscl = index.getMessagesOfType("ControlLoops"); 2 for (int i = 0; i < msgscl.size();i++) { 3 IMCMessage m = index.getMessage(msgscl.get(i)); 4 System.out.println(m.getRawData("0xFFFFFFFF")); 5 } 6 System.out.println(msgscl); 7 int msgs3n = index.getNumberOfMessages(); 8 System.out.println(msgs3n+": n. mensagens"); Lista 3 - Método para mensagens do tipo ControlLoops. Para as mensagens PlanControlState utilizou-se um código idêntico ao do LogBookEntry com os métodos getTypeOf(String), getString(String), e getTimestamp(). Também se criou um método LsfTest para colocar o código que se tinha desenvolvido no método main, como podemos ver na lista 4. 1 public static void LsfTest(LsfIndex index) { 2 } Lista 4 – Método LsfTest. Para invocar este método no main do LsfIndex utilizou-se a linha de código descrita na lista 5. 1 LsfTest (index); Lista 5 – método para invocar LsfIndex no main. Depois de efetuar estes testes estava preparado para pensar num código que permitisse concatenar todos os logs num único e que posteriormente mostrasse todas as mensagens. Antes de pensar na estrutura do código verificou-se que as mensagens criadas nos logs estavam com a ordem que foram geradas, o que implica que estas ficam organizadas no tempo. Isto permitiu pensar em duas abordagens. A primeira abordagem era colar um log ao outro, isto é, juntar um log no final do outro acrescentando os bits de um log no outro.
Abordagem do Problema 37 Contudo, como tínhamos interesse que as mensagens ficassem organizadas na sequência temporal em que foram geradas, esta solução tinha a desvantagem de consumir muita memória para organizar o log final, uma vez que teria de criar um vetor do tamanho do log, pelo que se optou pela seguinte abordagem descrita em pseudocódigo, na lista 6. 1 while ( i < logA.NumberOfMessages and j < logB.NumberOfMessages ) do 2 if (logA[i].timestamp > logB[j].timestamp and i < logA.NumberOfMessages) then 3 resultado[k++] = logB[j++]; 4 else 5 if (logA[i].timestamp < logB[j].timestamp and j < logA.NumberOfMessages) then 6 resultado[k++] = logA[i++]; 7 else 8 if (logA[i].timestamp > logB[j].timestamp and i = logA.NumberOfMessages and j < logA.NumberOfMessages) then 9 while (j < logA.NumberOfMessages) do 10 resultado[k++] = logB[j++]; 11 else 12 if (logA[i].timestamp < logB[j].timestamp and j = logA.NumberOfMessages and i < logA.NumberOfMessages) then 13 while (i < logA.NumberOfMessages) do 14 resultado[k++] = logA[i++]; 15 end Lista 6 – Descrição do LsfLogMerge. Como podemos verificar, enquanto os logs tiverem mensagens vamos verificar o tempo em que foram geradas e colocar no novo log as mensagens mais antigas. É de salientar que também se verifica se algum dos logs já não tem mais mensagens, pois se não fizéssemos essa verificação o programa poderia parar nessa altura. Quando um dos logs chega ao fim, vamos escrever só as mensagens do outro log até este chegar igualmente ao final. Esse método denomina-se “public static void writestream(String OutFile1, LsfIndex index1, LsfIndex index2)”, e pode ser consultado a versão completa do código efetuado na SVN do LSTS como LsfLogMerge.java. Esta estrutura pode ser verificada no diagrama de classes na figura 17. Para identificar quantos nós existem na rede e qual o seu id criei o método “public static void NString(LsfIndex index, String stList)”. Este método permite identificar os nós da rede e verificar a origem das mensagens. Para isso procede à leitura do campo src, que corresponde ao sistema origem e que deve ser definido ao invocar o método, pois este também aceita como entrada o src_ent, o qual corresponde ao módulo, dentro do sistema, que originou a mensagem o que nos irá permitir verificar quantos módulos enviaram mensagens. Este código também se encontra na SVN do LSTS como LsfLogMerge.java. 4.2 - Criar grafo de comunicações Na criação de grafos de comunicações efetuei três abordagens diferentes, nas quais utilizei a classe LinkedHashMap para criar mapas de entitiesToTasks, msgConsumers, e msgsGenerated. O mapa das entitiesToTasks, como o próprio nome indica, vai criar um link de uma entidade para uma tarefa; por sua vez, as msgConsumers são as mensagens consumidas, isto é, vão indicar o destinatário das mensagens, em que um id vai ligar a um vetor de consumidores; por último, as msgsGenerated vão indicar as mensagens geradas, onde um sistema de origem corresponde a um vetor de módulos dentro desse sistema. A primeira abordagem foi bastante simplista, pois foram criados mapas utilizando os campos src e src_ent, ligados aos campos dst e dst_ent das mensagens. Todavia, viemos a
Abordagem do Problema 38 constatar que esta abordagem era uma solução incompleta, pois os sistemas que compõem a rede enviam as mensagens no modo broadcast, em que o dst das mensagens é igual a 255; esta perceção permitiu-me ter uma melhor compreensão do funcionamento da rede e passar à abordagem seguinte. Na segunda abordagem foi importante a ajuda de uma API em java criada por Laszlo Szathmary[72], em que é necessário ter o graphviz instalado; numa primeira fase foi preciso definir o caminho da instalação do dot do graphviz que, mais tarde, o Doutor José Pinto otimizou para a deteção do sistema operativo, removendo assim a necessidade de configuração. Esta API efetua uma otimização automática e aceitável dos grafos até 100 nós e também permite criar ou converter grafos da linguagem DOT para gv, gif, dot, fig, pdf, ps, svg, png, etc., o que me possibilitou criar os primeiros grafos com a linguagem DOT. O código da API encontra-se na SVN do LSTS como GraphViz.java. Por último, alterou-se o código dos mapas do entitiesToTasks para as mensagens do tipo EntityInfo que descrevem as entidades; para msgConsumers utilizei as mensagens TransportBindings que são criadas aquando das tarefas e fornecem o nome do consumidor e o id das mensagens a serem ouvidas; o msgsGenerated associa a cada id de tarefa src_ent os tipos de mensagens que foram produzidas por essa tarefa. Os grafos gerados podem ser visualizados com as ferramentas graphviz, o yEd Graph Editor e o Microsoft Automatic Graph Layout. 4.3 - Criar ferramentas de visualização Na criação de ferramentas de visualização, a API já existente em Java desempenhou um papel fundamental. Com ela foi possível desenvolver (com ajuda de investigadores do LSTS) o método showGraph(String) e adicionar uma nova opção “View communications graph” ao Neptus MRA. Esta opção permite, através de um clique do rato nas mensagens que se pretendem visualizar, o diagrama de comunicações correspondente. Além disso existe a opção de salvar esse diagrama clicando com o botão do lado direito do rato no grafo e escolhendo um formato e nome do ficheiro de saída. A visualização de informações provenientes dos logs processados pode ser efetuada de duas formas: a primeira é através do NEPTUS MRA, que nos permite ver o grafo do tipo mensagens selecionado e as mensagens transmitidas entre os vários sistemas, e a segunda é executando a classe IMCGraph.java, que permite a visualização das mensagens utilizando “g.showGraph(String)” e a criação de ficheiros “g.writeGraphToFile(String, String)” nos formatos descritos em 4.3. É de ter em consideração que quando se tenta visualizar um número muito elevado de nós em simultâneo, pode levar ao consumo de muitos recursos e a ter de cancelar a operação, sendo que o grafo final pode não ser legível. Por essa razão ficou também disponível a opção de criar ficheiros GraphViz (.gv), o que permite utilizar ferramentas como o graphviz, Gephi, yEd Graph Editor, etc. para otimizar e visualizar os grafos. Também foi implementado o highlight das comunicações na qual se utilizou a classe colormap do NEPTUS, a qual vai criar uma cor em função do argumento de entrada. Este tem que ser um valor entre zero e um e corresponde ao resultado do quociente entre o número de vezes que a mensagem foi enviada e o número total de edges criados.
Abordagem do Problema 39 Para a visualização do tipo de mensagens trocadas entre os veículos e as várias consolas desenvolveu-se a classe “generateSystemsGraph” a qual mostra um grafo a indicar quais as mensagens trocadas. A implementação dos highlight neste grafo não tinha muito interesse pois o que se pretendia visualizar era quais as mensagens que são trocadas entre sistemas, e para ter informação mais detalhada deve-se recorrer á análise individual de cada mensagem. Na figura 17 encontra-se o diagrama de classes para uma melhor compreensão da abordagem do problema. Figura 17 - Diagrama de classes.
Resultados 46 Figura 21 - Resultado obtido no Neptus, com highlights. Na figura 20 e 21 podemos ver a evolução do projeto com a implementação dos highlights. Os grafos são criados através da classe IMCGraph.java, que se encontra na biblioteca IMCJava, a qual tem bibliotecas partilhadas com o Neptus; assim sendo, todas as vezes que se atualiza a classe IMCGraph.java é necessário atualizar a biblioteca no Neptus. Na figura 22 encontra-se representada a visualização de todas as comunicações, obtido no gephi a partir do ficheiro .dot do grafo da figura 19, com um template predefinido, alterando apenas as cores das legendas.
Resultados 47 Figura 22 - Grafo de comunicações editado no gephi. Se compararmos o grafo apresentado na figura 19 com este que é apresentado na figura 22, é possível constatar que este último proporciona uma maior facilidade no seguimento das ligações entre os nós, fato que demonstra que com este tipo de ferramentas é possível visualizar e otimizar os grafos. A figura 23, foi recortada e ampliada da figura 22 e a sua observação atenta facilmente corrobora a ideia anteriormente expressa.
Resultados 48 Figura 23 - Recorte da figura 21. Os resultados obtidos após a implementação dos highlights para todas as comunicações encontram-se expressos na figura 24.
Resultados 49 Figura 24 - Grafo de comunicações para todas as mensagens, após implementação dos highlights.
Resultados 50 As mensagens com highlights estão definidas para serem criadas com um mapa de cores que vai do azul (código #0000FF em hexadecimal) para o vermelho (código #FF0000 em hexadecimal), em que o azul corresponde a ter zero ligações e o vermelho corresponde a ter o número máximo de ligações. Figura 25 - Grafo de comunicações para as mensagens Voltage. Da análise da figura 25 podemos concluir que o número de mensagens trocadas entre Power_DOAMv1 e o Actuators_SCRT tem uma maior frequência, uma vez que aparecem a vermelho; por oposição, as mensagens trocadas entre Actuators_SCRT e Transports_UDP são as menos frequentes porque aparecem a uma cor muito próxima do azul. Para validar esta conclusão encontra-se seguidamente exposto para análise o log de debugging gerado pelo eclipse, ou o ficheiro .dot, no qual podemos constatar que: Power_DOAMv1 -> Actuators_SCRT [ label="Voltage" color="#FF0000"]; Actuators_SCRT -> Transports_UDP [ label="Voltage" color="#3F00BF"]; Daqui facilmente verificamos que a cor #FF0000 corresponde ao vermelho e que a cor #3F00BF corresponde a uma cor próxima do azul e através de uma análise mais aprofundada,
Resultados 51 com a ajuda do eclipse, vamos poder verificar que o número máximo de mensagens trocadas foi quatro, o que gerou a cor #FF0000, e o número mínimo foi uma, com a cor #3F00BF. Caso pretendamos visualizar quais foram os veículos e sistemas que estiveram ativos durante a missão, é necessário ver o grafo das mensagens Heartbeat. Como podemos verificar no log da figura 26, só estiveram ativos o veículo lauv_xtreme_2 e o sistema ccu_lsts_106_26, como. Figura 26 - Grafo de comunicações para as mensagens Heartbeat. Com o decorrer do projeto verificou-se que os grafos necessitavam de uma legenda, para uma fácil perceção do que aconteceu como podemos ver na figura 27 e figura 28. Para criar esta legenda recorreu-se a utilização de um subgraph no canto inferior direito do grafo que pode conter no máximo cinco cores dependendo do numero de edges, se for superior a cinco é calculado dividindo o código de cores em cinco partes. Figura 27 - Grafo de comunicações EntityList, com legenda.
Resultados 52 Figura 28 - Grafo de comunicações Current, com legenda. Como podemos verificar a figura 27, as mensagens do tipo EntityList são transmitidas apenas uma vez enquanto as mensagens do tipo Current são transmitidas no máximo quatro vezes (figura 28). Se compararmos a figura 27 com a figura 29 vamos verificar que em vez das três mensagens que deveríamos ter apenas aparecem duas. Isto deve-se ao Daemon não estar a gerar id, fato que teve de ser reportado, resultando na necessidade de criar uma rotina que verifica quando este tipo de mensagens aparece e que as vai colocar na hashmap para poderem ser criadas no grafo, pois estas estavam a ser descartadas.
Resultados 53 Figura 29 - Análise no MRA dos TransportBindings. Na figura 29 podemos confirmar que temos três mensagens com id 5, pelo que podemos concluir que foram enviadas 3 mensagens do tipo EntityList. Também houve indicação para substituir os Transports.UDP pelas CCUs, em que se criou uma rotina muito idêntica à do Daemon, o que facilitou muito o trabalho. Estas alterações podem ser visualizadas na figura 30. Figura 30 - Grafo de comunicações EntityList final. Para uma análise ainda mais simples pensou-se em implementar um grafo que identifica quais as mensagens transmitidas entre os vários sistemas. Essa visualização pode ser efetuada através da janela Network do Neptus MRA (figura 31), se a imagem for maior do que a janela e possível utilizar as scrollbars, ou através da classe IMCGraph (figura 32).
Resultados 54 Figura 31 - Grafo de comunicações da rede no Neptus MRA.
Resultados 55 Figura 32 - Grafo de comunicações da rede a partir da classe IMCgraph.
Referências 62 [52] V. Potdar, A. Sharif, and E. Chang, “Wireless sensor networks: A survey,” in Advanced Information Networking and Applications Workshops, 2009. WAINA’09. International Conference on, 2009, pp. 636–641. [53] “LSTS Development Server.” [Online]. Available: https://whale.fe.up.pt/svn/neptus/IMCJava/. [Accessed: 05-Jul-2012]. [54] J. Pinto, P. S. Dias, J. B. Sousa, and F. L. Pereira, “Large scale data collection using networks of heterogeneous vehicles and sensors,” in OCEANS 2009 - EUROPE, 2009, pp. 1–6. [55] S. Rowe and C. R. Wagner, “An Introduction to the Joint Architecture for Unmanned Systems (JAUS),” Ann Arbor, vol. 1001, p. 48108, 2008. [56] D. C. Fallside and P. Walmsley, “XML schema part 0: primer second edition,” W3C recommendation, 2004. [57] A. Berglund, Extensible Stylesheet Language (XSL) Version 1.1. W3C Recommendation 05 December 2006. 2006. [58] “Java (programming language) - Wikipedia, the free encyclopedia.” [Online]. Available: http://en.wikipedia.org/wiki/Java_(programming_language). [Accessed: 05-Jul-2012]. [59] “java.com: Java + You.” [Online]. Available: http://www.java.com. [Accessed: 05-Jul-2012]. [60] “Oracle Documentation.” [Online]. Available: http://docs.oracle.com/. [Accessed: 05-Jul2012]. [61] K. Arnold, J. Gosling, and D. Holmes, The Java programming language, vol. 2. Addisonwesley Reading, MA, 1996. [62] K. Arnold, J. Gosling, and D. Holmes, Java (TM) Programming Language, The. AddisonWesley Professional, 2005. [63] “Eclipse - The Eclipse Foundation open source community website.” [Online]. Available: http://www.eclipse.org/. [Accessed: 05-Jul-2012]. [64] “Eclipse Public License - Version 1.0.” [Online]. Available: http://www.eclipse.org/legal/eplv10.html. [Accessed: 04-Jul-2012]. [65] E. Clayberg and D. Rubel, Eclipse: Building Commercial-Quality Plug-ins (Eclipse). AddisonWesley Professional, 2006. [66] J. D’Anjou, The Java developer’s guide to Eclipse. Addison-Wesley Professional, 2005. [67] J. McAffer and J. M. Lemieux, Eclipse Rich Client Platform: Designing, Coding, and Packaging Java (TM) Applications. Addison-Wesley Professional, 2005. [68] “Version Control with Subversion.” [Online]. Available: http://svnbook.red-bean.com/. [Accessed: 05-Jul-2012]. [69] “Apache Subversion - Wikipedia, the free encyclopedia.” [Online]. Available: http://en.wikipedia.org/wiki/Apache_Subversion. [Accessed: 05-Jul-2012]. [70] “Apache Subversion.” [Online]. Available: http://subversion.apache.org/. [Accessed: 05-Jul2012]. [71] E. R. Gansner and S. C. North, “An open graph visualization system and its applications to software engineering,” Software Practice and Experience, vol. 30, no. 11, pp. 1203–1233, 2000. [72] “GraphViz Java API.” [Online]. Available: http://www.loria.fr/~szathmar/off/projects/java/GraphVizAPI/index.php. [Accessed: 19Jul-2012]. [73] “Ubigraph: Free dynamic graph visualization software.” [Online]. Available: http://ubietylab.net/ubigraph/. [Accessed: 10-Jul-2012].