ROS2 na prática: como devs programam robôs autônomos

ROS2 na prática: como devs programam robôs autônomos

2>Um robô na porta da faculdade: por que isso importa mais do que parece

Quando li no Sapo.pt que a Universidade Politécnica do Cávado e do Ave (UPCA) vai receber calouros com um humanoide e um cão robótico, a primeira reação foi: finalmente alguém tratando robótica como o que ela é — uma área de engenharia de software séria, e não um show de palanque. A dupla, programada por investigadores do 2Ai — Laboratório de Inteligência Artificial Aplicada, é só a ponta visível de uma stack que envolve visão computacional, navegação autônoma, ROS2 e modelos de linguagem rodando on-device.

Na minha experiência, quem está entrando na faculdade agora vai se deparar com um mercado que exige fluência em embodied AI — aquela IA que não vive só numa API, mas que se move, vê e reage ao mundo físico. E a melhor forma de começar é exatamente o que o 2Ai está fazendo: deixar o calouro botar a mão no robô antes de entender o que é um classificador.

O que provavelmente está rodando dentro desses robôs

O texto do Sapo não diz qual plataforma o 2Ai está usando, mas dá para inferir algumas coisas. Cães robóticos com mobilidade quadrúpede, autônomos, com bom suporte a ROS e preço viável para uma universidade pública brasileira (ou portuguesa, no caso) costumam vir de um destes dois fabricantes:

  • Unitree — Go1, Go2 ou B2. Preço agressivo, SDK aberto em Python e C++, suporte oficial a ROS2 Humble/Iron.
  • Boston Dynamics Spot — referência de mercado, mas custa uma ordem de grandeza acima e o SDK é mais restrito.

Para o humanoide, o leque é menor. As opções mais prováveis em ambiente acadêmico são:

  • Unitree H1/G1 — a tendência atual; código aberto, torque control, sim no Isaac Sim da NVIDIA.
  • NAO / Pepper (SoftBank) — clássicos em pesquisa de HRI (Human-Robot Interaction), mas hardware datado.
  • Unitree H1-2 ou Booster Robotics T1 — se a UPCA investiu pesado recentemente.

O “Ben-ben”, como foi batizado o cão, segue uma tradição interessante de dar identidade a robôs de pesquisa. Isso não é firula — tem um motivo prático: quando você precisa anotar datasets, treinar políticas de RL ou debugar comportamento, “o robô fez X” vira “o Ben-ben tropeçou na rampa do terceiro andar”. Nome próprio vira identificador de log, e isso ajuda muito em reprodutibilidade de experimentos.

A stack invisível: o que ninguém vê

Para um dev que está olhando isso de fora e achando que é só “ligar o robô e mandar ele andar”, deixa eu abrir a caixa-preta. Por trás de uma demonstração aparentemente simples como o “Dia i” da UPCA, normalmente existe:

  1. Middleware de comunicação — ROS2 com DDS (CycloneDDS ou Fast DDS), rodando tópicos como /cmd_vel, /odom, /camera/depth.
  2. Pipeline de percepção — câmeras RGB-D + LiDAR, passando por detecção de pessoas (YOLOv8/v11 ou RT-DETR) e tracking (ByteTrack ou SORT).
  3. Planejamento de movimento — Nav2 para navegação 2D no cão; para o humanoide, algo como MoveIt2 ou políticas aprendidas via RL.
  4. Camada de interação — STT (Whisper ou Vosk), TTS (Piper ou XTTS) e um LLM local rodando em Jetson Orin ou RTX A5000 onboard.
  5. Safety layer — emergency stop por hardware, watchdog timers, zonas de exclusão virtual. Isso nunca é opcional.

Comparativo honesto: ROS2 vs. middleware proprietário

