Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Optional OpenAI-compatible policy endpoint. Keep real API keys out of source control.
DEXBENCH_LLM_BASE_URL=https://api.openai.com/v1
DEXBENCH_LLM_API_KEY=
DEXBENCH_LLM_MODEL=gpt-4.1-mini
XEBENCH_LLM_BASE_URL=https://api.openai.com/v1
XEBENCH_LLM_API_KEY=
XEBENCH_LLM_MODEL=gpt-4.1-mini
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

- Rename the toolkit to XEbench (Cross-Embodiment Benchmark), with the `rc-xebench` distribution, `xebench` Python package and command, and `XEBENCH_*` configuration.
- Lead the README with the cross-embodiment σ, mean success, and embodiment coverage, and document the controlled-cohort aggregation rules.
- Keep legacy imports, command, environment variables, recording topics, and submission identifiers compatible.

## 0.1.0 — 2026-09-27

- Define the three benchmark tasks: `keypress-ldr`, `piano-seq`, and `pick-place-ab`.
Expand Down
4 changes: 2 additions & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cff-version: 1.2.0
message: "If you use RC DexBench, please cite this software."
title: "RC DexBench: An Open Benchmark for Dexterous Robot Evaluation"
message: "If you use RC XEbench, please cite this software."
title: "RC XEbench: An Open Cross-Embodiment Benchmark for Robotic Manipulation"
type: software
authors:
- name: Robotics Center
Expand Down
2 changes: 1 addition & 1 deletion NOTICE
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
RC DexBench
RC XEbench
Copyright 2026 Robotics Center
66 changes: 45 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<img src="assets/robotics-center-logo.png" alt="Robotics Center" width="360">
</p>

# RC DexBench
# RC XEbench — Cross-Embodiment Benchmark

<p align="center">
<a href="https://github.com/RoboticsCenter/dexbench/actions/workflows/lint.yml"><img src="https://github.com/RoboticsCenter/dexbench/actions/workflows/lint.yml/badge.svg?branch=main" alt="CI status"></a>
Expand All @@ -12,9 +12,33 @@
<a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-green.svg" alt="Apache 2.0 license"></a>
</p>

RC DexBench is an open benchmark and evaluation toolkit for dexterous robotic hands. It defines tasks, hardware and session metadata, event-based scoring, and a common adapter interface so teams can compare teleoperation, replay, and learned policies with the same protocol.
RC XEbench (Cross-Embodiment Benchmark) evaluates how one robotic manipulation policy performs across different robot bodies. Its headline cross-embodiment statistic is **σ: the spread in a policy's task success rate across eligible embodiments**, reported alongside **mean success and embodiment coverage**. Evaluate teleoperation, replay, and learned policies under the same protocol on different hands and arm-and-hand systems.

DexBench measures finger-level contact and force control, plus fixed-scene arm-and-hand pick-and-place. The benchmark records MIDI velocity, keyboard events, tactile measurements, command-to-contact latency, and clock alignment.
XEbench measures finger-level contact and force control, plus fixed-scene arm-and-hand pick-and-place. The benchmark records MIDI velocity, keyboard events, tactile measurements, command-to-contact latency, and clock alignment.

The Python package and command are `xebench`. Existing `dexbench` imports and commands, `DEXBENCH_*` environment variables, MCAP event topics, and submission schema identifiers remain supported for compatibility with recorded runs and existing integrations.

## Cross-embodiment score

**Same policy. Same task. Different bodies.** Measure task success on each embodiment, then report how much performance changes with the body. For pick and place, an embodiment is the complete arm + hand system; keyboard and piano tasks use the mounted hand and its fixture.

| Measure | What it tells you | Read it as |
| --- | --- | --- |
| **Cross-embodiment σ ↓** | Population standard deviation of per-body success rates | Lower σ means less variation between bodies; report in percentage points |
| **Mean success ↑** | Arithmetic mean of the same per-body success rates | Each eligible embodiment has equal weight |
| **Embodiment coverage** | Number and identity of eligible bodies | Compare policies on the same body set |

```text
SR_body (%) = 100 × successes / valid trials
mean_SR = mean(SR_body)
σ_body = √ mean((SR_body − mean_SR)²)
```

**Low σ alone does not establish a good policy:** consistent failure also produces low σ. Read consistency together with mean success, coverage, per-body uncertainty, and recordings. Human-relative throughput is reported separately against human teleoperation on each identical embodiment.

Use a controlled cohort: hold the task, protocol, scene distribution, scoring rules, and checkpoint fixed; disclose every embodiment adapter. For the RC cross-embodiment summary, the proposed publication floor is at least **three eligible embodiments** and **40 valid trials per body × policy × task cell**. Compare policy columns over their common eligible body set. Different checkpoints or fine-tuning per body must be labeled as an adapted-policy comparison, rather than zero-shot transfer.

