ROS2 - Fundamentos

ROS2 - Fundamentos


Introdução

Na aula anterior , vimos como instalar o ROS2 no computador e deixá-lo funcional. Assim, consideramos nests aula atual que o você já tem acesso ao ROS2 e suas funcionalidades através do terminal/cmd.
Neste contexto, a partir desta aula, começaremos a aprender sobre os fundamentos do Robot Operating System, entendendo como se dá seu funcionamento básico, o que são os nós (nodes), como os nós trocam dados entre si (tópicos, serviços, etc.), quais ferramentas elementares o ROS disponibiliza, dentre diversas outros conceitos. O intuito é fazer uma aula expositiva aliada à pratica, introduzindo os conceitos e concomitantemente praticando seu funcionamento no terminal.

O que é o ROS 2

Como discutido nas aulas introdutórias, um robô pode ser visto como um sistema constituído de sensores, atuadores e elementos de computação que devem se comunicar para funcionar de maneira coordenada a fim de atingir os objetivos da missão do robô. Para ilustrar, veja a seguir o vídeo de um robô humanóide da Boston Dynamics.
No vídeo acima, percebe-se que o robô humanóide deve, ciclicamente, capturar de forma correta os dados provenientes de seus sensores, tratá-los e utilizá-los como insumo para seus algoritmos de controle e navegação e, então, calcular e enviar comandos adequados a seus atuadores. Assim, diversos algoritmos devem estar em execução simultâneamente, como por exemplo, algoritmos de comunicação com drivers e captura de dados, filtros de dados, algoritmos de SLAM (Simultaneous Localization and Mapping), modelos de Reinforcement Learning, leis de controle, módulos de comunicação, etc. Além disto, é essencial ao funcionamento do sistema que estes diversos algoritmos sejam capazes de trocar dados entre si de maneira eficiente e robusta, a fim de viabilizar a coordenação de todo o sistema.
Fig. 1 —
Exemplo ilustrativo de como os módulos funcionais de um robô humanóide poderiam ser organizados no ROS.
É neste contexto que entra o Robot Operating System (ROS), que pode ser definido como um conjunto de infraestrutura e aplicações que dão suporte e facilitam a implementação de softwares para robôs, tendo como filosofia principal a modularização das diversas aplicações e funcionalidades do robô em microsserviços que trocam dados entre si. Como exemplo ilustrativo (veja ), o robô humanoide do vídeo poderia ter em execução simultânea um módulo que se comunica com os dispositivos-sensores para coletar seus dados, outro para gerar o mapa do ambiente e localizar o robô nele (Simultaneous Localization and Mapping - SLAM), um nó para controle de equilíbrio do corpo do robô e um módulo que recebe os sinais de controle dos modelos e envia os comandos de atuação para os drivers dos motores.
Assim, o problema central que o ROS resolve é o de desacoplar o software de um robô em módulos independentes (nós/nodes) que conversam entre si, facilitando assim a implementação de um sistema distribuído, onde cada algoritmo em execução é uma unidade autônoma de processamento capaz de trocar dados com as demais.
Neste framework, os algoritmos de cada módulo podem ser escrito por pessoas diferentes, em linguagens diferentes, e mesmo assim serem executados no mesmo sistema, trocando dados entre si e podendo ser reiniciados/alterados sem afetar os demais.
Dica
Uma analogia seria pensar no robô como em um navio, onde os diversos tripulantes são os nós e o ROS é a infraestrutura que permite com que eles troquem informações entre si. Para o navio alcançar um destino, é necessário um cartógrafo para estimar a posição do navio e definir sua rota, comunicar esta informação para o capitão que, baseado em regras de navegação, envia comandos de direcionamento e alteração de velocidade do navio para o piloto, que então as executa. Nota-se então que cada tripulante é especialista em sua função, necessitando porém de haver comunicação de informações entre os tripulantes para que o navio funcione de forma adequada.

Arquitetura básica

Apesar de seu nome, o ROS não é um sistema operacional no sentido estrito. De fato, o ROS roda sobre um sistema operacional existente, sendo o principal deles o Linux e, com diferentes níveis de suporte, também o Windows e o macOS.
Em essência, o ROS é um conjunto de quatro coisas (veja ):
  • um middleware de comunicação, que viabiliza tecnicamente e facilita a troca síncrona e assíncrona de dados entre os diversos nós (módulos de algoritmos);
  • um conjunto de bibliotecas que implementam as estruturas básicas e mais usuais na implementação de sistemas robóticos;
  • um conjunto de ferramentas que facilitam diversos aspectos na implementação de sistemas robóticos (e.g., ferramentas de depuração, diagnóstico, visualização espacial, simulação dinâmica, etc.);
  • uma comunidade com convenções compartilhadas, que compartilham entre si soluções já prontas para diversos problemas robóticos (e.g., manipulação, navegação, mapeamento, etc.).
