Compreender o processamento de dados em tempo real com ROS2

O sistema operacional de robô 2 (ROS2) tornou-se o framework padrão para a construção de sistemas robóticos de produção que exigem comunicação determinística e de baixa latência. O processamento de dados em tempo real é essencial em aplicações como condução autônoma, manipulação industrial e drones aéreos, onde falta um prazo pode causar falha no sistema. O ROS2 aborda esses desafios através de sua arquitetura modular de assinatura de editoras, apoiada pelo middleware Data Distribution Service (DDS). Ao contrário do ROS1, o ROS2 foi projetado desde o zero até às restrições em tempo real, oferecendo políticas configuráveis de qualidade de serviço (QoS), modelos de execução múltiplos e compatibilidade com sistemas operacionais em tempo real. Este guia explica como alavancar o ROS2 para processamento de dados em tempo real, desde fundações arquitetônicas até técnicas avançadas de otimização.

Arquitetura Core: Nós, Tópicos, Serviços e Ações

O paradigma de comunicação da ROS2 depende de quatro abstrações-chave:

  • Nós são executáveis independentes que executam computação. Em sistemas em tempo real, cada nó normalmente roda em seu próprio processo, proporcionando isolamento de memória e permitindo que o designer de sistema atribua afinidades de CPU e políticas de agendamento por nó.
  • Tópicos habilitar mensagens de publicação-assinatura assíncronas. Os produtores de dados publicam para um tópico nomeado, e os consumidores assinam para receber mensagens. O middleware DDS lida com descoberta, serialização e transporte, permitindo que nós sejam adicionados ou removidos em tempo de execução sem reconfiguração.
  • Serviços fornecer uma comunicação síncrona de requisição-resposta. Embora não inerentemente em tempo real, os serviços são úteis para alterações de configuração ou atualizações de parâmetros que não exigem prazos difíceis.
  • Acções Estender os serviços para objetivos de longo prazo com feedback periódico, adequado para tarefas como o point de navegação, na sequência da necessidade de status intermediário.

Para aplicações em tempo real, o modelo de publicação-subscrição baseado em tópicos é a escolha mais comum, pois suporta comunicação dissociada e pode ser sintonizado para entrega determinística através de configurações de qualidade de serviço DDS.

Configurar ROS2 para processamento de dados em tempo real

Instalação e Seleção DDS

Comece instalando uma distribuição ROS2 recente, como Monumento de Hawksbill, Irwini de ferro, ou Rolando Ridley em um sistema operacional que suporta agendamento em tempo real—Linux com um patch de kernel em tempo real, QNX ou VxWorks. A implementação padrão de DDS (DDS Rápido) funciona bem para muitos sistemas, mas para requisitos em tempo real rigorosos consideram alternativas:

  • Ciclone DDS – Conhecido por baixa latência e alta escalabilidade; usado em sistemas de produção de veículos autônomos.
  • RTI Connext Pro – Um DDS comercial que oferece agendamento avançado em tempo real, recursos de segurança e memória compartilhada de cópia zero.
  • DDS Rápido – A opção padrão; versões recentes incluem um transporte de memória compartilhada com baixo jitter.

Após a instalação, configure o domínio DDS e o padrão QoS para corresponder aos requisitos de tempo da sua aplicação. Defina a variável de ambiente para isolar o seu sistema de outras redes ROS2. Ajuste o arquivo de configuração DDS (por exemplo, ] para DDS Rápido ou para Cyclone DDS) para permitir o transporte de memória compartilhada e definir as prioridades de thread.

Programação de Kernel e Processo em Tempo Real

Alcançar o tempo determinístico requer executar o loop de controle do seu robô com prioridade elevada. No Linux:

  1. Instale um kernel em tempo real – para o Ubuntu, use . Alternativamente, aplique o patch PREEMPT RT no seu kernel.
  2. Editar para permitir que seu usuário defina prioridades em tempo real, por exemplo: .
  3. Atribuir políticas de agendamento em tempo real aos seus nós ROS2 usando ou a chamada do sistema . Tipicamente, com uma prioridade de 80–95 funciona bem para loops de controle.

Para isolamento avançado, use o parâmetro de inicialização do kernel para reservar núcleos de CPU para tarefas em tempo real, então pise os threads de cada nó para núcleos dedicados usando ] ou . Isso impede a interferência de processos e interrupções não-tempo real.

Desenvolvendo nós de dados em tempo real

Princípios de Desenho de Nós

