Skip to main content

A generalizable Viser-based keyframe editor for any MuJoCo robot

Project description

Robot Keyframe Kit

PyPI version Python 3.9+ License: MIT

A web-based keyframe editor for any MuJoCo robot. Design robot motions through an intuitive 3D interface—no robot-specific code required.

https://github.com/user-attachments/assets/demo-video-placeholder

✨ Features

  • Universal Compatibility — Works with any MuJoCo XML model out of the box
  • Zero Configuration — Auto-detects joints, actuators, end-effectors, and mirror pairs
  • Web-Based Interface — 3D visualization powered by Viser
  • Mirror Mode — Automatically synchronize left/right joint movements
  • Physics Simulation — Test keyframes with full MuJoCo physics
  • Keyframe Sequencing — Build timed motion sequences
  • Trajectory Recording — Record and export motion data
  • YAML Configuration — Optional per-robot config files for advanced customization

🚀 Installation

pip install robot-keyframe-kit

Or install from source:

git clone https://github.com/Stanford-TML/robot_keyframe_kit.git
cd robot_keyframe_kit
pip install -e .

📖 Quick Start

Command Line

# Just provide your robot's MuJoCo XML file
keyframe-editor path/to/robot.xml

# With a custom name and save directory
keyframe-editor path/to/robot.xml --name my_robot --save-dir ./keyframes

# Using a YAML configuration file
keyframe-editor path/to/robot.xml --config robot_config.yaml

# Generate a config template for your robot
keyframe-editor path/to/robot.xml --generate-config

Then open http://localhost:8081 in your browser.

Python API

from robot_keyframe_kit import ViserKeyframeEditor, EditorConfig

# Minimal usage — just provide the XML path
editor = ViserKeyframeEditor("path/to/robot.xml")

# With configuration
config = EditorConfig(
    name="my_robot",
    root_body="base_link",
    save_dir="my_keyframes",
)
editor = ViserKeyframeEditor("path/to/robot.xml", config=config)

# Keep the server running
import time
while True:
    time.sleep(1.0)

Loading from YAML Config

from robot_keyframe_kit import ViserKeyframeEditor, EditorConfig

# Load configuration from YAML
config = EditorConfig.from_yaml("robot_config.yaml")
editor = ViserKeyframeEditor("path/to/robot.xml", config=config)

⚙️ Configuration

YAML Configuration File

Create a robot_config.yaml for robot-specific settings:

name: my_robot
root_body: torso

# End-effector sites for pose tracking
end_effectors:
  - left_hand
  - right_hand
  - left_foot
  - right_foot

# Joint mirror pairs (left: right)
mirror_pairs:
  left_shoulder: right_shoulder
  left_elbow: right_elbow
  left_hip: right_hip
  left_knee: right_knee

# Mirror sign corrections (-1 to flip, 1 to keep same)
mirror_signs:
  left_shoulder: 1
  left_elbow: -1
  left_hip: 1
  left_knee: 1

# Output settings
save_dir: keyframes

EditorConfig Options

Option Type Default Description
name str "robot" Project name for saved files
root_body str auto-detect Body used for ground alignment
end_effector_sites list auto-detect Sites for end-effector tracking
mirror_pairs dict auto-detect Left-to-right joint mapping
mirror_signs dict auto-detect Sign corrections for mirroring
save_dir str "keyframes" Directory for saved keyframes
dt float 0.02 Trajectory timestep (50 Hz)
n_frames int 20 Physics substeps per control step
physics_dt float 0.001 Physics simulation timestep
show_com bool True Show center of mass marker
show_grid bool True Show ground grid

🎮 UI Guide

The editor interface has three main sections:

Left Panel — Keyframe Controls

  • Save Motion — Export keyframes to compressed .lz4 files
  • Keyframe List — Select, add, remove, and reorder keyframes
  • Keyframe Operations — Update, Test (with physics), Ground (place on floor)
  • Sequence Builder — Create timed motion sequences

Center Panel — Left-Side Joints

  • Joint sliders for left-side actuators
  • End Effector Poses — Save and restore end-effector positions

