Skip to content

jmni/zarr_registry - #600

Open
jaynye wants to merge 6 commits into
mainfrom
jmni/zarr-registry
Open

jmni/zarr_registry#600
jaynye wants to merge 6 commits into
mainfrom
jmni/zarr-registry

Conversation

@jaynye

@jaynye jaynye commented Sep 2, 2026

Copy link
Copy Markdown

Adds a registry for end effector+base factorized embodiments and defines a new transform naming convention A_T_B (frame B to frame A) to remove ambiguity when dealing with robot data

James Miaoxin Ni and others added 6 commits September 2, 2026 13:55
Replace environment-specific Zarr/Lerobot comparison tests with self-contained temporary EVA and human episodes, and restore coverage of the active transform pipelines. Add focused frame-convention and pose-shape unit tests, while constraining pytest discovery to the maintained Zarr test suite.

Adopt explicit A_T_B-style names for camera, head, hand, and gaze transforms across ingestion, visualization, embodiment, and pose utilities. Document extrinsics as ref_T_cam/base_T_cam, correct the inspector interpretation, and retain the same coordinate-transform math.

Also remove stale imports and minor dead code uncovered by test collection, and update the contributor guide and writer diagnostics to describe the unambiguous extrinsics contract.
`zarr_writer.py` and CONTRIBUTING_DATA.md were shipped pointing at
`docs/CONVENTIONS.md` for the `A_T_B` transform naming rule, but the page
itself never landed. Add it, so the normative statement of the convention
exists exactly once and every reference resolves.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MeahyCWrAFdxR8yiGxic6A
…rs and aliases

Phase 1 of DEXTEROUS_EMBODIMENT_DESIGN_V2.md (PR-05 … PR-08), landed together
because the files interleave and the phase ships as one PR. Nothing about the
stored schema, the trained weights or any existing episode changes: this is the
registry the later phases are built on.

PR-05 — one `_EMBODIMENT_CLASSES`. The six-entry name -> class dict was pasted
into `viz_language.py` and again into `dataset_view.py`, the second copy
carrying a comment asking a future editor to keep it in sync with the first.
Both callers now import `get_embodiment_class` from
`egomimic/rldb/embodiment/__init__.py`. Adding the package's `__init__.py` also
means `egomimic.rldb.embodiment` is packaged at all — `find_packages` had been
skipping it, so it was missing from every non-editable install.

PR-06 — an alias table. `get_embodiment_id` was `EMBODIMENT[name.upper()].value`
with no fallback, which is why the 07/08/2026 human-embodiment collapse cost a
fleet-wide "RE-DOWNLOAD your data": the name is baked into each episode's
`zarr.json`, so the rename hard-crashed every cached episode with
`KeyError: 'ARIA_BIMANUAL'`. `registry/aliases.yaml` maps the twelve
`aria_*`/`mecka_*`/`scale_*` names onto `human_*`; a live name always wins over
an alias, so the table can never shadow a current spelling. `eve_*` is
deliberately absent — Eve was a different robot, not a renamed one. The table is
a read shim only: `ZarrWriter.create_and_write` still refuses to *write* a
deprecated name.

PR-07 — `registry/platforms.yaml` + `registry/end_effectors.yaml` and a loader.
The two axes that are actually combinatorial are declared separately: a platform
fixes the arm chain, aux chain, camera set and reference frame; an end-effector
fixes DOF, keypoint topology and `action_space`. Calibration is deliberately
absent, being per-episode data rather than a specification. The loader rejects
unknown fields, unknown action spaces, out-of-range keypoint slots, dof/joint
mismatches and a `reference_frame` naming an undeclared camera — a registry that
silently swallows a typo would be a fifth source of truth beside the four it
replaces.

PR-08 — `Embodiment.resolve()`. Composes a platform with one end-effector per
side, from either an embodiment name or a `morphology` block, and derives
`action_space` from the end-effector classes (mixed sides are refused, not
silently resolved). `Human` and `Eva` are reached through the registry's
`embodiment_class:` escape hatch rather than rewritten: they encode real
subtlety and uniformity is not worth the risk. `EMBODIMENT_CLASSES` is now
*derived* from `platforms.yaml`, so the registry is load-bearing in the same
cycle it lands and cannot quietly go stale.

Adds 51 tests, including the design's acceptance test: swapping the declared
end-effector on a known platform re-routes the head with zero lines of Python.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MeahyCWrAFdxR8yiGxic6A
The draft CI installed from a hand-written `requirements-test.txt` — a third
dependency list beside `pyproject.toml` and `uv.lock`, pinned differently from
both (a CPU torch index, `zarr==3.1.5` restated, `ruff==0.8.6` restated) and
with nothing to keep it honest. CI now syncs the same environment developers
get: `uv sync --locked` from `pyproject.toml` + `uv.lock`, then `uv run` for
collection, tests and lint. `--locked` fails the build if the lock and the
manifest have drifted, which is the check the separate file could never provide.

