Skip to content

Adding PS4Eye feature to current repository. First batch of test succ…#2993

Draft
rafafelixphd wants to merge 31 commits intohuggingface:mainfrom
rafafelixphd:feature/ps4eye
Draft

Adding PS4Eye feature to current repository. First batch of test succ…#2993
rafafelixphd wants to merge 31 commits intohuggingface:mainfrom
rafafelixphd:feature/ps4eye

Conversation

@rafafelixphd
Copy link
Copy Markdown

@rafafelixphd rafafelixphd commented Feb 20, 2026

feat(cameras): Implement Sony PS4 Eye stereo camera driver

Type / Scope

  • Type: Feature
  • Scope: lerobot/cameras/ps4eye

Summary / Motivation

The PS4 Eye is an inexpensive (~$10–15 used) stereo USB camera that enumerates as a standard UVC device. This PR creates the full driver, bringing the PS4 Eye to the same standard as OpenCVCamera.

The key design challenge is running two eye instances (left / right) as independent cameras in the lerobot pipeline without opening the device twice. A class-level shared VideoCapture registry solves this: the device is opened once and both instances read from the same raw frame buffer, each applying its own stereo crop.

Related issues

  • Related: # (none — community contribution)

What was created

No breaking changes. Existing camera types are unaffected.

How was this tested (or how to run locally)

Verified on macOS (Apple Silicon) with a PS4 Eye connected via USB.

Find the device index:

lerobot-find-cameras ps4eye

--- Detected Cameras ---
Camera #0:
  Name: PS4 Eye @ 1
  Type: PS4Eye
  Id: 1
  Backend api: AVFOUNDATION
  Default stream profile:
    Width: 1748
    Height: 408
    Fps: 30.00003
--------------------

Run teleoperation with both eyes as independent cameras:

lerobot-teleoperate \
  --robot.type=so101_follower \
  --robot.port=/dev/tty.usbmodemXXX \
  --robot.id=my_robot \
  --teleop.type=so101_leader \
  --teleop.port=/dev/tty.usbmodemYYY \
  --teleop.id=my_leader \
  --robot.cameras='{ left: {type: ps4eye, index_or_path: 1, width: 3448, height: 808, fps: 30, eye: left}, right: {type: ps4eye, index_or_path: 1, width: 3448, height: 808, fps: 30, eye: right}}' \
  --display_data=true
image

Python API:

cameras = {
    "left":  PS4EyeCamera(PS4EyeCameraConfig(index_or_path=1, eye="left",  width=3448, height=808, fps=30)),
    "right": PS4EyeCamera(PS4EyeCameraConfig(index_or_path=1, eye="right", width=3448, height=808, fps=30)),
}
for cam in cameras.values():
    cam.connect()
left_img  = cameras["left"].read()   # → (800, 1264, 3)
right_img = cameras["right"].read()  # → (800, 1264, 3)

Manual checks:

  • ✅ Both eyes resolve to the correct crop dimensions
  • ✅ Two instances share one VideoCapture (device opened once)
  • read_latest() available immediately after connect()
  • ✅ Full teleoperation loop at 60 Hz with --display_data=true
  • ✅ Clean connect / disconnect lifecycle

No automated tests in this PR (can be added as follow-up).

Checklist (required before merge)

  • Linting/formatting run (pre-commit run -a)
  • All tests pass locally (pytest)
  • Documentation updated
  • CI is green

Reviewer notes

  • The _SHARED_CAPTURES class-level registry in camera_ps4eye.py is the core non-obvious design — worth a close read
  • Firmware upload (needed on some Linux distros to enumerate the device) is intentionally out of scope
  • EyeSelection enum instead of Literal is a draccus requirement — see inline comment in configuration_ps4eye.py

rafafelixphd and others added 30 commits February 20, 2026 17:25
…gingface#2974)

* feat(dataset): init stream encoding

* feat(dataset): use threads to fix frame pickle latency

* refactor(dataset): remove HW encoded related changes

