LeRobot documentation
Representações de Ação
Representações de Ação
Este guia explica as diferentes formas de representar ações de robôs no LeRobot, como elas se relacionam entre si e quando usar cada uma.
Espaço Conjunto vs Espaço do Efeito Final
Antes de discutir as representações de ação, é útil entender os dois espaços de coordenadas em que as ações podem existir.
Espaço Conjunto
Ações no espaço de juntas especificam diretamente as posições-alvo para cada motor. Para um braço de 6-DOF com um garra, uma ação no espaço de juntas pode ser:
action = [shoulder_pan: 45.0, shoulder_lift: -20.0, elbow: -30.0, wrist_pitch: 10.0, wrist_roll: 0.0, wrist_yaw: 5.0, gripper: 0.8]O espaço de juntas é o padrão no LeRobot. Ele é simples, não requer um modelo de cinemática e mapeia diretamente para os comandos dos motores. A maioria dos setups para iniciantes (SO-100, Koch) usa ações no espaço de juntas.
Espaço do Efeito Terminal (EE)
Ações no espaço do efetuor final especificam a posição e a orientação desejadas da ponta da ferramenta do robô (garras) em coordenadas cartesianas:
action = [x: 0.25, y: -0.10, z: 0.15, wx: 0.0, wy: 0.0, wz: 0.1, gripper: 0.8]O espaço EE é mais intuitivo para tarefas como pick-and-place, pois descreve diretamente para onde o garra deve ir, mas requer um modelo de cinemática (URDF) para converter entre poses do EE e ângulos das juntas.
Convertendo Entre Espaços
LeRobot fornece etapas de processamento para converter entre os espaços de juntas e EE usando cinemática direta e inversa. Essas etapas são construídas sobre o RobotKinematics, que carrega um modelo URDF do seu robô.
from lerobot.model.kinematics import RobotKinematics
from lerobot.robots.so_follower.robot_kinematic_processor import (
ForwardKinematicsJointsToEE,
InverseKinematicsEEToJoints,
)
kinematics = RobotKinematics(
urdf_path="./SO101/so101_new_calib.urdf",
target_frame_name="gripper_frame_link",
joint_names=["shoulder", "elbow", "wrist_pitch", "wrist_roll", "wrist_yaw"],
)
# Joints → EE (for observations: "where is my gripper?")
fk_step = ForwardKinematicsJointsToEE(kinematics=kinematics, motor_names=[...])
# EE → Joints (for actions: "move my gripper here")
ik_step = InverseKinematicsEEToJoints(kinematics=kinematics, motor_names=[...])Veja examples/so100_to_so100_EE/ para um exemplo completo e funcional de gravação, reprodução e avaliação com ações no espaço EE em um braço SO-100.
Ações absolutas, relativas e delta
Independentemente de você trabalhar no espaço articulado ou no espaço do efetuor, os valores de ação podem ser expressos de três maneiras diferentes. A terminologia segue UMI (Chi et al., 2024).
Ações Absolutas (padrão do LeRobot)
Cada ação especifica diretamente a posição de destino.
Exemplo (espaço conjunto, bloco de 4):
current_state = [45.0, -30.0, 10.0]
action_chunk = [
[46.0, -29.0, 11.0], # go to 46, -29, 11
[47.5, -27.0, 12.0], # go to 47.5, -27, 12
[49.0, -25.0, 13.5], # go to 49, -25, 13.5
[50.0, -24.0, 15.0], # go to 50, -24, 15
]Cada valor é uma posição alvo no referencial de coordenadas do robô. Simples e direto, mas requer um referencial de coordenadas global consistente. Este é o padrão no LeRobot.
Ações Relativas (usadas por OpenPI / pi0)
Cada ação no chunk é um deslocamento em relação ao estado atual no momento da previsão. Todas as ações no chunk compartilham o mesmo ponto de referência:
current_state = [45.0, -30.0, 10.0]
relative_chunk = [
[1.0, 1.0, 1.0], # +1 from current → target 46, -29, 11
[2.5, 3.0, 2.0], # +2.5 from current → target 47.5, -27, 12
[4.0, 5.0, 3.5], # +4 from current → target 49, -25, 13.5
[5.0, 6.0, 5.0], # +5 from current → target 50, -24, 15
]A conversão é direta: relative = absolute - current_state. Para recuperar o valor absoluto: absolute = relative + current_state.
Por que usar ações relativas? O modelo aprende a prever deslocamentos centralizados em torno de zero, o que é mais fácil de normalizar e leva a um treinamento mais estável. Como cada bloco referencia o mesmo estado atual, não há acúmulo de erro entre os blocos.
Ações Delta (diferenças sequenciais)
Cada ação é um deslocamento em relação à ação anterior (ou em relação ao estado atual, no primeiro passo):
current_state = [45.0, -30.0, 10.0]
delta_chunk = [
[1.0, 1.0, 1.0], # current → 46, -29, 11
[1.5, 2.0, 1.0], # previous action → 47.5, -27, 12
[1.5, 2.0, 1.5], # previous action → 49, -25, 13.5
[1.0, 1.0, 1.5], # previous action → 50, -24, 15
]Aqui, cada passo é relativo ao passo anterior. Para recuperar as posições absolutas, é necessário somar todos os deltas anteriores, o que significa que os erros se acumulam ao longo do tempo. O UMI argumenta explicitamente contra essa representação por esse motivo.
Comparação Visual
A figura abaixo (baseada em uma figura de UMI, Chi et al., 2024) ilustra a diferença principal. Com trajetória relativa, cada ação no chunk aponta de volta para a mesma origem (estado atual), de modo que uma nova etapa de inferência redefine a referência de forma limpa. Com delta, cada ação depende da anterior, de modo que os erros se acumulam. Ações absolutas exigem um sistema de coordenadas global consistente.
Usando Ações Relativas no LeRobot
LeRobot fornece RelativeActionsProcessorStep para converter entre ações absolutas e relativas dentro do pipeline do processador. É assim que pi0, pi0.5 e pi0_fast suportam ações relativas.
Observação: Todos os modelos pi (pi0, pi0.5, pi0fast) aplicam a conversão relativa _antes da normalização (
relative → normalize), de modo que o normalizador sempre recebe valores delta (relativos). Isso significa que estatísticas de ação relativa são obrigatórias para todos eles ao treinar comuse_relative_actions=true. No pi0_fast, oRelativeActionsProcessorStepmodifica apenas a ação — a observação do estado permanece inalterada —, portanto oNormalizerProcessorStepainda é executado antes do tokenizer de estado e o tokenizer continua a receber o estado normalizado, conforme esperado.
Como funciona
Durante o treinamento (pré-processamento), as ações são convertidas de absolutas para relativas antes de o modelo as ver:
raw absolute action → RelativeActionsProcessorStep → normalize → modelDurante a inferência (pós-processamento), as previsões do modelo são convertidas de volta para valores absolutos antes de serem enviadas para o robô:
model output → unnormalize → AbsoluteActionsProcessorStep → robotO AbsoluteActionsProcessorStep lê o estado atual em cache do seu RelativeActionsProcessorStep correspondente, portanto, os dois devem ser conectados (isso é tratado automaticamente pela fábrica de políticas).
Habilitando ações relativas para a família pi (pi0, pi0.5, pi0_fast)
Etapa 1: Pré-compute as estatísticas de ação relativas para o seu conjunto de dados:
lerobot-edit-dataset \
--repo_id your_dataset \
--new_repo_id your_dataset \
--operation.type recompute_stats \
--operation.overwrite true \
--operation.relative_action true \
--operation.chunk_size 50 \
--operation.relative_exclude_joints "['gripper']"Etapa 2: Treine com ações relativas habilitadas:
lerobot-train \
--dataset.repo_id=your_dataset \
--policy.type=pi0 \
--policy.use_relative_actions=true \
--policy.relative_exclude_joints='["gripper"]'O parâmetro relative_exclude_joints especifica as juntas que devem permanecer no espaço absoluto. Por exemplo, os comandos de garras são tipicamente binários (abrir/fechar) e não se beneficiam da codificação relativa.
Para configurações de política que definem action_feature_names, make_policy preenche essa lista a partir dos metadados names do recurso de ação do conjunto de dados.
Os nomes podem ser uma sequência plana ou um dicionário cujos valores são todas listas ou tuplas.
Por exemplo, {"arm": ["shoulder", "elbow"], "hand": ["gripper"]} se torna ["shoulder", "elbow", "gripper"], e não as chaves dos grupos.
A ordem de inserção dos grupos e a ordem dentro de cada grupo são preservadas, portanto, declare os nomes na mesma ordem do vetor de ação.
Mapeamentos legados de nome para índice mantêm seu comportamento de ordem de chaves.
Combinando ações relativas com RTC
RTC executa a inferência da política em alta frequência e envia as ações para o robô conforme são previstas, em vez de aguardar um chunk completo. Ações relativas e RTC são totalmente compatíveis: como cada chunk no modo relativo referencia o mesmo estado atual (capturado no início da inferência), cada ação prevista no chunk permanece um deslocamento válido, mesmo que o robô já tenha se movido. Não é necessário tratamento especial — RelativeActionsProcessorStep faz o cache do estado uma vez por chamada de inferência e AbsoluteActionsProcessorStep o aplica a cada ação na saída transmitida.
Combinando ações relativas com o espaço EE
Ações relativas funcionam tanto no espaço articular quanto no espaço do efector final. Por exemplo, se seu conjunto de dados armazena ações do efector final, a codificação relativa as converte em deslocamentos a partir da pose atual do efector final:
current_ee_state = [x: 0.25, y: -0.10, z: 0.15, gripper: 0.8]
absolute_ee_chunk = [
[0.26, -0.09, 0.16, 0.8],
[0.28, -0.07, 0.18, 0.8],
]
relative_ee_chunk = [
[0.01, 0.01, 0.01, 0.0], # offset from current EE pose
[0.03, 0.03, 0.03, 0.0], # offset from current EE pose
]Resumo do Pipeline de Processamento
Aqui está como os diferentes processadores se compõem. Cada seta é uma etapa de processador e eles podem ser encadeados em um RobotProcessorPipeline ou PolicyProcessorPipeline:
┌─────────────────────────────────────────┐
Action Space │ Joint Space ←──IK──→ EE Space │
│ ForwardKinematicsJointsToEE │
│ InverseKinematicsEEToJoints │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
Representation │ Absolute ←────→ Relative │
│ RelativeActionsProcessorStep (pre) │
│ AbsoluteActionsProcessorStep (post) │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
Normalization │ Raw ←────→ Normalized │
│ NormalizerProcessorStep (pre) │
│ UnnormalizerProcessorStep (post) │
└─────────────────────────────────────────┘A typical training preprocessor might chain: raw absolute joint actions → relative → normalize. A typical inference postprocessor: unnormalize → absolute → (optionally IK to joints).
Referências
- Universal Manipulation Interface (UMI) - Chi et al., 2024. Define a representação de ação de trajetória relativa e a compara com ações absolutas e delta.
- Introdução aos Processadores - Como funcionam os pipelines de processadores no LeRobot.
examples/so100_to_so100_EE/- Exemplo completo de gravação e avaliação com ações no espaço EE.