Skip to content

feat(imitation): add native OpenYAM collection - #3854

Closed
TomCC7 wants to merge 31 commits into
mainfrom
feat/openyam-native-collection
Closed

TomCC7 wants to merge 31 commits into
mainfrom
feat/openyam-native-collection

Conversation

@TomCC7

@TomCC7 TomCC7 commented Sep 1, 2026 •

Copy link
Copy Markdown
Member

Contribution path

Problem

  • Collection needs to record robot streams with their dataset schema so offline export preserves camera mappings and joint order.

Solution

  • Replace the Python collection recorder with a RustRecorder subclass that saves MCAP/SQLite and schema.json from one CollectionProfile.
  • Add OpenYAM Quest collection and publish accepted position commands from the base ControlCoordinator.
  • Export recordings to LeRobot/HDF5, reconstruct partial command updates, and exclude discarded or incomplete episodes.
  • Keep base recorder changes to subclass path resolution and disabled-topic filtering; update message bindings to preserve episode timestamps.
  • Migrate xArm/Piper collection; keep G1 on the Python recorder for its shared-memory camera transport.

How to Test

  • Run dimos --can-port follower_l run openyam-quest-collection --recorder.recording recordings/session-001 --episodes.task "pick up the cube"; Quest B starts/saves and Y discards.
  • 254 stack tests and 9 native integration tests passed, plus mypy and hooks; CI installs libturbojpeg for Python JPEG readback tests.
  • Real hardware collection still needs verification.

AI assistance

  • OpenAI Codex (GPT-5 and GPT-6) assisted extensively with implementation, tests, documentation, and stack updates; description edited by Codex (agent).

Checklist

  • I have read and approved the CLA.

@TomCC7
TomCC7 changed the base branch from feat/experimental-lerobot-policy to feat/openyam-lerobot-policy-runtime September 1, 2026 02:57
@TomCC7
TomCC7 changed the base branch from feat/openyam-lerobot-policy-runtime to feat/experimental-lerobot-policy September 1, 2026 03:06
@codecov

codecov Bot commented Sep 1, 2026 •

Copy link
Copy Markdown

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
6225 1 6224 293
View the full list of 1 ❄️ flaky test(s)
dimos.e2e_tests.test_voice_browser::test_hold_to_talk_ships_a_decodable_recording[firefox]

Flake rate in main: 35.29% (Passed 33 times, Failed 18 times)

