CoolFace
Datasetpublic

ExylosAi/egocentric-vr-capture-20h-multimodal-sample

Egocentric VR Capture — 20-Hour Multimodal Inspection Sample 195 real-world task episodes / 2,283,482 frames / 21.14 delivered hours captured with consumer VR hardware. Each episode combines egocentric RGB and audio with synchronized headset, camera, body, and hand tracking in a LeRobot v3-style package. This publicly accessible 20-hour-scale dataset is produced by the EXYLOS real-world data pipeline. Files and the Dataset Viewer can be accessed without individual approval;… See the full description on the dataset page: https://huggingface.co/datasets/ExylosAi/egocentric-vr-capture-20h-multimodal-sample.

sourceHugging Faceotherupdated 4d agoView on Hugging Face
0likes803downloads
Dataset Card

Egocentric VR Capture — 20-Hour Multimodal Inspection Sample

195 real-world task episodes / 2,283,482 frames / 21.14 delivered hours captured with consumer VR hardware. Each episode combines egocentric RGB and audio with synchronized headset, camera, body, and hand tracking in a LeRobot v3-style package.

This publicly accessible 20-hour-scale dataset is produced by the EXYLOS real-world data pipeline. Files and the Dataset Viewer can be accessed without individual approval; use remains subject to the proprietary evaluation license. It demonstrates multi-operator task coverage, capture structure, synchronization, hierarchical temporal annotations, calibration, and pose provenance before a larger commercial delivery.

Use it / Skip it

Use it for

  • —Evaluating real-world egocentric consumer-VR capture at multi-hour scale.
  • —Inspecting synchronized video, audio, head, body, and hand tracking.
  • —Testing human-motion preprocessing, tracking masks, temporal annotations, retargeting, and ingestion.
  • —Reviewing EXYLOS delivery structure, task coverage, and QA evidence.

Skip it if you need

  • —Robot actions, torques, force, tactile, or contact measurements.
  • —Depth, segmentation, or object-pose ground truth.
  • —Outcome, success/failure, reward labels, or a declared closed action ontology.
  • —Externally validated mocap accuracy or a clean benchmark without additional pose filtering.
This is human XR capture, not robot execution data. The frame data contains no robot-control action feature or robot-control signal.

At a glance

Episodes / frames195 / 2,283,482
Duration76,116.07 seconds, approximately 21 hours 9 minutes
Tasks / operators43 distinct tasks / 6 pseudonymous operators
Coverage110 household, 74 food-prep, 11 vehicle-care episodes
EnvironmentsKitchen, laundry room, room, bathroom, cafe, garage, residential, dining room
CaptureConsumer VR hardware, 30 Hz
RGB1 egocentric 1280 x 960 H.264 stream with audio
Physical video files189; some files contain multiple episode intervals
AudioAAC, 48 kHz, dual-mono
State390-D float32 head, camera, body, and hand tracking
Annotations195 episode captions, 12,399 temporal actions, 23,244 body-part sub-actions
FormatLeRobot v3-style Parquet + MP4 + JSON metadata
Repository sizeApproximately 97.22 GB
Split / licenseTrain only / proprietary

Verify the core numbers

python
import json
from huggingface_hub import hf_hub_download

repo = "ExylosAi/egocentric-vr-capture-20h-multimodal-sample"
path = hf_hub_download(repo, "meta/info.json", repo_type="dataset")
info = json.load(open(path, encoding="utf-8"))
print(info["robot_type"], info["fps"], info["total_episodes"], info["total_frames"])
# -> egocentric_capture 30 195 2283482

Load it

Coordinate convention: all poses in observation.state are expressed in the ROS 2 REP-103 convention — a right-handed, Z-up world with +X forward, +Y left, +Z up; positions in meters, quaternions ordered (x, y, z, w). headset and head_camera are body frames (x forward, y left, z up). The camera optical frame (x right, y down, z forward, the frame the intrinsics are calibrated in) is reached from the head_camera body frame by the fixed rotation published as body_to_optical in meta/calibration.json, alongside T_head_camera (camera body frame in the headset frame) and the pinhole intrinsics. A map → headset → head_camera → head_camera_optical TF tree built from these values, with a sensor_msgs/CameraInfo from the intrinsics, projects the hand joints onto the published video. supplemental/pose_contract.json → coordinate_frame records the convention and the exact basis change from the headset's native left-handed Y-up frame, which is lossless and invertible.
Viewer provenance: the default viewer_data/ mirror is published together with the canonical frame Parquet in the vendor-neutral media snapshot revision 8a095939c2df9d9fe26986e909b82cb730f8b8af. It preserves the canonical pose values and adds only task, environment, video-path, video-timestamp, and episode-duration columns. The videos config resolves repository-local media through @main, while the snapshot revision records the verified immutable payload. The episodes, annotations_l2, and annotations_l3 configs use the same unchanged metadata and annotations.

Stream the frame-level Viewer mirror without downloading the full table:

python
from datasets import load_dataset

repo = "ExylosAi/egocentric-vr-capture-20h-multimodal-sample"
frames = load_dataset(repo, split="train", streaming=True)
first = next(iter(frames))
print(len(first["observation.state"]))  # 390

Load the episode index and video rows:

python
episodes = load_dataset(repo, "episodes", split="train")
videos = load_dataset(repo, "videos", split="train")
print(episodes.num_rows, videos.num_rows)  # 195 195

The videos config is episode-oriented. When several episodes share one physical MP4, use clip_start_s and clip_end_s to resolve the delivered episode interval.

Load temporal action and body-part annotation tables:

python
level2 = load_dataset(repo, "annotations_l2", split="train")
level3 = load_dataset(repo, "annotations_l3", split="train")
print(level2.num_rows, level3.num_rows)  # 12399 23244

