FTH 1 · Ensinar a andar|INEMA.CLUB-PRO

Aula 4 · 16 min

Desenhar a recompensa de marcha

A política aprende o que a recompensa paga, não o que você quis dizer. Nesta aula você lê os termos de marcha da tarefa de velocidade do mjlab, grava um rollout andando e outro parado, mede quanto cada termo pagou e descobre que, com um peso trocado, ficar parado passa a valer mais do que andar.

Começar a aula
Robô humanoide andando num laboratório escuro sobre um piso com marcas retangulares de pegadas em sequência, ao lado de uma fita amarela de segurança.

Nesta aula você vai

  1. 1Os 7 termos de marcha que o kit copia do mjlab, com nome, peso e escala
  2. 2Andando: 53,60. Parado com o mesmo comando: 42,32
  3. 3Um peso trocado: parado (40,22) passa a ganhar de andar (39,65)
  4. 4Como o unitree_rl_lab escolheu termos diferentes para o mesmo robô

Objetivo: medir quanto cada termo da recompensa paga num rollout gravado e prever o efeito de mudar um peso antes de treinar.

01Prêmios e punições

Clique em cada bloco. Cada termo vale peso × valor × 0,02 s por passo da política.

Clique em cada bloco do diagrama para ver o que ele faz.

Nomes, pesos e std copiados da tarefa de velocidade do mjlab (commit 8bb2bc9, 18/10/2026). O kit usa um std só para pose.

02A recompensa do kit

Um YAML com um termo por linha. É o arquivo que você vai copiar e mudar.

Arquivo · kit/recompensa.yaml
# Recompensa de marcha do kit (FTH 1). Nomes, pesos e std seguem a tarefa de velocidade do mjlab
# (src/mjlab/tasks/velocity/velocity_env_cfg.py, commit 8bb2bc9, 18/10/2026); "pose" usa um std só.
# Cada termo vale weight × valor × 0,02 s por passo da política. Positivo = prêmio; negativo = punição.
track_linear_velocity: {weight: 2.0, std: 0.5}     # exp(-erro² / std²) entre comando e velocidade xy
track_angular_velocity: {weight: 2.0, std: 0.707}  # o mesmo para a rotação em z
upright: {weight: 1.0, std: 0.447}                 # tronco em pé (gravidade sem componente x/y)
pose: {weight: 1.0, std: 0.3}                      # juntas perto da pose padrão
dof_pos_limits: {weight: -1.0}                     # quanto as juntas passaram do limite (rad)
action_rate_l2: {weight: -0.1}                     # ação que muda de um passo para o outro
foot_slip: {weight: -0.1}                          # pé que escorrega enquanto está no chão

03Gravar dois rollouts e medir cada termo

A política pronta anda 10 s com 0,7 m/s e depois fica parada com comando 0. O termos.py refaz a conta termo a termo; --comando-vx refaz a conta do parado como se o pedido fosse 0,7 m/s.

Terminal · gravar andando e parado
F=${FTH:-$HOME/fth}; cd $F/locomocao && . $F/.venv/bin/activate
mkdir -p $F/treino
python3 kit/andar_demo.py --vx 0.7 --gravar $F/treino/andando.npz | tail -1
python3 kit/andar_demo.py --vx 0 --gravar $F/treino/parado.npz | tail -1
Terminal · termos do rollout andando
F=${FTH:-$HOME/fth}; cd $F/locomocao && . $F/.venv/bin/activate
python3 kit/termos.py $F/treino/andando.npz; echo "saída: $?"
Terminal · parado, cobrado como se devesse andar
F=${FTH:-$HOME/fth}; cd $F/locomocao && . $F/.venv/bin/activate
python3 kit/termos.py $F/treino/parado.npz --comando-vx 0.7
Exemplo do repositório
gravado: ~/fth/treino/andando.npz (500 passos)
gravado: ~/fth/treino/parado.npz (500 passos)
rollout: andando.npz · 500 passos (10 s) · comando vx = 0.7 m/s
termo                     weight  valor médio    total
track_linear_velocity          2        0.930    18.59
track_angular_velocity         2        0.814    16.28
upright                        1        0.995     9.95
pose                           1        0.925     9.25
dof_pos_limits                -1        0.000     0.00
action_rate_l2              -0.1        0.421    -0.42
foot_slip                   -0.1        0.054    -0.05
RECOMPENSA DO EPISÓDIO                           53.60
saída: 0

Andando, quem mais paga é rastrear a velocidade (18,59) e o giro (16,28). As punições quase não pesam: a política já é suave.

04Mude um peso e refaça a conta

Uma cópia do YAML com track_linear_velocity em 0,5 em vez de 2,0. Nada é treinado: só a conta muda.

Terminal · peso 0,5 no rastreio
F=${FTH:-$HOME/fth}; cd $F/locomocao && . $F/.venv/bin/activate
sed "s/track_linear_velocity: {weight: 2.0/track_linear_velocity: {weight: 0.5/" kit/recompensa.yaml > $F/treino/minha.yaml
python3 kit/termos.py $F/treino/andando.npz --recompensa $F/treino/minha.yaml | tail -1
python3 kit/termos.py $F/treino/parado.npz --comando-vx 0.7 --recompensa $F/treino/minha.yaml | tail -1
Exemplo do repositório
RECOMPENSA DO EPISÓDIO                           39.65
RECOMPENSA DO EPISÓDIO                           40.22

Primeira linha: andando, 39,65. Segunda: parado, 40,22. Com esse peso, um treino que encontre "ficar parado e ereto" é recompensado por isso: é recompensa hackeada antes de qualquer treino. Fazer essa conta custa segundos; descobrir depois de um treino custa horas de GPU.

05Mesmo robô, outra receita

O unitree_rl_lab (commit 4960b84) treina o mesmo G1 com termos diferentes. Clique para comparar.

1. Vivo

alive com peso 0,15: um prêmio pequeno por passo de pé. A aula 6 mostra o que acontece quando ele falta e quando ele é grande demais.

06Prática

Conferir a recompensa antes de gastar um treino.

E1 · Termo a termo

5 min

Grave os dois rollouts e rode o termos.py no rollout andando.

Pronto quando: python3 kit/termos.py $F/treino/andando.npz; echo "saída: $?" → RECOMPENSA DO EPISÓDIO … 53.60 e saída: 0.

E2 · O parado

5 min

Rode o rollout parado cobrado como se devesse andar e calcule quanto ele vale em relação ao andando.

Pronto quando: a saída termina em 42.32 e você escreveu "ficar parado vale 79 % de andar".

E3 · O peso que vira o jogo

10 min

Rode o bloco do peso 0,5. Depois, numa cópia sua do YAML, procure o menor peso de track_linear_velocity em que andar ainda vale mais que ficar parado.

Pronto quando: com 0,5, a segunda linha (40.22) é maior que a primeira (39.65); você anotou o peso a partir do qual andando volta a ganhar (em 19/10/2026: 0,55 ainda perde, 0,6 ganha).

07Teste da aula

A explicação aparece depois da sua resposta.

Pergunta 1 de 4

Parado com pedido de 0,7 m/s, o robô ainda soma 42,32. De onde vem a maior parte?competência

08Em três frases

SomaA recompensa é uma soma de termos com peso; cada termo paga ou pune por passo.
MedidaAndando 53,60, parado 42,32; com o rastreio em 0,5, parado passa a ganhar.
HábitoAntes de treinar, meça a recompensa de um rollout bom e de um ruim.

Para ir além

Aula anteriorPróxima aula