motiondata-lib is a MuJoCo + PySide6 desktop tool for browsing humanoid motion datasets, previewing clips on a robot model, and exporting selected motions to a unified .npz format.
- Browse all motion files under a dataset directory, including nested subdirectories
- Filter the motion list by filename from the right-side panel
- Auto-detect supported dataset formats when a directory contains only one format
- Preview clips on a MuJoCo robot model with mouse camera control
- Play, pause, scrub frames, adjust playback speed, and optionally follow the root body
- Trim the current clip with timeline markers and export the selected span as
.npz - Batch-export checked clips to the project's standardized
.npzlayout
- Python 3.11+
- Linux desktop environment with OpenGL support
uvfor dependency management and reproducible runs
Python dependencies are declared in pyproject.toml:
mujoconumpyPySide6
Install uv first if it is not already available:
curl -LsSf https://astral.sh/uv/install.sh | shCreate the environment and install project dependencies:
uv syncOn Ubuntu, install the Qt X11 runtime dependency before launching the GUI:
sudo apt install libxcb-cursor0uv run python main.py <dataset_dir> [--robot unitree_g1] [--format auto]After launching, the GUI lets you filter motions by name, select a clip, move the current frame, drag trim markers on the timeline, and export either checked clips or the trimmed span of the current clip.
Command-line options:
dataset: directory containing motion files of a single supported format--robot: robot profile name loaded fromrobots/*.toml--model: temporary URDF override for the selected robot profile--format: force one ofauto,retargeted_npz,sonic,lafan1,amass
Robot profiles live in robots/*.toml. A profile defines:
namedisplay_namemodelroot_bodyjoint_names
Currently included:
unitree_g1->robots/unitree_g1.toml
The corresponding URDF and meshes are stored under robots/resources/unitree_g1/.
The browser currently supports four input formats. Internally, all of them are converted to the same MotionClip representation and can be exported as standardized .npz.
File suffix: .npz
Required arrays:
frameratejoint_namesjoint_posbase_pos_wbase_quat_w
This is the project's canonical format and the export target.
File suffix: .csv
Expected header prefix:
Frameroot_translateX,root_translateY,root_translateZroot_rotateX,root_rotateY,root_rotateZ- one
<joint_name>_dofcolumn for every joint in the selected robot profile
Importer behavior:
- root translation is interpreted in centimeters and converted to meters
- root rotation is interpreted as XYZ Euler angles in degrees
- joint angles are interpreted in degrees
- default frame rate is
120
File suffix: .csv
Expected numeric layout per frame:
- columns
0:3: root position - columns
3:7: root quaternion inxyzw - remaining columns: joint positions in robot-profile joint order
Default frame rate is 30.
File suffix: .npy
Expected numeric layout per frame:
- columns
0:3: root position - columns
3:7: root quaternion inxyzw - remaining columns: joint positions in robot-profile joint order
Importer behavior:
- frame rate is inferred from the last integer in the filename
- base
zis shifted upward by0.75
Use uv for dependency and package management in this repository. Prefer:
uv add <package>
uv sync
uv run python main.py --help
uv run python -m py_compile main.py motiondata_lib/*.py motiondata_lib/importers/*.pyThere is no committed pytest suite yet, so the main validation flow is currently import smoke tests and GUI startup checks.
- Add a new TOML profile under
robots/<name>.toml - Put the URDF and assets under
robots/resources/<name>/ - Fill in
model,root_body, andjoint_names - Launch with:
uv run python main.py <dataset_dir> --robot <name>Example profile:
name = "my_robot"
display_name = "My Robot"
model = "resources/my_robot/my_robot.urdf"
root_body = "pelvis"
joint_names = ["joint_a", "joint_b", "joint_c"]- Create a new module under
motiondata_lib/importers/ - Define:
FORMAT_NAMEcan_load(path: Path) -> boolload_motion_clip(clip_ref, robot_profile) -> MotionClip
- Register the importer in
motiondata_lib/importers/__init__.py - Convert incoming data with
build_motion_clip(...)
For new formats, the important contract is:
- output joint order must match
robot_profile.joint_names - root pose must be converted to
base_pos_wandbase_quat_w - quaternions should be normalized before use
- A dataset directory must contain only one supported input format when using
--format auto - Nested subdirectories are supported; they appear in the list as
subdir/file_name - Checked exports are written into a timestamped folder chosen from the GUI
