Metadata-Version: 2.5
Name: urdf2any
Version: 0.2.0
Summary: Convert URDF robot descriptions to USD and MJCF without Isaac Sim or Omniverse
Project-URL: Homepage, https://github.com/syundo0730/urdf2any
Project-URL: Repository, https://github.com/syundo0730/urdf2any
Project-URL: Issues, https://github.com/syundo0730/urdf2any/issues
Author: Shundo Kishi
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: mjcf,mujoco,openusd,robotics,simulation,urdf,usd
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.11
Requires-Dist: numpy>=1.24
Requires-Dist: scipy>=1.10
Requires-Dist: trimesh>=4.0
Requires-Dist: usd-core>=24.5
Provides-Extra: mjcf-validate
Requires-Dist: mujoco>=3.0; extra == 'mjcf-validate'
Provides-Extra: skin
Requires-Dist: pycollada>=0.9; extra == 'skin'
Description-Content-Type: text/markdown

# urdf2any

[![CI](https://github.com/syundo0730/urdf2any/actions/workflows/ci.yml/badge.svg)](https://github.com/syundo0730/urdf2any/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/urdf2any)](https://pypi.org/project/urdf2any/)
[![Python](https://img.shields.io/pypi/pyversions/urdf2any)](https://pypi.org/project/urdf2any/)
[![License](https://img.shields.io/badge/license-Apache--2.0-green)](LICENSE)

Convert URDF robot descriptions to **USD** (OpenUSD / Isaac Sim) and **MJCF**
(MuJoCo) — in pure Python, with no Isaac Sim, Omniverse, or GPU required.

- **Self-contained** — runs anywhere `pip` works (`usd-core`, `trimesh`, `numpy`)
- **One source of truth** — a single simulator-agnostic intermediate
  representation drives both backends, so USD and MJCF describe the same
  physical robot
- **Verified** — output is checked in CI against the real reference
  implementations: the IsaacLab URDF importer (golden comparison) and MuJoCo's
  native URDF loader (live comparison)

## Installation

```bash
pip install urdf2any
```

## Quick start

The output format is inferred from the file extension:

```bash
urdf2any robot.urdf -o robot.usd   # USD (UsdPhysics articulation)
urdf2any robot.urdf -o robot.xml   # MJCF (with actuators)
```

Or from Python:

```python
from urdf2any import convert, ConvertConfig, JointDriveCfg

convert(
    "robot.urdf",
    "robot.usd",
    ConvertConfig(joint_drive=JointDriveCfg(stiffness=100.0, damping=1.0)),
)
```

By default every URDF link becomes one body and no lossy transformation is
applied — the same config yields the same robot in both formats.

## Compatibility presets

To reproduce the behavior of an existing converter, start from a preset;
individual flags still override it:

```bash
urdf2any robot.urdf -o robot.usd --preset isaaclab   # IsaacLab URDF importer defaults
urdf2any robot.urdf -o robot.xml --preset mujoco     # MuJoCo native URDF conversion
```

| Preset | Matches | Effect |
|---|---|---|
| `isaaclab` | IsaacLab `UrdfConverter` defaults | merges all fixed-joint links |
| `mujoco` | MuJoCo's built-in URDF loader | merges fixed-joint links and derives missing link masses from collision geometry (needs `pip install "urdf2any[mjcf-validate]"`) |

The same presets are available in Python as `ConvertConfig.isaaclab()` /
`ConvertConfig.mujoco()`, and their definitions are what the parity test suites
validate against the real implementations.

## Feature support

| | |
|---|---|
| Joints | revolute, continuous, prismatic, fixed (optional merging with inertia composition) |
| Geometry | box, sphere, cylinder, capsule, mesh (STL / OBJ / DAE via trimesh) |
| Inertials | authored mass/inertia/COM; optional geometry-derived backfill via MuJoCo |
| Drives | position / velocity PD gains → USD DriveAPI / MJCF actuators |
| Materials | URDF colors → UsdPreviewSurface / MJCF materials |
| Skins | skinned Collada (DAE) → MuJoCo `<skin>` assets, bone weights rebound to link frames (`pip install "urdf2any[skin]"`) |
| Not yet | mimic joints, sensors, UsdSkel skins, `package://` ROS package resolution beyond a search root |

Robot-specific preprocessing (renaming links, removing parts) is deliberately
out of scope: parse with `parse_urdf`, mutate the IR, then emit with
`convert_robot`.

## Development

```bash
uv sync
uv run pytest        # includes the parity suites (CPU only)
uv run ruff check .
```

Releases are published to PyPI by pushing a `vX.Y.Z` tag
(Trusted Publishing via `.github/workflows/release.yml`).

### Parity testing

- **USD vs IsaacLab importer** — `tests/test_golden_parity.py` diffs urdf2any's
  output against committed golden summaries (`tests/golden/`) generated by the
  real importer. Regenerate them inside an IsaacLab container with
  `scripts/generate_reference.py` (the import itself needs no GPU).
- **MJCF vs MuJoCo** — `tests/test_mjcf_parity.py` compiles both urdf2any's MJCF
  and the source URDF with MuJoCo and compares the resulting models live; no
  golden files needed.

Sample robots under `tests/assets/` are vendored from
[IsaacLab](https://github.com/isaac-sim/IsaacLab) (BSD-3-Clause) and
[Isaac Sim](https://github.com/isaac-sim/IsaacSim) (Apache-2.0); see the
`NOTICE` file next to each.

## License

[Apache-2.0](LICENSE)
