Introdução Limelight - Visão ao seu robô sem código A Limelight foi projetada para tornar a percepção de um robô tão fácil e confiável possível sem sacrificar nenhum desempenho! A Limelight é fácil o suficiente para iniciantes completos e poderoso o suficiente para profissionais. Configure pipelines de visão computacional sem código para bolhas de cor, AprilTags, redes neurais e muito mais usando a interface web integrada. Escreva pipelines personalizadas em Python com SnapScript usando tensorflow, opencv e muito mais usando a interface web integrada ou o Visual Studio Code. O hardware Limelight integra um sensor de imagem MIPI-CSI de alta largura de banda e baixa latência, um computador arm64, condicionamento de energia e o LimelightOS. O LimelightOS suporta os protocolos REST/HTTP, Websocket, Modbus e NetworkTables, além de formatos de saída JSON, Protobuf e bruto. Montagem Limelight 3 Use quatro parafusos de 1 1/2” #10-32 ou #10-24 e porcas de nylon para prender sua Limelight. Limelight 2/2+ Use quatro parafusos de 1 1/2” #10-32 ou #10-24 e porcas de nylon para prender sua Limelight. Conexão A Limelight recebe 12V de alimentação, porém é construida para funcionar até 4.5V. Os LEDs tem brilho constante até 7V Não utilize o Radio Power Module da REV para alimentar sua Limelight. A tensão é muito alta Credito - Christian Femia Conexão Padrão Não conecte os cabos na VRM Passe dois fios do seu Limelight para um slot no seu PDP/PDH (NÃO no seu VRM). Adicione qualquer disjuntor (5A, 10A, 20A, etc.) ao mesmo slot no seu PDP. Passe um cabo ethernet do seu Limelight para o rádio. Conexão POE PoE permite que você adicione tanto energia quanto a conexão de rede a sua Limelight por meio de um cabo Ethernet. Isto não é padrão IEEE 802.3 (44V-48V) PoE - é por isso que você deve usar um injetor passivo com 12V. Conecte um Injetor PoE Passivo ao seu PDP (NÃO ao seu VRM). Adicione qualquer disjuntor (5A, 10A, 20A, etc.) ao mesmo slot no seu PDP. Passe um cabo ethernet do seu Limelight para o seu injetor POE passivo. Melhores Práticas de Fiação Adicione alívio de tensão a todos os cabos de energia e ethernet que vão para o sua LL. Cole com cola quente todas as conexões. Adicione um switch de rede ao seu robô para permitir tethering ethernet durante os eventos e para evitar a segunda porta de rádio. Use cabos Cat6 trançados com fios flexíveis. Não é recomendado o uso da segunda porta de rádio. Roteie todos os dispositivos através do seu switch de rede, se possível. Atualizando o LimelightOS Siga esse guia para atualizar sua Limelight para a versão mais recente do LimelightOS Limelight 3 Desligue a sua Limelight. Baixe os últimos drivers USB, a imagem do sistema operacional Limelight e a ferramenta Balena Flash da Página de Downloads da Limelight. Conecte um cabo USB->USB-C do seu laptop ao seu Limelight. Seu Limelight ligará automaticamente. Execute o "Balena Etcher" como administrador. Pode levar até 20 segundos para que seu computador reconheça a câmera. Selecione a última imagem .zip na sua pasta de downloads. Selecione um dispositivo "Módulo de Computação" no menu "Drives". Clique em "Flash". Uma vez concluída a gravação, remova o cabo USB do seu Limelight. Limelight 2/2+ Desligue o seu Limelight. Baixe os mais recentes drivers USB, a imagem do sistema operacional Limelight e a ferramenta Balena Flash da Página de Downloads. Conecte um cabo USB->MicroUSB do seu laptop para o seu Limelight. O Limelight ligará automaticamente. Execute o "Balena Etcher" como administrador. Pode levar até 20 segundos para que o seu computador reconheça a câmera. Selecione a imagem .zip mais recente na sua pasta de downloads. Selecione um dispositivo "Compute Module" no menu "Drives". Clique em "Flash". Uma vez que a gravação esteja completa, remova o cabo USB do seu Limelight. Conecte o cabo USB-C apenas durante a gravação. O Limelight entra em um modo especial de flash enquanto o cabo microUSB está conectado. Você não poderá acessar a interface web enquanto o Limelight estiver no modo flash. Setup de Comunicação/Network Nós recomendamos fortemente seguir as instruções de IP estático para confiabilidade durante eventos. Siga estes passos antes de começar: Vá em adicionar/remover programas no Windows e procure por "bonjour" Quantos itens você vê? Se houver dois (2) itens com "bonjour" em seus nomes, desinstale "bonjour print services" Se não houver (0) itens com "bonjour" em seus nomes, instale bonjour da nossa página de Downloads. Reinicie seu Limelight/Robô e computador. Baixe a Ferramenta de Localização do Limelight da página de Downloads Definir Número da Equipe Ligue o seu robô e conecte seu computador à rede do seu robô. Após o seu Limelight piscar seus LEDs verdes, abra a Ferramenta de Localização do Limelight e procure pelo seu Limelight ou navegue para http://limelight.local:5801. Este é o painel de configuração. Navegue até a aba "Configurações" no lado esquerdo da interface. Insira o número da sua equipe e pressione o botão "Atualizar Número da Equipe". Definir Endereço IP Endereçamento Estático Mude o seu "Atribuição de IP" para "Estático". Defina o endereço IP do seu Limelight para "10.TE.AM.11". NOTA: Equipes com zeros precisam prestar atenção especial: A equipe 916 usa 10.9.16.xx, A equipe 9106 usa 10.91.6.xx A equipe 9016 usa 10.90.16.xx Defina a Máscara da Sub-rede para "255.255.255.0". Defina o Gateway para "10.TE.AM.1". Clique no botão "Atualizar". Dê ao seu roboRIO o seguinte endereço IP estático: "10.TE.AM.2" Recicle a energia do seu robô. Agora você poderá acessar o seu painel de configuração em 10.TE.AM.11:5801, e a transmissão da sua câmera em 10.TE.AM.11:5800. Endereçamento Dinâmico Mude sua "Atribuição de IP" para "Automático". Clique no botão "Atualizar". Reinicie o Robô. Você pode continuar acessando seu painel de configuração em http://limelight.local:5801, e sua transmissão de câmera em http://limelight.local:5800 Conecte o cabo USB-C apenas durante a gravação de imagem. O Limelight entra em um modo especial de flash enquanto o cabo microUSB está conectado. Você não será capaz de acessar a interface web enquanto o Limelight estiver em modo flash. Por que recomendamos o uso de um endereço IP estático? Primeiro, isso reduz vários segundos do tempo de inicialização do Limelight. Segundo, as equipes historicamente tiveram problemas em campos FRC reais e com firmwares de rádio de eventos. Recomendamos configurar endereços IP estáticos no seu robo-rio e driverstation também. As configurações de rede para usar em todos esses dispositivos podem ser encontradas perto da metade inferior desta página web. Como eu reseto o endereço IP? Após o seu Limelight iniciar, segure o botão de configuração por 10 segundos. Na próxima vez que o Limelight iniciar, sua configuração de rede será redefinida para endereçamento dinâmico. Antes de se Conectar ao Campo Configure um IP estático para o seu laptop. IP: 10.TE.AM.5 Máscara de Sub-rede: 255.0.0.0 Gateway: 10.TE.AM.1 Configure um IP estático para o seu RIO. IP: "10.TE.AM.2" Máscara de Sub-rede: 255.255.255.0 <- NOTE A DIFERENÇA AQUI Gateway: 10.TE.AM.1 Dê as suas Limelights nomes de host únicos (se estiver usando vários). Dê as suas Limelights configurações de IP estático únicas. Comece sempre com endereços ".11" e vá subindo. (10.9.87.11, etc.) O uso de outros endereços pode causar mau funcionamento das suas unidades quando conectado ao FMS. IP: "10.TE.AM.11" Máscara de Sub-rede: 255.255.255.0 Gateway: 10.TE.AM.1 Nota: Equipes com zeros precisam prestar atenção especial: A equipe 916 utiliza 10.9.16.xx A equipe 9106 utiliza 10.91.6.xx A equipe 9016 utiliza 10.90.16.xx Estado das luzes Luz de status verde A luz de status verde piscará lentamente se nenhum alvo for detectado pela pipeline atual. Ela piscará rapidamente se algum alvo for detectado pela pipeline atual. Luz de status amarela A luz de status amarela piscará quando um endereço IP estático não tiver sido atribuído. Se um endereço IP estático for atribuído, a luz permanecerá constantemente acesa ou apagada, sem piscar. LEDs de iluminação verde Os LEDs de iluminação verde no Limelight 1, 2 e 3 são controláveis via interface web e várias APIs, mas existem alguns padrões especiais de piscar projetados para ajudar a solucionar problemas de hardware e software: Piscar alternado Esquerda/Direita ou Superior/Inferior: O cabo interno da câmera se soltou ou o sensor de imagem sofreu danos. Piscar Rápido (todos os LEDs): O botão de reinicialização de rede foi mantido pressionado por pelo menos 10 segundos. Sequência de Inicialização Repetida (três piscadas ou várias piscadas de desvanecimento): O software está falhando, possivelmente devido a danos no hardware. Início a Programação O Limelight suporta os protocolos REST/HTTP, Websocket, Modbus e NetworkTables para dados de mira, dados de status e configuração ao vivo. Formatos de saída JSON, Protobuf e bruto estão disponíveis. Consulte a seção de APIs da documentação para obter mais informações. Para equipes de FRC, o protocolo recomendado é o NetworkTables. O Limelight envia todos os dados de mira, incluindo um despejo completo em JSON, para o NetworkTables a 100hz. As equipes também podem definir controles, como ledMode, janela de corte e mais via NetworkTables. As equipes de FRC podem usar as bibliotecas Limelight Lib Java e C++ para começar com o Limelight em segundos. Limelight Lib é a maneira mais fácil de começar. Biblioteca Limelight: Java, C++ Java double tx = LimelightHelpers.getTX(""); C++ #include "LimelightHelpers.h" double tx = LimelightHelpers::getTX(""); double ty = LimelightHelpers::getTY(""); Python wip NetworkTables Java import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; import edu.wpi.first.networktables.NetworkTable; import edu.wpi.first.networktables.NetworkTableEntry; import edu.wpi.first.networktables.NetworkTableInstance; NetworkTable table = NetworkTableInstance.getDefault().getTable("limelight"); NetworkTableEntry tx = table.getEntry("tx"); NetworkTableEntry ty = table.getEntry("ty"); NetworkTableEntry ta = table.getEntry("ta"); //Lê os valores periodicamente double x = tx.getDouble(0.0); double y = ty.getDouble(0.0); double area = ta.getDouble(0.0); //Manda o valor para a smart dashboard periodicamente SmartDashboard.putNumber("LimelightX", x); SmartDashboard.putNumber("LimelightY", y); SmartDashboard.putNumber("LimelightArea", area); C++ #include "frc/smartdashboard/Smartdashboard.h" #include "networktables/NetworkTable.h" #include "networktables/NetworkTableInstance.h" #include "networktables/NetworkTableEntry.h" #include "networktables/NetworkTableValue.h" #include "wpi/span.h" std::shared_ptr table = nt::NetworkTableInstance::GetDefault().GetTable("limelight"); double targetOffsetAngle_Horizontal = table->GetNumber("tx",0.0); double targetOffsetAngle_Vertical = table->GetNumber("ty",0.0); double targetArea = table->GetNumber("ta",0.0); double targetSkew = table->GetNumber("ts",0.0); LabVIEW Python import cv2 import numpy as np # runPipeline() é chamado todo frame pelo backend da Limelight def runPipeline(image, llrobot): # converte a imagem de input para o espaço de cor do HSV img_hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # converte o hsv para uma imagem binaria removendo qualquer pixel # que não sejam de acordo com os seguintes valores minimos e máximos do HSV img_threshold = cv2.inRange(img_hsv, (60, 70, 70), (85, 255, 255)) # ache contornos na nova imagem binaria contours, _ = cv2.findContours(img_threshold, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) largestContour = np.array([[]]) # inicializa um array vazio para mandar devolta ao robô llpython = [0,0,0,0,0,0,0,0] # se os contornos foram detectados, desenhe eles if len(contours) > 0: cv2.drawContours(image, contours, -1, 255, 2) # grava o maior contorno largestContour = max(contours, key=cv2.contourArea) # pega a caixa delimitadora não rotacionada que envolve o contorno x,y,w,h = cv2.boundingRect(largestContour) # desenha a caixa delimitadora não rotacionada cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,255),2) # grave alguns dados customizados para mandar devolta ao robô llpython = [1,x,y,w,h,9,8,7] #retorna o maior contor para a mira da LL, a imagem modificada, e os dados customizados return largestContour, image, llpython Melhores práticas Lista de Verificação de Preparação para o Evento Baixe e faça backup de todas as pipelines para o seu laptop de programação. Faça o download de uma cópia da imagem mais recente do Limelight para o seu laptop de programação. Registre uma lista das suas pipelines e seus índices. 1 - Dual Target Low 2 - Dual Target High Cargo Adicione alívios de tensão a todos os cabos de energia e Ethernet que vão para o seu Limelight. Considere aplicar cola quente a todas as conexões. Certifique-se de estar usando um painel de controle (Smartdashboard, Shuffleboard) e não um navegador da web para visualizar o stream durante treinos e eventos. Os controles web padrão não têm a capacidade de reconectar automaticamente a streams após desconexões acidentais, mas o SmartDashboard e o Shuffleboard têm reconexão automática incorporada por padrão. Adicione um switch de rede ao seu robô para habilitar a conexão Ethernet enquanto estiver em um evento e evitar a segunda porta de rádio. Use cabos Cat6 torcidos com fios flexíveis. Não use cabos Ethernet planos. Não use a segunda porta de rádio. Encaminhe todos os dispositivos por meio do seu switch de rede, se possível. Configure o encaminhamento de porta (Port Forwarding) para permitir a comunicação do Limelight ao ser conectado ao seu robô via USB. Encaminhe as portas 5800, 5801, 5802, 5803, 5804, 5805, 5806 e 5807. Java import edu.wpi.first.wpiutil.net.PortForwarder; @Override public void robotInit() { // Certifique-se de configurar o encaminhamento de porta apenas uma vez no código do robô. // Não coloque essas chamadas de funções em funções periodicas for (int port = 5800; port <= 5807; port++) { PortForwarder.add(port, "limelight.local", port); } } C++ import edu.wpi.first.wpiutil.net.PortForwarder; @Override public void robotInit() { // Certifique-se de configurar o encaminhamento de porta apenas uma vez no código do robô. // Não coloque essas chamadas de funções em funções periodicas for (int port = 5800; port <= 5807; port++) { PortForwarder.add(port, "limelight.local", port); } } Calibração durante o evento Role seu robô até cada alvo no campo. Certifique-se de que a segmentação está funcionando corretamente. Mude para a visualização "threshold" durante este processo (localizada abaixo do fluxo de imagem). Role seu robô próximo ao alvo e longe do alvo. Garanta que as miras estejam calibradas corretamente. Enquanto estiver longe do alvo, gire seu robô para a esquerda e para a direita ~ 30 graus para garantir que outros alvos não sejam rastreados erroneamente. Consulte a seção de ajuste abaixo para mais dicas de ajuste. Certifique-se de que nenhum outro elemento do campo/arena esteja sendo rastreado acidentalmente. Verifique seus filtros de área e proporção se estiver captando as luzes da arena. Tire capturas de tela de todos os alvos e rastreamentos incorretos. Você pode usá-los para ajustar suas pipelines nos boxes. Melhorando o pipeline Utilize a exposição mais baixa possível e aumente o deslocamento do nível de preto até que as luzes do campo e reflexos de LEDs sejam removidos da imagem. Teste sua segmentação enquanto estiver longe e inclinado para longe do seu alvo. Use o recurso "Smart Speckle Rejection" da versão 2019.7 para filtrar reflexos indesejados de LEDs. Antes de conectar ao campo Configure seu laptop com uma configuração de IP estático. IP: 10.TE.AM.5 Máscara de Sub-rede: 255.0.0.0 Gateway: 10.TE.AM.1 Configure seu RIO com uma configuração de IP estático. IP: "10.TE.AM.2" Máscara de Sub-rede: 255.255.255.0 <- ATENÇÃO PARA A DIFERENÇA AQUI Gateway: 10.TE.AM.1 Dê nomes de host exclusivos para seus Limelights (se estiver usando vários). Forneça configurações de IP estático únicas para seus Limelights. Comece sempre com endereços terminados em ".11" e vá aumentando. (10.9.87.11, etc.) O uso de outros endereços pode fazer com que suas unidades apresentem mau funcionamento quando conectadas ao FMS. IP: "10.TE.AM.11" Máscara de sub-rede: 255.255.255.0 Gateway: "10.TE.AM.1" Nota: As equipes com zeros precisam prestar atenção especial: - _Team 916 uses 10.9.16.xx,_ - _Team 9106 uses 10.91.6.xx_ - _Team 9016 uses 10.90.16.xx_ Informação adicional: https://docs.wpilib.org/en/stable/docs/networking/networking-introduction/ip-configurations.html Lista de checagem Pré-Partida Verifique todos os cabos de energia e Ethernet que vão para seus Limelights. Verifique todas as conexões elétricas quanto a folgas e fios desgastados. Verifique todos os parafusos de fixação / abraçadeiras / fita adesiva. Observe precauções contra descarga eletrostática (ESD) o tempo todo. Largura de banda Algumas equipes utilizam dois Limelights com duas câmeras USB, mantendo-se bem abaixo do limite de largura de banda. Siga as etapas abaixo para reduzir a largura de banda. Em vez de usar o modo de condução, crie uma pipeline "driver". Reduza a exposição para diminuir a largura de banda do stream. Está usando uma câmera USB? Utilize a chave NT "stream" para ativar o modo picture-in-picture. Isso reduzirá drasticamente a largura de banda do stream. Configure a taxa de stream para "baixa" na página de configurações se o streaming não for crítico para a condução. Utilize a opção de stream 160x120 introduzida na versão 2019.7. Solução de erros Tente acessar o stream em IP:5800 com um navegador da web. Isso deve ajudar a determinar a origem dos seus problemas. Reinicie o seu painel de controle. Reinicie o seu computador. Reinicie o seu robô se o campo tiver sido redefinido. Cabos Ethernet danificados podem ser a causa de problemas intermitentes de rede. Sempre use configurações de IP estático no campo. Calibração de mira As miras do Limelight transformam a calibração angular 2D em um processo simplificado. Em vez de armazenar desvios angulares no código, você pode alinhar manualmente seu robô a um alvo e clicar no botão "calibrar". Calibrar uma mira move o "zero" dos seus dados de mira. Isso é muito útil se o Limelight não estiver perfeitamente centrado no seu robô. Modo de mira única Posicione o seu robô na sua localização e rotação ideais para pontuar e clique em "calibrar". Agora, um tx e ty de "zero" equivalem a um robô perfeitamente alinhado. Se o seu robô precisar ser recalibrado para um novo campo, simplesmente realize uma partida de treino para encontrar o alinhamento perfeito para o seu robô e clique em "calibrar" durante a partida. Modo de mira dupla Imagine um robô com uma câmera ou atirador fora do eixo que precisa lançar objetos do jogo em um gol de várias posições no campo. À medida que o robô se aproxima do gol, sua mira deve ajustar em tempo real para compensar. O modo de mira dupla foi criado para essa funcionalidade. Alinhe o seu robô na sua posição e rotação mais próxima de pontuação e calibre a mira "A". Alinhe o seu robô na sua posição e rotação mais distante de pontuação e calibre a mira "B". Ao calibrar no modo de mira dupla, as miras também armazenam um valor de área. Você perceberá que, à medida que o seu robô se move entre as distâncias mínima e máxima de pontuação, a mira se move entre a mira "A" e a mira "B". Isso é feito verificando a área do alvo e comparando-a com as duas áreas de alvo vistas durante a calibração. Configuração Pipeline O LimelightOS armazena até 10 pipelines de visão exclusivas. Você pode alterar a pipeline ativa em tempo real com o LimelightLib. Para editar várias pipelines, você deve primeiro marcar a caixa "Ignore NetworkTables Index" na interface web. Isso forçará o robô a permitir temporariamente que você altere o índice da pipeline por meio da interface web, em vez de por meio do NetworkTables. Para baixar suas pipelines para backup e compartilhamento, basta clicar no botão "download" próximo ao nome da sua pipeline. Para carregar uma pipeline, clique no botão "upload". Aqui está um exemplo de um robô que utiliza duas pipelines: Exemplo de Robô com Duas Pipelines A primeira pipeline é ajustada para identificar faixas verticais únicas. A segunda pipeline é ajustada para encontrar uma combinação de duas faixas horizontais. O código para este robô está disponível no estudo de caso "Aim and Range". Observe que, quando o robô alterna entre pipelines, a interface web carrega automaticamente a nova pipeline. Aba de entrada A guia de entrada (Input Tab) oferece controles para alterar a imagem da câmera antes que ela seja processada pela pipeline de processamento. Tipo da pipeline Controla o tipo desejado de pipeline (AprilTags, Redes Neurais, Python, etc.). Imagem de origem Controla a fonte da imagem que é passada pela pipeline. Mude para "Snapshot" para testar suas pipelines de visão em snapshots armazenados. Este controle é redefinido automaticamente para "Camera" quando a interface gráfica é fechada. Resolução + zoom Controla a resolução da câmera e da pipeline de visão. Recomendamos o uso da pipeline 320x240, a menos que você esteja utilizando funcionalidades 3D. Pipelines de 320x240 executam a 90fps, enquanto pipelines de 960x720 executam a 22 fps. Em 2020, foram adicionadas opções de Zoom de Hardware 2x e 3x para este campo. As opções de zoom não são digitais e usam pixels reais do sensor a 100%. LEDs Controla o modo padrão de LED para esta pipeline. Isso pode ser substituído durante uma partida com a opção de tabela de rede "LED". Usuários do Limelight 2+ têm acesso a um controle deslizante de "Brilho do LED" que permite ajustar o brilho dos LEDs. Orientação Controla a orientação dos frames de entrada. Defina como "inverted" se sua câmera estiver montada de cabeça para baixo. Exposição Controla a configuração de exposição da câmera em intervalos de 0,01 milissegundos. Pense em uma câmera como uma grade de "buckets" (recipientes) para coletar luz - o tempo de exposição controla por quanto tempo os "buckets" da sua câmera ficam abertos por quadro. Reduzir o tempo de exposição efetivamente escurecerá sua imagem. Tempos de exposição baixos e fixos são cruciais no FRC, pois escurecem a maior parte dos dados de imagem recebidos. Fitas retrorrefletivas bem iluminadas se destacarão em uma imagem principalmente escura, tornando o processamento de visão um processo direto. Deslocamento do nível de preto Aumentar o deslocamento do nível de preto pode escurecer significativamente o stream da sua câmera. Isso deve ser aumentado para remover ainda mais as luzes da arena e pontos brilhantes da sua imagem. Esta é uma configuração de nível de sensor e não uma configuração de brilho digital falso. Ganho do Sensor Aumentar o ganho do sensor efetivamente aumentará o brilho da imagem, mas geralmente adicionará ruído à imagem também. Você pode usar o Ganho do Sensor e o Deslocamento do Nível de Preto para iluminar a imagem sem aumentar o tempo de exposição. Isso minimizará o desfoque de movimento para aplicações de rastreamento em alta velocidade. Balanço de Vermelho, Balanço de Azul Controla a intensidade dos componentes de cor vermelha e azul na sua imagem. Isso controla coletivamente o balanço de branco do seu Limelight. Recomendamos deixar esses valores inalterados.