Download canonical Parquet and metadata without the video payloads:

python
from pathlib import Path
from huggingface_hub import snapshot_download
import pyarrow.dataset as ds

root = Path(snapshot_download(
    repo, repo_type="dataset",
    allow_patterns=["data/**/*.parquet", "meta/**", "supplemental/**"],
))
frames = ds.dataset(root / "data", format="parquet")

What you get

  • —RGB + audio: one head-mounted stream, with 189 physical MP4 files covering 195 episode intervals.
  • —Head: headset and head-camera position plus quaternion.
  • —Body: positions, rotations, and binary validity for 26 joints.
  • —Hands: 21 joint positions per hand plus visibility flags.
  • —Provenance: video PTS, video-frame index, and native pose-frame index.
  • —Metadata: task, family, environment, pseudonymous operator, and per-episode camera calibration (pinhole intrinsics, T_head_camera, body_to_optical).
  • —Annotations: episode captions plus timestamped action and body-part sub-action spans.
  • —Pose disclosure: sensing provenance, coordinate conventions, generated lower-body status, and validation limitations.

<details> <summary><b>390-D state breakdown</b></summary>

SignalDimensions
Headset + head-camera poses14
26 body positions78
26 body quaternions104
26 body-validity flags26
Two 21-joint hand positions126
Two sets of hand-visibility flags42
Total390

Body confidence is binary, not calibrated. Upper-body and hand joints are camera-based estimates. Lower-body joints are generated rather than directly sensed. </details>

<details> <summary><b>Task coverage</b></summary>

TaskEpisodes
Check and adjust tire pressure2
Check engine oil level2
Clean a bathroom mirror6
Clean a bathtub or shower4
Clean a sink and faucet7
Clean a toilet3
Clean a vehicle5
Clean the windshield and mirrors1
Cook eggs1
Cook food in a pot4
Cook food in an oven1
Cook ingredients in a pan1
Cut food ingredients14
Fold clean laundry9
Heat a meal in a microwave2
Iron clean laundry9
Load a dishwasher4
Load a washing machine7
Make a bed10
Make a sandwich4
Mix batter in a bowl5
Mop a hard floor1
Organize items in the trunk1
Pack a meal into a food container4
Peel a fruit or vegetable6
Prepare a hot drink11
Prepare a salad6
Put clean clothes away7
Put groceries away4
Put items away in a cabinet or drawer3
Put toys away3
Serve food onto a plate1
Set a dining table1
Sort laundry before washing2
Sweep a hard floor3
Take out trash and replace the bin liner2
Transfer leftovers into storage containers1
Unload a dishwasher2
Unload a washing machine4
Vacuum a floor3
Wash dishes by hand11
Wash fruits or vegetables13
Wipe a kitchen countertop5

</details>

Temporal annotations

supplemental/annotations.json provides a three-level timeline for every episode. All timestamps are relative to the start of the delivered episode interval.

LevelCountContents
Level 1195One English caption describing each episode goal
Level 212,399Temporal action spans with start/end time and an action label
Level 323,244Body-part-specific sub-actions nested inside Level 2 spans

Tracking and QA

All poses share one static REP-103 world frame (right-handed, +X forward, +Y left, +Z up); positions are meters and quaternions use (x, y, z, w). Native poses are mapped to the 30 Hz video grid, and source indices remain available for synchronization checks. Audio, video, and pose share one capture clock.

Structural validation passed for all 195 episode IDs, data/video references, frame counts, annotation IDs, and Level 3 parent containment. The delivered frame total exactly matches the episode index. Aggregate state statistics contain no NaN or infinite values, and body-confidence and hand-visibility fields stay in the declared [0, 1] range.

File layout

text
meta/                info, calibration, tasks, episode metadata and stats
supplemental/        annotations, delivery metadata and pose contract
data/                canonical synchronized frame Parquet
videos/              189 canonical head-RGB MP4 files
viewer_data/         enriched 2,283,482-row post-repair Viewer mirror
viewer_index/        195-row episode index
viewer_videos/       195-row episode-oriented video config
viewer_annotations/  flattened Level 2 and Level 3 annotation tables

Scaling up

This repository is a 20-hour-scale sample. Larger commercial deliveries can add hours, operators, tasks, environments, modalities, customer-specific annotations, QA thresholds, retargeting, and alternative schemas. Volume, rights, acceptance criteria, and supported modalities are scoped separately.

Notes and limitations

  • —195 episodes and six pseudonymous operators across 43 tasks.
  • —One egocentric RGB view; no depth, segmentation, object state, force, torque, or tactile streams.
  • —Temporal Level 2 and Level 3 spans are descriptive natural-language annotations; no outcome, reward, or success/failure labels are included.
  • —Body and hands are estimated; lower-body pose is generated.
  • —Absolute translation, rotation, drift, and retargeting accuracy were not measured against external ground truth.
  • —The world origin is the headset's tracking origin, with z = 0 at the headset's floor estimate; that estimate can differ from the physical floor (e.g. outdoors), so subtract the episode's median foot-joint height where floor-referenced z is needed. See pose_contract.json → world_origin.
  • —Camera calibration varies across episodes; lens-distortion coefficients are absent.
  • —Not a benchmark and not sufficient by itself for robot-transfer or model-performance claims.
  • —The repository is publicly accessible. Do not redistribute its real-world video or audio without permission under the proprietary license.

License and access

This dataset and its files are publicly accessible without individual access approval. It remains proprietary. Public file access does not grant rights to redistribute, publish extracts, train commercial models, create derivative datasets, sublicense, or deploy commercially. Permitted uses require a separate written agreement with EXYLOS.

Citation

If required by the governing agreement, cite the repository and the exact snapshot revision used.