Skip to content

Task/hri 7607 add act training relative pose - #66

Merged
xyyeh-flexiv merged 7 commits into
mainfrom
task/HRI-7607-add-act-training-relative-pose
Nov 2, 2026
Merged

xyyeh-flexiv merged 7 commits into
mainfrom
task/HRI-7607-add-act-training-relative-pose

Conversation

@xyyeh-flexiv

Copy link
Copy Markdown
Collaborator

Train and roll out ACT with chunk-relative SE(3) pose actions

Policies trained on absolute poses learn the frame they were recorded in: the SLAM map for a UMI gripper, the robot base for teleop. This adds UMI-style relative pose actions as a training option, so one policy can be trained on both teleop and UMI data and rolled out on the robot.

What changes

  • Relative pose (policies/lerobot_plugins/relative_pose.py):
    • Each action pose in a chunk is trained as T_cur^-1 * T_action, where T_cur is the newest observed pose. Rollout converts each chunk back with T_cur * T_rel.
    • LeRobot processor steps wrap the normalizers. The pre step makes action poses relative and puts the identity in place of the state pose. The post step converts back. They are saved with the checkpoint, so rollout needs no setting.
    • Poses are found by axis name, in both this repo's layout and the UMI export's.
    • Action statistics are recomputed in the relative frame.
  • Normalization as UMI does it:
    • The rotation inputs (tcp_motion_<ms>ms, tcp_rotation_wrt_start) normalize to themselves. Before, mean/std blew a fast turn up to about -110.
    • The gripper width maps its recorded range onto [-1, 1].
  • Training:
    • POST /training takes relative_pose, for act, diffusion and multi_task_dit only, on datasets with named pose axes.
    • The training form has a relative_pose checkbox. It is hidden for fine-tunes and warns when temporal ensembling is on.
    • Each checkpoint gets a state_names.json sidecar.
  • Rollout:
    • Feeds exactly the trained state columns, in trained order. Old checkpoints fall back to their dataset's info.json or the state width.
    • rollout/pose_history.py computes UMI's pose inputs (recent motion, rotation since start) from the measured TCP poses each tick, in both runners. gripper.force is fed the gripper's measured force.
    • The anchor is held while a cached chunk plays out.
    • Refuses ACT with temporal ensembling, relative-pose step skills, and absolute-pose checkpoints trained on a UMI export (those would drive the arm to SLAM map coordinates).
    • Warms up the policy (warmup_inferences, default 3) before the first tick, so compiling no longer drops the first chunk's waypoints.
  • README: covers capping a rollout with FLEXIV_TRAINER_ROLLOUT__MAX_STEPS, the warm-up, and how settings map to environment variables.
  • open_items/todo.md: lists what is done, what is open, and what to check before rolling out.

Tests

  • tests/test_relative_pose.py: the conversion round trip, the held anchor, layout checks, which statistics change, rotations passing through and the width mapping onto [-1, 1].
  • tests/test_pose_history.py: UMI pose inputs computed at rollout.
  • tests/test_rollout_observations.py, tests/test_rollout_service.py: state fed by name, and the rollout refusals.
  • tests/test_hub_integration.py: the state names sidecar.
  • UI contract tests follow the asset version bump.

Notes

  • Relative pose rollout will disable temporal ensembling

xyyeh-flexiv and others added 6 commits October 27, 2026 15:17
Adds UMI-style relative pose actions as an option for training. Each
action pose in a chunk is trained as T_cur^-1 * T_action, where T_cur is
the newest observed pose. Rollout converts each predicted chunk back with
T_cur * T_rel.

- New LeRobot processor steps
  (policies/lerobot_plugins/relative_pose.py):
  - The pre step makes the action poses relative, and replaces the pose
    in observation.state with the identity.
  - The post step converts predicted chunks back to absolute poses.
  - The pose is found by its axis names.
- POST /training takes a `relative_pose` flag. Training only accepts it
  for act, diffusion and multi_task_dit, and only on datasets with named
  pose axes.
