Implementação de um Sistema de Monitoramento Marítimo AIS com MATLAB GUI

Arquitetura do Sistema de Visualização

O desenvolvimento de um sistema de monitoramento baseado em AIS (Automatic Identification System) exige uma estrutura robusta para lidar com o fluxo contínuo de dados geoespaciais. A arquitetura é dividida em quatro pilares fundamentais:

  • Captura de Dados: Interface com hardware via porta serial (RS232/USB) ou via protocolos de rede (UDP/TCP) para receber sentenças NMEA.
  • Processador de Protocolos: Algoritmo responsável por decodificar as mensagens, extraindo identificadores como MMSI, latitude, longitude, curso (COG) e velocidade (SOG).
  • Motor de Renderização: Camada gráfica que projeta as coordenadas geográficas em um mapa dinâmico utilizando o Mapping Toolbox.
  • Gerenciador de Estado: Painel de controle para mnoitorar a saúde da conexão e exibir logs de erros em tempo real.

Implementação do Núcleo de Processamento

Abaixo, apresenta-se uma abordagem para a configuração da comunicação e o processamento das strings de dados recebidas.

% Configuração da comunicação serial
portaCom = "COM4";
baudRate = 38400; % Velocidade padrão para muitos receptores AIS
receptorAIS = serialport(portaCom, baudRate);
configureTerminator(receptorAIS, "CR/LF");

% Função de decodificação de pacotes NMEA
function infoNavio = decodificarMensagem(rawLine)
    partes = strsplit(rawLine, ',');
    % Exemplo simplificado para pacotes do tipo $GPRMC ou similares
    if numel(partes) > 10 && contains(rawLine, '$GPRMC')
        mmsi_mock = "ID-" + partes{1}; 
        latitude = converterCoordenada(partes{4}, partes{5});
        longitude = converterCoordenada(partes{6}, partes{7});
        infoNavio = struct('ID', mmsi_mock, 'Lat', latitude, 'Lon', longitude);
    else
        infoNavio = [];
    end
end

function deg = converterCoordenada(valor, direcao)
    % Lógica de conversão de formato NMEA para Graus Decimais
    num = str2double(valor);
    graus = floor(num/100);
    minutos = (num - graus*100)/60;
    deg = graus + minutos;
    if direcao == 'S' || direcao == 'W'
        deg = -deg;
    end
end

Visualização Dinâmica e Interface Gráfica

Para a exibição das embarcações, utiliza-se um componente de eixos configurado para projeções geográficas, permitindo a sobreposição de ícones representativos.

% Inicialização do ambiente geográfico no GUI
axes(handles.mapDisplay);
geobasemap('streets');
hold on;

% Atualização da posição de uma embarcação específica
function plotarMovimentacao(dadosAtualizados)
    % Limpa o rastro anterior ou atualiza o marcador
    delete(findall(handles.mapDisplay, 'Tag', dadosAtualizados.ID));
    
    % Renderiza o novo marcador
    h = geoplot(handles.mapDisplay, dadosAtualizados.Lat, dadosAtualizados.Lon, ...
        'p', 'MarkerColor', 'blue', 'MarkerSize', 12);
    h.Tag = dadosAtualizados.ID;
    
    % Adiciona rótulo de identificação
    text(dadosAtualizados.Lat, dadosAtualizados.Lon, dadosAtualizados.ID, ...
        'FontSize', 9, 'FontWeight', 'bold');
end

Automação via Timer

Para garantir que a interface permaneça responsiva enquanto processa novos dados, implementamos um objeto de temporização (timer).

% Criação do loop de execução em segundo plano
loopTemporal = timer('ExecutionMode', 'fixedSpacing', ...
                     'Period', 0.5, ...
                     'TimerFcn', @(~,~) executarLeitura());

function executarLeitura()
    global receptorAIS;
    if receptorAIS.NumBytesAvailable > 0
        linhaBruta = readline(receptorAIS);
        dados = decodificarMensagem(linhaBruta);
        if ~isempty(dados)
            atualizarInterface(dados);
        end
    end
end

start(loopTemporal);

Análise de Segurança: Cálculo de Proximidade

Uma funcionalidade crítica em sistemsa AIS é a prevenção de colisões através do cálculo do Ponto de Aproximação Máxima (CPA).

function detectarRisco(alvoA, alvoB)
    % Cálculo da distância ortodrômica entre dois pontos
    distanciaKm = deg2km(distance(alvoA.Lat, alvoA.Lon, alvoB.Lat, alvoB.Lon));
    
    limiarSeguranca = 1.0; % 1 km
    if distanciaKm < limiarSeguranca
        warning('Risco de colisão detectado entre %s e %s', alvoA.ID, alvoB.ID);
        % Aciona alerta visual na GUI
        set(handles.statusText, 'String', 'ALERTA DE PROXIMIDADE', 'ForegroundColor', 'red');
    end
end

Otimização de Performance e Debugging

Ao lidar com centenas de embarcações simultaneamente, a performance do MATLAB pode ser afetada. Recomenda-se:

  • Bufferização: Ler múltiplos pacotes por ciclo do timer para reduzir o overhead de chamadas de função.
  • Atualização Seletiva: Utilizar propriedades XData e YData em objetos gráficos existentes em vez de recriar o plot a cada ciclo.
  • Simulação para Testes: Desenvolver um gerador de trajetórias aleatórias para validar a lógica de colisão e visualização sem a necessidade de hardware conectado.
% Exemplo de simulador de tráfego
vesselSim = struct('Lat', 22.9 + randn()*0.1, 'Lon', -43.1 + randn()*0.1);

Tags: MATLAB AIS NMEA gui sistemas-embarcados

Publicado em 6-23 19:01