* add lp (huggingface#2977)

* feat(dataset): add Hw encoding + log drop frames (huggingface#2978)

* chore(docs): add streaming video encoding guide

* fix(dataset): style docs + testing

* chore(docs): simplify sttreaming video encoding guide

* chore(dataset): add commands + streaming encoding default false + print note if false + queue default is now 30

* chore(docs): add verification note advice

* chore(dataset): adjusting defaults & docs for streaming encoding

* docs(scripts): improve docstrings

* test(dataset): polish streaming encoding tests

* chore(dataset): move FYI log related to streaming

* chore(dataset): add arg vcodec to suggestions

* refactor(dataset): better handling for auto and available vcodec

* chore(dataset): change log level

* docs(dataset): add note related to training performance vcodec

* docs(dataset): add more notes to streaming encoding

---------

Co-authored-by: Caroline Pascal <caroline8.pascal@gmail.com>
Co-authored-by: Pepijn <pepijn@huggingface.co>
Signed-off-by: Steven Palma <imstevenpmwork@ieee.org>
Co-authored-by: Steven Palma <imstevenpmwork@ieee.org>
* feat(motors): add initial implementation of robstride

Co-authored-by: Virgile <virgilebatto@gmail.com>

* chore(motors): solve some linter

* remove kp/kd attribute

* code uniformisation between damiao and robstride

* remove normalization warning

* remove non valid baudrates and small docstring update

* remove all useless files. Only keeping robstride.py and table.py

* typing for mypy

* reduce NameOrId usage

* align signature with damiao

* put the same helper than in the damiao implementation

* bug correction : expect a response after each bus.send

---------

Co-authored-by: Virgile <virgilebatto@gmail.com>
…se the examples (huggingface#2991)

* update the document for Phone teleope to clarify how to use the examples

* Update docs/source/phone_teleop.mdx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Yuta Nakagawa <ytnkgw@gmail.com>

---------

Signed-off-by: Yuta Nakagawa <ytnkgw@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Steven Palma <imstevenpmwork@ieee.org>
Co-authored-by: Steven Palma <imstevenpmwork@ieee.org>
…face#2932)

* Fix HF_USER extraction command in documentation

Updated command to extract the username from hf auth output.

Signed-off-by: Yuan Haokuan <138340416+WilbertYuan@users.noreply.github.com>

* Correct HF_USER variable assignment in documentation

Fix the variable extraction from hf auth output.

Signed-off-by: Yuan Haokuan <138340416+WilbertYuan@users.noreply.github.com>

* Update docs/source/il_robots.mdx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Yuan Haokuan <138340416+WilbertYuan@users.noreply.github.com>

---------

Signed-off-by: Yuan Haokuan <138340416+WilbertYuan@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Steven Palma <imstevenpmwork@ieee.org>
Add a note in the installation guide explaining that users on WSL need to install evdev to avoid build issues.
See: huggingface#2528

Signed-off-by: Steven Palma <imstevenpmwork@ieee.org>
Co-authored-by: Steven Palma <imstevenpmwork@ieee.org>
…#2486)

Co-authored-by: Steven Palma <imstevenpmwork@ieee.org>
* fix(dataset): Reindex videos based on frame and not on time

Sometimes during split operations the frame timestamp floating
precision leads to frame ending up in the wrong split.

This changes fixes the issues by directly working with frame indices
instead.

* Fix formatting
…ror crash (huggingface#3017)

1. Include metaworld_config.json in package distributions by adding it to
   both MANIFEST.in (for sdist) and pyproject.toml package-data (for wheels).
   Without this, pip-installed lerobot raises FileNotFoundError when
   importing the metaworld environment.

2. Fix crash in sanity_check_dataset_name where the error message accesses
   policy_cfg.type when policy_cfg is None, raising AttributeError instead
   of the intended ValueError.

Fixes huggingface#2958
…decoding (huggingface#3016)

Replaced assert statements with FrameTimestampError exceptions in
decode_video_frames_torchvision and decode_video_frames_torchcodec.

Assertions are unsuitable for runtime validation because they can be
silently disabled with python -O, and they produce unhelpful
AssertionError tracebacks. The codebase already defines
FrameTimestampError for this exact purpose but it was only used
in one of the three validation sites.

Also removed AssertionError from the except clause in
LeRobotDataset.__init__, which was masking video timestamp errors
by silently triggering a dataset re-download instead of surfacing
the actual problem.
…ion (huggingface#3021)

* fix annotation mode check

* fix: SARM dense_only mode always load episodes_df for target computation

---------

Co-authored-by: John Newsom <jackmnewsom@gmail.com>
Co-authored-by: Pepijn <138571049+pkooij@users.noreply.github.com>
…d creation with repo_id (huggingface#3005)

* feat: add visualization badge to card template and update dataset card creation with repo_id

* Update src/lerobot/datasets/card_template.md

* Update src/lerobot/datasets/card_template.md

---------

Signed-off-by: Mishig <dmishig@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: hukongtao <hukongtao@agibot.com>
Co-authored-by: Steven Palma <imstevenpmwork@ieee.org>
* add OpenArm Mini config and module init

* add OpenArm Mini teleoperator implementation

* add OpenArm Mini into factory and setup motors

---------

Co-authored-by: Pepijn <138571049+pkooij@users.noreply.github.com>
* Fix SmolVLA meta tensor error by removing device_map

- Remove device_map parameter from VLM model loading
- Change torch_dtype from string to torch.bfloat16
- Add explicit .to(device) calls after initialization

This resolves NotImplementedError when training SmolVLA policy.
Fixes meta tensor copy issue in factory.py:418.

* fix: remove manual device movement logic and fix dtype handling

---------

Co-authored-by: Highsky7 <albert31115@gmail.com>
…e#2425)

* feat(async-inference) Try using async inference server with plugins

* Fix import

* Fix import error in Robot Client

---------

Signed-off-by: Steven Palma <imstevenpmwork@ieee.org>
Co-authored-by: Steven Palma <imstevenpmwork@ieee.org>
…ntical (huggingface#3019)

Co-authored-by: Steven Palma <imstevenpmwork@ieee.org>
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.