Critério ROS2 Humble/Iron SDK proprietário (Spot, Optimus)
Curva de aprendizado Alta, mas documentada Média, mas fechada
Customização Total Limitada por NDA
Comunidade Enorme (ROS Discourse, GitHub) Pequena e oficial
Portabilidade de código Alta entre fabricantes Zero (vendor lock-in)
Simulação Gazebo, Isaac Sim, Webots Apenas a do fabricante

Para um lab de pesquisa como o 2Ai, a escolha é quase óbvia: ROS2. E é por isso que vale a pena, se você é dev, aprender isso agora, antes de virar commodity.

Na Prática: controlando um quadrúpede com Python e ROS2

Vou montar um exemplo mínimo de como enviar comandos de movimento para um robô compatível com ROS2 — o mesmo tipo de nó que o 2Ai provavelmente roda para o “Ben-ben” passear entre os calouros. Não é toy code: é o esqueleto que vira base de produto.

# ben_ben_welcome.py
# Nó ROS2 que faz o cão robótico patrulhar um waypoint
# e parar quando detecta uma pessoa a menos de 1.5m.

import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist
from sensor_msgs.msg import LaserScan
from vision_msgs.msg import Detection2DArray
import math

class WelcomePatrol(Node):
    def __init__(self):
        super().__init__('welcome_patrol')
        self.cmd_pub = self.create_publisher(Twist, '/cmd_vel', 10)
        self.scan_sub = self.create_subscription(
            LaserScan, '/scan', self.scan_callback, 10)
        self.det_sub = self.create_subscription(
            Detection2DArray, '/detections', self.det_callback, 10)
        self.timer = self.create_timer(0.1, self.control_loop)

        self.person_detected = False
        self.min_distance = float('inf')
        self.state = 'PATROL'  # PATROL | APPROACH | STOP

    def scan_callback(self, msg: LaserScan):
        # filtra infinitos e NaN
        valid = [r for r in msg.ranges
                 if math.isfinite(r) and msg.range_min < r < msg.range_max]
        self.min_distance = min(valid) if valid else float('inf')

    def det_callback(self, msg: Detection2DArray):
        self.person_detected = any(
            d.results[0].hypothesis.class_id == 'person'
            for d in msg.detections if d.results
        )

    def control_loop(self):
        cmd = Twist()
        if self.person_detected and self.min_distance < 1.5:
            self.state = 'STOP'
            cmd.linear.x = 0.0
            cmd.angular.z = 0.0
            self.get_logger().info('Bem-vindo à UPCA!')
        elif self.min_distance < 0.8:
            self.state = 'STOP'  # segurança
            cmd.linear.x = 0.0
        else:
            self.state = 'PATROL'
            cmd.linear.x = 0.4      # m/s
            cmd.angular.z = 0.15    # curva suave

        self.cmd_pub.publish(cmd)

def main(args=None):
    rclpy.init(args=args)
    node = WelcomePatrol()
    rclpy.spin(node)
    node.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

Esse código não vai funcionar sozinho — você precisa de um launch file, de um driver de hardware e de um detector YOLO publicando em /detections. Mas a estrutura é exatamente a que se usa em produção. A separação entre percepção, decisão e atuação é o que permite testar cada camada isoladamente no simulador antes de colocar o robô real em movimento.

Erros Comuns que eu já vi em projetos de robótica

Depois de alguns anos vendo gente migrar de backend tradicional para robôs, esses são os tropeços mais frequentes:

  • Testar direto no hardware. Parece óbvio, mas tem time que pula o Gazebo/Isaac Sim e só descobre que a política de RL derruba o robô quando o joelho dele já foi pro espaço. Sempre simule primeiro.
  • Ignorar QoS do ROS2. Se você publica cmd_vel com QoS de "best effort" e o cão está a 20m, vai ter lag crítico. Use RELIABLE + TRANSIENT_LOCAL para config e BEST_EFFORT só para streams de vídeo.
  • Confundir coordenadas do robô com coordenadas do mundo. Sem um TF tree bem montado (usando tf2), seu robô vai se perder em três salas. Esse é o bug mais caro de debugar.
  • Colocar LLM pesado no loop síncrono. Se o calouro perguntar "qual o horário da biblioteca" e você chamar GPT-4 via API síncrona, o robô fica parado 4 segundos. Parece pouco até um humano bater nele achando que travou.
  • Esquecer do emergency stop por hardware. Software falha. O botão físico vermelho que corta torque nos motores precisa existir e ser testado semanalmente. Não é burocracia, é o que separa pesquisa de acidente.

