#### NOTE
This is a **Hugging Face dataset**. For large datasets, ensure `huggingface_hub>=1.1.3` to avoid rate limits. Learn more in the <a href="https://docs.voxel51.com/integrations/huggingface.html#loading-datasets-from-the-hub" target="_blank">Hugging Face integration docs</a>.

<a href="https://huggingface.co/datasets/Voxel51/xense-tron2rt-pnp-115ep" target="_blank">![Hugging Face](https://img.shields.io/badge/%F0%9F%A4%97%20Hugging%20Face-Dataset-yellow)</a>

# Dataset Card for Xense Tron2 RT Pick and Place (115 episodes)

![Xense Tron2 RT Pick and Place preview](https://huggingface.co/datasets/Voxel51/xense-tron2rt-pnp-115ep/resolve/main/xsense_tron2rt_pnp.gif)

This is a [FiftyOne](https://github.com/voxel51/fiftyone) dataset with 115 samples. Each sample is one teleoperated episode.

## Installation

```bash
pip install -U fiftyone
```

## Usage

### Load from the Hub

```python
import fiftyone as fo
from fiftyone.utils.huggingface import load_from_hub

dataset = load_from_hub("Voxel51/xense-tron2rt-pnp-115ep")

session = fo.launch_app(dataset)
```

### Download a snapshot and load it locally

```python
import fiftyone as fo
from huggingface_hub import snapshot_download

snapshot_download(
    repo_id="Voxel51/xense-tron2rt-pnp-115ep",
    repo_type="dataset",
    local_dir="xense-tron2rt-pnp-115ep",
)

dataset = fo.Dataset.from_dir(
    dataset_dir="xense-tron2rt-pnp-115ep",
    dataset_type=fo.types.LeRobotDataset,
    name="xense_tron2rt_pnp",
)

session = fo.launch_app(dataset)
```

## Dataset Details

### Dataset Description

115 teleoperated episodes (48,999 frames, 30 fps) on robot type `tron2_rt`. The task is “Put the block into the box”. Each episode has three RGB camera streams, four tactile video streams (left and right sensor on each side), and 20-D TCP state and action. The source is a LeRobot v3.0 repo recorded with the Xense LeRobot fork.

- **Shared by:** `Xense` on Hugging Face
- **Language(s):** en
- **License:** apache-2.0

### Dataset Sources

- **Repository:** https://huggingface.co/datasets/Xense/tron2rt-pnp-0918

## Dataset Structure

**Topology.** `media_type: multimodal`, 115 samples, one per episode, 30 fps, 321-666 frames (10.7-22.2 s), 48,999 frames total. Samples hold a `media_reference` to the per-frame parquet data and 7 video streams.

| Field             | FiftyOne type             | Description                                           |
|-------------------|---------------------------|-------------------------------------------------------|
| `media_reference` | `LeRobotEpisodeReference` | Pointers into `data/` parquet and the 7 video streams |
| `episode_index`   | `IntField`                | Episode index (0-114)                                 |
| `task`            | `StringField`             | The single task instruction                           |
| `tasks`           | `ListField(StringField)`  | All task strings of the episode                       |
| `length`          | `IntField`                | Frames in the episode                                 |
| `duration`        | `FloatField`              | Episode duration in seconds                           |
| `robot_type`      | `StringField`             | `tron2_rt`                                            |
| `fps`             | `FloatField`              | 30                                                    |

**Data behind `media_reference`** (per-frame, from `meta/info.json`):

| Feature                                                                                                   | Shape     | Description                                                                                                  |
|-----------------------------------------------------------------------------------------------------------|-----------|--------------------------------------------------------------------------------------------------------------|
| `observation.state`                                                                                       | (20,)     | Bimanual TCP: `left_tcp.{x,y,z,r1..r6}`, `right_tcp.{x,y,z,r1..r6}`, `left_gripper.pos`, `right_gripper.pos` |
| `action`                                                                                                  | (20,)     | Same 20 names and layout as `observation.state`                                                              |
| `observation.images.top`, `left_wrist`, `right_wrist`                                                     | 480x640x3 | RGB cameras (H.264 yuv420p)                                                                                  |
| `observation.images.left_tactile_left`, `left_tactile_right`, `right_tactile_left`, `right_tactile_right` | 400x700x3 | Four tactile video streams (H.264 yuv420p)                                                                   |

**Label types and why.** The importer produces episode-level samples with a `media_reference`; numeric streams (state, action) are read through the viewer and are not stored as FiftyOne label fields. The source has a single task, so `task` is constant. No custom fields were added, so the FiftyOne dataset matches what the LeRobot export contains.

**`dataset.info`.** `lerobot` entry with `format`, `format_major`, `episode_count`, `imported_episode_count`, `skipped_episodes` (empty).

**Parsing decisions.**

- All episodes imported from the full repo (2.5 GB). No source file was modified, and no transcoding or metadata repair was needed.
- All 7 video streams were imported; no modality was excluded. All streams are standard H.264 yuv420p.
- The source does not state the tactile sensor model or the physical meaning of the tactile images.

## Dataset Creation

### Source Data

#### Data Collection and Processing

The source card states only that it was created using LeRobot.

### Annotations

#### Annotation process

A single task string is stored in `meta/tasks.parquet`.