Stack Traces | 4.14s run time
voice_bridge = ('http://127.0.0.1:58757/', [AudioChunk(sid='676a352f-a4c3-44b8-8568-8f3b55dd77a5', seq=0, mime='audio/webm;codecs=opu...), AudioChunk(sid='676a352f-a4c3-44b8-8568-8f3b55dd77a5', seq=1, mime='audio/webm;codecs=opus', data=b'', final=True)])
fake_mic_page = <Page url='http://127.0.0.1:58757/'>

    def test_hold_to_talk_ships_a_decodable_recording(
        voice_bridge: tuple[str, list[AudioChunk]], fake_mic_page: Page
    ) -> None:
        url, chunks = voice_bridge
        chunks.clear()  # the module fixture is shared across both engines
        fake_mic_page.goto(url)
        mic = fake_mic_page.get_by_test_id("chat-audio_in-mic")
        # Enabled == transport connected; the manifest already placed the panel.
        expect(mic).to_be_enabled(timeout=120_000)
        expect(mic).to_have_attribute("data-state", "idle")
    
        mic.hover()
        fake_mic_page.mouse.down()
        expect(mic).to_have_attribute("data-state", "recording", timeout=15_000)
        fake_mic_page.wait_for_timeout(1_500)
        fake_mic_page.mouse.up()
        expect(mic).to_have_attribute("data-state", "idle", timeout=30_000)
    
        # The bridge acks each frame only after Out.publish() returned, so by the
        # time the page settled back to idle the port has (about) everything;
        # tolerate the last callback still crossing threads.
        deadline = time.monotonic() + 10.0
        while time.monotonic() < deadline and not any(chunk.final for chunk in chunks):
            time.sleep(0.1)
    
        assert chunks and chunks[-1].final and chunks[-1].data == b""
        assert {chunk.sid for chunk in chunks} == {chunks[0].sid}
        assert [chunk.seq for chunk in chunks] == list(range(len(chunks)))
        assert chunks[0].mime.startswith("audio/")
        audio = b"".join(chunk.data for chunk in chunks)
        assert len(audio) > 1_000  # ~1.5 s of compressed audio, not an empty shell
        # Whatever container this engine produced, the owned ffmpeg decode turns
        # it into the PCM shape the Whisper pipeline assumes.
        event = decode_audio_bytes(audio)
        assert event is not None and event.sample_rate == 16_000
>       assert event.data.ndim == 1 and event.data.shape[0] > 8_000  # > 0.5 s
E       assert (1 == 1 and 7256 > 8000)
E        +  where 1 = array([  0.0013733,   0.0025635,  0.00094604, ...,           0,           0,           0], shape=(7256,), dtype=float32).ndim
E        +    where array([  0.0013733,   0.0025635,  0.00094604, ...,           0,           0,           0], shape=(7256,), dtype=float32) = AudioEvent(shape=(7256,), dtype=float32, sample_rate=16000, channels=1).data

audio      = b'\x1aE\xdf\xa3\x01\x00\x00\x00\x00\x00\x00\x1fB\x86\x81\x01B\xf7\x81\x01B\xf2\x81\x04B\xf3\x81\x08B\x82\x84webmB\x87\...5\xff\xef\x1b\xa1\xcf\xc5\x1d\xeb\x98\xff?\xbf\xe3]/\xf1\'\x8b\x94A\xd2\x1b\x83\x13\x88\xded\xaf\xd0\xc9\xa9\x04L\xe2I'
chunks     = [AudioChunk(sid='676a352f-a4c3-44b8-8568-8f3b55dd77a5', seq=0, mime='audio/webm;codecs=opus', data=b'\x1aE\xdf\xa3\x01...e), AudioChunk(sid='676a352f-a4c3-44b8-8568-8f3b55dd77a5', seq=1, mime='audio/webm;codecs=opus', data=b'', final=True)]
deadline   = 994250.3799415
event      = AudioEvent(shape=(7256,), dtype=float32, sample_rate=16000, channels=1)
fake_mic_page = <Page url='http://127.0.0.1:58757/'>
mic        = <Locator frame=<Frame name= url='http://127.0.0.1:58757/'> selector='internal:testid=[data-testid="chat-audio_in-mic"s]'>
url        = 'http://127.0.0.1:58757/'
voice_bridge = ('http://127.0.0.1:58757/', [AudioChunk(sid='676a352f-a4c3-44b8-8568-8f3b55dd77a5', seq=0, mime='audio/webm;codecs=opu...), AudioChunk(sid='676a352f-a4c3-44b8-8568-8f3b55dd77a5', seq=1, mime='audio/webm;codecs=opus', data=b'', final=True)])

dimos/e2e_tests/test_voice_browser.py:128: AssertionError

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@TomCC7
TomCC7 force-pushed the feat/openyam-native-collection branch from 17256b0 to 933facf Compare September 1, 2026 04:46
@TomCC7
TomCC7 force-pushed the feat/experimental-lerobot-policy branch from 34ff638 to 89cc9f6 Compare September 1, 2026 05:15
@TomCC7
TomCC7 force-pushed the feat/openyam-native-collection branch from 933facf to 0307ebb Compare September 1, 2026 05:15
@TomCC7
TomCC7 force-pushed the feat/experimental-lerobot-policy branch from 89cc9f6 to b8a7241 Compare September 1, 2026 17:00
@TomCC7
TomCC7 force-pushed the feat/openyam-native-collection branch 2 times, most recently from 13940ff to 275e358 Compare September 1, 2026 17:16
@TomCC7
TomCC7 force-pushed the feat/experimental-lerobot-policy branch 2 times, most recently from 0c8996a to 564d788 Compare September 1, 2026 17:17
@TomCC7
TomCC7 force-pushed the feat/openyam-native-collection branch from 275e358 to 31dd683 Compare September 1, 2026 17:17
Comment thread dimos/experimental/memory/README.md Resolved
@TomCC7
TomCC7 force-pushed the feat/openyam-native-collection branch 2 times, most recently from 2ca3643 to c871ce7 Compare September 1, 2026 18:54
@TomCC7
TomCC7 force-pushed the feat/experimental-lerobot-policy branch from 582da9d to 80b882f Compare September 1, 2026 18:54
Comment thread dimos/imitation/dataprep/cli.py Resolved
Comment thread dimos/hardware/sensors/camera/module.py Resolved
@TomCC7
TomCC7 marked this pull request as ready for review September 2, 2026 00:50
TomCC7 and others added 22 commits September 20, 2026 21:52
Co-authored-by: Mustafa Bhadsorawala <39084056+mustafab0@users.noreply.github.com>
(cherry picked from commit 5fe19db89be37221b7ee482fb878692e60a9115c)

@github-actions github-actions Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

go2 replay realtime

Details
Benchmark suite Current: 4dc0d8d Previous: 58acbee Ratio
first frame wall 9.656 s 9.623 s 1.00
first frame cpu 19.912 s 21.264 s 0.94
run cpu 33.634 s 33.16 s 1.01
run cpu (user) 26.109 s 24.525 s 1.06
run cpu (system) 7.525 s 8.635 s 0.87
peak memory 2741.066 MB 2701.34 MB 1.01
peak threads 415 threads 408 threads 1.02
disk read 33.031 MB 19.965 MB 1.65
disk write 10.895 MB 11.285 MB 0.97
network (transport) 2738.989 MB 2725.519 MB 1.00
network (external rx) 0.063 MB 0.069 MB 0.91
network (external tx) 0.158 MB 0.346 MB 0.46

This comment was automatically generated by workflow using github-action-benchmark.

@github-actions github-actions Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'go2 replay realtime'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.08.

Benchmark suite Current: 4dc0d8d Previous: 58acbee Ratio
disk read 33.031 MB 19.965 MB 1.65

This comment was automatically generated by workflow using github-action-benchmark.

@TomCC7

TomCC7 commented Oct 1, 2026

Copy link
Copy Markdown
Member Author

Replaced by #4343 on a compliant branch at the identical head commit 4dc0d8dccdb941788e5f93a7cf248b3a334ce3b5. The seven layer diffs and downstream PR IDs were verified unchanged in native stack #4345: #4343 → #4344 → #3921 → #3931 → #3942 → #4088 → #4156.

Closing this PR only for the user-approved branch naming migration. This branch and all review comments remain available; unresolved findings and existing main/CI blockers are not marked resolved. No behavior changes were included in this migration.

This branch was previously deployed

1 inactive deployment
cachix — 4dc0d8dc Deployed Sep 30, 2026 by TomCC7 via cachix-build-macos #11138
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.

2 participants