Por que isso é relevante para você, dev

Se você trabalha com backend, frontend ou dados, talvez esteja pensando "isso não é comigo". Ledo engano. As mesmas técnicas que fazem o Ben-ben navegar pelo campus — SLAM, fusão sensorial, planejamento sob incerteza — são as que alimentam:

  • Carros autônomos (Waymo, Tesla, Mobileye)
  • Drone delivery (Zipline, Amazon Prime Air)
  • Robôs de armazém (Amazon Hercules, Symbotic)
  • Próteses robóticas com controle mioelétrico

Na minha experiência, quem aprende ROS2, Python para sistemas embarcados e um pouco de visão computacional hoje está três anos à frente de quem fica esperando "o mercado de robótica amadurecer". Spoiler: já amadureceu, só não estava no seu LinkedIn feed.

FAQ — Perguntas que um dev realmente faz

1. Preciso saber ROS para entrar em robótica?

Não obrigatoriamente, mas é o equivalente a saber Git antes de 2015. ROS2 é o de facto padrão open source. Aprender dá portabilidade entre fabricantes e acesso a uma comunidade gigante de pacotes prontos (Nav2, MoveIt2, ros2_control).

2. Qual linguagem usar? Python ou C++?

Python para prototipagem rápida, percepção e orquestração. C++ para nós de controle com latência crítica (controle de motor, fusão sensorial). No ROS2, dá pra misturar sem dor — um nó Python chama um serviço C++ via DDS normalmente.

3. Quanto custa um cão robótico desses?

O Unitree Go2 educacional sai por algo entre 1.800 e 3.500 USD dependendo do kit. Spot da Boston Dynamics passa dos 75.000 USD. Para estudar, o Go2 entrega 90% do valor didático por 5% do preço.

4. Dá pra simular sem comprar robô?

Sim. Gazebo Fortress + Ignition ou NVIDIA Isaac Sim rodam com GPUs modestas (RTX 3060 já dá conta). Você pode treinar políticas inteiras em simulação e fazer sim-to-real transfer depois.

5. Vale a pena aprender CUDA para isso?

Se for trabalhar com percepção (YOLO, segmentação, NeRF) ou RL, sim. Para navegação pura com Nav2, dá pra sobreviver com CPU. Mas a diferença de performance ao rodar um VLM onboard é brutal com CUDA.

O que a UPCA está comunicando, de verdade

Lendo entre as linhas, o que o 2Ai está fazendo com o "Dia i" é mais do que marketing — é uma declaração de stack. Eles estão dizendo aos calouros: "aqui você vai aprender a programar coisas que andam, vêem e falam". Em 2026, com humanoides entrando em fábricas (veja a Figure 01 na BMW e o Optimus da Tesla), essa é a mensagem certa.

Se eu fosse calouro em Barcelos, já chegaria com ROS2 instalado no notebook, um docker com Gazebo rodando e um repositório no GitHub com meus primeiros experimentos. Mostra pro lab que você não está lá pra esperar o professor explicar — está lá pra construir.

Gostou? Me segue no GitHub e deixa um comentário se tiver dúvida ou quiser aprofundar algum ponto.

Y

Yuri Sousa

Front-End Developer / Designer

Desenvolvedor apaixonado por criar experiências digitais acessíveis e visualmente perfeitas. Escrevo sobre desenvolvimento web, design e tecnologia.