Skip to content

feat(zarr): persist camera intrinsics in zarr.json#386

Open
ElmoPA wants to merge 3 commits into
mainfrom
elmo/intrinsic-zarr
Open

feat(zarr): persist camera intrinsics in zarr.json#386
ElmoPA wants to merge 3 commits into
mainfrom
elmo/intrinsic-zarr

Conversation

@ElmoPA

@ElmoPA ElmoPA commented May 4, 2026

Copy link
Copy Markdown
Contributor

Add an intrinsics parameter to ZarrWriter (and create_and_write) that
serializes a single np.ndarray K matrix or a {camera_key: K} dict into
zarr metadata. Expose ZarrEpisode.intrinsics / ZarrDataset.intrinsics
that read it back as ndarray(s), or None when not written.

This unblocks per-episode intrinsics so viz no longer has to rely on
class-level Embodiment.INTRINSICS constants.

ElmoPA commented May 4, 2026

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@ElmoPA ElmoPA marked this pull request as ready for review May 4, 2026 18:57
@ElmoPA ElmoPA force-pushed the elmo/intrinsic-zarr branch 2 times, most recently from 66a49fd to f058830 Compare May 5, 2026 16:33
@ElmoPA ElmoPA force-pushed the elmo/lightwheel-emb branch from 5265946 to fb7e066 Compare June 12, 2026 20:59
@ElmoPA ElmoPA force-pushed the elmo/intrinsic-zarr branch 3 times, most recently from c73430a to 75a9774 Compare June 16, 2026 20:24
@ElmoPA ElmoPA changed the base branch from elmo/lightwheel-emb to graphite-base/386 June 16, 2026 21:03
@ElmoPA ElmoPA force-pushed the elmo/intrinsic-zarr branch from 75a9774 to 5f26d41 Compare June 16, 2026 21:03
@ElmoPA ElmoPA force-pushed the graphite-base/386 branch from fb7e066 to 1c23942 Compare June 16, 2026 21:03
@ElmoPA ElmoPA changed the base branch from graphite-base/386 to main June 16, 2026 21:03
@ElmoPA ElmoPA force-pushed the elmo/intrinsic-zarr branch 10 times, most recently from c9cf920 to fea4ea8 Compare June 22, 2026 20:59
ElmoPA and others added 3 commits June 23, 2026 21:29
…odiments

Squashed combining the intrinsics/embodiment work:
- move intrinsics/extrinsics into embodiment classes (remove CameraTransforms)
- gaze viz mode + zarr_data_viz notebook update; add LightWheel embodiment
- persist camera intrinsics in zarr.json; make them MANDATORY (validated {camera_key: 3x4} dict)
- collapse aria/mecka/scale/lightwheel human data into human_* (ids 1-3); eva = 4-6
- strict extrinsics (None or non-empty dict); embodiment validated at write time
- aria right-hand ee-pose + wrist-pose orientation fix
- sweep all hydra configs + tests to the collapsed embodiment

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop RIGHT_HAND_ORIENTATION_FIX (ee, diag(-1,-1,1) X/Y) and
RIGHT_WRIST_ORIENTATION_FIX (wrist, diag(-1,1,-1) X/Z) so the right
hand uses T_ROT_CAM like the left. Verified in dataset viz: both hands
share one convention after revert. Intrinsics + human_bimanual kept.
@ElmoPA ElmoPA force-pushed the elmo/intrinsic-zarr branch from d70ad6c to e84a5e9 Compare June 24, 2026 01:29
@github-actions

Copy link
Copy Markdown

Claude Code Review

Review of PR #386

Summary

This PR is described as "persist camera intrinsics in zarr.json" but actually does much more than that — it collapses all human embodiments (aria_*, mecka_*, scale_*) into a single human_* embodiment, rewrites coordinate conventions for Aria, restructures embodiment classes, and updates ~30 config files. The intrinsics work itself looks reasonable, but the scope creep is dangerous.

Key concerns

1. PR scope vs. title — major mismatch