Right Panel — Right-Side Joints & Settings

  • Joint sliders for right-side actuators
  • Mirror Mode — Sync left/right movements
  • Reverse Mirror — Invert the mirror direction
  • Physics Toggle — Enable/disable simulation
  • Visualization Options — Grid, COM marker, etc.

Camera Controls

  • Scroll — Zoom in/out
  • Left-click + Drag — Rotate view
  • Right-click + Drag — Pan view

📁 Output Format

Keyframe data is saved as compressed .lz4 files:

{
    "keyframes": [
        {
            "name": "stand",
            "motor_pos": [...],      # Actuator positions
            "joint_pos": [...],      # Joint positions
            "qpos": [...],           # Full MuJoCo qpos
        },
        ...
    ],
    "timed_sequence": [
        ("stand", 0.0),
        ("crouch", 0.5),
        ("jump", 1.0),
    ],
    "time": [...],           # Trajectory timestamps
    "qpos": [...],           # Full qpos trajectory
    "body_pos": [...],       # Body positions over time
    "body_quat": [...],      # Body orientations over time
}

Loading Saved Keyframes

import lz4.frame
import pickle

with lz4.frame.open("keyframes/my_robot/motion.lz4", "rb") as f:
    data = pickle.load(f)

print(data["keyframes"][0]["name"])  # First keyframe name
print(data["timed_sequence"])        # Motion sequence

🤖 Tested Robots

Works with robots from MuJoCo Menagerie and custom models:

  • Humanoids — Unitree G1, H1, ToddlerBot, OP3
  • Quadrupeds — Unitree A1, Go1, Boston Dynamics Spot
  • Arms — Franka Panda, UR5, xArm
  • Hands — Leap Hand, Shadow Hand
  • Custom Models — Any valid MuJoCo XML

📋 Requirements

  • Python ≥ 3.9
  • MuJoCo ≥ 3.0
  • Modern web browser (Chrome, Firefox, Safari, Edge)

🛠️ Troubleshooting

Port Already in Use

# Use a different port
keyframe-editor robot.xml --port 8082

Mirror Mode Not Working Correctly

Generate a config file and manually adjust mirror_signs:

keyframe-editor robot.xml --generate-config
# Edit the generated YAML, then:
keyframe-editor robot.xml --config robot_config.yaml

Robot Floating in Air

The editor auto-detects root_body for grounding. If incorrect, specify it:

keyframe-editor robot.xml --root-body base_link

📄 License

MIT License — see LICENSE for details.

🤝 Contributing

Contributions welcome! Please open an issue or pull request on GitHub.

📚 Citation

If you use this tool in your research, please cite:

@software{robot_keyframe_kit,
  title = {Robot Keyframe Kit},
  author = {Stanford TML},
  year = {2024},
  url = {https://github.com/Stanford-TML/robot_keyframe_kit}
}

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

robot_keyframe_kit-0.1.0.tar.gz (38.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

robot_keyframe_kit-0.1.0-py3-none-any.whl (38.4 kB view details)

Uploaded Python 3

File details

Details for the file robot_keyframe_kit-0.1.0.tar.gz.

File metadata

  • Download URL: robot_keyframe_kit-0.1.0.tar.gz
  • Upload date:
  • Size: 38.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.19

File hashes

Hashes for robot_keyframe_kit-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d8a88b68e3c076676bfc2d2107671801254961d3ce4f1a7dfdcaf8a1c66ba0b8
MD5 bd4f2150c15d95c1e483bea1c1956ae6
BLAKE2b-256 049dedd8f9545c779b8507aefac705eea696f184a13362c422473a4a89473518

See more details on using hashes here.

File details

Details for the file robot_keyframe_kit-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for robot_keyframe_kit-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 556309e5763abf18f8cd443415dd91af6116996ce0038953428b72594b942284
MD5 e60ac5feae98dfb8b23ad14afc40a4dc
BLAKE2b-256 3f976319f9ad7b1f9e837a12e858806e32c4feae1f724896afa598a87cbfa6ad

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page