Fig. 2 —
Robot Operating System e seus quatro pilares.
Também é importante saber o o ROS não é. O ROS 2 não é, por si só, um sistema de tempo real: o comportamento temporal depende da configuração do sistema operacional base sobre o qual ele roda e do código dos nós implementados. Assim, ele não substitui naturalmente o controle de baixo nível que roda nos microcontroladores do robô (a malha de corrente de um motor, por exemplo).
Considerando o exposto, nota-se então que o ROS é uma camada de aplicação incorporada aos níveis mais altos de um sistema robótico. A ilustra uma arquitetura típica de sistemas robóticos que embarcam o Robot Operating System.
Fig. 3 —
Diagrama de arquitetura típica em camadas de robô equipado com o ROS.

Por que usar o ROS 2?

Antes do ROS, cada projeto de robótica reinventava drivers, protocolos de comunicação e ferramentas de depuração. Com ele, os roboticistas passaram a reaproveitar infraestruturas e ferramentas comuns a aplicações robóticas, dispondo assim de mais tempo para desenvolver o que é realmente novo em seu robô . Os principais argumentos para se utilizar o ROS são:
  • Modularidade e reuso: como exemplo, um driver de uma câmera específica escrito uma vez serve a todos os demais robôs que vão utilizar aquela mesma câmera.
  • Comunidade e ecossistema: existem diversos pacotes prontos para utilização que oferecem desde funcionalidades básicas às mais avançadas(como o Nav2 para navegação e o MoveIt 2 para manipulação.
  • Ferramentas: rqt, RViz2, gravação de dados (bags) e arquivos de launch aceleram a depuração e o desenvolvimento dos sistemas robóticos.
  • Independência de linguagem: os nós podem ser escritos em C++ e Python, sendo que a comunicação entre eles ocorre de forma seamless.
  • Relevância acadêmica e industrial: é uma competência requisitada tanto nas áreas de pesquisa quanto em empresas de robótica.
Em contrapartida, o ROS 2 também pode ser um exagero, a depender das especificadas do robô a ser implementado. Em sistemas muito simples a infraestrutura do ROS 2 adiciona complexidade sem trazer benefício proporcional . Por exemplo, um microcontrolador que lê um sensor e aciona um motor, sem precisar se comunicar com outros módulos, é um tipo de aplicação onde o ROS seria um overkill. Antes de criar um sistema robótico, vale a pergunta: "esse sistema tem vários módulos que precisam trocar dados, ou será reaproveitado em outros robôs?". Se a resposta for não, talvez uma solução mais enxuta seja melhor.

ROS 1 versus ROS 2

O ROS surgiu no fim dos anos 2000, em laboratórios de pesquisa, e se consolidou ao longo da década seguinte como a principal plataforma de software para robótica . Com o tempo, porém, ficaram evidentes algumas limitações de sua arquitetura original, pensada para robôs de pesquisa, operando em uma única máquina ou em uma rede bem comportada, e sem requisitos rígidos de confiabilidade ou segurança. O ROS 2 foi concebido como uma reescrita profunda para superar tais limitações e atender também a aplicações comerciais e industriais .
Hoje, a primeira geração passou a ser chamada de ROS 1 e chegou ao fim de vida com a distribuição Noetic, em 2025. Isto significa que ela não recebe mais atualizações nem correções, e a comunidade migrou para o ROS 2, que é o foco de todo este módulo. As principais diferenças entre as duas gerações estão resumidas a seguir.
AspectoROS 1ROS 2
CoordenaçãoMestre central (roscore)Descoberta distribuída, sem mestre
ComunicaçãoProtocolos próprios (TCPROS/UDPROS)DDS, padrão de mercado
Qualidade de serviçoNão configurávelQoS configurável (Quality of Service)
Sistemas operacionaisPraticamente apenas LinuxLinux, Windows e macOS, com diferentes níveis de suporte
LinguagensC++ e Python (2 e 3)C++ e Python 3
SegurançaSem mecanismo nativoSROS2
Ciclo de vida dos nósNão previstoNós gerenciados (lifecycle)
MultirrobôDifícil, pois depende de um único mestreFacilitado por domínios e namespaces
Situação atualFim de vida (Noetic, 2025)Desenvolvimento ativo (Lyrical, LTS de 2026)
Dentre estas diferenças, a mais sentida no dia a dia é a ausência do roscore. No ROS 1, era obrigatório manter em execução um processo central, responsável por registrar os nós e apresentá-los uns aos outros. Se ele fosse encerrado, o sistema perdia a capacidade de estabelecer novas conexões. No ROS 2 não há mestre: os nós se descobrem mutuamente de forma automática e distribuída, e o sistema não possui mais um único ponto de falha desse tipo. Outra diferença importante é que a comunicação passou a ser baseada no DDS, o que traz consigo a possibilidade de configurar a qualidade de serviço de cada canal de comunicação, assunto que retomaremos na Aula 2.
Atenção
Boa parte dos tutoriais, vídeos e respostas de fóruns disponíveis na internet ainda se refere ao ROS 1. Desconfie quando encontrar comandos como roscore, rosrun, roslaunch, rostopic ou catkin_make. No ROS 2, os equivalentes são, respectivamente, ros2 run, ros2 launch, ros2 topic e colcon build. Sempre confira a qual distribuição o material se refere.

ROS 2 Distros

Ao longo desta aula já falamos várias vezes em "Lyrical", "Jazzy" e "Humble". Vale então entender o que são estes nomes. Uma distribuição (distro) do ROS 2 é um conjunto versionado e coerente de pacotes (o núcleo do ROS 2, bibliotecas, ferramentas e pacotes de apoio) que foram compilados e testados juntos para funcionarem bem uns com os outros. Em outras palavras, escolher uma distro é escolher "qual ROS 2" você vai usar, e é por isso que o nome dela aparece em caminhos como /opt/ros/lyrical, em pacotes como ros-lyrical-desktop e na variável de ambiente ROS_DISTRO.

Ritmo de lançamento

O ROS 2 segue um calendário de lançamentos regular . Nos primeiros anos, as distribuições saíam a cada seis meses, mas desde a Foxy o ritmo se estabilizou em uma nova distro por ano, publicada em maio, por volta do Dia Mundial da Tartaruga (23 de maio). As distribuições alternam entre dois tipos de suporte:
  • LTS (Long Term Support), lançadas em anos pares e com suporte de cerca de 5 anos, como a Humble, a Jazzy e a Lyrical;
  • Regulares, lançadas em anos ímpares e com suporte curto, em geral de cerca de um ano e meio, como a Iron e a Kilted.
Além das distribuições numeradas por nome, existe também a Rolling, uma distribuição contínua que reúne o desenvolvimento mais recente. Ela é útil para quem desenvolve o próprio ROS 2, mas não é indicada para quem precisa de estabilidade.
Dica
Para um robô de produção, ou para um curso como este, prefira sempre uma distro LTS. Ela recebe correções por mais tempo e a documentação, os tutoriais e os pacotes de terceiros a acompanham por mais tempo.

Compatibilidade com sistemas operacionais

Cada distro é desenvolvida e testada tendo como alvo principal uma versão LTS do Ubuntu. É por isso que a Lyrical aponta para o Ubuntu 26.04, a Jazzy para o 24.04 e a Humble para o 22.04. As versões regulares do Ubuntu não são alvo porque têm apenas nove meses de suporte. Além do Ubuntu, a documentação de cada distro lista outras plataformas com suporte oficial, como o Windows, e outras com suporte mantido pela comunidade, como o macOS. O nível de suporte varia de uma distro para outra e por isso deve ser consultado na página de cada uma .
Atenção
Instalar uma distro em uma versão do Ubuntu diferente da prevista costuma não funcionar. Se você estiver em um Ubuntu mais antigo, a saída é usar um contêiner Docker com a distro desejada, como vimos na aula de instalação.

A lógica dos nomes

O nome de uma distro segue uma regra simples: ele é composto por um adjetivo seguido do nome de uma tartaruga (um gênero, uma espécie ou um nome popular), ambos começando com a mesma letra, e as letras seguem a ordem alfabética a cada lançamento: Ardent Apalone (A), Bouncy Bolson (B), Crystal Clemmys (C), e assim por diante até a atual Lyrical Luth (L). A próxima será, portanto, a de letra M. O nome é escolhido pela pessoa que lidera o lançamento (o ROS Boss), a partir de uma discussão aberta com a comunidade no fórum Open Robotics Discourse, levando em conta fatores como conflitos de marca, duplos sentidos indesejados e facilidade de pronúncia. A tabela de lançamentos também registra o ROS Boss de cada distro .
A tartaruga é um tema recorrente no ROS e costuma ser associada ao turtlesim, o simulador que usaremos na próxima aula, que por sua vez homenageia a tartaruga da linguagem de programação Logo.

Mascotes e curiosidades

Cada distro ganha também um mascote, uma ilustração encomendada a um artista a partir do nome escolhido. Os mascotes estampam camisetas, adesivos e outros brindes da comunidade e são sempre uma boa forma de reconhecer, de relance, de qual distro se trata. Algumas curiosidades:
  • Lyrical Luth: em francês, luth é tanto a tartaruga-de-couro (tortue luth) quanto o alaúde. O mascote da nossa distro é uma tartaruga tocando um instrumento de cordas, cercada de águas-vivas, que são justamente o principal alimento das tartarugas-de-couro.
  • Foxy Fitzroy: o nome remete à tartaruga-do-rio-Fitzroy, uma espécie australiana.
  • Humble Hawksbill: hawksbill é o nome em inglês da tartaruga-de-pente.
  • Nomes científicos: Apalone (Ardent), Elusor (Eloquent) e Geochelone (Galactic) são nomes de gêneros de tartarugas, o que mostra que a escolha envolve também certa pesquisa em zoologia.

Todas as distribuições do ROS 2

A tabela a seguir reúne todas as distribuições do ROS 2 lançadas até hoje, com os respectivos mascotes oficiais, as datas de lançamento e de fim de suporte (EOL, End of Life) e o Ubuntu alvo de cada uma.
MascoteDistribuiçãoLançamentoFim de suporte (EOL)UbuntuTipo
Mascote do ROS 2 Ardent ApaloneArdent Apalone8 dez 2017dez 201816.04Regular
Mascote do ROS 2 Bouncy BolsonBouncy Bolson2 jul 2018jul 201918.04Regular
Mascote do ROS 2 Crystal ClemmysCrystal Clemmys14 dez 2018dez 201918.04Regular
Mascote do ROS 2 Dashing DiademataDashing Diademata31 mai 2019mai 202118.04LTS
Mascote do ROS 2 Eloquent ElusorEloquent Elusor22 nov 2019nov 202018.04Regular
Mascote do ROS 2 Foxy FitzroyFoxy Fitzroy5 jun 202020 jun 202320.04LTS
Mascote do ROS 2 Galactic GeocheloneGalactic Geochelone23 mai 20219 dez 202220.04Regular
Mascote do ROS 2 Humble HawksbillHumble Hawksbill23 mai 2022mai 202722.04LTS
Mascote do ROS 2 Iron IrwiniIron Irwini23 mai 20234 dez 202422.04Regular
Mascote do ROS 2 Jazzy JaliscoJazzy Jalisco23 mai 2024mai 202924.04LTS
Mascote do ROS 2 Kilted KaijuKilted Kaiju23 mai 2025dez 202624.04Regular
Mascote do ROS 2 Lyrical LuthLyrical Luth22 mai 2026mai 203126.04LTS
Logos e datas conforme a documentação oficial do ROS 2 . As distribuições com EOL já passado não recebem mais atualizações.

ROS 2 Distributions

Página oficial com as distribuições do ROS 2, suas datas de lançamento, EOL e plataformas suportadas.


Arquitetura conceitual do ROS 2

Até aqui, vimos que o ROS 2 organiza o software de um robô em módulos que conversam entre si. Vamos agora dar nome a cada elemento desta organização.
Inspirado no conteúdo de Renard , apresentaremos os conceitos, acompanhados de uma analogia e, em seguida, verificaremos seu funcionamento no terminal.

Nós (nodes)

Um nó é um processo que executa uma função específica dentro do sistema, como ler um sensor, estimar a posição do robô ou calcular uma lei de controle. É a unidade básica de execução do ROS e, na analogia do navio, é o tripulante com sua tarefa bem definida. Cada nó possui um nome, que o identifica no sistema, e pode ser escrito em Python ou C++.
Os nós são distribuídos em pacotes (packages), que são a unidade de organização e distribuição de software no ROS. Por exemplo, os nós talker e listener que usaremos ainda nesta aula fazem parte dos pacotes demo_nodes_cpp e demo_nodes_py, instalados junto com o ROS 2.
A animação a seguir (), extraída do tutorial oficial do ROS 2 sobre nós, ilustra esta ideia: um conjunto de nós trocando dados entre si, onde as conexões entre eles são tópicos e serviços, que veremos nas próximas seções.
Animação de nós do ROS 2 se comunicando por tópicos e serviços
Fig. 4 —
Nós do ROS 2 trocando dados por meio de tópicos e serviços. Fonte: ROS 2 Documentation (Foxy) — Understanding ROS 2 nodes, Open Robotics, licenciado sob CC BY 4.0.

Tópicos (topics) e mensagens

Um tópico é um canal de comunicação do tipo publicar/assinar (publish/subscribe) e possui um nome-identificador único. Os nós que geram dados para um tópico são os publicadores (publishers); em contrapartida, os que os consomem estes dados são os assinantes (subscribers). A comunicação é assíncrona e desacoplada: quem publica não sabe quem está recebendo, e quem assina não sabe quem está publicando. Um mesmo tópico pode ter vários publicadores e vários assinantes. A analogia aqui é a de uma estação de rádio ou de um quadro de avisos: quem quiser, sintoniza.
O tutorial oficial do ROS 2 apresenta o modelo de publicar/assinar por meio de animações. Na , um único nó publica dados em um tópico e outro nó os recebe. Já na , o mesmo tópico recebe dados de vários publicadores e os entrega a vários assinantes, sem que nenhum deles precise conhecer os demais.
Animação de um publicador enviando mensagens a um assinante por um tópico
Fig. 5 —
Um publicador e um assinante em um tópico. Fonte: ROS 2 Documentation (Foxy) — Understanding ROS 2 topics, Open Robotics, licenciado sob CC BY 4.0.
Animação de vários publicadores e vários assinantes em um mesmo tópico
Fig. 6 —
Vários publicadores e vários assinantes no mesmo tópico. Fonte: ROS 2 Documentation (Foxy) — Understanding ROS 2 topics, Open Robotics, licenciado sob CC BY 4.0.
Todo tópico possui um nome-identificador único na rede ROS (por exemplo, /chatter) e um tipo de mensagem . A mensagem (message) é a estrutura de dados que trafega no tópico, ou seja, o conteúdo do aviso. O tipo da mensagem é identificado pelo formato pacote/msg/Nome, como em std_msgs/msg/String. Só é possível conectar publicadores e assinantes que usem o mesmo tipo de mensagem.
Como exemplo de tipo de mensagem, veja a definição de geometry_msgs/msg/Twist, que é uma mensagem padrão do ROS2:
bash
# Expressa a velocidade no espaço livre dividida em partes linear e angular.
geometry_msgs/Vector3 linear
	float64 x
	float64 y
	float64 z
geometry_msgs/Vector3 angular
	float64 x
	float64 y
	float64 z
Para visualizá-la em seu terminal, simplesmente digite:
bash
ros2 interface show geometry_msgs/msg/Twist

Serviços (services)

Um serviço implementa uma comunicação do tipo requisição/resposta (request/response). Um nó cliente envia uma requisição e aguarda a resposta do nó servidor, que a processa e a devolve. Do ponto de vista do cliente, a chamada é síncrona, e por isso os serviços são adequados a tarefas curtas. A analogia é uma ligação telefônica: pergunta e resposta. O tipo de um serviço tem o formato pacote/srv/Nome e descreve tanto a requisição quanto a resposta.
Para visualizar a diferença em relação aos tópicos, observe a , extraída do tutorial oficial: o cliente envia uma requisição e o servidor devolve uma única resposta, e só. Diferentemente de um tópico, o serviço só trabalha quando é chamado. N Na vemos que um mesmo servidor pode atender a vários clientes, mas sempre existe um único servidor para cada serviço.
Animação de um cliente enviando uma requisição a um servidor de serviço e recebendo a resposta
Fig. 7 —
Requisição e resposta entre um cliente e um servidor de serviço. Fonte: ROS 2 Documentation (Foxy) — Understanding ROS 2 services, Open Robotics, licenciado sob CC BY 4.0.
Animação de vários clientes chamando o mesmo servidor de serviço
Fig. 8 —
Vários clientes chamando o mesmo servidor de serviço. Fonte: ROS 2 Documentation (Foxy) — Understanding ROS 2 services, Open Robotics, licenciado sob CC BY 4.0.

Ações (actions)

Uma ação serve para tarefas de longa duração, em que o cliente precisa acompanhar o andamento e, eventualmente, cancelar a tarefa. Além do objetivo (goal) e do resultado (result), a ação oferece um canal de acompanhamento contínuo, o feedback. A analogia é a de uma encomenda com rastreio de entrega: você faz o pedido, recebe atualizações enquanto ela viaja e pode cancelá-la antes da entrega. O tipo de uma ação tem o formato pacote/action/Nome.
A , também do tutorial oficial, mostra o ciclo de uma ação: o cliente envia o objetivo, o servidor o aceita, informa o progresso por meio do feedback durante a execução e, ao final, devolve o resultado. Internamente, as ações são construídas sobre tópicos e serviços.
Animação de um cliente de ação enviando um objetivo, recebendo feedback e o resultado final
Fig. 9 —
Ciclo de uma ação: objetivo, feedback e resultado. Fonte: ROS 2 Documentation (Foxy) — Understanding ROS 2 actions, Open Robotics, licenciado sob CC BY 4.0.

Parâmetros (parameters)

Um parâmetro é um valor de configuração pertencente a um nó, como um ganho de controlador ou a taxa de amostragem de um sensor. Cada parâmetro possui um nome e um tipo, e pode ser lido e alterado enquanto o nó está em execução, sem recompilar o código. É o painel de configurações de um aparelho.

Grafo de computação

Ao conjunto de nós em execução e das conexões entre eles (através de tópicos, serviços, etc) damos o nome de grafo de computação (computation graph) da rede ROS. Este grafo é o mapa da rede e que atualiza em tempo real, e.g., sempre que um nó é criado, ou uma comunicação por tópico é estabelecida/removida, o grafo é atualizado dinamicamente.
Considere um exemplo simplificado do código de exemplo do turtlesim na . Neste exemplo, perceba que existe o nó teleop_turtle que publica mensagens no tópico /turtle1/cmd_vel, que é por sua vez consumida pelo nó turtlesim.
Fig. 10 —
Exemplo do grafo de computação da rede ROS obtida utilizando a ferramenta rqt_graph para o exemplo de teleoperação do turtlesim. Fonte: Visualizing the ROS Graph with rqt_graph, Robot Software Practicals (RO47003) team.
No ROS2, existe a ferramenta nativa rqt_graph que permite visualizar o grafo de comunicação do sistema do robô. Para executá-la, basta rodar no terminal:
bash
ros2 run rqt_graph rqt_graph

Qual paradigma usar?

Uma vez conhecidos os quatro mecanismos de troca de dados entre os nós, a pergunta natural é qual deles escolher em cada situação. Os critérios mais úteis são a continuidade do fluxo de dados, a necessidade de uma resposta e a duração da tarefa. A tabela a seguir pode ser utilizada como referência para se inferir qual tipo de estrutura utilizada para uma comunicação em específico:
ParadigmaQuando usarExemplo
TópicoFluxo contínuo de dados, sem respostaLeitura de um sensor, comando de velocidade
ServiçoPergunta pontual com resposta imediata"Qual o nível da bateria?", "Zere a odometria"
AçãoTarefa demorada, com acompanhamento e possibilidade de cancelamento"Navegue até a sala 3"
ParâmetroConfiguração de um nóGanho do controlador, taxa de amostragem
Exercício 5·Classificando situações
Classifique cada situação abaixo como tópico, serviço ou ação: (a) leitura de uma IMU a 100 Hz; (b) comando de habilitar/desabilitar o motor; (c) comando para "ir até o ponto X", com informação do progresso.
Pergunte-se: o dado é contínuo? Existe uma resposta imediata? A tarefa demora e precisa ser acompanhada?
(a) Tópico, pois é um fluxo contínuo de dados. (b) Serviço, pois é um comando pontual que se espera ter uma confirmação como resposta. (c) Ação, pois é uma tarefa longa, com feedback de progresso e possibilidade de cancelamento.

DDS, RMW e distribuições

Por baixo de tudo o que vimos até aqui existe uma camada que efetivamente transporta os dados de um nó a outro. Não é necessário dominá-la para usar o ROS 2, mas conhecer o seu papel ajuda a entender o comportamento do sistema e a diagnosticar problemas.

DDS e a camada RMW

O DDS (Data Distribution Service) é um padrão de comunicação do tipo publicar/assinar, amplamente utilizado na indústria, sobre o qual o ROS 2 foi construído . O ROS 2 não obriga você a programar diretamente em DDS: ele o esconde atrás de uma camada de abstração chamada RMW (ROS Middleware Interface). Graças a ela, o mesmo código de um nó funciona com diferentes implementações de middleware. A pilha de camadas pode ser resumida como:
text
Seu código (rclpy / rclcpp)
        │
       rcl
        │
       RMW
        │
DDS (Fast DDS)
        │
      rede
Na Lyrical, a implementação padrão é o Fast DDS (rmw_fastrtps_cpp) . Existem alternativas, como o Cyclone DDS, que podem ser selecionadas por meio da variável de ambiente RMW_IMPLEMENTATION (por exemplo, rmw_cyclonedds_cpp), sem alterar uma linha do código dos nós. Detalhes sobre as camadas RMW e RCL, os fornecedores de DDS e as opções de configuração podem ser encontrados em Joseph e Cacace .

Descoberta automática e ROS_DOMAIN_ID

Uma consequência direta do uso do DDS é a descoberta automática: nós executados na mesma rede e com o mesmo domínio se enxergam sem nenhuma configuração adicional de endereços ou portas. O domínio é definido pela variável de ambiente ROS_DOMAIN_ID, que assume valores inteiros (em geral, de 0 a 101) e cujo padrão é 0. Nós em domínios diferentes simplesmente não se enxergam, como se estivessem em redes separadas.
Isto é muito conveniente, mas tem um efeito colateral em sala de aula: se todas as máquinas do laboratório estiverem no mesmo domínio, os nós de uma dupla serão vistos pelas demais, e mensagens "estranhas" aparecerão nos seus terminais. Para contornar este problema, cada aluno/grupo deve definir um ROS_DOMAIN_ID diferente como variável ambiente de seu terminal.

Prática: verificando o ambiente e explorando a linha de comando

Chegou a hora de ir para o terminal. À medida que forem realizando os exercícios, sugerimos que crie um arquivo CHEAT-CHEET.md em seu computador, onde você pode ir anotando os principais comandos utilizados a fim de reutilizá-los de maneira simplificada em momento futuro.
Dica
Você precisará de vários terminais abertos ao mesmo tempo. Se estiver no Ubuntu, ferramentas como o Terminator ou o tmux permitem dividir uma janela em vários painéis e ajudam bastante. Se estiver usando Docker, abra um novo terminal no mesmo contêiner com docker exec -it nome_do_container bash, substituindo pelo nome do seu contêiner.

Prática 1: o ritual do terminal

O erro mais comum em todo o módulo é esquecer de carregar o ambiente do ROS 2 em um terminal. Para entender o porquê, abra um terminal novo e execute:
bash
ros2 --help
Se a ajuda do comando for exibida, o seu .bashrc já carrega o ambiente automaticamente, como configurado na instalação. Caso apareça a mensagem ros2: command not found, o terminal ainda não conhece o ROS 2. Resolva carregando o ambiente com o comando source e verifique as variáveis definidas:
bash
source /opt/ros/lyrical/setup.bash  # carrega o referente arquivo na memória do terminal
printenv | grep -i ROS  # printa variáveis de ambiente do terminal e filtra (grep) pelas que possuem 'ROS' em seu nome
A saída deve conter, entre outras, as seguintes linhas:
text
ROS_VERSION=2
ROS_PYTHON_VERSION=3
ROS_DISTRO=lyrical
AMENT_PREFIX_PATH=/opt/ros/lyrical
O comando source lê o arquivo setup.bash e carrega, no terminal atual, variáveis de ambiente como PATH, AMENT_PREFIX_PATH e ROS_DISTRO. Observe que isto vale apenas para aquele terminal: cada terminal novo precisa repetir o processo. Para automatizá-lo, a linha de source é adicionada ao final do arquivo ~/.bashrc, que é executado sempre que um terminal é aberto .
Em seguida, defina o domínio da sua bancada. Use um número aleatório, de modo que cada aluno/grupo utilize um valor diferente:
bash
export ROS_DOMAIN_ID=10 # cria uma nova variável de ambiente definida na memória do terminal
echo "export ROS_DOMAIN_ID=10" >> ~/.bashrc # salva no .bashrc a nova variável de ambiente de maneira a ser carregada automaticamente nas próximas aberturas de terminal.
Atenção
Os erros mais frequentes nesta etapa são: esquecer o source em um terminal novo; digitar o caminho com a distribuição errada (por exemplo, jazzy no lugar de lyrical); e usar um ROS_DOMAIN_ID repetido entre bancadas, o que faz aparecerem mensagens vindas de outras duplas.
Caso o seu ambiente ainda não esteja funcionando, chame o professor durante o plantão de instalação. Existem alternativas de contingência, como uma imagem Docker pronta ou uma máquina virtual.

Prática 2: talker e listener

Com o ambiente funcionando, vamos fazer dois nós se comunicarem. O ROS 2 já vem com nós de demonstração: o talker, que publica mensagens de texto periodicamente, e o listener, que as assina e as exibe. Em um terminal, execute o talker escrito em C++:
bash
ros2 run demo_nodes_cpp talker
Em um segundo terminal, também com o ambiente carregado, execute o listener escrito em Python:
bash
ros2 run demo_nodes_py listener
O primeiro terminal exibirá mensagens como Publishing: 'Hello World: 1' e o segundo, mensagens como I heard: [Hello World: 1]. A estrutura do comando é ros2 run pacote executável, ou seja, ele executa o programa indicado que pertence ao pacote indicado.
Agora, faça algumas variações:
  1. Encerre o talker com Ctrl+C e observe que o listener "se cala", mas continua em execução. Execute o talker novamente e note que as mensagens voltam a chegar.
  2. Troque o talker em C++ por um talker em Python (ros2 run demo_nodes_py talker). O listener continua recebendo as mensagens normalmente. Isto evidencia a interoperabilidade entre linguagens.
  3. Em um terceiro terminal, defina um domínio diferente (por exemplo, export ROS_DOMAIN_ID=11) e execute o listener. Ele não receberá nada, pois não enxerga o talker que está em outro domínio. Em seguida, encerre-o e volte ao seu domínio.
Repare que em nenhum momento configuramos endereço IP, porta ou quem fala com quem. O ROS 2 fez a descoberta sozinho.

Prática 3: investigando com a linha de comando

Mantenha o talker e o listener em execução e abra um novo terminal. O ROS 2 disponibiliza o comando ros2, com diversos subcomandos para inspecionar um sistema em execução. Vamos começar com os nós e os tópicos:
bash
ros2 node list
ros2 node info /talker
ros2 topic list
ros2 topic list -t
ros2 topic echo /chatter
ros2 topic info /chatter
ros2 topic hz /chatter
O comando ros2 node list lista os nós ativos e ros2 node info detalha um deles, mostrando os tópicos que o nó publica e assina, além dos serviços e ações que ele oferece. A saída é semelhante a esta (abreviada):
text
/talker
  Subscribers:
    /parameter_events: rcl_interfaces/msg/ParameterEvent
  Publishers:
    /chatter: std_msgs/msg/String
    /parameter_events: rcl_interfaces/msg/ParameterEvent
    /rosout: rcl_interfaces/msg/Log
  ...
Os tópicos /parameter_events e /rosout são criados automaticamente pelo ROS 2 para notificar alterações de parâmetros e para o registro de mensagens de log. Já o ros2 topic list -t exibe também o tipo de cada tópico, e o ros2 topic echo mostra as mensagens que estão trafegando. Os comandos info e hz informam, respectivamente, o tipo e as quantidades de publicadores e assinantes, e a frequência de publicação.
O tipo das mensagens do /chatter é o std_msgs/msg/String. Para ver a sua estrutura, use:
bash
ros2 interface show std_msgs/msg/String
Dica
O comando ros2 possui autocompletar. Digite ros2 seguido de espaço e pressione a tecla Tab duas vezes para ver os subcomandos disponíveis. Isto vale também para nomes de nós, tópicos e tipos de mensagem, e economiza muita digitação.
Exercício 6·Lendo o sistema
Com o talker e o listener em execução, responda: quantos nós existem? Quem publica em /chatter? Qual é o tipo da mensagem? Qual é a frequência de publicação?
Use ros2 node list, ros2 node info /talker, ros2 topic info /chatter e ros2 topic hz /chatter.
Existem dois nós, /talker e /listener. Quem publica em /chatter é o /talker (e o /listener o assina). O tipo da mensagem é std_msgs/msg/String. A frequência é de aproximadamente 1 Hz.

Prática 4: mini-desafio do grafo

Para encerrar a parte prática, obtenha o grafo do sistema que você acabou de executar: os nós, os tópicos e o sentido das setas (de quem publica para quem assina). Depois, compare o seu desenho com o gerado pelo próprio ROS 2, executando em um novo terminal:
bash
ros2 run rqt_graph rqt_graph

Conclusão

Nesta aula, vimos que:
  • o ROS 2 não é estritamente um sistema operacional, mas sim um conjunto de middleware, bibliotecas, ferramentas e comunidade;
  • o software do robô é organizado em nós, que trocam dados por tópicos, serviços e ações e são configurados por parâmetros;
  • o DDS, acessado por meio da camada RMW, é responsável por transportar os dados, e o ROS_DOMAIN_ID separa grupos de nós que não devem se enxergar;
  • a distribuição adotada, a Lyrical, é do tipo LTS;
  • todo terminal novo precisa carregar o ambiente com o source.

Para aprofundar

Se deseja se aprofundar ainda mais no assunto, leia o capítulo 3 de Renard , até a seção sobre tópicos, e o capítulo 2 de Joseph e Cacace , páginas 57 a 71.
Na próxima aula, utilizaremos o simulador turtlesim para explorar na prática tópicos, serviços, ações e parâmetros. Para isso, é essencial que você venha com o ambiente funcionando.

Referências

  1. Renard, E. (2024). ROS 2 from Scratch. Packt Publishing.
  2. Open Robotics. (2026). ROS 2 Documentation: Lyrical Luth — Release notes. https://docs.ros.org/en/lyrical/Releases/Release-Lyrical-Luth.html
    https://docs.ros.org/en/lyrical/Releases/Release-Lyrical-Luth.html
  3. Joseph, L., & Cacace, J. (2025). Mastering ROS 2 for Robotics Programming: design, build, simulate, and prototype complex robots using the Robot Operating System 2 (4th ed.). Packt Publishing.

Autor: FILIPE A. S. ROCHA

Publicado em 19 de outubro de 2026· Atualizado em 20 de outubro de 2026