The title says "persist camera intrinsics" but the diff includes:

  • Embodiment collapse (aria_bimanualhuman_bimanual, Aria/Mecka/Scale classes → single Human)
  • Aria right-hand EE-pose / wrist-pose orientation fix (README admits this is a canonical convention change)
  • Removal of CameraTransforms from HPT.__init__ (dead param now)
  • Embodiment ID renumbering (1-3 for human, 4-6 for eva — was 3,4,5 for aria, 6,7,8 for eva)

Each of these is a separate, breaking change. They should be separate PRs, or at minimum the PR title/description must say so. As-is, reviewers will under-scrutinize the orientation fix and the embodiment renumbering.

2. Embodiment ID renumbering will silently break old checkpoints/data

Old IDs: aria_bimanual=5, eva_bimanual=8. New IDs: human_bimanual=3, eva_bimanual=6. Any code, checkpoint, or stored norm-stat keyed on the integer ID will silently mis-map. Was there a discussion to keep new IDs disjoint from old (e.g., start at 20)? Reusing IDs 1-6 with different meanings is a footgun.

3. SQL/DB inconsistency is now load-bearing and undocumented in code

human.yaml filter still queries robot_name == 'aria_bimanual' (correctly, since SQL hasn't been migrated), but the data config is keyed human_bimanual, and CONTRIBUTING_DATA.md tells contributors to write embodiment="human_bimanual" in both zarr.attrs and the DB row. So:

  • Old episodes: DB says aria_bimanual, zarr says aria_bimanual (until reprocessed).
  • New episodes per the new docs: DB says human_bimanual, zarr says human_bimanual.
  • The human.yaml filter only matches the old. New contributors following the new docs will be filtered out.

This needs to be reconciled before merge — either migrate the SQL column now, or document a transitional dual-write/dual-read.

4. Aria orientation "fix" is a coordinate-frame change

README says: "fixed the right-hand EE-pose and wrist-pose orientations ... so that, after reprocessing, human (aria) hand orientations follow the same canonical right-handed convention as the robot (Eva)". This means:

  • All existing Aria zarrs are now wrong in the new convention.
  • Any training run using existing Aria data + new code will silently train on inconsistent right-hand orientations vs. the new transforms.
  • Norm stats computed on old data won't match new data.

This must be gated explicitly. At minimum: a version field in zarr.attrs (e.g., convention_version: 2) and a runtime assertion in the loader. Otherwise mixed old/new caches will silently corrupt training.

5. Intrinsics validation in create_and_write

The doc claims create_and_write raises if intrinsics is not a non-empty dict, and validates 3×4 shape. I don't see the actual zarr_writer.py changes in this diff (truncated at 80k). Please confirm:

  • The "front" key requirement from §10 validation is also enforced at write time (not just in validate_episode).
  • extrinsics=None is the documented default for human, and the writer signature reflects that (not a required kwarg).
  • The 3×4 (zero last column) convention is enforced, not 3×3. The doc is unusually emphatic about this — suggests it has bitten people before.

6. Test coverage looks thin for the scope

Only test_pi.py is updated, and only with string rename aria_bimanualhuman_bimanual. For a change this large I'd expect:

  • Tests that ZarrWriter.create_and_write raises on missing/malformed intrinsics.
  • Tests that ZarrEpisode.intrinsics round-trips ndarray and dict correctly.
  • Tests that Human.get_keymap(has_head_pose=False) produces the right keys.
  • A test that the merged mecka + scale filter in industry_eva_pi.yaml actually loads both labs.

7. industry_eva_pi.yaml and mecka_scale_cotrain_pi.yaml — judgment call buried in comments

The comment "JUDGMENT CALL to sanity-check: mecka has a head pose and scale does not, so the merged human keymap uses has_head_pose=false (scale-compatible)" is exactly the kind of decision that silently regresses training. Mecka had a head pose; dropping it for cotrain means the model loses that signal on mecka data. Has anyone confirmed this doesn't regress the active Mecka+Eva cotrain experiments?

8. Minor

  • hpt.py: self.camera_transforms = camera_transforms removed but the param is still in __init__ signature — fine, but worth a deprecation comment on the param itself (only in the YAML it has one).
  • scale_pi.yaml valid filter is broken: task: - "lambda row: ..." is a list under a task key, not a filter_lambdas list. This was probably broken before, but worth fixing while touching.
  • pi_cartesian.yaml: missing trailing newline

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