Escrever nós em tempo real em ROS2 requer atenção cuidadosa ao uso de recursos dentro de callbacks:

  • Evite a alocação dinâmica de memória inside callbacks. Use buffers pré-alocados e evite , , ou operações de container STL como que podem causar fragmentação de pilha. Se alocação dinâmica é inevitável, execute-o durante a inicialização do nó, não no caminho quente.
  • Mantenha chamadas curtas e determinísticasO processamento complexo deve ser descarregado para um thread ou executor separado, com callbacks relegados para analisar dados e publicar novos tópicos.
  • Utilizar o executor adequado. A memória pré-aloca para todos os timers e assinaturas, fornecendo agendamento de retorno de chamadas previsível. Para nós multi-threaded, aplicar com um número fixo de threads. Evite o padrão para nós críticos do tempo porque não garante ordenação determinística.

Além disso, considere usar a ROS2 executor suportado em tempo real (disponível em Ferro e posterior) que respeita as prioridades do thread e evita inversão de prioridade durante a execução do callback.

Implementação de Políticas de Qualidade de Serviço

As políticas ROS2 QoS são a principal ferramenta para a aplicação do comportamento em tempo real. As políticas-chave para o processamento de dados em tempo real incluem:

  • Confiabilidade: Definir como para entrega garantida de comandos críticos; use para dados de sensores onde gotas ocasionais são toleráveis, mas latência mínima é essencial.
  • Durabilidade: para dados de sensores transitórios; para informações de estado persistentes, como dados de mapas.
  • Prazo: Força que uma mensagem é recebida dentro de uma duração especificada. Se o editor não cumprir o prazo, o middleware alerta os assinantes. Isto é vital para loops de controle que exigem dados a uma taxa fixa (por exemplo, a cada 10 ms).
  • Orçamento de Lateridade:Diz ao middleware o atraso aceitável de ponta a ponta. Implementações DDS otimizam o transporte em conformidade, por exemplo, usando memória compartilhada em vez de rede se o orçamento é muito apertado.
  • Duração da vida: Descarta automaticamente dados mais antigos do que um limiar, impedindo que informações antigas sejam processadas.
  • Histórico: Definir para com profundidade 1 ou 2 para minimizar o uso da memória e reduzir o tempo de pesquisa.

Exemplo de trecho C++ para um editor com QoS em tempo real:

Para assinantes, defina perfis correspondentes. Configurações inconsistentes de QoS entre editor e assinante podem causar falhas de conexão; sempre teste com para verificar a compatibilidade.

Teste e otimização

Medindo a Latência e a Produção

ROS2 fornece várias ferramentas para avaliar o desempenho em tempo real:

  • com os horários da mensagem de registo de bandeira para análise offline do jitter.
  • (do pacote ) mede o atraso de ida e volta entre dois nós.
  • Medição de latência personalizada usando mensagens carimbadas: publicar uma mensagem com um timestamp sintético e calcular o atraso no lado do assinante. Isso dá granularidade mais fina do que ferramentas de linha de comando.
  • Verifica questões comuns como descompassos QoS e congestionamento de rede.

Uso do nó de perfil CPU com ou para identificar gargalos. Preste atenção especial para o tempo de execução de chamada de volta; se as chamadas excederem alguns microssegundos, o processamento de descarregamento para um thread separado ou reduzir a taxa de mensagem. Use inside callbacks para medir o tempo de execução, mas tenha cuidado para não introduzir alocação dinâmica através do objeto de relógio.

Otimizar o Transporte de Mensagens

Grandes fluxos de dados – nuvens de pontos, imagens, dados IMU de alta taxa – beneficiam-se de otimizações de transporte:

  • Memória partilhada de cópia zero: Active isto quando usar um DDS que suporta SHMEM (DDS rápido com , DDS ciclone com memória partilhada activada, ou RTI Connext Pro com transporte de memória partilhada). Isto elimina a serialização em cima e reduz as cópias de memória para mensagens grandes.
  • Reduzir a sobrecarga de serialização: Use estruturas de mensagens planas em vez de tipos profundamente aninhados. Evite campos em mensagens de alta frequência; use arrays de comprimento fixo ou identificadores inteiros em vez disso.
  • Ajustar a profundidade do histórico do DDS: Com profundidade 1, o middleware só mantém a última amostra, minimizando a memória e tempo de pesquisa.
  • Utilizar a Comunicação Intra-Processo (IPC) funcionalidade quando nós rodam no mesmo processo. Habilite e defina no seu nó. Isto ignora o DDS inteiramente para a comunicação do mesmo processo, oferecendo a menor latência possível.

Técnicas avançadas em tempo real

Executor em tempo real e Programação do Temporizador

O é ideal para execução determinística de retorno de chamadas porque pré-aloca toda a memória necessária e evita decisões de agendamento dinâmico. Para as loops de controle com temporizadores periódicos, crie o timer com um intervalo fixo e anexá-lo a um executor dedicado preso a um núcleo em tempo real:

Para sistemas multi-taxa, use executores separados para cada grupo de taxa, cada um preso a um núcleo diferente. Isto impede que uma chamada de baixa taxa de bloquear um de alta taxa.

Integrando com o Linux em Tempo Real (PREEMPT RT)

