Por dentro do software: DDS, SDK, alto e baixo nível
O seu programa não chama uma função do robô: ele publica e assina mensagens num barramento DDS. Nesta aula você monta a bancada do fabricante (simulador, SDK e CycloneDDS 0.10.2), sobe o G1 simulado e lê a primeira mensagem de estado, pelo mesmo caminho que usaria com o robô real.
1O caminho: seu programa → SDK → DDS → robô ou simulador
2A bancada em ~/fth com versões fixadas, incluindo o CycloneDDS compilado
3Alto nível (locomoção pronta) × baixo nível (motor a motor)
4Domínio e interface: o erro que faz o robô parecer morto
Objetivo: montar a bancada do fabricante (simulador, SDK, CycloneDDS 0.10.2) e ler a primeira mensagem de estado do G1 por DDS.
01 · Do seu programa ao motor
Clique em cada bloco.
Clique em cada bloco do diagrama para ver o que ele faz.
Trocar o simulador pelo robô muda o domínio e a interface, não o seu código.
02 · Três coisas para saber antes de instalar
Clique em cada uma.
1. Alto × baixo
Alto nível: o controle de locomoção do fabricante anda e você pede velocidade (LocoClient no serviço "sport": SetVelocity, Move, Damp, ZeroTorque).
Baixo nível: você manda em cada motor por rt/lowcmd. Antes, o exemplo oficial libera o controle interno (MotionSwitcherClient, CheckMode e ReleaseMode), senão os dois disputam os motores.
2. Domínio e interface
O simulador usa domínio 1 na interface lo (config.py do unitree_mujoco). Os exemplos do SDK usam domínio 0 e o nome da placa de rede ligada ao robô.
Programa e robô em domínios diferentes não se enxergam: o script espera e o robô parece morto. A aba "Erro comum" mostra a mensagem.
Rede do robô realO README do unitree_ros2 põe o PC em IP fixo na sub-rede 192.168.123.x (exemplo: 192.168.123.99) e a interface vai pelo nome (enp3s0).
3. Qual G1
O G1 base custa US$ 13,5 mil na página oficial (lida em 19/10/2026), mas não tem desenvolvimento secundário: sem SDK. Para programar como neste curso é preciso a versão EDU, vendida sob consulta.
Revendas citadas pela pesquisa da formação (out/2026): US$ 43,5 mil a 73,9 mil (relatado; varia por versão e revenda). O simulador não custa nada e fala o mesmo DDS.
03 · Montar a bancada (uma vez)
Venv em ~/fth (o mesmo do curso 0, se você fez), simulador e SDK fixados em commits, e o CycloneDDS 0.10.2 compilado: o pip sozinho falha em aarch64 sem a biblioteca C. Precisa de python3.12 (com venv), git, cmake e compilador C.
cyclonedds C 0.10.2 instalado em ~/fth/cyclonedds/install
cyclonedds 0.10.2 · unitree_sdk2py 1.0.1 · mujoco 3.16.0
Os dois commits e as três versões. A compilação leva alguns minutos; o aviso do compilador fica escondido no /dev/null.
04 · Subir o G1 simulado e ler o estado
O kit/sim.py roda a ponte do unitree_mujoco sem janela, em segundo plano, por 8 s; o ler_estado.py é outro processo que só assina rt/lowstate. O G1 está pendurado no elástico (o pórtico do simulador).
class Estado:
"""Assina rt/lowstate e guarda a última mensagem e quantas chegaram."""
def __init__(self):
from unitree_sdk2py.core.channel import ChannelSubscriber
from unitree_sdk2py.idl.unitree_hg.msg.dds_ import LowState_
self.ultima, self.n, self.t_ultima = None, 0, 0.0
self.sub = ChannelSubscriber("rt/lowstate", LowState_)
self.sub.Init(self._chegou, 10)
Mostrado · só com o robô real, depois do checklist
# Trecho de example/g1/low_level/g1_low_level_example.py (unitree_sdk2_python 814556d)
ChannelFactoryInitialize(0, sys.argv[1]) # domínio 0 + nome da placa ligada ao robô
self.msc = MotionSwitcherClient()
self.msc.SetTimeout(5.0)
self.msc.Init()
status, result = self.msc.CheckMode()
while result['name']: # libera o controle interno antes do baixo nível
self.msc.ReleaseMode()
status, result = self.msc.CheckMode()
time.sleep(1)
Exemplo do repositório
simulador: G1 29 motores · DDS domínio 1 em lo · 8 s · suspenso: sim
tópico: rt/lowstate · tipo: unitree_hg LowState_
IMU quatérnio (w, x, y, z): [1.0, 0.0, 0.1, 0.0] · tronco em pé (inclinação < 20°): sim
junta 0 (left_hip_pitch): q = 0.0 rad · torque estimado = 0 N·m
motores no pacote: 35 (o G1 de 29 GDL usa os índices 0 a 28)
saída: 0
simulador: fim em t = 8.0 s · robô suspenso (pés fora do chão)
O pacote tem 35 posições de motor; o G1 de 29 GDL usa as 29 primeiras. Motores soltos: torque zero.
ERRO: nenhuma mensagem em rt/lowstate em 10 s. O simulador está rodando? (kit/sim.py)
saída: 1
Nenhuma mensagem em 10 s: o simulador não está rodando, ou o seu programa está noutro domínio ou interface.
05 · Prática
Bancada pronta e primeira mensagem lida.
E1 · Montar a bancada
15 min
Rode os dois blocos de preparação. Se o cmake reclamar, instale cmake e um compilador C pelo gerenciador do seu sistema e rode o segundo bloco de novo.
Pronto quando: a saída mostra cyclonedds 0.10.2 · unitree_sdk2py 1.0.1 · mujoco 3.16.0.
E2 · Ler o G1
5 min
Rode o bloco do simulador com a leitura e explique por que o pacote tem 35 motores se o G1 tem 29.
Pronto quando:python3 kit/ler_estado.py; echo "saída: $?" (com o sim.py rodando) → motores no pacote: 35 (o G1 de 29 GDL usa os índices 0 a 28) e saída: 0.
E3 · Ver o erro do domínio
3 min
Rode só o ler_estado.py, sem o simulador, e espere os 10 s.
Pronto quando:ERRO: nenhuma mensagem em rt/lowstate em 10 s e saída: 1.
06 · Teste da aula
A explicação aparece depois da sua resposta.
Pergunta 1 de 4
O ler_estado.py ficou 10 s esperando e deu erro. Qual a causa mais provável?competência
Correto
Publicador e assinante só se acham no mesmo domínio e na mesma interface. O simulador usa domínio 1 em lo; o exemplo do SDK, domínio 0.
Estado vem em rt/lowstate e comando vai em rt/lowcmd, ambos do IDL unitree_hg. /robot_state e RobotState_ eram de um curso antigo e não existem no SDK.
Não é essa
Estado vem em rt/lowstate e comando vai em rt/lowcmd, ambos do IDL unitree_hg. /robot_state e RobotState_ eram de um curso antigo e não existem no SDK.Rever: Do seu programa ao motor
Pergunta 3 de 4
Antes de mandar comando de baixo nível no robô real, o exemplo oficial faz o quê?
Correto
CheckMode e ReleaseMode até o controle interno sair; senão o seu rt/lowcmd e o controlador do fabricante disputam os motores. No simulador esse serviço não existe.
Não é essa
CheckMode e ReleaseMode até o controle interno sair; senão o seu rt/lowcmd e o controlador do fabricante disputam os motores. No simulador esse serviço não existe.Rever: Montar a bancada (uma vez)
Pergunta 4 de 4
Por que o curso compila o CycloneDDS em vez de só usar o pip?
Correto
O pacote Python cyclonedds 0.10.2 precisa da biblioteca C; em aarch64 não havia binário pronto. Compila-se a tag 0.10.2 e aponta-se CYCLONEDDS_HOME.
Não é essa
O pacote Python cyclonedds 0.10.2 precisa da biblioteca C; em aarch64 não havia binário pronto. Compila-se a tag 0.10.2 e aponta-se CYCLONEDDS_HOME.Rever: Montar a bancada (uma vez)
Teste concluído
Você acertou {a} de {n}. Acertando todas, a aula é marcada como concluída.
Escolha uma alternativa. A explicação aparece depois da sua tentativa.
07 · Em três frases
BarramentoPrograma e robô conversam por DDS: rt/lowstate e rt/lowcmd.
DomínioSimulador no domínio 1 em lo; robô no 0 na placa de rede.
Bancadaunitree_mujoco 1eb6642, SDK 814556d e CycloneDDS 0.10.2.