The CLI records and scores individual runs; it does not compute a fleet-level σ from a single run. See the [cross-embodiment evaluation page](https://dexterity.roboticscenter.ai/benchmark) for the matrix, cohort rules, human baseline, and inspectable results. Its preview and XE-Table demonstration values are illustrative, not measured benchmark results. The detailed aggregation contract is in [SPEC.md](SPEC.md#cross-embodiment-evaluation).

## Tasks

Expand Down Expand Up @@ -47,19 +71,19 @@ Each square GIF shows its matching task. The photo shows the robot hand and arm
Install from a fresh checkout with Python 3.10 or later:

```bash
git clone https://github.com/RoboticsCenter/dexbench.git
cd dexbench
git clone https://github.com/RoboticsCenter/dexbench.git xebench
cd xebench
python -m venv .venv
source .venv/bin/activate
python -m pip install -e .
dexbench tasks
xebench tasks
```

Run the bundled pipeline example and inspect its per-trial MCAP and JSON summary:

```bash
dexbench run --task keypress-ldr --policy scripted --adapter mock --trials 2
dexbench score --task keypress-ldr --mcap runs/<run-id>/trial-001.mcap
xebench run --task keypress-ldr --policy scripted --adapter mock --trials 2
xebench score --task keypress-ldr --mcap runs/<run-id>/trial-001.mcap
```

The scripted policy and mock adapter generate synthetic events to demonstrate the recording and scoring workflow.
Expand All @@ -71,11 +95,11 @@ Real-robot runs use an adapter for the hand, sensors, and arm in the configured
The built-in GPT-6 Astra policy is an example for `keypress-ldr`. It uses the OpenAI Chat Completions API and returns one bounded `press` action at a time for `index`, `middle`, or `ring`; the adapter maps that action to the robot's configured finger motion. Use a [custom policy factory](docs/add_an_adapter.md#add-a-task-policy) for `piano-seq`, `pick-place-ab`, or another policy. See the [GPT-6 Astra API documentation](https://developers.openai.com/api/docs/models/gpt-6-astra).

```bash
export DEXBENCH_LLM_BASE_URL="https://api.openai.com/v1"
export XEBENCH_LLM_BASE_URL="https://api.openai.com/v1"
export OPENAI_API_KEY="<your-api-key>"
export DEXBENCH_LLM_MODEL="gpt-6-astra"
export DEXBENCH_LLM_REASONING_EFFORT="low"
dexbench run --task keypress-ldr --policy llm --adapter mock --trials 1
export XEBENCH_LLM_MODEL="gpt-6-astra"
export XEBENCH_LLM_REASONING_EFFORT="low"
xebench run --task keypress-ldr --policy llm --adapter mock --trials 1
```

The request and response are recorded on `/dexbench/policy_trace`; credentials are omitted. The policy accepts only the listed finger actions or `stop`. Replace `mock` with your robot adapter to connect the policy to a hand. See [the adapter guide](docs/add_an_adapter.md).
Expand All @@ -85,12 +109,12 @@ The request and response are recorded on `/dexbench/policy_trace`; credentials a
A robot adapter can expose `teleop_action(observation)` to collect an operator baseline. The replay policy reads the command stream from one successful teleop trial and preserves its original relative timing. To select the successful teleop trial closest to the median completion time and replay it on the same rig:

```bash
dexbench run --task keypress-ldr --policy teleop \
--adapter my_robot.dexbench_adapter:create_adapter --trials 20 \
xebench run --task keypress-ldr --policy teleop \
--adapter my_robot.xebench_adapter:create_adapter --trials 20 \
--calib-id session-2026-09-27-a --session-metadata session.json

dexbench run --task keypress-ldr --policy replay \
--adapter my_robot.dexbench_adapter:create_adapter --trials 20 \
xebench run --task keypress-ldr --policy replay \
--adapter my_robot.xebench_adapter:create_adapter --trials 20 \
--calib-id session-2026-09-27-a --session-metadata session.json \
--replay-results runs/<teleop-run-id>/results.json
```
Expand All @@ -106,13 +130,13 @@ Keep every trial in the run's `results.json`, including failures and hardware-in
| Episode 4 | Success | [View recording](examples/keypress-ldr/episode_4_success.mcap) |
| Episode 5 | Failure | [View recording](examples/keypress-ldr/episode_5_failure.mcap) |

These recordings are examples, not DexBench-scored results or a complete benchmark round. The source GUI logger may report repeated key events while a key is held; see the [example notes](examples/keypress-ldr/) and the key-repeat event contract in [SPEC.md](SPEC.md#event-format).
These recordings are examples, not XEbench-scored results or a complete benchmark round. The source GUI logger may report repeated key events while a key is held; see the [example notes](examples/keypress-ldr/) and the key-repeat event contract in [SPEC.md](SPEC.md#event-format).

## Baselines and protocol

Each policy run writes one JSON summary and one MCAP per trial. Benchmark runs keep failures. The reference baselines are:

- **Teleop:** a human operator using the same robot and task setup. Its run can be generated by a hardware adapter that maps the operator's controls into DexBench actions.
- **Teleop:** a human operator using the same robot and task setup. Its run can be generated by a hardware adapter that maps the operator's controls into XEbench actions.
- **Replay:** open-loop playback of the `/hand/command` stream, plus `/arm/command` for pick-and-place, from the successful teleop episode with the median completion time. Keep hardware and calibration fixed between source and replay runs.
- **Learned policy:** report the model, weights, endpoint/provider, prompt or policy version, action limits, and all run settings.

Expand All @@ -127,16 +151,16 @@ For piano-seq, report each note's MIDI velocity, within-trial velocity standard
- [Recordings and scoring](docs/recordings-and-scoring.md)
- [Hardware reference sheets](hardware/)

The command-line workflow is native to DexBench. Its packaging and benchmark workflow take inspiration from [Inspect Robots](https://github.com/robocurve/inspect-robots), [WorldEvals](https://github.com/robocurve/worldevals), and [StationeryBench](https://github.com/robocurve/stationerybench), while remaining independent so tactile and contact-event channels are part of its own event and scoring contract.
The command-line workflow is native to XEbench. Its packaging and benchmark workflow take inspiration from [Inspect Robots](https://github.com/robocurve/inspect-robots), [WorldEvals](https://github.com/robocurve/worldevals), and [StationeryBench](https://github.com/robocurve/stationerybench), while remaining independent so tactile and contact-event channels are part of its own event and scoring contract.

## License and citation

Released under the Apache License 2.0. See [LICENSE](LICENSE).

```bibtex
@software{rc_dexbench,
@software{rc_xebench,
author = {{Robotics Center}},
title = {RC DexBench: An Open Benchmark for Dexterous Robot Evaluation},
title = {RC XEbench: An Open Cross-Embodiment Benchmark for Robotic Manipulation},
year = {2026},
url = {https://github.com/RoboticsCenter/dexbench},
version = {0.1.0},
Expand Down
30 changes: 25 additions & 5 deletions SPEC.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,32 @@
# RC DexBench Interface and Scoring Specification
# RC XEbench Interface and Scoring Specification

Version 0.1.0

This repository implements the benchmark workflow and reference scorers from the RC DexBench operating specification. Physical task definitions are fixed before a baseline run. Record actual dimensions, model numbers, settings, calibration, and photos in each hardware/session record. Do not tune the task after inspecting results.
This repository implements the benchmark workflow and reference scorers from the RC XEbench operating specification. Physical task definitions are fixed before a baseline run. Record actual dimensions, model numbers, settings, calibration, and photos in each hardware/session record. Do not tune the task after inspecting results.

## Cross-embodiment evaluation

XEbench's cross-embodiment statistic is the population standard deviation of a single policy's success rates over eligible robot bodies, in percentage points:

```text
SR_body (%) = 100 × successes_body / valid_trials_body
mean_SR = (1 / B) × sum(SR_body)
σ_body = sqrt((1 / B) × sum((SR_body − mean_SR)²))
```

Here `B` is the number of eligible embodiments in one controlled cohort. Report `σ_body`, `mean_SR`, `B`, and the included embodiment IDs together. Each body has equal weight; pooling all trials across bodies gives a different statistic. Lower σ means less variation, and cannot establish good performance without high mean success.

The RC publication rules proposed on the [evaluation page](https://dexterity.roboticscenter.ai/benchmark) require at least three eligible bodies and 40 valid trials per body × policy × task cell. A cell may combine repeated complete protocol rounds within the same cohort. Standard community rounds remain 20 trials for keyboard/piano or 30 for pick and place; a single complete round is insufficient for this summary.

For a comparison across policies, use the intersection of eligible bodies across every policy column in the selected controller group. Never aggregate different tasks, protocol revisions, scene sets, or cohorts. Record the fixed checkpoint, task settings, time cap, scoring rules, calibration, observation setup, exclusions, adapter, and session/episode structure in the cohort manifest. Disclose any body-specific fine-tuning or checkpoint change as an adapted-policy comparison. Pick-and-place embodiments include both the arm and hand; hand-only tasks include the mounted hand and fixture.

Policy failures and timeouts stay in the valid-trial denominator. Justified hardware-invalid trials are excluded and reported separately. Publish per-body counts, uncertainty, and full-run recordings so the summary can be reproduced. Meeting the trial floor does not establish statistical significance. Mean reported successful-trial completion time cannot substitute for human-relative throughput, which requires matched full-run timing and a human reference on the same embodiment.

The current command-line toolkit scores individual runs. The evaluation page computes cohort summaries; a run's `success_rate` is its per-body outcome, not a cross-embodiment σ. Preview and XE-Table demonstration values do not establish measured cross-embodiment results.

## Core interfaces

An adapter connects DexBench to a robot or simulator. A policy reads an `Observation` and returns one bounded `Action` or `None` to stop. Adapter event timestamps and action timestamps use the same monotonic clock.
An adapter connects XEbench to a robot or simulator. A policy reads an `Observation` and returns one bounded `Action` or `None` to stop. Adapter event timestamps and action timestamps use the same monotonic clock.

```python
class Adapter:
Expand All @@ -25,7 +45,7 @@ class Policy:
def act(self, observation: Observation) -> Action | None: ...
```

The Python versions of these contracts live in `dexbench.models`. A hardware adapter factory is loaded with `--adapter package.module:factory` and is called with the session metadata dictionary. `execute` must enforce that policy actions remain within the rig's configured limits. Adapters may expose only the observations/actions supported by the hardware; they should not fabricate sensor events.
The Python versions of these contracts live in `xebench.models`. A hardware adapter factory is loaded with `--adapter package.module:factory` and is called with the session metadata dictionary. `execute` must enforce that policy actions remain within the rig's configured limits. Adapters may expose only the observations/actions supported by the hardware; they should not fabricate sensor events.

## Event format

Expand Down Expand Up @@ -54,7 +74,7 @@ Common topics:
| `/glove/*` | glove skeleton, tactile, EMF, IMU | Operator glove |
| `/camera/*` | image data and camera timestamps | Camera adapter |
| `/scorer/tray_state` | `object_inside`, `stable_duration_s` | Depth + color scorer |
| `/dexbench/actions` | policy action and step | DexBench runner |
| `/dexbench/actions` | policy action and step | XEbench runner |
| `/dexbench/policy_trace` | model, request, response | Example LLM policy |

Scorers require these event fields: keyboard `key` values are uppercase `LEFT`, `DOWN`, or `RIGHT`; MIDI `note` and `velocity` are integers; `/hand/command` uses `finger` and `pressed`; `/hand/state` uses `open` as a boolean; `/scorer/tray_state` uses boolean `object_inside` and numeric `stable_duration_s`. Put fields inside the event's `data` object. Emit `/dexbench/invalid` with a `reason` string for hardware faults.
Expand Down
12 changes: 6 additions & 6 deletions docs/add_an_adapter.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Connect a hand, simulator, or rig

An adapter maps the DexBench action space to one configured embodiment, reads sensors, and emits timestamped `Event` records. Install DexBench in the adapter's environment, then pass its factory to the runner:
An adapter maps the XEbench action space to one configured embodiment, reads sensors, and emits timestamped `Event` records. Install XEbench in the adapter's environment, then pass its factory to the runner:

```bash
dexbench run \
xebench run \
--task keypress-ldr \
--policy llm \
--adapter my_robot.dexbench_adapter:create_adapter \
--adapter my_robot.xebench_adapter:create_adapter \
--trials 20 \
--calib-id session-2026-09-27-a \
--session-metadata session.json
Expand All @@ -27,16 +27,16 @@ For Wuji Hand 2, record `/hand/command` and `/hand/state` separately. Read the d
The built-in GPT-6 Astra and scripted policies support `keypress-ldr`. Supply a custom policy factory to run a policy for `piano-seq` or `pick-place-ab`, or to connect another learned policy:

```bash
dexbench run \
xebench run \
--task piano-seq \
--policy custom \
--policy-factory my_project.policies:create_policy \
--adapter my_robot.dexbench_adapter:create_adapter \
--adapter my_robot.xebench_adapter:create_adapter \
--trials 20 \
--calib-id session-2026-09-27-a \
--session-metadata session.json
```

The policy factory receives the session metadata dictionary and returns an object with `name`, `reset(task, trial_id)`, and `act(observation)` methods. `act` returns an `Action` or `None`. The observation contains the task instruction, recent timestamped events, and run metadata; for `pick-place-ab`, `observation.metadata` includes the selected `object_id` and `grasp_type`. Robot-specific action kinds are handled by the adapter. Implement the policy and factory in an importable Python module in the environment running DexBench.
The policy factory receives the session metadata dictionary and returns an object with `name`, `reset(task, trial_id)`, and `act(observation)` methods. `act` returns an `Action` or `None`. The observation contains the task instruction, recent timestamped events, and run metadata; for `pick-place-ab`, `observation.metadata` includes the selected `object_id` and `grasp_type`. Robot-specific action kinds are handled by the adapter. Implement the policy and factory in an importable Python module in the environment running XEbench.

See [SPEC.md](../SPEC.md) for the shared task event fields and outcome rules.
Loading