Ao usar o patch do kernel PREEMPT RT, assegure que os nós ROS2 evitem bloquear chamadas do sistema dentro de threads em tempo real. As armadilhas comuns incluem:

  • Alocação dinâmica de memória: Use pools pré-alocados em callbacks.
  • Ficheiro E/S: O registro no disco deve acontecer em um thread separado não-em tempo real.
  • Depuração em estilo Printf: Use apenas no desenvolvimento; estas chamadas podem bloquear em mutexes.
  • Inversão Prioritária: Use os mutexes de herança de prioridade () ao proteger recursos compartilhados. As implementações DDS da ROS2 normalmente lidam com isso corretamente, mas mutexes personalizados devem ser configurados explicitamente.

Teste o seu sistema sob carga de pior caso com ferramentas como para medir a latência máxima e garantir que ele fique abaixo dos seus prazos.

Manipulação de Criticidade Múltipla e Mista

Os sistemas robóticos têm frequentemente sensores que funcionam a diferentes velocidades – uma câmara a 30 Hz, LiDAR a 10 Hz, IMU a 1 kHz. Use executores separados para cada grupo de taxa, cada um fixado a um núcleo de CPU dedicado. Atribua prioridades mais elevadas a tarefas com prazos mais apertados (por exemplo, processamento IMU na prioridade 95, controlo a 90, LiDAR a 80, registo não crítico a 50). Para a criticidade mista, isole nós críticos de segurança num domínio separado em tempo real utilizando filtros de middleware ou o mecanismo de partição DDS. rclcpp ciclo de vida framework para gerenciar transições de estado de nó (não configuradas → inativas → ativas) e garantir que os componentes em tempo real só estejam ativos quando o sistema estiver pronto.

Caso de uso prático: Processamento de dados LiDAR em tempo real

Considere um robô móvel autônomo que deve processar uma varredura de Velodyne LiDAR (300.000 pontos por segundo) e produzir uma nuvem de ponto filtrado com uma latência máxima de 10 ms. O gasoduto consiste em:

  1. Nó do controlador: Lê dados brutos do LiDAR através de um soquete Ethernet e publica pacotes brutos () à taxa nativa do sensor (10 Hz).
  2. Nó de filtro em tempo real: Assina pacotes brutos, aplica um filtro de passagem (removendo pontos acima de 2 metros de altura), e publica pontos filtrados ().
  3. Nó de localização: Usa a nuvem filtrada para a verificação correspondente em 10 Hz.

Para cumprir o prazo de 10 ms:

  • Defina o prazo QoS para 10 ms em tópicos brutos e filtrados.
  • Pin o driver e nós filtrar para núcleos dedicados de CPU com SCHED FIFO prioridade 95.
  • Use o transporte de memória compartilhada para evitar serialização de dados de nuvem de 2 MB ponto. Com DDS rápido, definir e configurar o tamanho da fila de memória compartilhada para corresponder ao rendimento esperado.
  • Dentro do callback do filtro, use buffers pré-alocados de tamanho fixo. Por exemplo, aloque um com durante a inicialização do nó, então reutilize-o em cada callback com (que não realoca a capacidade).
  • Evite estruturas dinâmicas: não use ; rastreie o número de pontos válidos com um contador e insira através de indexação de arrays.

Após a implantação, monitore a latência usando um nó personalizado que marca o tempo de cada nuvem filtrada e a compare com o horário do pacote original. Use para verificar os tempos de ida e volta e para detectar preempções desnecessárias. Se os prazos ainda não forem cumpridos, considere aumentar a prioridade do nó filtro ou mover-se para uma implementação DDS mais rápida como o Cyclone DDS com memória compartilhada.

Conclusão

O ROS2 fornece um ecossistema robusto para o processamento de dados em tempo real de robôs, combinando flexibilidade computacional distribuída com o determinismo exigido pelos sistemas autônomos modernos. O sucesso depende da seleção correta da implementação do DDS, configuração correta das políticas do QoS e concepção de nós com restrições em tempo real desde o início. Ao usar kernels em tempo real, agendamento prioritário e transporte de cópia zero, os desenvolvedores podem construir sistemas que processam dados de sensores de alta taxa com latências previsíveis. À medida que o ROS2 evolui, o suporte para redes sensíveis ao tempo (TSN) e integração mais apertada com aceleradores de hardware como FPGAs e GPUs ampliarão ainda mais suas capacidades para robóticas críticas à missão.

Para mais informações, consultar a documentação oficial ROS2 em tempo real (Tutorial de Programação em Tempo Real), os índices de desempenho DDS da eProsima (DDS Rápido), e o projecto PREEMPT RT (Wiki Linux em Tempo Real). ROS2 Fundo em Tempo Real O artigo fornece um mergulho mais profundo na filosofia de design por trás do suporte em tempo real do framework. Para experimentação prática, o repositório demos ROS2 inclui exemplos em tempo real com código executável.