Ir para o conteúdo

Projeto Conceitual de Software

1. Visão Geral e Premissas

1.1 Propósito

O software do Grupo 1 é responsável por duas frentes complementares:

  1. Firmware embarcado, executado no microcontrolador do robô, responsável por perceber o ambiente, mapear o labirinto, decidir a trajetória, acionar os atuadores e empacotar a telemetria.
  2. Aplicação web de telemetria, executada fora do robô, responsável por receber os pacotes transmitidos durante a prova, exibir o estado da corrida em tempo real e persistir o histórico para consulta posterior.

As duas frentes são independentes em execução: o robô cumpre a prova de forma autônoma mesmo sem o painel web conectado, conforme o RNF-SFT01. A aplicação web é um observador do processo, nunca um controlador.

1.2 Premissas de hardware

As decisões deste documento partem das definições registradas no TAP e na EAP. Os itens abaixo dependem de confirmação do núcleo de Eletrônica (issues #20 a #22) e devem ser revisados caso a especificação mude.

Premissa Origem Impacto no software
Microcontrolador ESP32 no robô TAP / EAP Linguagem do firmware e rádio integrado para a telemetria
Segundo ESP32 na bancada, conectado por USB ao computador, atuando como receptor ESP-NOW Proposta do núcleo de Software (seção 6) Canal de telemetria sem dependência de rede Wi-Fi, atendendo ao RF-ELE04
Sensores de distância do tipo ToF (VL53L0X) nas laterais e à frente TAP Base do controle de trajetória e da detecção de paredes
Motores com encoder acoplado TAP / RF-ELE02 Odometria, controle de deslocamento e detecção de travamento
Unidade inercial (IMU) para referência angular EAP Precisão das rotações ortogonais
Botão físico de largada e seleção de geometria RF-SFT02 / regulamento Estados iniciais do fluxo de operação

1.3 Escopo do documento

Este documento trata do projeto conceitual, ou seja, da definição de comportamento, estrutura e arquitetura que antecede a implementação. Não contém código-fonte, que será produzido na fase de desenvolvimento prevista na EAP.


2. Diagrama de Atividades UML

O diagrama a seguir representa o comportamento funcional do produto, do acionamento do robô até o encerramento da corrida, organizado em raias por ator.

Atores e responsabilidades

Raia Papel
Operador Aciona o robô, seleciona a geometria da pista e dá a largada física. Não interfere durante a prova (RNF-SFT01).
Firmware Executa a lógica de mapeamento, decisão de trajetória, monitoramento de segurança e empacotamento da telemetria.
Sensores e Atuadores Fornecem leituras de distância, odometria e tensão de bateria, e convertem comandos em movimento.
Painel Web Recebe os pacotes de telemetria, atualiza a interface em tempo real e persiste a corrida.

Entradas e saídas do fluxo

  • Entradas: geometria selecionada, sinal de largada, leituras de distância, pulsos de encoder, leitura de tensão da bateria.
  • Saídas: comandos de tração, matriz de paredes descobertas, pacotes de telemetria a 1 Hz, registro histórico da corrida.
flowchart TB
    subgraph OP[Raia: Operador]
        A1([Início]) --> A2[Ligar o robô]
        A2 --> A3[Selecionar geometria 4x4, 8x4 ou 12x4]
        A3 --> A4[Acionar largada: segurar o botão 2 s e soltar]
    end

    subgraph FW[Raia: Firmware]
        B1[Inicializar periféricos]
        B2[Calibrar sensores e zerar odometria]
        B3[Aguardar sinal de largada]
        B4[Iniciar cronômetro]
        B5[Ler sensores de distância]
        B6[Registrar paredes na matriz do labirinto]
        B7{Objetivo alcançado?}
        B8[Decidir próxima célula]
        B9[Comandar deslocamento ou rotação]
        B10{Travamento detectado?}
        B11[Cortar tração e sinalizar erro]
        B12[Parar motores e congelar cronômetro]
        B13{Executar speed run?}
        B14[Calcular rota ótima e percorrer]
        B15[Empacotar telemetria]
        B16([Fim])
    end

    subgraph HW[Raia: Sensores e Atuadores]
        C1[Fornecer distâncias, odometria e tensão]
        C2[Converter comando em movimento das rodas]
    end

    subgraph WEB[Raia: Painel Web]
        D1[Receber pacote de telemetria]
        D2[Atualizar grade, rastro e indicadores]
        D3[Persistir corrida no banco de dados]
    end

    A2 --> B1 --> B2 --> B3
    A4 --> B3
    B3 --> B4 --> B5
    C1 --> B5
    B5 --> B6 --> B7
    B7 -- Não --> B8 --> B9 --> C2
    C2 --> B10
    B10 -- Sim --> B11 --> B16
    B10 -- Não --> B5
    B7 -- Sim --> B12 --> B13
    B13 -- Sim --> B14 --> B12
    B13 -- Não --> B16
    B4 -.fluxo paralelo a 1 Hz.-> B15
    B15 --> D1 --> D2 --> D3

Observação: o envio de telemetria ocorre em paralelo ao laço de navegação, a uma taxa fixa de 1 Hz, conforme RF-SFT05 e RNF-SFT03. A verificação de travamento acompanha continuamente qualquer comando de tração ativo.

Comandos do botão

O operador usa um único botão físico no robô (GPIO 15, doc 4.3). Os gestos só têm efeito no estado AGUARDANDO; depois da largada o botão é ignorado, pois a prova não admite intervenção (RNF-SFT01).

Gesto Efeito
Toque triplo Alterna a geometria: 4x4, 8x4, 12x4 e de volta a 4x4. O LED pisca em ciano 1, 2 ou 3 vezes conforme a geometria escolhida
Segurar por 2 s e soltar Largada: o cronômetro da prova começa e o estado passa a MAPEANDO. Ao completar 2 s com o botão pressionado, o LED fica branco para indicar que pode soltar; a largada acontece na soltura, para o robô não arrancar com a mão do operador em cima
Soltar antes de 2 s (pressão a partir de 1 s) Nenhum efeito
Toque simples e toque duplo Reservados ao autoteste dos motores e dos sensores ToF (doc 4.3)

Toques são pressões de menos de 1 s, contadas até passarem 400 ms sem novo toque. Cada mudança do botão só é aceita depois de 25 ms de leitura estável (debounce). O campo timestamp_ms da telemetria vale 0 até a largada e, a partir dela, conta o tempo da prova.


3. Backlog do Produto

3.1 Requisitos Funcionais

O backlog do produto foi registrado no GitHub Projects da equipe, na coluna Backlog do Produto do quadro de tarefas. Cada requisito funcional de software corresponde a um épico, desdobrado em histórias de usuário (HUs) cadastradas como sub-issues. As tabelas a seguir foram geradas a partir da exportação da visão Backlog do Produto do projeto.

Atores das histórias

Ator Descrição
Operador Membro da equipe que prepara o robô, dá a largada e acompanha a prova pelo painel
Equipe Equipe de desenvolvimento, que utiliza os dados e comportamentos do sistema para validar e aprimorar o robô

Prioridade: P0 corresponde a Must have, P1 a Should have e P2 a Could have, conforme a classificação do documento de requisitos.

Épico RF-SFT01: Controle e Alinhamento de Trajetória

Issue: #31 | Prioridade: P0

ID História de usuário Critérios de aceitação Issue
HU-01 Manter o robô centralizado nas retas
Eu, como equipe, quero que o robô se mantenha centralizado no corredor durante as retas, para que ele percorra o labirinto sem encostar nas paredes.
• O robô percorre 3 células consecutivas em reta com desvio lateral inferior a 15 mm em relação à linha de centro
• Não há contato com as paredes laterais durante o percurso
• Em trechos sem parede lateral, o robô mantém o rumo usando IMU e encoders
#32
HU-02 Executar curvas de 90 graus com precisão
Eu, como equipe, quero que o robô faça rotações de 90° com precisão, para que a orientação real do robô continue coerente com o mapa em memória.
• O erro angular acumulado das rotações é de no máximo ±3°
• Ao final de cada rotação, o robô está alinhado ao eixo do corredor
• A orientação interna do firmware é atualizada após cada rotação
#33

Épico RF-SFT02: Mapeamento Topológico das Geometrias Oficiais

Issue: #34 | Prioridade: P0

ID História de usuário Critérios de aceitação Issue
HU-03 Registrar as paredes de cada célula visitada
Eu, como equipe, quero que o robô registre em memória as paredes de cada célula que visita, para que ele construa o mapa do labirinto durante a exploração.
• Cada célula visitada é marcada como visitada na matriz
• Uma parede registrada em uma célula também é registrada na célula vizinha correspondente
• Ao final da exploração, a matriz é 100% idêntica à configuração física da pista
#35
HU-04 Selecionar a geometria da pista antes da largada
Eu, como operador, quero informar ao robô, antes da largada, se a pista é 4x4, 8x4 ou 12x4, para que ele trabalhe com as dimensões corretas do labirinto.
• A seleção da geometria está disponível antes da largada
• Os limites da matriz em memória correspondem à geometria selecionada
• A geometria selecionada é enviada na telemetria (campo labirinto)
#36

Épico RF-SFT03: Navegação e Resolução Autônoma de Labirinto

Issue: #37 | Prioridade: P0

ID História de usuário Critérios de aceitação Issue
HU-05 Dar a largada por botão físico
Eu, como operador, quero iniciar a prova por um botão no próprio robô, para dar a largada sem enviar nenhum comando remoto.
• Após ligado, o robô permanece parado no estado AGUARDANDO até o acionamento do botão
• O cronômetro da prova inicia no acionamento
• O status muda para MAPEANDO e o painel passa a exibir "Explorando"
#38
HU-06 Decidir o caminho de forma autônoma
Eu, como equipe, quero que o robô escolha sozinho a próxima célula com base no mapa descoberto, para que ele alcance o objetivo sem nenhuma intervenção externa.
• O robô conclui a corrida em pista 4x4 em menos de 3 minutos
• Nenhum comando externo é recebido durante a prova
• O robô não repete indefinidamente um mesmo trajeto entre células já exploradas
#39

Épico RF-SFT04: Reconhecimento de Objetivo e Parada Automática

Issue: #40 | Prioridade: P0

ID História de usuário Critérios de aceitação Issue
HU-07 Parar automaticamente ao chegar no objetivo
Eu, como operador, quero que o robô pare sozinho ao entrar na célula de chegada, para que o tempo da prova seja registrado corretamente.
• A tração é interrompida em menos de 200 ms após a entrada na célula de chegada
• O cronômetro da prova é congelado no mesmo instante
• A telemetria passa a enviar status CONCLUIDO e desafio cumprido verdadeiro
#41

Épico RF-SFT05: Despacho Contínuo dos Parâmetros de Telemetria

Issue: #42 | Prioridade: P0

ID História de usuário Critérios de aceitação Issue
HU-08 Transmitir os dados da prova a cada segundo
Eu, como operador, quero que o robô envie os dados da corrida a cada segundo, para acompanhar a prova pelo computador enquanto ela acontece.
• Um pacote é enviado a cada 1 segundo (1 Hz)
• O pacote contém os 6 parâmetros do edital: tipo do labirinto, trajeto percorrido (posição), bateria, velocidade média, tempo decorrido e status de desafio cumprido
• Os pacotes chegam íntegros ao gateway receptor durante todo o percurso
#43
HU-09 Ser avisado quando a conexão com o robô cair
Eu, como operador, quero ser avisado quando o painel parar de receber dados do robô, para saber que as informações exibidas não estão mais atualizadas.
• Após 3 segundos sem pacote válido, o painel exibe "Conexão RF perdida"
• O painel volta ao estado normal assim que a recepção é retomada
• A perda de conexão não interfere na navegação do robô
#44

Épico RF-SFT06: Dashboard Web de Monitoramento em Tempo Real

Issue: #45 | Prioridade: P0

ID História de usuário Critérios de aceitação Issue
HU-10 Visualizar o mapa do labirinto em tempo real
Eu, como operador, quero ver a grade do labirinto sendo desenhada conforme o robô explora, para acompanhar o mapeamento durante a prova.
• A grade é exibida na geometria da prova (4x4, 8x4 ou 12x4)
• As paredes detectadas aparecem na tela em até 1 segundo
• A posição atual e a orientação do robô ficam destacadas
• O rastro percorrido é exibido sobre a grade
Protótipo: seção 3.2
#46
HU-11 Acompanhar os indicadores da prova
Eu, como operador, quero ver tempo, velocidade, bateria e status do robô durante a prova, para avaliar o desempenho e antecipar problemas.
• O cronômetro é exibido junto ao limite de 10 minutos
• Velocidade média e instantânea são exibidas em cm/s
• A bateria é exibida em porcentagem e tensão, com destaque visual quando baixa
• O status é exibido com rótulo legível (Em espera, Explorando, Travado etc.)
Protótipo: seção 3.2
#47

Épico RF-SFT07: Persistência Histórica de Corridas

Issue: #48 | Prioridade: P1

ID História de usuário Critérios de aceitação Issue
HU-12 Salvar automaticamente cada corrida
Eu, como equipe, quero que cada corrida seja salva automaticamente, inclusive as interrompidas, para analisar o desempenho do robô depois da prova.
• O registro da corrida é criado no momento da largada
• Cada leitura de telemetria é gravada assim que recebida
• A corrida é encerrada com status final, incluindo INTERROMPIDA quando não houver encerramento normal
• A corrida fica disponível para consulta imediatamente após o encerramento
#49

Épico RF-SFT08: Consulta e Filtragem Histórica Web

Issue: #50 | Prioridade: P1

ID História de usuário Critérios de aceitação Issue
HU-13 Filtrar as corridas anteriores
Eu, como equipe, quero filtrar o histórico por geometria do labirinto e por data, para encontrar rapidamente as corridas que quero comparar.
• Há filtro por geometria (4x4, 8x4, 12x4) e por data de execução
• A lista filtrada exibe data, geometria, modo, tentativa, tempo final e status
• O resultado é exibido em menos de 2 segundos com até 500 corridas registradas
Protótipo: seção 3.2
#51
HU-14 Rever o trajeto de uma corrida passada
Eu, como equipe, quero reproduzir o trajeto de uma corrida salva, para identificar onde o robô perdeu tempo ou tomou decisões ruins.
• Ao selecionar uma corrida, o mapa final e as estatísticas são exibidos
• A reprodução percorre as posições em ordem de tempo
• Há controle de reproduzir, pausar e avançar pela barra de tempo
• Os detalhes da corrida carregam em menos de 2 segundos
Protótipo: seção 3.2
#52

Épico RF-SFT09: Execução de Trajetória Otimizada (Speed Run)

Issue: #53 | Prioridade: P1

ID História de usuário Critérios de aceitação Issue
HU-15 Calcular a rota mais curta após a exploração
Eu, como equipe, quero que, após a exploração, o robô calcule a menor rota até o objetivo, para utilizá-la na tentativa rápida.
• A rota é calculada apenas com células e paredes já conhecidas
• A rota escolhida tem o menor número de células entre as rotas possíveis no mapa conhecido
#54
HU-16 Executar o speed run
Eu, como operador, quero que o robô percorra a rota ótima em velocidade maior que a de exploração, para reduzir o tempo da prova.
• O tempo do speed run é pelo menos 20% menor que o tempo da exploração
• A telemetria envia status SPEED_RUN durante o percurso
• A corrida é registrada com modo Speed Run no histórico
#55

Épico RF-SFT10: Suavização Contínua de Trajetória em Curva

Issue: #56 | Prioridade: P2

ID História de usuário Critérios de aceitação Issue
HU-17 Fazer curvas em movimento contínuo no speed run
Eu, como equipe, quero que no speed run o robô faça as curvas sem parar, para não perder tempo freando e girando parado.
• A curva de 90° é executada sem parada total do robô
• Cada transição de célula com curva é pelo menos 300 ms mais rápida que o giro parado
• Não há contato com as paredes durante a curva
#57

Épico RF-SFT11: Detecção e Tratamento de Travamento Mecânico (Stall)

Issue: #58 | Prioridade: P0

ID História de usuário Critérios de aceitação Issue
HU-18 Cortar os motores quando as rodas travarem
Eu, como equipe, quero que o robô corte os motores quando as rodas travarem, para evitar danos aos motores e ao driver de potência.
• Com comando de tração ativo e sem rotação das rodas por mais de 1,0 s, o travamento é detectado
• A potência dos motores é cortada em no máximo 1,2 s após o bloqueio físico
• O robô sinaliza o travamento por indicador local e envia status TRAVADO na telemetria
#59
HU-19 Ver no painel que o robô travou
Eu, como operador, quero ser avisado no painel quando o robô travar, para saber o motivo do encerramento da tentativa.
• O status "Travado" é exibido em destaque no painel
• A corrida é encerrada no histórico com status final TRAVADO
Protótipo: seção 3.2
#60

3.2 Protótipos de Interface

Requisitos atendidos: RF-SFT05, RF-SFT06, RF-SFT07 e RF-SFT08.

A aplicação web é composta por duas telas: a tela de monitoramento, usada durante a prova, e a tela de histórico, usada para consulta posterior das corridas registradas.

3.2.1 Tela de Monitoramento em Tempo Real

A tela de monitoramento é atualizada a cada pacote de telemetria recebido (1 Hz) e se adapta às três geometrias oficiais do edital.

Painel de monitoramento, labirinto 4x4

Painel de monitoramento, labirinto 8x4

Painel de monitoramento, labirinto 12x4

Painel de monitoramento, robô em espera

Bloco Conteúdo exibido Origem do dado
Cabeçalho Indicador de conexão com o gateway receptor Watchdog de enlace (seção 6.7)
Mapeamento em tempo real Grade na geometria da prova, células de largada e chegada, paredes detectadas, rastro percorrido e posição e orientação atuais do robô Campos posicao, orientacao e paredes do pacote
Status Estado atual do robô e número da tentativa Campo status e contagem de tentativas do backend
Tempo Cronômetro da prova e barra de progresso até o limite de 10 minutos Campo timestamp_ms
Velocidade Velocidade média e instantânea Campos velocidade_media e velocidade_atual
Bateria Carga em porcentagem, tensão e faixa de alerta Campos bateria_pct e bateria_volts
Histórico da sessão Tentativas já realizadas no labirinto atual e seus tempos Tabela Corrida (seção 4.6)

Convenção de exibição: a coluna é identificada por letra (A a D) e a linha por número (1 a 12). A largada fica na célula A1, no canto superior esquerdo da grade, e o norte corresponde ao topo da tela.

Estados exibidos no painel

Estado no protocolo Rótulo na tela Significado
AGUARDANDO Em espera Robô ligado, aguardando a largada
MAPEANDO Explorando Exploração do labirinto em andamento
SPEED_RUN Speed Run Percurso otimizado após a exploração (RF-SFT09)
CONCLUIDO Concluído Robô alcançou a célula objetivo
COLISAO Colisão Prova encerrada por colisão
TIMEOUT Tempo esgotado Limite de 10 minutos atingido
TRAVADO Travado Corte de tração por travamento das rodas (RF-SFT11)
(estado do painel) Conexão RF perdida Nenhum pacote recebido há mais de 3 segundos

3.2.2 Tela de Histórico de Corridas

A tela de histórico lista todas as corridas persistidas e permite inspecionar individualmente cada uma delas.

Tela de histórico de corridas

Bloco Conteúdo exibido Origem do dado
Histórico geral Lista de corridas com identificador, data, geometria, modo, tentativa, tempo final, velocidade média, células visitadas e status final Tabela Corrida
Filtros Seleção por geometria do labirinto e por data de execução (RF-SFT08) Consulta à tabela Corrida
Inspecionar corrida Mapa final da corrida selecionada e reprodução do trajeto com controle de tempo Tabelas Celula e Leitura
Estatísticas da corrida Tempo final, velocidade média e eficiência de rota Tabela Corrida
Métricas comparativas Bateria inicial e final, tempo estimado e real, células novas descobertas Tabelas Corrida e Celula

A reprodução do trajeto percorre os registros da tabela Leitura em ordem de timestamp_ms, deslocando o marcador do robô pelas posições registradas. Com o campo visitada_em_ms da tabela Celula, o mapa pode ser revelado progressivamente conforme o instante reproduzido.

3.3 Requisitos Não Funcionais

Os requisitos não funcionais de software também integram o backlog do produto, cadastrados como issues independentes. A coluna de rastreabilidade relaciona cada RNF aos requisitos funcionais e às histórias de usuário que ele restringe.

ID Requisito Descrição Critério de aceitação Prioridade Rastreabilidade Issue
RNF-SFT01 Autonomia Operacional Plena e Não-Intervenção Uma vez acionada a largada física na pista, o robô deve operar de forma 100% autônoma, sendo estritamente proibida qualquer intervenção humana externa, pilotagem remota, envio manual de instruções ou carregamento de mapas prévios do traçado do labirinto durante a execução da prova. Demonstração prática de corrida autônoma sem recepção de sinais de controle externo e auditoria do código-fonte para comprovar ausência de mapas pré-carregados. P0 RF-SFT03
HU-05, HU-06
#61
RNF-SFT02 Compatibilidade com as Geometrias Oficiais do Labirinto O software embarcado e o sistema de telemetria devem ser plenamente compatíveis e capazes de explorar, mapear e exibir os dados para as três geometrias oficiais estipuladas pelo edital: labirintos de 4x4, 8x4 e 12x4 células (células de 180x180 mm, paredes de 12x50 mm e corredores de 168 mm). Execução de baterias de testes de navegação autônoma e exibição correta no painel web nas três configurações oficiais (4x4, 8x4 e 12x4). P0 RF-SFT02, RF-SFT06
HU-04, HU-10
#62
RNF-SFT03 Taxa de Atualização e Latência da Telemetria Web A aplicação web deve receber dados e atualizar os componentes do painel em tempo real com taxa mínima de 1 Hz e latência de exibição ponta a ponta inferior a 1,0 segundo em rede local. Comparação por gravação em vídeo de alta taxa de quadros entre a movimentação física do robô na pista e a atualização do componente gráfico no painel web. P0 RF-SFT05, RF-SFT06
HU-09, HU-10
#63
RNF-SFT04 Tempo de Resposta de Consultas ao Histórico As consultas e recuperação de corridas armazenadas no banco de dados devem apresentar tempo de renderização na interface web inferior a 2,0 segundos para bases com até 500 registros. Medição do tempo de resposta (Time to First Byte e renderização completa) no console de desenvolvimento (DevTools) do navegador. P1 RF-SFT08
HU-13, HU-14
#64
RNF-SFT05 Compatibilidade e Responsividade Desktop A aplicação web deve ser plenamente funcional e sem distorções visuais nos principais navegadores modernos (Google Chrome e Mozilla Firefox) em resoluções a partir de 1366 x 768 pixels. Testes automatizados ou manuais de layout e redimensionamento de janela nos navegadores em resolução 1366x768 e 1920x1080. P1 RF-SFT06, RF-SFT08
HU-10, HU-11, HU-13
#65
RNF-SFT06 Responsividade para Dispositivos Móveis A interface do dashboard web deve adaptar seus componentes principais (status, cronômetro e telemetria essencial) para visualização legível em telas verticais de smartphones (largura a partir de 360 px). Emulação de viewport móvel (360x640 px a 412x915 px) com conferência de legibilidade e ausência de barra de rolagem horizontal desnecessária. P2 RF-SFT06
HU-11
#66

4. Arquitetura da Solução

4.1 Propósito e Padrão Adotado

Propósito do software

O software desempenha dois papéis no sistema. O firmware embarcado é o núcleo de decisão do robô: interpreta os sensores, mantém o mapa do labirinto, escolhe a trajetória e comanda os atuadores, garantindo a operação autônoma exigida pelo RNF-SFT01. A aplicação web é a camada de observação: recebe a telemetria, exibe a prova em tempo real e preserva o histórico das corridas para análise posterior. A aplicação web nunca envia comandos ao robô.

Padrão arquitetural: monolito cliente-servidor em camadas

A solução web adota uma arquitetura monolítica cliente-servidor: um único backend concentra ingestão da telemetria, regras de negócio, persistência e API, e um único frontend, do tipo aplicação de página única (SPA), consome esse backend. Internamente, o backend é organizado em camadas (interface, serviços e acesso a dados) e o frontend em componentes reutilizáveis.

Justificativa:

  • Escopo e equipe: o sistema tem um único produtor de dados (o robô), poucos usuários simultâneos e uma equipe pequena. Microsserviços trariam custos de implantação, comunicação entre serviços e monitoramento sem benefício proporcional.
  • Implantação local: todo o software web roda em um único computador na bancada de prova (seção 4.5). Um monolito é implantado com um só processo, o que reduz pontos de falha no dia da avaliação.
  • Tempo real simples: como ingestão e difusão ocorrem no mesmo processo, o pacote recebido pela serial é repassado ao navegador sem intermediários, favorecendo a latência inferior a 1 segundo do RNF-SFT03.
  • Evolução: a separação em camadas mantém o código organizado e permite extrair partes no futuro, caso o projeto cresça.

O firmware segue uma organização própria de sistemas embarcados: módulos funcionais coordenados por uma máquina de estados, executados como tarefas concorrentes do FreeRTOS, sistema operacional de tempo real já incluído no suporte ao ESP32.

Resumo das tecnologias

Camada Linguagem Frameworks e bibliotecas Justificativa
Firmware do robô C++ Arduino-ESP32 sobre FreeRTOS, compilado com PlatformIO Suporte nativo ao ESP32, bibliotecas consolidadas para sensores ToF, encoders e ESP-NOW
Firmware do gateway C++ Arduino-ESP32, ArduinoJson Recebe o pacote ESP-NOW e o converte em JSON na porta serial com pouco código
Backend Python FastAPI, Uvicorn, pySerial, SQLAlchemy WebSocket e API REST nativos, documentação automática da API e acesso simples à porta serial
Frontend JavaScript React, Vite, Recharts Componentização adequada à grade do labirinto e aos indicadores; grade desenhada em SVG
Banco de dados SQL MySQL Ver justificativa abaixo

Banco de dados: relacional (MySQL) em vez de NoSQL

Os dados de telemetria têm estrutura fixa e conhecida (dicionário de dados da seção 6.5), e as consultas exigidas pelo RF-SFT08 combinam filtros por geometria e intervalo de datas, além de junções entre corrida, leituras e células. Esse perfil favorece um banco relacional, que oferece integridade referencial entre as entidades (seção 4.6) e consultas por índice dentro do limite de 2 segundos do RNF-SFT04. Um banco orientado a documentos não traria vantagem, pois não há variação de esquema entre corridas.

4.2 Visão Lógica

A visão lógica apresenta os módulos do sistema e suas responsabilidades, organizados pelos quatro elementos de software.

flowchart LR
    subgraph ROBO["Firmware do Robô (ESP32)"]
        FSM["Máquina de Estados"]
        SEN["Sensoriamento"]
        ODO["Odometria"]
        MAP["Mapeamento"]
        NAV["Navegação"]
        CTL["Controle de Movimento"]
        SEG["Segurança (stall)"]
        TEL["Telemetria"]
    end

    subgraph GW["Firmware do Gateway (ESP32)"]
        REC["Receptor ESP-NOW"]
        CONV["Conversor para JSON"]
    end

    subgraph BACK["Backend (FastAPI)"]
        ING["Ingestão Serial"]
        SRV["Serviço de Corridas"]
        REPO["Repositórios"]
        WS["WebSocket /ws/telemetria"]
        API["API REST /api/corridas"]
        WD["Watchdog de Enlace"]
    end

    subgraph FRONT["Frontend (React)"]
        PAINEL["Painel em Tempo Real"]
        HIST["Histórico de Corridas"]
        SIM["Simulador do Labirinto"]
    end

    DB[("MySQL")]

    SEN --> MAP --> NAV --> CTL
    ODO --> CTL
    ODO --> SEG
    FSM --> NAV
    SEG --> FSM
    MAP --> TEL
    FSM --> TEL
    TEL -. "ESP-NOW" .-> REC --> CONV
    CONV -. "Serial USB" .-> ING
    ING --> SRV --> REPO --> DB
    ING --> WS
    WD --> WS
    API --> REPO
    WS --> PAINEL
    API --> HIST

Firmware do robô

Módulo Responsabilidade Requisitos
Máquina de Estados Controla o ciclo da prova: espera, exploração, speed run e encerramentos (seção 4.3) RF-SFT03, RF-SFT04
Sensoriamento Lê os sensores de distância e converte as leituras em presença de parede RF-SFT02
Odometria Lê encoders e IMU para estimar deslocamento, velocidade e orientação RF-SFT01
Mapeamento Mantém a matriz do labirinto e registra as paredes de cada célula (seção 5.1) RF-SFT02
Navegação Decide a próxima célula durante a exploração e calcula a rota ótima para o speed run RF-SFT03, RF-SFT09, RF-SFT10
Controle de Movimento Executa retas centralizadas e rotações ortogonais (seção 5.2) RF-SFT01
Segurança Detecta travamento das rodas e corta a tração (seção 5.3) RF-SFT11
Telemetria Monta e transmite o pacote a cada segundo (seção 6.2) RF-SFT05

Firmware do gateway

Módulo Responsabilidade Requisitos
Receptor ESP-NOW Recebe e valida os pacotes binários enviados pelo robô RF-ELE04
Conversor para JSON Converte o pacote para o formato de exibição e o envia pela porta serial (seções 6.2 e 6.3) RF-SFT05

Backend

Camada Módulo Responsabilidade Requisitos
Interface Ingestão Serial Lê as linhas JSON da porta serial e valida cada pacote contra o dicionário de dados RF-SFT05
Interface WebSocket Difunde cada pacote válido aos navegadores conectados RF-SFT06, RNF-SFT03
Interface API REST Atende as consultas ao histórico com filtros RF-SFT08
Serviços Serviço de Corridas Aplica o ciclo de vida da corrida: abertura, registro de leituras, atualização de células e encerramento (seção 6.6) RF-SFT07
Serviços Watchdog de Enlace Sinaliza perda de conexão após 3 segundos sem pacotes (seção 6.7) RF-SFT05
Dados Repositórios Isolam o acesso ao banco de dados para Corrida, Leitura e Celula RF-SFT07

API REST prevista

Método Rota Função
GET /api/corridas Lista corridas, com filtros opcionais por labirinto, data_inicio e data_fim
GET /api/corridas/{id} Retorna os dados consolidados de uma corrida
GET /api/corridas/{id}/leituras Retorna as leituras da corrida em ordem de tempo, usadas na reprodução do trajeto
GET /api/corridas/{id}/celulas Retorna o mapa final da corrida
WS /ws/telemetria Canal de tempo real do painel (seção 6.4)

Frontend

Módulo Responsabilidade Requisitos
Painel em Tempo Real Grade do labirinto, rastro, posição e indicadores da prova, alimentados pelo WebSocket RF-SFT06
Histórico de Corridas Lista com filtros, inspeção e reprodução de corridas, alimentado pela API REST RF-SFT08
Simulador do Labirinto Ambiente virtual para validar a lógica de navegação e a interface sem o robô físico, reaproveitando o componente de grade (pacote 5.1.3 da EAP) RNF-SFT02

4.3 Visão de Processos

A visão de processos descreve o que executa em paralelo e como os elementos se comunicam ao longo do tempo.

Estados do robô

O comportamento do firmware é governado por uma máquina de estados, cujos estados são os mesmos transmitidos no campo status da telemetria.

stateDiagram-v2
    [*] --> AGUARDANDO
    AGUARDANDO --> MAPEANDO: largada (exploração)
    AGUARDANDO --> SPEED_RUN: largada (rota conhecida)
    MAPEANDO --> CONCLUIDO: objetivo alcançado
    SPEED_RUN --> CONCLUIDO: objetivo alcançado
    CONCLUIDO --> AGUARDANDO: robô reposicionado na largada
    MAPEANDO --> TRAVADO: rodas bloqueadas
    SPEED_RUN --> TRAVADO: rodas bloqueadas
    MAPEANDO --> COLISAO: colisão detectada
    SPEED_RUN --> COLISAO: colisão detectada
    MAPEANDO --> TIMEOUT: 10 minutos
    SPEED_RUN --> TIMEOUT: 10 minutos
    TRAVADO --> [*]
    COLISAO --> [*]
    TIMEOUT --> [*]

Concorrência no firmware do robô

O firmware executa tarefas independentes do FreeRTOS, de modo que a transmissão de telemetria nunca atrase o controle do robô:

Tarefa Frequência Função
Controle e navegação Laço contínuo, com leitura de sensores a no mínimo 20 Hz (pacote 3.1.5 da EAP) Sensoriamento, mapeamento, decisão de trajetória e controle dos motores
Monitor de segurança Contínua, em paralelo ao controle Verificação de travamento enquanto houver comando de tração
Telemetria 1 Hz Leitura do estado compartilhado e envio do pacote ESP-NOW

O estado compartilhado entre as tarefas (posição, orientação, mapa e indicadores) é protegido por mecanismos de exclusão mútua do FreeRTOS, evitando que a telemetria leia um estado parcialmente atualizado.

Concorrência no backend

O backend opera de forma assíncrona em um único processo, com tarefas em paralelo:

  • Leitor serial: aguarda continuamente novas linhas na porta USB e as encaminha para validação.
  • Processamento do pacote: valida o pacote, difunde pelo WebSocket e registra no banco por meio do Serviço de Corridas.
  • Watchdog: verifica a cada segundo o tempo desde o último pacote válido.
  • Requisições HTTP: consultas ao histórico são atendidas em paralelo à ingestão, sem bloqueá-la.

Fluxo de um pacote de telemetria

sequenceDiagram
    participant R as Robô (ESP32)
    participant G as Gateway (ESP32)
    participant B as Backend
    participant D as MySQL
    participant F as Navegador

    loop a cada 1 segundo
        R->>G: Pacote binário (ESP-NOW, 18 bytes)
        G->>B: Linha JSON (serial USB, 115200 bps)
        B->>B: Validação do pacote
        B-->>F: Mensagem JSON (WebSocket)
        F->>F: Atualiza grade e indicadores
        B->>D: Insere Leitura e atualiza Celula
    end

A difusão ao navegador ocorre antes da gravação no banco, para que eventuais atrasos de persistência não afetem a exibição. Estimativa do tempo total, frente ao limite de 1 segundo do RNF-SFT03:

Etapa Tempo estimado
Transmissão ESP-NOW menos de 5 ms
Transmissão serial de cerca de 350 bytes a 115200 bps cerca de 30 ms
Validação e difusão no backend poucos milissegundos
Entrega WebSocket em rede local e renderização dezenas de milissegundos
Total bem abaixo de 1 segundo

4.4 Visão de Implementação

A visão de implementação descreve como o código é organizado no repositório. A estrutura segue as pastas do template da disciplina, com uma subpasta por elemento de software:

src/
├── firmware/
│   ├── robo/                  # Firmware do robô (PlatformIO)
│   │   ├── platformio.ini
│   │   ├── include/           # Cabeçalhos e estruturas compartilhadas (TelemetriaPacket)
│   │   └── src/
│   │       ├── main.cpp       # Inicialização e criação das tarefas
│   │       ├── estados/       # Máquina de estados
│   │       ├── sensores/      # Sensoriamento e odometria
│   │       ├── mapa/          # Matriz do labirinto
│   │       ├── navegacao/     # Exploração e rota ótima
│   │       ├── controle/      # Controle de movimento
│   │       ├── seguranca/     # Detecção de travamento
│   │       └── telemetria/    # Envio ESP-NOW
│   └── gateway/               # Firmware do receptor (PlatformIO)
│       ├── platformio.ini
│       └── src/main.cpp
├── backend/
│   ├── requirements.txt
│   └── app/
│       ├── main.py            # Inicialização do FastAPI e das tarefas
│       ├── api/               # Rotas REST e WebSocket
│       ├── ingestao/          # Leitura da porta serial e watchdog
│       ├── servicos/          # Ciclo de vida da corrida
│       ├── repositorios/      # Acesso ao banco
│       └── modelos/           # Entidades e esquemas de validação
└── frontend/
    ├── package.json
    └── src/
        ├── componentes/       # Grade, indicadores, tabela
        ├── paginas/           # Painel, Histórico, Simulador
        └── servicos/          # Clientes WebSocket e REST

Principais dependências

Elemento Dependência Uso
Firmware do robô Arduino-ESP32 Base de desenvolvimento, FreeRTOS e ESP-NOW
Firmware do robô Biblioteca do sensor ToF (VL53L0X) Leitura de distância às paredes
Firmware do gateway ArduinoJson Montagem da linha JSON
Backend FastAPI e Uvicorn API REST, WebSocket e servidor
Backend pySerial Leitura da porta USB do gateway
Backend SQLAlchemy e PyMySQL Mapeamento objeto-relacional e conexão com o MySQL
Frontend React e Vite Construção da interface
Frontend Recharts Gráficos de velocidade e bateria

A estrutura TelemetriaPacket (seção 6.2) é definida em um único cabeçalho compartilhado entre o firmware do robô e o do gateway, garantindo que emissor e receptor usem exatamente o mesmo formato.

4.5 Visão de Implantação

Todo o sistema é implantado localmente na bancada de prova, sem dependência de internet ou de rede Wi-Fi externa.

flowchart LR
    subgraph PISTA["Pista"]
        ROBO["Robô<br/>ESP32 emissor<br/>Firmware do robô"]
    end

    subgraph BANCADA["Bancada de prova"]
        GW["ESP32 receptor<br/>Firmware do gateway"]
        subgraph NOTE["Notebook da equipe"]
            BACK["Backend<br/>FastAPI + Uvicorn"]
            DB[("MySQL")]
            WEB["Frontend<br/>arquivos estáticos"]
        end
    end

    subgraph CLIENTES["Clientes"]
        NAV1["Navegador<br/>no notebook"]
        NAV2["Navegador em outro<br/>dispositivo da rede local"]
    end

    ROBO -. "ESP-NOW 2,4 GHz" .-> GW
    GW -- "USB serial" --> BACK
    BACK --> DB
    BACK -- "serve" --> WEB
    WEB -- "HTTP e WebSocket" --> NAV1
    WEB -. "HTTP e WebSocket" .-> NAV2
Nó Hardware Software implantado
Robô ESP32 embarcado Firmware do robô
Gateway ESP32 na bancada, ligado ao notebook por cabo USB Firmware do gateway
Notebook da equipe Computador da bancada Backend, banco MySQL e arquivos do frontend, servidos pelo próprio backend
Clientes Navegador no notebook ou em outro dispositivo da mesma rede local Aplicação web (SPA)

Observações de implantação

  • O backend identifica a porta serial do gateway por configuração (COMx no Windows, /dev/ttyUSBx no Linux).
  • O frontend é compilado para arquivos estáticos e servido pelo próprio backend, de modo que a aplicação inteira é iniciada com um único comando.
  • Recomenda-se executar o MySQL em contêiner Docker, padronizando o ambiente entre os computadores da equipe.
  • Dispositivos móveis na mesma rede local podem acompanhar o painel pelo navegador, o que viabiliza o RNF-SFT06.

4.6 Visão de Dados (MER e DER)

A persistência utiliza banco de dados relacional (MySQL), adequado à natureza estruturada da telemetria e às consultas históricas com filtros exigidas pelo RF-SFT08.

4.6.1 Modelo Entidade-Relacionamento (MER)

Entidades

Corrida: representa uma prova completa, da largada ao encerramento. É criada no início da prova e completada ao seu término.

Atributo Descrição
idCorrida Identificador único da corrida
inicio Data e hora da largada
fim Data e hora do encerramento
tempo_total_ms Duração total da prova em milissegundos
labirinto Geometria da pista: 4x4, 8x4 ou 12x4
modo Exploração ou Speed Run
tentativa Número sequencial da tentativa no mesmo labirinto
status_final CONCLUIDO, COLISAO, TIMEOUT, TRAVADO ou INTERROMPIDA
desafio_cumprido Indica se o robô alcançou a célula objetivo
velocidade_media Velocidade média da prova em cm/s
celulas_visitadas Quantidade de células fisicamente visitadas
bateria_inicial_pct Carga da bateria na largada, em porcentagem
bateria_final_pct Carga da bateria no encerramento, em porcentagem

Leitura: representa um pacote de telemetria recebido, ou seja, o estado do robô em um instante da prova. Uma corrida de 5 minutos gera cerca de 300 leituras.

Atributo Descrição
idLeitura Identificador único da leitura
Corrida_idCorrida Corrida à qual a leitura pertence
timestamp_ms Tempo decorrido de prova no momento da leitura
coluna Coluna atual do robô: A, B, C ou D
linha Linha atual do robô: 1 a 12
orientacao Direção para a qual o robô aponta: Norte, Sul, Leste ou Oeste
status Estado do robô no instante da leitura
velocidade_atual Velocidade instantânea em cm/s
velocidade_media Velocidade média acumulada até o instante, em cm/s
bateria_pct Carga da bateria em porcentagem
bateria_volts Tensão da bateria em volts

Celula: representa uma célula do labirinto e as paredes detectadas nela durante uma corrida. Todas as células da geometria são criadas no início da corrida.

Atributo Descrição
idCelula Identificador único da célula
Corrida_idCorrida Corrida à qual a célula pertence
coluna Coluna da célula: A, B, C ou D
linha Linha da célula: 1 a 12
parede_norte, parede_sul, parede_leste, parede_oeste Presença de parede em cada lado: detectada, ausente ou nulo quando ainda não observada
visitada_em_ms Instante da primeira visita do robô à célula; nulo se a célula nunca foi visitada

Relacionamentos

Relacionamento Cardinalidade Descrição
Corrida registra Leitura 1 : N Uma corrida possui várias leituras; cada leitura pertence a exatamente uma corrida
Corrida mapeia Celula 1 : N Uma corrida possui uma célula para cada posição da geometria (16, 32 ou 48); cada célula pertence a exatamente uma corrida

Regras de integridade

  • A combinação de Corrida_idCorrida, coluna e linha é única na entidade Celula, de modo que uma nova passagem do robô pela mesma posição atualiza a célula existente em vez de criar outra.
  • O valor de linha deve respeitar a geometria da corrida: 1 a 4, 1 a 8 ou 1 a 12.
  • O trajeto percorrido, um dos parâmetros obrigatórios do edital, é obtido pela sequência de posições da entidade Leitura ordenada por timestamp_ms, sem necessidade de armazenamento separado.

4.6.2 Diagrama Entidade-Relacionamento (DER)

Diagrama Entidade-Relacionamento


5. Detalhamento dos Algoritmos de Firmware

5.1 Mapeamento Topológico do Labirinto

Requisitos atendidos: RF-SFT02 e RNF-SFT02.

O labirinto é representado na memória como uma matriz de células, em que cada posição corresponde a uma célula física de 180 x 180 mm da pista. A célula inicial ocupa a posição (0,0) e a numeração cresce conforme o robô avança.

Convenção de coordenadas

Internamente, o firmware indexa linhas e colunas a partir de zero, com a célula de largada na posição (0,0), conforme o RF-SFT03. Na telemetria e no painel web, a mesma posição é exibida como A1: colunas identificadas pelas letras A a D e linhas numeradas de 1 a 12. A largada fica no canto superior esquerdo da grade, e o norte corresponde ao topo. A conversão entre os dois formatos é feita pelo gateway receptor (seção 6.2).

Cada célula armazena:

Campo Tamanho Conteúdo
Paredes 4 bits Presença de parede nas direções norte, sul, leste e oeste, no mesmo bitmask do campo paredes da telemetria (seção 6.2)
Lados conhecidos 4 bits Quais lados já foram observados, com parede ou sem ela. Um lado conhecido sem parede é passagem confirmada; um lado ainda não observado é não determinado
Visitada 1 bit Indica se o robô já esteve fisicamente na célula
Distância ao objetivo 1 byte Valor usado pelo algoritmo de busca durante a navegação

A distinção entre lado não determinado e passagem confirmada permite que a rota do speed run use apenas paredes conhecidas (RF-SFT09) e que a exploração saiba quais lados ainda faltam observar. Na telemetria só vai o bitmask de paredes: lados não determinados aparecem como sem parede.

As três geometrias oficiais são atendidas por parametrização: o número de linhas e colunas é definido na inicialização, a partir da seleção feita pelo operador, e toda a lógica opera sobre esses limites. Isso evita qualquer código específico por tamanho de pista e atende o RNF-SFT02.

Atualização do mapa

  1. Ao entrar em uma célula, o firmware marca o bit de visitada e registra como passagem conhecida o lado por onde entrou.
  2. As leituras dos sensores frontal e laterais são convertidas em presença ou ausência de parede, considerando a orientação atual do robô, e os lados correspondentes passam a ser conhecidos.
  3. A informação é gravada de forma simétrica: ao registrar parede a leste da célula (r, c), a mesma parede é registrada a oeste da célula (r, c+1), mantendo a consistência do mapa.
  4. As paredes de perímetro são conhecidas de antemão, pois toda pista oficial é fechada nas bordas: são registradas assim que a geometria é definida, e uma leitura de passagem no perímetro é descartada.

Orientação e posição

O firmware mantém dois estados internos: a célula atual e a direção apontada (norte, sul, leste ou oeste). Cada avanço incrementa a posição na direção corrente, e cada rotação ortogonal atualiza a direção. A consistência entre esses estados e a odometria é o que garante que o mapa gerado corresponda à pista real.

Exemplo de representação

Em uma pista 4x4 na qual o robô partiu de (0,0), seguiu para o leste até (0,2) e encontrou parede à frente, o estado parcial da matriz seria:

Célula Paredes registradas Visitada
(0,0) Norte, Oeste Sim
(0,1) Norte Sim
(0,2) Norte, Leste Sim
Demais Não determinadas Não

Ao fim da exploração, essa matriz deve ser idêntica à configuração física da pista, que é o critério de aceitação do RF-SFT02.

5.2 Controle de Movimento e Alinhamento de Trajetória

Requisitos atendidos: RF-SFT01.

O robô não navega apenas apontando para frente: ele se guia pela distância às paredes laterais do corredor. Durante o avanço em linha reta, os sensores ToF laterais medem continuamente a distância até a parede esquerda e até a parede direita.

  • Se as duas distâncias forem iguais, o robô está centralizado no corredor e mantém a mesma velocidade nas duas rodas.
  • Se uma distância for menor que a outra, o robô está se aproximando de um dos lados. O firmware reduz a velocidade da roda do lado mais próximo da parede, ou aumenta a do lado oposto, trazendo o robô de volta ao centro.
  • A correção é proporcional ao tamanho do desvio, com um termo adicional que reage à velocidade de variação do erro, caracterizando um controle proporcional e derivativo (PD). O erro é a diferença entre as distâncias laterais, e a saída ajusta a velocidade diferencial entre as rodas até que o erro tenda a zero.

O critério de aceitação do RF-SFT01 exige que o robô percorra três células consecutivas em reta mantendo desvio lateral inferior a 15 mm em relação à linha de centro, sem contato com as paredes. Como o corredor livre tem 168 mm, um desvio de 15 mm para cada lado só ocorre sem contato se a largura do robô for de no máximo 138 mm (168 mm menos 2 x 15 mm). Essa restrição deve ser compatibilizada com o projeto estrutural, já que o TAP admite largura de até 165 mm.

Trechos sem parede de referência

Em cruzamentos e entradas de corredores a comparação lateral deixa de ser confiável. Nesses trechos o firmware recorre a um critério auxiliar, mantendo o rumo pela referência angular da IMU e pela diferença de contagem entre os encoders, até voltar a ter parede nos dois lados.

Implementação do controle de retas (HU-01)

A classe ControleReta (src/firmware/robo/src/controle/ControleReta.h) não depende de hardware: o laço de controle entrega as leituras já prontas e ela devolve a velocidade desejada de cada roda, que a camada de acionamento dos motores converte em PWM.

Item Descrição
Entradas Distância lateral esquerda e direita (ToF), yaw do IMU, contagem dos encoders e millis(). Leitura negativa ou fora da faixa de 1 a 100 mm conta como ausência de parede.
Saídas Velocidade das rodas esquerda e direita (mm/s, nunca negativa), modo em uso (paredes ou rumo) e os erros lateral e de rumo, úteis para log.
Modo paredes PD sobre o erro lateral (distância esquerda menos direita): a correção reduz a roda do lado mais próximo da parede e aumenta a oposta, com saturação do giro.
Modo rumo Sem parede válida nos dois lados, mantém o rumo que o robô tinha no início da reta pelo yaw do IMU. Com o IMU inválido, usa a diferença de contagem dos encoders.
Chamada iniciar() quando a reta começa, com o robô alinhado ao corredor, e atualizar() a cada nova leitura dos ToF laterais (no mínimo 20 Hz).

Os ganhos iniciais (velocidade base de 150 mm/s, Kp de 1,0 mm/s por mm, Kd de 0,3 e Kp de rumo de 4,0 mm/s por grau) foram escolhidos em simulação e devem ser ajustados no robô durante o CT-01. A bitola de 78 mm vem do doc 4.1; os pulsos por milímetro dos encoders são um valor provisório a calibrar. Duas limitações são conhecidas: o rumo de referência é o do início da reta, então um início desalinhado seguido de trecho sem parede mantém o desalinhamento até as paredes voltarem; e, com uma só parede, o controle usa o rumo em vez de seguir essa parede.

Rotações ortogonais

As curvas de 90° são executadas por rotação diferencial das rodas, com o ângulo controlado por encoders e IMU. O RF-SFT01 limita o erro angular acumulado a ±3°, o que exige que cada rotação seja verificada ao final e corrigida antes do próximo avanço, evitando que pequenos desvios se somem ao longo da prova.

Implementação do controle de curvas (HU-02)

A classe ControleCurva (src/firmware/robo/src/controle/ControleCurva.h) segue o mesmo molde do ControleReta: não depende de hardware, o laço de controle entrega as leituras já prontas e ela devolve a velocidade desejada de cada roda, que a camada de acionamento dos motores converte em PWM.

Item Descrição
Entradas Yaw do IMU (de -180° a 180°, positivo para a esquerda), contagem dos encoders e millis().
Saídas Velocidade das rodas esquerda e direita (mm/s, pode ser negativa, pois a curva é feita no próprio eixo), estado da curva, erro de ângulo, giro medido pelos encoders e discrepância entre IMU e encoders, úteis para log.
Medida do giro O IMU (giroscópio integrado a 100 Hz) é a referência principal. Os encoders servem de conferência (giro = diferença entre as rodas ÷ bitola) e passam a ser a medida se o IMU estiver inválido.
Controle Proporcional sobre o erro de ângulo, com velocidade mínima (zona morta dos motores) e máxima. O alvo é o rumo ideal acumulado, e não o rumo medido: cada curva soma ±90° ao ideal, então o erro de uma curva não se soma ao da seguinte.
Conclusão Dentro da tolerância o robô para e a curva só é dada como feita depois do tempo de assentamento; se a inércia o levar para fora, o controle corrige antes de concluir. A orientação interna (N/L/S/O) só é atualizada nesse momento. Estourado o tempo limite, o estado vira CURVA_FALHOU e a orientação não muda.
Chamada iniciar() quando a curva começa e atualizar() a cada leitura do IMU, até o estado sair de CURVA_GIRANDO. Depois do realinhamento pelos ToF (HU-01), ressincronizar() com o yaw atual, para o rumo ideal absorver a deriva do giroscópio.

Os ganhos iniciais (Kp de 3,0 mm/s por grau, velocidade mínima de 12 mm/s e máxima de 100 mm/s, tolerância de 1°, assentamento de 100 ms) foram escolhidos em simulação e devem ser ajustados no robô; em especial a velocidade mínima depende da zona morta dos motores. A bitola de 78 mm vem do doc 4.1 e os pulsos por milímetro dos encoders são um valor provisório a calibrar. Duas limitações são conhecidas: depois de uma falha o rumo ideal já foi deslocado e quem chamou decide como realinhar; e o erro de ±3° do RF-SFT01 só é garantido se o giroscópio não derivar entre dois realinhamentos pelos ToF.

flowchart TD
    A[Medir distância lateral esquerda e direita] --> B{Há parede dos dois lados?}
    B -- Sim --> C[Calcular erro entre as distâncias]
    C --> D{Erro próximo de zero?}
    D -- Sim --> E[Manter velocidade igual nas duas rodas]
    D -- Não --> F[Aplicar correção proporcional na roda mais próxima]
    B -- Não --> G[Manter rumo por IMU e encoders]
    E --> A
    F --> A
    G --> A

5.3 Detecção e Tratamento de Travamento (Stall)

Requisitos atendidos: RF-SFT11.

Se o firmware está comandando os motores e a odometria não registra rotação das rodas por mais de 1,0 segundo, considera-se que o robô está travado, seja por roda presa, obstáculo ou perda de contato com o piso. Nessa condição a tração deve ser cortada para prevenir danos aos motores e ao driver.

O monitoramento ocorre em paralelo ao controle de movimento:

  1. A cada pulso de encoder registrado, o firmware guarda o instante da última rotação detectada.
  2. Enquanto houver comando de tração ativo, verifica-se periodicamente o tempo decorrido desde esse instante.
  3. Ultrapassado 1,0 segundo sem rotação, o travamento é confirmado: a potência dos motores é zerada, o robô entra em estado de erro e a condição é sinalizada por indicador local e pelo status TRAVADO na telemetria (seção 6).
  4. Se a odometria continuar respondendo, o temporizador é reiniciado e a navegação segue normalmente.

O critério de aceitação do RF-SFT11 admite o corte em até 1,2 segundo após o bloqueio físico das rodas, o que reserva 200 ms para o ciclo de verificação e a atuação do corte.

flowchart TD
    A[Comando de tração ativo] --> B[Monitorar pulsos do encoder]
    B --> C{Passou mais de 1,0 s sem rotação?}
    C -- Não --> B
    C -- Sim --> D[Zerar potência dos motores]
    D --> E[Entrar em estado de erro e enviar status TRAVADO]

6. Protocolo de Telemetria

Requisitos atendidos: RF-SFT05, RF-ELE04 e RNF-SFT03.

6.1 Visão Geral da Arquitetura de Comunicação

A telemetria opera via protocolo de rádio ESP-NOW, protocolo de camada de enlace em 2,4 GHz da Espressif que dispensa roteador ou rede Wi-Fi. A transmissão ocorre na frequência nominal de 1 Hz, com um envio a cada 1000 ms.

A integração com o computador de monitoramento utiliza um gateway receptor dedicado:

+--------------------------+                      +--------------------------+
|   ESP32 Emissor (Robo)   |       ESP-NOW        | ESP32 Receptor (Bancada) |
|   - Amostragem a 1 Hz    | ===================> | - Gateway / Bridge       |
|   - Payload: Struct C    |   (Pacote Binario)   | - Valida e converte      |
+--------------------------+                      +--------------------------+
                                                               |
                                                               | Serial / USB (JSON a 115200 bps)
                                                               v
+--------------------------+                      +--------------------------+
|      Dashboard Web       |      WebSocket       |     Servidor Backend     |
|  - Renderizacao da grade | <=================== | - Leitura da porta serial|
|  - Rastro e Metricas     |    ws://... (JSON)   | - Broadcast e Banco      |
+--------------------------+                      +--------------------------+
  1. ESP32 emissor (robô): coleta dados dos sensores, odometria, paredes e bateria, empacota em uma estrutura binária em C e transmite via ESP-NOW para o endereço MAC do receptor a cada 1 segundo.
  2. ESP32 receptor (gateway USB): conectado à porta USB da estação base. Recebe a estrutura binária, converte para JSON e envia pela interface serial.
  3. Servidor backend: lê continuamente a porta serial (/dev/ttyUSBx ou COMx), valida o pacote, redistribui via WebSocket para o front-end e persiste os dados no banco.
  4. Dashboard web: consome o WebSocket e atualiza o mapa e os indicadores em tempo real.

6.2 Camada de Rádio: Payload Binário ESP-NOW

No firmware do robô, a transmissão utiliza uma estrutura compactada de 18 bytes, bem abaixo do limite de 250 bytes por pacote do ESP-NOW. Posição e velocidade trafegam em formato interno do firmware e são convertidas pelo gateway para o formato de exibição.

typedef struct __attribute__((packed)) {
    uint32_t timestamp_ms;     // Tempo decorrido de corrida (ms)
    uint8_t  labirinto_id;     // 1: 4x4, 2: 8x4, 3: 12x4
    uint8_t  status_id;        // 0: AGUARDANDO, 1: MAPEANDO, 2: SPEED_RUN, 3: COLISAO,
                               // 4: CONCLUIDO, 5: TIMEOUT, 6: TRAVADO
    uint8_t  desafio_cumprido; // 0: Nao, 1: Sim
    uint8_t  bateria_pct;      // 0 a 100 %
    uint16_t bateria_mv;       // Tensao em milivolts (ex: 7420 mV = 7.42 V)
    int16_t  velocidade_atual; // Velocidade instantanea em mm/s
    int16_t  velocidade_media; // Velocidade media acumulada em mm/s
    uint8_t  coluna;           // Indice interno 0 a 3 (exibido como A a D)
    uint8_t  linha;            // Indice interno 0 a 11 (exibido como 1 a 12)
    uint8_t  orientacao;       // 0: Norte, 1: Sul, 2: Leste, 3: Oeste
    uint8_t  paredes;          // Bitmask: bit0=N, bit1=S, bit2=L, bit3=O
} TelemetriaPacket;

Conversões realizadas pelo gateway

Campo No pacote binário No JSON
Coluna Índice 0 a 3 Letra A a D
Linha Índice 0 a 11 Número 1 a 12
Velocidades Inteiro em mm/s Decimal em cm/s
Bateria Inteiro em mV Decimal em V
Paredes Bitmask de 4 bits Quatro campos booleanos

As direções de parede e de orientação são absolutas, isto é, referenciadas ao labirinto e não à frente do robô. O firmware converte as leituras dos sensores a partir da orientação atual antes de montar o pacote.

6.3 Camada Serial (Gateway para Backend)

O ESP32 receptor emite pela porta USB uma linha de texto em JSON a cada pacote recebido:

  • Taxa de transmissão: 115200 bps
  • Delimitador de quadro: quebra de linha (\n)

6.4 Camada de Aplicação: WebSocket

  • Protocolo: WebSocket (RFC 6455)
  • Endpoint: ws://<host>:<porta>/ws/telemetria
  • Frequência: 1 Hz
  • Formato: JSON em UTF-8

Exemplo de mensagem:

{
  "timestamp_ms": 142000,
  "labirinto": "8x4",
  "status": "MAPEANDO",
  "desafio_cumprido": false,
  "bateria_pct": 78,
  "bateria_volts": 7.42,
  "velocidade_atual": 35.0,
  "velocidade_media": 28.5,
  "posicao": {
    "coluna": "B",
    "linha": 4
  },
  "orientacao": "LESTE",
  "paredes": {
    "norte": false,
    "sul": true,
    "leste": true,
    "oeste": false
  }
}

6.5 Dicionário de Dados

Todos os campos são obrigatórios.

Campo Tipo Unidade Descrição e restrições
timestamp_ms Inteiro ms Tempo decorrido de prova, de 0 a 600.000 ms (limite de 10 minutos)
labirinto String - Geometria em execução: "4x4", "8x4" ou "12x4"
status String - Estado do robô: "AGUARDANDO", "MAPEANDO", "SPEED_RUN", "COLISAO", "CONCLUIDO", "TIMEOUT" ou "TRAVADO"
desafio_cumprido Booleano - true se o robô alcançou a célula objetivo
bateria_pct Inteiro % Carga restante estimada, de 0 a 100
bateria_volts Decimal V Tensão da bateria medida via ADC
velocidade_atual Decimal cm/s Velocidade instantânea estimada pela odometria
velocidade_media Decimal cm/s Velocidade média acumulada na prova
posicao.coluna String - Coluna atual: "A", "B", "C" ou "D"
posicao.linha Inteiro - Linha atual: 1 a 4, 1 a 8 ou 1 a 12, conforme a geometria
orientacao String - Direção absoluta do robô: "NORTE", "SUL", "LESTE" ou "OESTE"
paredes.norte Booleano - Parede detectada ao norte da célula atual
paredes.sul Booleano - Parede detectada ao sul da célula atual
paredes.leste Booleano - Parede detectada a leste da célula atual
paredes.oeste Booleano - Parede detectada a oeste da célula atual

6.6 Ciclo de Vida da Corrida no Backend

O backend identifica o início e o fim de cada corrida a partir das transições de status recebidas:

  1. Início: a transição de AGUARDANDO para MAPEANDO ou SPEED_RUN cria um registro na tabela Corrida, com o modo derivado do status e a tentativa numerada sequencialmente para o mesmo labirinto na sessão de monitoramento. No mesmo momento são criadas todas as células da geometria (16, 32 ou 48), com paredes ainda não observadas.
  2. Durante a prova: cada pacote recebido gera uma nova Leitura e atualiza a Celula correspondente à posição atual, registrando as paredes detectadas e o instante da primeira visita.
  3. Encerramento: um status terminal (CONCLUIDO, COLISAO, TIMEOUT ou TRAVADO) fecha a corrida, preenchendo horário de fim, tempo total, status final, velocidade média, células visitadas e bateria final.

O trajeto percorrido é reconstruído pela sequência de leituras ordenada por timestamp_ms.

6.7 Confiabilidade e Watchdog

  • Watchdog de enlace (3 segundos): se o backend passar 3000 ms consecutivos sem receber um pacote válido, o painel passa a exibir o estado CONEXAO RF PERDIDA, retornando ao normal quando a recepção for retomada.
  • Descarte de pacotes corrompidos: o ESP-NOW possui verificação CRC em hardware, e pacotes com ruído são descartados pelo receptor antes do envio à porta serial.
  • Persistência incremental: cada leitura é gravada no momento em que é recebida, e não apenas ao final da prova, preservando os dados em caso de falha. Uma corrida que não receba status terminal, por perda definitiva de conexão ou início de uma nova corrida, é encerrada com status final INTERROMPIDA, atendendo ao RF-SFT07 para corridas concluídas ou interrompidas.

7. Roteiro de Testes Funcionais

Os casos de teste abaixo verificam os requisitos funcionais de software a partir dos critérios de aceitação definidos no documento de requisitos e nas histórias de usuário (seção 3.1). Cada caso referencia as issues correspondentes no GitHub.

Resumo

Código Caso de teste Rastreabilidade Prioridade
CT-01 Centralização do robô em reta RF-SFT01, HU-01 P0
CT-02 Precisão das rotações de 90° RF-SFT01, HU-02 P0
CT-03 Fidelidade do mapeamento nas três geometrias RF-SFT02, HU-03, RNF-SFT02 P0
CT-04 Seleção da geometria antes da largada RF-SFT02, HU-04 P0
CT-05 Largada e navegação autônoma RF-SFT03, HU-05, HU-06, RNF-SFT01 P0
CT-06 Parada automática no objetivo RF-SFT04, HU-07 P0
CT-07 Transmissão da telemetria a 1 Hz RF-SFT05, HU-08 P0
CT-08 Aviso de perda de conexão RF-SFT05, HU-09 P0
CT-09 Painel sincronizado com a pista RF-SFT06, HU-10, HU-11, RNF-SFT03 P0
CT-10 Persistência de corridas concluídas e interrompidas RF-SFT07, HU-12 P1
CT-11 Filtragem do histórico RF-SFT08, HU-13, RNF-SFT04 P1
CT-12 Reprodução de corrida passada RF-SFT08, HU-14 P1
CT-13 Speed run mais rápido que a exploração RF-SFT09, HU-15, HU-16 P1
CT-14 Curva em movimento contínuo RF-SFT10, HU-17 P2
CT-15 Corte de tração por travamento RF-SFT11, HU-18, HU-19 P0

CT-01: Centralização do robô em reta

Campo Descrição
Código CT-01
Nome Centralização do robô em reta
Rastreabilidade RF-SFT01, HU-01
Objetivo Verificar se o controle de movimento mantém o robô centralizado no corredor durante trechos retos.
Pré-condições • Robô calibrado e com bateria acima de 50%
• Pista montada com um corredor reto de pelo menos 3 células com paredes nos dois lados
• Linha de centro do corredor marcada no piso para referência
Procedimento 1. Posicionar o robô no início do corredor, alinhado à linha de centro
2. Acionar a largada
3. Filmar o percurso de cima, com régua milimetrada visível ao lado do corredor
4. Medir no vídeo o maior afastamento lateral em relação à linha de centro
5. Repetir o ensaio 5 vezes
Resultado esperado Em todas as repetições, o desvio lateral máximo é inferior a 15 mm e não há contato com as paredes.

CT-02: Precisão das rotações de 90°

Campo Descrição
Código CT-02
Nome Precisão das rotações de 90°
Rastreabilidade RF-SFT01, HU-02
Objetivo Verificar se as rotações ortogonais mantêm o erro angular acumulado dentro do limite.
Pré-condições • Robô calibrado e com bateria acima de 50%
• Área livre com marcação de referência angular no piso
Procedimento 1. Posicionar o robô sobre a marcação de referência
2. Comandar uma sequência de 8 rotações de 90° no mesmo sentido (duas voltas completas)
3. Medir o ângulo final do robô em relação à orientação inicial
4. Repetir no sentido oposto
Resultado esperado O erro angular acumulado ao final de cada sequência é de no máximo ±3°.

CT-03: Fidelidade do mapeamento nas três geometrias

Campo Descrição
Código CT-03
Nome Fidelidade do mapeamento nas três geometrias
Rastreabilidade RF-SFT02, HU-03, RNF-SFT02
Objetivo Verificar se a matriz registrada pelo firmware ao final da exploração corresponde à pista física.
Pré-condições • Pistas 4x4, 8x4 e 12x4 montadas com traçados conhecidos e desenhados em papel
• Painel web em execução para leitura do mapa final
Procedimento 1. Selecionar a geometria correspondente à pista
2. Executar a exploração completa
3. Ao final, comparar célula a célula as paredes exibidas no mapa final com o desenho da pista
4. Repetir para as três geometrias
Resultado esperado Em todas as geometrias, as paredes registradas nas células visitadas são 100% idênticas à configuração física da pista.

CT-04: Seleção da geometria antes da largada

Campo Descrição
Código CT-04
Nome Seleção da geometria antes da largada
Rastreabilidade RF-SFT02, HU-04
Objetivo Verificar se a geometria escolhida pelo operador é aplicada ao mapa e informada na telemetria.
Pré-condições • Robô ligado no estado AGUARDANDO
• Painel web conectado ao gateway
Procedimento 1. Selecionar a geometria 8x4 no robô
2. Observar a grade exibida no painel
3. Acionar a largada e conferir o campo labirinto da telemetria
4. Repetir para 4x4 e 12x4
Resultado esperado O painel exibe a grade com as dimensões da geometria selecionada e a telemetria informa o valor correspondente em todos os casos.

CT-05: Largada e navegação autônoma

Campo Descrição
Código CT-05
Nome Largada e navegação autônoma
Rastreabilidade RF-SFT03, HU-05, HU-06, RNF-SFT01
Objetivo Verificar se o robô inicia a prova pelo botão físico e alcança o objetivo sem intervenção externa.
Pré-condições • Pista 4x4 com traçado desconhecido pela equipe de firmware
• Robô sem mapa pré-carregado
• Robô ligado no estado AGUARDANDO
Procedimento 1. Verificar que o robô permanece parado antes do acionamento
2. Acionar o botão de largada e iniciar um cronômetro externo
3. Acompanhar a prova sem qualquer interação com o robô
4. Registrar o tempo até a chegada à célula objetivo
Resultado esperado O robô permanece parado até a largada, muda para o status MAPEANDO ao ser acionado e alcança o objetivo em menos de 3 minutos sem intervenção.

CT-06: Parada automática no objetivo

Campo Descrição
Código CT-06
Nome Parada automática no objetivo
Rastreabilidade RF-SFT04, HU-07
Objetivo Verificar se o robô para e congela o cronômetro ao entrar na célula de chegada.
Pré-condições • Pista 4x4 montada
• Câmera com gravação de alta taxa de quadros posicionada sobre a célula de chegada
Procedimento 1. Executar uma prova completa
2. No vídeo, identificar o quadro em que o robô cruza a entrada da célula de chegada e o quadro em que as rodas param
3. Calcular o intervalo entre os dois quadros
4. Conferir no painel o status e o tempo final
Resultado esperado A tração é interrompida em menos de 200 ms após a entrada na célula, o cronômetro é congelado e a telemetria informa CONCLUIDO com desafio cumprido.

CT-07: Transmissão da telemetria a 1 Hz

Campo Descrição
Código CT-07
Nome Transmissão da telemetria a 1 Hz
Rastreabilidade RF-SFT05, HU-08
Objetivo Verificar se o robô envia os 6 parâmetros obrigatórios do edital na frequência especificada.
Pré-condições • Gateway conectado ao computador
• Monitor serial ou registro do backend ativo
Procedimento 1. Executar uma prova de pelo menos 60 segundos
2. Registrar todos os pacotes recebidos pelo backend com seus horários de chegada
3. Conferir em cada pacote a presença dos campos de tipo de labirinto, posição, bateria, velocidade média, tempo e desafio cumprido
4. Calcular o intervalo médio entre pacotes e a quantidade de pacotes perdidos
Resultado esperado Todos os pacotes contêm os 6 parâmetros do edital, o intervalo médio entre pacotes é de 1 segundo e não há perda de pacotes ao longo do percurso.

CT-08: Aviso de perda de conexão

Campo Descrição
Código CT-08
Nome Aviso de perda de conexão
Rastreabilidade RF-SFT05, HU-09
Objetivo Verificar se o painel sinaliza a interrupção da telemetria e se o robô continua a prova.
Pré-condições • Prova em andamento com o painel recebendo dados
Procedimento 1. Durante a prova, desconectar o cabo USB do gateway
2. Cronometrar o tempo até a mudança de estado no painel
3. Reconectar o cabo após 10 segundos
4. Observar o comportamento do robô durante todo o intervalo
Resultado esperado O painel exibe Conexão RF perdida cerca de 3 segundos após a desconexão, volta ao normal ao reconectar, e o robô continua navegando sem interrupção.

CT-09: Painel sincronizado com a pista

Campo Descrição
Código CT-09
Nome Painel sincronizado com a pista
Rastreabilidade RF-SFT06, HU-10, HU-11, RNF-SFT03
Objetivo Verificar se o painel reflete a movimentação e as paredes descobertas em tempo real.
Pré-condições • Prova em andamento
• Câmera gravando simultaneamente a pista e a tela do painel
Procedimento 1. Executar uma prova de exploração
2. No vídeo, comparar o instante em que o robô entra em cada célula com o instante em que o painel atualiza a posição
3. Conferir se paredes, rastro, orientação, tempo, velocidade, bateria e status são exibidos
4. Medir o maior atraso observado
Resultado esperado Todos os indicadores são exibidos, a grade reflete as paredes descobertas e o atraso entre a pista e o painel é inferior a 1 segundo.

CT-10: Persistência de corridas concluídas e interrompidas

Campo Descrição
Código CT-10
Nome Persistência de corridas concluídas e interrompidas
Rastreabilidade RF-SFT07, HU-12
Objetivo Verificar se as corridas são gravadas integralmente no banco de dados, inclusive quando interrompidas.
Pré-condições • Backend e banco de dados em execução
Procedimento 1. Executar uma prova completa até o objetivo
2. Consultar a corrida no histórico logo após o encerramento
3. Iniciar uma nova prova e desligar o robô no meio do percurso
4. Consultar a segunda corrida no histórico
Resultado esperado A primeira corrida aparece com status CONCLUIDO e todas as leituras; a segunda aparece com status INTERROMPIDA e as leituras recebidas até a interrupção.

CT-11: Filtragem do histórico

Campo Descrição
Código CT-11
Nome Filtragem do histórico
Rastreabilidade RF-SFT08, HU-13, RNF-SFT04
Objetivo Verificar se os filtros por geometria e data retornam as corridas corretas no tempo exigido.
Pré-condições • Banco de dados populado com corridas nas três geometrias e em datas diferentes, totalizando até 500 registros
• Ferramentas de desenvolvedor do navegador abertas na aba de rede
Procedimento 1. Abrir a tela de histórico
2. Aplicar o filtro de geometria 8x4
3. Aplicar um intervalo de datas
4. Registrar o tempo de resposta e renderização
Resultado esperado Somente as corridas que atendem aos filtros são listadas e o resultado é exibido em menos de 2 segundos.

CT-12: Reprodução de corrida passada

Campo Descrição
Código CT-12
Nome Reprodução de corrida passada
Rastreabilidade RF-SFT08, HU-14
Objetivo Verificar se uma corrida salva pode ser inspecionada e reproduzida.
Pré-condições • Ao menos uma corrida concluída registrada no banco
Procedimento 1. Selecionar a corrida na tela de histórico
2. Conferir o mapa final e as estatísticas exibidas
3. Acionar a reprodução e usar a barra de tempo para avançar e retroceder
4. Comparar o trajeto reproduzido com o vídeo da prova original
Resultado esperado O mapa e as estatísticas carregam em menos de 2 segundos, e a reprodução percorre as posições na mesma ordem da prova real.

CT-13: Speed run mais rápido que a exploração

Campo Descrição
Código CT-13
Nome Speed run mais rápido que a exploração
Rastreabilidade RF-SFT09, HU-15, HU-16
Objetivo Verificar se a corrida pela rota ótima reduz o tempo em relação à exploração.
Pré-condições • Exploração completa realizada na pista, com o mapa mantido na memória do robô
Procedimento 1. Registrar o tempo da exploração
2. Reposicionar o robô na largada
3. Acionar a largada do speed run
4. Registrar o tempo do speed run e conferir o modo registrado no histórico
Resultado esperado O tempo do speed run é pelo menos 20% menor que o da exploração, e a corrida é registrada com modo Speed Run.

CT-14: Curva em movimento contínuo

Campo Descrição
Código CT-14
Nome Curva em movimento contínuo
Rastreabilidade RF-SFT10, HU-17
Objetivo Verificar se as curvas suavizadas reduzem o tempo de transição entre células.
Pré-condições • Trecho de pista com uma curva de 90° entre dois corredores
• Câmera com gravação de alta taxa de quadros
Procedimento 1. Percorrer o trecho com giro parado e medir o tempo de transição na curva
2. Percorrer o mesmo trecho com curva contínua e medir o tempo
3. Repetir cada modo 5 vezes e calcular as médias
Resultado esperado A curva contínua é executada sem parada total, sem contato com as paredes e com tempo médio pelo menos 300 ms menor que o giro parado.

CT-15: Corte de tração por travamento

Campo Descrição
Código CT-15
Nome Corte de tração por travamento
Rastreabilidade RF-SFT11, HU-18, HU-19
Objetivo Verificar se o robô corta os motores ao detectar as rodas bloqueadas e se o painel informa o travamento.
Pré-condições • Robô em movimento em trecho reto
• Painel conectado
• Câmera gravando o robô e a tela
Procedimento 1. Bloquear manualmente as rodas motrizes com o robô em movimento
2. No vídeo, medir o tempo entre o bloqueio e o corte dos motores
3. Conferir o status exibido no painel e o registro da corrida no histórico
Resultado esperado Os motores são cortados em no máximo 1,2 segundo após o bloqueio, o painel exibe o status Travado e a corrida é encerrada com status final TRAVADO.