Conteúdo detalhado
🧠 O que é o ROS 2 e por que usar
Até a Trilha 3, o robô era um ou dois programas que você escrevia inteiros. Quando entram LiDAR, mapa, câmera e navegação, um programa só vira um nó impossível de manter. O ROS 2 (Robot Operating System 2) resolve isso: cada tarefa vira um programa pequeno, e todos trocam dados por nome, sem saber quem está do outro lado nem em qual computador. Apesar do nome, ele não é um sistema operacional: roda em cima do Linux, como um conjunto de bibliotecas e ferramentas.
🌱 Novo aqui?
Middleware é o software "do meio": fica entre os seus programas e a rede e cuida de entregar as mensagens. No ROS 2 esse papel é do DDS (Data Distribution Service), um padrão industrial que descobre sozinho quem publica e quem assina cada dado. Um pacote é a unidade de código que você instala ou escreve: um driver de LiDAR, o Nav2, o seu robô.
Como ler: cada caixa âmbar é um programa independente (um nó). Nenhum fala direto com o outro: todos se ligam à faixa ciano. A navegação pede "/scan" e recebe do driver do LiDAR sem saber quem ele é. A caixa tracejada está em outro computador da rede e participa do mesmo jeito.
✓ Use ROS 2 quando
- ✓O robô tem LiDAR, mapa ou navegação.
- ✓Há mais de um computador (Pi, PC, ESP32) trabalhando junto.
- ✓Você quer simular antes de montar.
✗ Não precisa de ROS 2 para
- ✗Seguidor de linha ou rover que desvia (Trilhas 1 e 2).
- ✗Um ESP32 sozinho, sem computador por perto.
- ✗Um protótipo de fim de semana com um sensor só.
Por que aprender
O ROS 2 é o idioma comum da robótica de pesquisa e de boa parte da indústria. Aprendendo o básico, você passa a usar de graça drivers de sensores, o slam_toolbox para mapas e o Nav2 para navegação, em vez de escrever tudo do zero.
Conceitos-chave
📅 Qual distro: Lyrical ou Jazzy
O ROS 2 sai em distribuições (distros) com nome de tartaruga, uma por ano. As de número par, lançadas em maio, são LTS (suporte longo, cinco anos) e casam com uma versão LTS do Ubuntu. Em outubro de 2026 há duas boas escolhas: Lyrical Luth, lançada em 22/05/2026 para o Ubuntu 26.04 e suportada até maio de 2031, e Jazzy Jalisco, a LTS anterior, para o Ubuntu 24.04, suportada até 2029 e com mais tutoriais e pacotes prontos.
Como ler: cada barra é o período em que a distro recebe correções. A linha ciano é hoje. A Humble (cinza tracejada) acaba em menos de um ano: não comece por ela. Jazzy e Lyrical cobrem você por anos; cada uma traz o Ubuntu e o Gazebo do mesmo par.
| Se você... | Escolha |
|---|---|
| vai começar do zero hoje, em um PC novo | Lyrical (Ubuntu 26.04, Gazebo Jetty) |
| segue um tutorial, livro ou robô que pede Jazzy | Jazzy (Ubuntu 24.04, Gazebo Harmonic) |
| precisa de um pacote que ainda não saiu para Lyrical | Jazzy, ou Lyrical em Docker para testar |
| tem um projeto antigo em Humble | Planeje migrar para Jazzy antes de maio/2027 |
🌱 Novo aqui?
Neste curso os comandos usam <distro> como parte variável: troque por lyrical ou jazzy, sempre em minúsculas. Exemplo: source /opt/ros/jazzy/setup.bash. O resto do comando é igual nas duas.
Por que aprender
A maioria dos "não funciona" em ROS vem de mistura: tutorial de uma distro, pacote de outra, Gazebo de uma terceira. Decidir a distro no começo e manter o par Ubuntu ↔ ROS ↔ Gazebo evita esse tipo de defeito.
Conceitos-chave
📦 Instalar (Ubuntu, Docker ou Pi)
Há três caminhos. No Ubuntu (no PC ou numa máquina virtual), você instala pacotes prontos e tem o melhor desempenho no Gazebo. Com Docker, você roda um contêiner que já vem com o ROS, em qualquer Linux (e no Windows ou macOS, com mais ajuste para janelas gráficas). No Raspberry Pi 5, a forma direta é instalar o Ubuntu da mesma versão da distro; no Raspberry Pi OS, use Docker.
Passo a passo no Ubuntu
Confira o Ubuntu
Lyrical pede Ubuntu 26.04; Jazzy pede 24.04. Veja com lsb_release -a.
Adicione o repositório do ROS
Siga a seção "Setup Sources" da página oficial de instalação da sua distro em docs.ros.org. Esse passo muda de tempos em tempos; copie de lá, não de tutoriais antigos.
Instale e ative
Rode o bloco abaixo. O pacote desktop traz RViz2, exemplos e ferramentas; ros-dev-tools traz o colcon e o rosdep.
Objetivo: instalar o ROS 2 e deixar cada terminal novo já com ele ativado.
# depois de configurar o repositório pela página oficial
sudo apt update && sudo apt upgrade -y
sudo apt install -y ros-<distro>-desktop ros-dev-tools
# ativa o ROS em todo terminal novo
echo "source /opt/ros/<distro>/setup.bash" >> ~/.bashrc
source ~/.bashrc
# teste: dois nós de exemplo, um em cada terminal
ros2 run demo_nodes_cpp talker
ros2 run demo_nodes_py listener
Como verificar
- ✓O talker imprime "Publishing: 'Hello World: 1'", "...: 2"; o listener imprime "I heard: [Hello World: 1]".
- ✓printenv ROS_DISTRO mostra lyrical ou jazzy.
- ✗"ros2: command not found"? Faltou o source neste terminal.
Caminho rápido com Docker: a imagem oficial osrf/ros:<distro>-desktop já vem com tudo. As opções de DISPLAY deixam o contêiner abrir janelas (RViz, turtlesim) no seu Linux. Confira as tags disponíveis no Docker Hub antes de baixar.
# permite que o contêiner use a tela (rode uma vez por sessão)
xhost +local:docker
docker run -it --rm --net=host \
-e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix \
-v ~/ros2_ws:/root/ros2_ws \
osrf/ros:<distro>-desktop
# dentro do contêiner o ROS já está ativado:
ros2 run turtlesim turtlesim_node
Como verificar: abre uma janela azul com uma tartaruga no meio. A pasta ~/ros2_ws do seu PC aparece dentro do contêiner em /root/ros2_ws, então o código que você escrever não some quando o contêiner fechar.
💡 E no Raspberry Pi 5?
Grave o Ubuntu Server da versão do par (26.04 para Lyrical, 24.04 para Jazzy) com o Raspberry Pi Imager e instale ros-<distro>-ros-base (sem as ferramentas gráficas). Visualize no PC: RViz e Gazebo pesam demais para o Pi. Se quiser manter o Raspberry Pi OS da Trilha 3, use a imagem ros:<distro>-ros-base no Docker.
Por que aprender
Instalar certo uma vez poupa horas depois. O Docker também é a saída para sala de aula: todos os alunos rodam exatamente a mesma imagem, sem diferenças entre máquinas.
Conceitos-chave
🔗 Nós, tópicos, mensagens
Um nó é um processo que faz uma coisa: ler o LiDAR, girar os motores, planejar a rota. Nós conversam por tópicos, canais com nome como /cmd_vel ou /scan. Quem envia é o publisher; quem recebe é o subscriber. Um tópico pode ter vários de cada lado. O conteúdo tem formato fixo, a mensagem: /cmd_vel usa geometry_msgs/msg/Twist, com velocidade linear e angular.
🌱 Novo aqui?
Twist é a mensagem de "quero andar assim": linear.x em metros por segundo (para a frente) e angular.z em radianos por segundo (girar; positivo é anti-horário visto de cima). Um robô diferencial ignora os outros quatro campos. QoS (qualidade de serviço) é o combinado de entrega de cada tópico, como "guardar as últimas 10 mensagens".
Como ler: caixas retas são nós (programas); cápsulas ciano são tópicos (canais). A seta sai de quem publica e entra em quem assina. Repare que /scan tem dois assinantes: o mesmo dado do laser alimenta o mapa e a tela sem nenhum código extra.
Objetivo: inspecionar um grafo de verdade com o turtlesim. Abra três terminais (todos com o ROS ativado).
# terminal 1: o simulador da tartaruga
ros2 run turtlesim turtlesim_node
# terminal 2: dirija com as setas do teclado
ros2 run turtlesim turtle_teleop_key
# terminal 3: olhe o grafo
ros2 node list
ros2 topic list -t
ros2 topic info /turtle1/cmd_vel
ros2 interface show geometry_msgs/msg/Twist
ros2 topic echo /turtle1/pose
# publique você mesmo: a tartaruga anda em círculo
ros2 topic pub --rate 2 /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 1.0}, angular: {z: 0.8}}"
Como verificar
- ✓ros2 node list mostra /turtlesim e /teleop_turtle.
- ✓topic info diz "Publisher count: 1, Subscription count: 1" (2 publishers quando o topic pub estiver rodando).
- ✓O echo imprime x, y e theta mudando enquanto a tartaruga anda. Para ver o grafo desenhado, rode rqt_graph.
Por que aprender
Quando o robô não anda, o primeiro passo é sempre o mesmo: ros2 topic echo /cmd_vel. Se o comando chega, o defeito está no motor; se não chega, está em quem publica. Ler o grafo pelo terminal é a ferramenta de diagnóstico mais usada de toda a trilha.
Conceitos-chave
🔁 Serviços, ações e parâmetros
Tópico é fluxo contínuo, sem resposta. Para os outros casos o ROS 2 tem mais três peças. Um serviço é pergunta e resposta rápida: "crie uma tartaruga aqui", "salve o mapa". Uma ação é uma tarefa demorada com progresso e possibilidade de cancelar: "vá até a cozinha" (o Nav2 inteiro funciona assim). Um parâmetro é um ajuste do nó que você muda sem recompilar: velocidade máxima, nome da porta serial, cor do fundo.
Como ler: as linhas verticais são os dois lados da conversa, e o tempo corre para baixo. No tópico, A só envia. No serviço, o cliente espera uma única resposta. Na ação, o servidor manda progresso (tracejado) enquanto trabalha e, no fim, o resultado.
# serviço: cria uma segunda tartaruga
ros2 service list
ros2 service call /spawn turtlesim/srv/Spawn "{x: 2.0, y: 2.0, theta: 0.0, name: 'robo2'}"
# parâmetro: muda a cor do fundo sem reiniciar
ros2 param list /turtlesim
ros2 param set /turtlesim background_r 150
# ação: gira até 90 graus (1,57 rad) e mostra o progresso
ros2 action list
ros2 action send_goal --feedback /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: 1.57}"
Como verificar: aparece uma tartaruga nova em (2, 2); o fundo fica arroxeado; o terminal da ação imprime várias linhas "Feedback: remaining: ..." e termina com "Goal finished with status: SUCCEEDED".
✓ Padrão certo
- ✓Leitura de sensor e velocidade: tópico.
- ✓Ligar um relé, salvar o mapa: serviço.
- ✓Ir até um ponto, girar o braço: ação.
✗ Gambiarra comum
- ✗Serviço que demora 30 s (trava quem chamou).
- ✗Tópico "/pronto" para simular uma resposta.
- ✗Constante no código que deveria ser parâmetro.
Por que aprender
No módulo 4.5 você vai mandar o robô até um ponto por uma ação do Nav2 e, no 4.4, salvar o mapa por um serviço. Reconhecer o padrão faz a documentação desses pacotes ficar legível.
Conceitos-chave
🐍 Seu primeiro nó em Python (rclpy) publicando e ouvindo
Agora você escreve os seus nós. Em Python a biblioteca é a rclpy. Todo nó segue o mesmo molde: inicia o rclpy, cria um objeto Node, registra publishers, subscribers e timers, e entrega o controle ao spin, que fica esperando eventos e chamando as suas funções. Você vai criar um pacote meu_robo com dois nós: falante publica uma frase duas vezes por segundo; ouvinte recebe e imprime.
Como ler: o relógio (timer) do falante chama publicar(), que joga uma String no tópico. O ouvinte não pergunta nada: o ROS chama ao_receber() toda vez que chega mensagem. Esse "você não chama, você é chamado" é o callback.
Objetivo: criar o workspace e o pacote. O ros2 pkg create gera a estrutura; depois você só substitui os arquivos pelos blocos abaixo.
mkdir -p ~/ros2_ws/src && cd ~/ros2_ws/src
ros2 pkg create --build-type ament_python --license MIT meu_robo --dependencies rclpy std_msgs
# crie os dois nós dentro da pasta de código do pacote
touch meu_robo/meu_robo/falante.py meu_robo/meu_robo/ouvinte.py
# Nó que publica uma frase no tópico /conversa duas vezes por segundo
import rclpy
from rclpy.node import Node
from rclpy.executors import ExternalShutdownException
from std_msgs.msg import String
class Falante(Node):
def __init__(self):
super().__init__('falante')
self.pub = self.create_publisher(String, 'conversa', 10) # fila de 10 mensagens
self.contador = 0
self.timer = self.create_timer(0.5, self.publicar) # chama publicar() a cada 0,5 s
def publicar(self):
msg = String()
msg.data = f'Ola do robo #{self.contador}'
self.pub.publish(msg)
self.get_logger().info(f'Publicado: {msg.data}')
self.contador += 1
def main(args=None):
rclpy.init(args=args)
no = Falante()
try:
rclpy.spin(no)
except (KeyboardInterrupt, ExternalShutdownException):
pass
finally:
no.destroy_node()
rclpy.try_shutdown()
if __name__ == '__main__':
main()
# Nó que assina /conversa e imprime cada mensagem recebida
import rclpy
from rclpy.node import Node
from rclpy.executors import ExternalShutdownException
from std_msgs.msg import String
class Ouvinte(Node):
def __init__(self):
super().__init__('ouvinte')
self.sub = self.create_subscription(String, 'conversa', self.ao_receber, 10)
def ao_receber(self, msg):
self.get_logger().info(f'Ouvi: {msg.data}')
def main(args=None):
rclpy.init(args=args)
no = Ouvinte()
try:
rclpy.spin(no)
except (KeyboardInterrupt, ExternalShutdownException):
pass
finally:
no.destroy_node()
rclpy.try_shutdown()
if __name__ == '__main__':
main()
O setup.py diz ao ROS quais comandos o pacote oferece (os entry_points), e o package.xml lista as dependências. Substitua os dois gerados pelos mínimos abaixo.
from setuptools import find_packages, setup
package_name = 'meu_robo'
setup(
name=package_name,
version='0.1.0',
packages=find_packages(exclude=['test']),
data_files=[
('share/ament_index/resource_index/packages', ['resource/' + package_name]),
('share/' + package_name, ['package.xml']),
],
install_requires=['setuptools'],
zip_safe=True,
maintainer='voce',
maintainer_email='voce@exemplo.com',
description='Primeiros nos do curso de robotica',
license='MIT',
entry_points={
'console_scripts': [
'falante = meu_robo.falante:main',
'ouvinte = meu_robo.ouvinte:main',
],
},
)
<?xml version="1.0"?>
<package format="3">
<name>meu_robo</name>
<version>0.1.0</version>
<description>Primeiros nos do curso de robotica</description>
<maintainer email="voce@exemplo.com">voce</maintainer>
<license>MIT</license>
<exec_depend>rclpy</exec_depend>
<exec_depend>std_msgs</exec_depend>
<export>
<build_type>ament_python</build_type>
</export>
</package>
cd ~/ros2_ws
colcon build --symlink-install
source install/setup.bash
ros2 run meu_robo falante # terminal 1
ros2 run meu_robo ouvinte # terminal 2 (faça o source de novo nele)
Como verificar
- ✓O colcon termina com "Summary: 1 package finished".
- ✓Terminal 1: "[falante]: Publicado: Ola do robo #0", "#1"... Terminal 2: "[ouvinte]: Ouvi: Ola do robo #3".
- ✓Num terceiro terminal, ros2 topic hz /conversa mostra cerca de 2 Hz.
- ✗"Package 'meu_robo' not found"? Faltou source install/setup.bash naquele terminal.
💡 Desafio
Troque o falante para publicar geometry_msgs/msg/Twist em /turtle1/cmd_vel (adicione geometry_msgs ao package.xml) e faça a tartaruga desenhar um quadrado: anda 2 s, gira 90 graus, repete. É exatamente o que um nó de navegação faz com o seu robô.
Por que aprender
Este molde (classe Node, publisher, subscriber, timer, spin) é a base de todo nó da trilha: o que calcula a odometria no 4.3, o que manda o robô até um ponto no 4.5. Mudam os tipos de mensagem e a lógica do callback; a estrutura é a mesma.
Conceitos-chave
✅ Resumo do módulo
Para ir além
- Documentação do ROS 2 Lyrical — instalação e tutoriais oficiais
- Documentação do ROS 2 Jazzy — a mesma estrutura, para a LTS anterior
- Tutoriais de linha de comando — nós, tópicos, serviços, ações e parâmetros com o turtlesim
- Imagens osrf/ros no Docker Hub — confira as tags de cada distro
Próximo módulo
4.2 · Descrever e simular o robô: URDF, quadros TF, RViz2 e o robô andando no Gazebo.