| """ |
| readme_gen.py β dynamically generated README for downloaded RoboGen datasets. |
| """ |
|
|
| from __future__ import annotations |
| import datetime |
| from typing import Dict, List |
|
|
|
|
| COLUMN_DOCS = { |
| "state_0": "Joint 0 β base rotation (rad)", |
| "state_1": "Joint 1 β shoulder pitch (rad)", |
| "state_2": "Joint 2 β elbow (rad)", |
| "state_3": "Joint 3 β wrist roll (rad)", |
| "state_4": "Joint 4 β wrist pitch (rad)", |
| "state_5": "Joint 5 β gripper (rad, 0=closed β 1=open)", |
| "action_0": "Velocity command joint 0 β base (rad/s)", |
| "action_1": "Velocity command joint 1 β shoulder (rad/s)", |
| "action_2": "Velocity command joint 2 β elbow (rad/s)", |
| "action_3": "Velocity command joint 3 β wrist roll (rad/s)", |
| "action_4": "Velocity command joint 4 β wrist pitch (rad/s)", |
| "action_5": "Velocity command joint 5 β gripper (rad/s)", |
| "timestamp": "Seconds since episode start (50 Hz β Ξt=0.02 s)", |
| "episode_index": "Integer episode identifier (0-indexed)", |
| "frame_index": "Frame number within episode (0β49 for 50-frame episodes)", |
| "task": "Task label string", |
| "use_for_training":"True for successful episodes only; False for failure episodes", |
| "failure_type": "'success' | 'grasp_slip' | 'velocity_spike' | 'torque_saturation'", |
| "quality_score": "Per-episode quality score (0β100) from HaptalAI scorer", |
| "robot": "Robot model string: 'SO-100' | 'SO-101' | 'Koch'", |
| } |
|
|
| FAILURE_DESCRIPTIONS = { |
| "grasp_slip": "Smooth trajectory until 60-70% of episode, then gripper opens " |
| "unintentionally (position discontinuity β₯ 0.18 rad) and contact " |
| "force collapses. Mimics inadequate grasp force.", |
| "velocity_spike": "1-2 isolated frames with joint velocity MAD z-score > 6.5 rad/s, " |
| "surrounded by normal motion. Mimics servo glitch or controller " |
| "communication dropout.", |
| "torque_saturation": "One arm joint clamped at its angular limit for β₯ 3 consecutive frames " |
| "with near-zero velocity. Mimics joint hitting mechanical stop or " |
| "exceeding torque budget.", |
| } |
|
|
|
|
| def generate_readme( |
| robot: str, |
| task: str, |
| n_episodes: int, |
| success_rate: float, |
| force_min: float, |
| force_max: float, |
| failures: List[str], |
| score: float, |
| band: str, |
| n_passed: int, |
| n_flagged: int, |
| mean_mismatch: float, |
| failure_breakdown: Dict[str, int], |
| scorer_used: str, |
| ) -> str: |
| """Generate a complete README.md for the downloaded dataset.""" |
|
|
| task_display = task.replace("_", " ").title() |
| failures_list = "\n".join(f"- **{f}**: {FAILURE_DESCRIPTIONS.get(f, f)}" for f in failures) |
| col_table_rows = "\n".join( |
| f"| `{col}` | {desc} |" for col, desc in COLUMN_DOCS.items() |
| ) |
| fb_lines = "\n".join(f"- {k}: {v} episodes" for k, v in failure_breakdown.items()) or "- None" |
| generated_at = datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M UTC") |
| band_emoji = "" |
|
|
| return f"""# RoboGen Synthetic Dataset β {robot} / {task_display} |
| |
| > Generated by [HaptalAI RoboGen](https://huggingface.co/spaces/HaptalAI/robogen) |
| > on {generated_at} |
| |
| --- |
| |
| ## Dataset Summary |
| |
| | Field | Value | |
| |---|---| |
| | Robot | **{robot}** | |
| | Task | **{task_display}** | |
| | Total episodes | **{n_episodes}** | |
| | Success rate (configured) | **{success_rate * 100:.0f}%** | |
| | Contact force range | **{force_min:.1f} β {force_max:.1f} N** | |
| | Frames per episode | **50** (50 Hz, Ξt = 0.02 s) | |
| | Total rows | **{n_episodes * 50:,}** | |
| |
| --- |
| |
| ## Quality Score |
| |
| | Metric | Value | |
| |---|---| |
| | Overall score | **{score:.1f} / 100** | |
| | Band | **{band}** | |
| | Episodes passed | **{n_passed}** | |
| | Episodes flagged | **{n_flagged}** | |
| | Mean mismatch rate | **{mean_mismatch:.4f}** | |
| | Scorer | `{scorer_used}` | |
| |
| **Quality bands:** |
| - **Clean** (>= 80): suitable for policy training and augmentation |
| - **Review** (55-79): usable with caution; inspect flagged episodes |
| - **Flagged** (< 55): high anomaly rate; use for failure analysis only |
| |
| --- |
| |
| ## What the Dataset Contains |
| |
| This dataset contains **{n_episodes} synthetic episodes** of a **{robot}** robot performing |
| the **{task_display}** task. Each episode is 50 frames (1 second at 50 Hz). |
| |
| **Episode composition:** |
| - Success episodes (`use_for_training=True`): ~{success_rate * 100:.0f}% of total |
| - Failure episodes: ~{(1 - success_rate) * 100:.0f}% of total |
| |
| ### Failure types included |
| {failures_list} |
| |
| ### Failure breakdown in this dataset |
| {fb_lines} |
| |
| --- |
| |
| ## Column Reference |
| |
| | Column | Description | |
| |---|---| |
| {col_table_rows} |
| |
| --- |
| |
| ## Physics Model |
| |
| Joint trajectories are generated using **cubic spline interpolation** over |
| task-specific waypoints (approach β contact/grasp β lift/push β retract). |
| Velocities are the **analytical first derivative** of the position spline β not |
| independently sampled β ensuring physical consistency between state and action. |
| |
| - Sensor noise: Gaussian Ο_pos = 0.002 rad, Ο_vel = 0.004 rad/s |
| - Contact force: spring-damper model during contact window (30β75% of episode) |
| - Episode variation: small Gaussian perturbations on target position (Β±2.5 cm equivalent) |
| - Joint limits: enforced per robot specification |
| |
| --- |
| |
| ## Recommended Use |
| |
| Synthetic data is best used for: |
| 1. **Policy bootstrapping** β pre-train before collecting real demonstrations |
| 2. **Augmentation** β mix with real data to increase diversity and robustness |
| 3. **Failure analysis / anomaly detection** β the labelled failure episodes are |
| especially useful for training or evaluating anomaly detectors |
| 4. **Simulation-to-real transfer research** β study domain gap with known ground truth |
| |
| > **Do not** rely solely on synthetic data for safety-critical deployments. |
| > Always validate against real demonstrations before deploying to physical hardware. |
| |
| --- |
| |
| ## Validation & Benchmark |
| |
| This dataset was generated and validated by **HaptalAI's misalignment failure benchmark |
| and physical failure scorer** β the same pipeline used to evaluate community SO-100 |
| datasets. Calibrated thresholds: |
| - Velocity spike: MAD z-score > 6.5 rad/s |
| - Mismatch fraction: > 0.50 per episode β flagged |
| |
| For questions, dataset requests, or benchmark access: |
| **aarav@haptal.ai** |
| |
| --- |
| |
| *RoboGen is open source. Star us on GitHub and contribute at |
| [HaptalAI/robogen](https://github.com/aaravbedi/robogen).* |
| """ |
|
|