The locked environment carries the CUDA torch stack, so the job frees the
hosted runner's unused toolchains first and does not cache the ~5 GB uv cache
(it would consume most of the repository's 10 GB Actions quota).

AGENTS.md pointed at `source emimic/bin/activate`, a gitignored directory.
Point it at the uv environment instead, and note the two environment variables
worth setting on a machine with a small home quota — `UV_CACHE_DIR` and
`UV_PYTHON_INSTALL_DIR` — plus `UV_PROJECT_ENVIRONMENT` for a venv that is not
named `.venv`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MeahyCWrAFdxR8yiGxic6A
Replace design narrative with contracts that state inputs, outputs, shapes, frame directions, and failure conditions. Use short, active sentences and consistent terms in comments and reference text.\n\nThis commit does not change runtime code.
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown

Claude Code Review

Review

Summary

Introduces a YAML-based embodiment registry (platforms + end-effectors + aliases) and renames coordinate-frame variables/methods to follow the A_T_B convention. Also adds CI, docs, and a deprecated-name alias shim for cached zarr episodes.

Key concerns

  1. Alias shim only works on read, not writetest_aliases_are_a_read_shim_only confirms ZarrWriter still rejects aria_bimanual. That's the intended contract, but be aware: any scripts still passing legacy vendor names to writers will break. Worth grepping egomimic/scripts/ for aria_bimanual, mecka_bimanual, scale_bimanual string literals before merge — the diff doesn't touch them.

  2. ARIA_T_RGB_CPFARIA_RGB_T_CPF rename — this is a semantic reversal in the new convention (rgb ← cpf vs. old aria "T from rgb to cpf"). Please verify against the original Aria SDK matrix that the underlying numeric values still mean "map CPF → RGB". If the original was already RGB_T_CPF under the new convention (i.e., p_rgb = M @ p_cpf), this is correct. If not, the gaze viz will silently render in the wrong frame. This matrix is used only in viz, so no training regression, but worth a manual check by someone who knows the Aria SDK convention.

  3. Registry says reference_frame: camera:front_1 for EVA, but docs say extrinsics are base_T_cam — these are consistent (extrinsics express camera pose in base frame, and calibration reference is the front camera), but the semantics of reference_frame in platforms.yaml are underdocumented. What is it used for downstream? Currently nothing in the diff consumes it — is this a future hook? If unused, drop it or add a docstring pointing at the consumer.

  4. Cached EMBODIMENT_CLASSES at import time_build_embodiment_classes() runs during egomimic.rldb.embodiment import and calls _import_embodiment_class for every platform. This introduces an import-time dependency chain: importing the embodiment package now imports Eva and Human transitively via string paths. Fine now, but if a platform ever lists a class with heavy deps (torch models, etc.), it will slow all imports. Consider lazy resolution in get_embodiment_class.

  5. ResolvedEmbodiment.get_keymap / get_transform_list delegate to class, ignoring end-effector selection — the test test_resolve_delegates_to_the_hand_written_pipeline shows eva.get_transform_list(...) == Eva.get_transform_list(...). So resolving {platform: eva_x5, end_effector: mano_hand} returns the jaw transform pipeline. This makes the "swap end-effectors without code" promise (test name test_a_new_hand_on_a_known_platform_costs_no_code) misleading — the registry lets you declare the swap, but the pipeline is still hand-written per class. Recommend either (a) documenting this limitation clearly in ResolvedEmbodiment docstring, or (b) renaming the test to reflect that only metadata is registry-driven today.

Suggestions

  • Add a migration test that loads a real cached zarr with embodiment="aria_bimanual" in attrs and confirms training data loading still works end-to-end (not just get_embodiment_id).
  • Document what reference_frame in platforms.yaml will be used for, or drop it until a consumer exists.
  • In CONVENTIONS.md, add one sentence stating this is a naming-only migration — no stored data changes — since that's the load-bearing claim.
  • Consider adding ruff check to pre-commit given CI now enforces it.
  • The variable renames in ActionChunkCoordinateFrameTransform.transform (chunk_se3chunk_pose_transforms, etc.) are verbose but clearer. Fine.
  • Minor: _build_eva_bimanual_eef_frame_transform_list and _build_eva_bimanual_transform_list have duplicated extrinsicsbase_T_cam_pose conversion logic. Consider a small helper to reduce drift risk.

Verdict: Comment

The registry design is solid and the naming convention doc is welcome. Before approving I'd want:

  1. Confirmation that no writer scripts still pass deprecated names (grep result).
  2. Confirmation on the ARIA_RGB_T_CPF semantic direction against the Aria SDK.
  3. A real cached-episode load test to prove the alias shim works end-to-end.

None of these should block landing if verified out-of-band, but they aren't visible in this diff.


Reviewed by Claude · Review workflow

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