Repository navigation
Task/hri 7607 add act training relative pose - #66
Merged
Merged
Conversation
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>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
policies/lerobot_plugins/relative_pose.py):T_cur^-1 * T_action, whereT_curis the newest observed pose. Rollout converts each chunk back withT_cur * T_rel.tcp_motion_<ms>ms,tcp_rotation_wrt_start) normalize to themselves. Before, mean/std blew a fast turn up to about -110.POST /trainingtakesrelative_pose, for act, diffusion and multi_task_dit only, on datasets with named pose axes.relative_posecheckbox. It is hidden for fine-tunes and warns when temporal ensembling is on.state_names.jsonsidecar.info.jsonor the state width.rollout/pose_history.pycomputes UMI's pose inputs (recent motion, rotation since start) from the measured TCP poses each tick, in both runners.gripper.forceis fed the gripper's measured force.warmup_inferences, default 3) before the first tick, so compiling no longer drops the first chunk's waypoints.FLEXIV_TRAINER_ROLLOUT__MAX_STEPS, the warm-up, and how settings map to environment variables.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.Notes