- Rollout holds the anchor while a cached chunk plays out. It refuses
  two cases: ACT with temporal ensembling, and relative-pose step skills.
- tests/test_relative_pose.py covers the conversion round trip, the held
  anchor, and the layout checks.
- open_items/relative_pose.md lists what is still open, such as rollout
  refusing the UMI export's state width.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Follows 65b38d0 (chunk-relative SE(3) pose actions), so ACT can be
trained with and without relative pose on teleop and UMI data.

- Rollout feeds the trained state columns. Training writes the
  dataset's observation.state names beside each checkpoint as
  state_names.json. Rollout builds each arm's full 23-value state and
  feeds the policy only the named columns, in trained order. Checkpoints
  without the sidecar take the names from their dataset's info.json, or
  fall back to matching the state width.
- UMI's pose inputs at rollout (rollout/pose_history.py). A UMI export
  can add the recent motion (tcp_motion_<ms>ms.*,
  gripper.width_change_<ms>ms) and the rotation since start
  (tcp_rotation_wrt_start.*). PoseHistory computes the same values from
  the robot's measured TCP poses each tick, in both runners.
- A tactile grip-force column (gripper.force) is fed the electric
  gripper's measured force; a gripper with no force reading is refused
  by name.
- The training form has a relative_pose checkbox for act, diffusion and
  multi_task_dit. It is hidden for fine-tuning, and warns when temporal
  ensembling is also on.
- UMI poses as absolute poses are refused. They are in a SLAM map frame
  (meta/flexiv_extras.json world_frame), so an absolute policy would
  drive the arm to map coordinates. Training refuses it without relative
  pose; rollout refuses an absolute checkpoint whose local training
  dataset is a UMI export.
- open_items/relative_pose.md is merged into open_items/todo.md, which
  lists what is done, what is open, and what to check before rolling
  out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The exporter no longer tares the fingertip tactile force, so the notes
on the tactile grip-force input describe the recorded |Fz|, and the
training/rollout sensor mismatch item notes its open-gripper drift.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With relative pose on, the plugin rewrites the dataset's statistics in
lerobot-train before the processors are built, so new runs and
fine-tunes use them and the checkpoint's saved processor carries them to
resume and rollout.

- The rotation entries of tcp_motion_<ms>ms and tcp_rotation_wrt_start
  get statistics that normalize them to themselves in every LeRobot mode
  (mean 0 / std 1, min -1 / max 1, quantiles -1 / 1). Their diagonal
  entries stay near 1, so mean/std blew a fast turn up to about -110 on
  the screw export.
- The gripper width, in state and action, gets mean (min+max)/2 and std
  (max-min)/2, so its recorded range maps onto [-1, 1] instead of about
  [-1.2, +1.4]. The values stay in metres. A width that never changes
  keeps its statistics.
- tests/test_relative_pose.py covers which columns change, and that the
  normalizer passes the rotations through and maps the width range onto
  [-1, 1].
- open_items/todo.md moves the normalization item to Done and
  renumbers the open items.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
torch.compile and CUDA-graph recording ran inside the first inference of
the control loop, so the first chunk's waypoints were already past due
and dropped. The waypoint runner now runs warmup_inferences (default 3)
throwaway inferences on one real observation, on the planner thread,
before the waypoint executor starts. It then resets the policy queue,
the relative-pose anchor and the pose history, and logs the timings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread tests/test_relative_pose.py Fixed
Comment thread tests/test_relative_pose.py Fixed
Comment thread tests/test_relative_pose.py Fixed
Comment thread tests/test_relative_pose.py Fixed
Comment thread tests/test_relative_pose.py Fixed
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
@xyyeh-flexiv
xyyeh-flexiv merged commit 0588d77 into main Nov 2, 2026
10 checks passed
@xyyeh-flexiv
xyyeh-flexiv deleted the task/HRI-7607-add-act-training-relative-pose branch November 2, 2026 23:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant