Metadata-Version: 2.4
Name: mjxml
Version: 0.1.0
Summary: Utilities to programatically create MuJoCo XML configuration files
Author-email: Lena <lenazhu2007@gmail.com>
Requires-Python: >=3.13
Description-Content-Type: text/markdown
Requires-Dist: numpy
Requires-Dist: pydantic

# mjxml

Programmatic, type-checked helpers for composing MuJoCo XML. Define assets and worldbody elements in Python (with Pydantic validation), serialize to XML, and write files you can load in MuJoCo.

## Highlights

- Strong typing and validation via Pydantic v2.
- Easy XML serialization: `to_xml()`, `to_xml_str()`, `write()`.
- Assets: `TextureAsset`, `MeshAsset`, `HFieldAsset`, `ModelAsset`.
- Bodies: `Geom` (with many MuJoCo attributes), `WorldBody` base.
- Utilities: `Defaults` blocks, rotation helpers, and runtime type protocols.

## Requirements

- Python >= 3.13
- Runtime deps: `numpy`, `pydantic`

## Install

From a checkout of this repository:

```bash
pip install -e .
```

For development (tests and linting):

```bash
pip install pytest ruff
```

If you run examples or tests without installing, set `PYTHONPATH` to include `src`.

```bash
export PYTHONPATH=src
```

## Quickstart

Below are minimal examples showing how to construct elements and serialize them.

### Texture asset

```python
from asset.texture import TextureAsset

tex = TextureAsset(
		name="tex_grid",
		file="albedo.png",
		type="2d",
		colorspace="srgb",
		content_type="image/png",
		nchannel=3,
)

# ElementTree element
elem = tex.to_xml()

# Pretty string
print(tex.to_xml_str())

# Write to a file
tex.write("texture.xml")
```

Generated `<texture>` will include only attributes you set and perform validation (e.g., `nchannel` must be 1, 3, or 4; `random` in [0,1]).

### Mesh asset

```python
from asset.mesh import MeshAsset

mesh = MeshAsset(
		name="m_cube",
		file="cube.obj",
		content_type="model/obj",
		scale=[1.0, 1.0, 1.0],
		inertia="exact",
)

print(mesh.to_xml_str())
```

`MeshAsset` supports inline data (vertex/normal/texcoord/face), reference poses (`refpos`/`refquat`), and procedural builtin shapes.

### Height field asset

```python
from asset.hfield import HFieldAsset

hfield = HFieldAsset(
		name="terrain",
		file="height.png",
		content_type="image/png",
		nrow=256,
		ncol=256,
		size=[5.0, 5.0, 1.0, 0.0],  # required
)

print(hfield.to_xml_str())
```

`size` is required and encodes `(radius_x, radius_y, elevation_z, base_z)`.

### Geom

```python
from body.geom import Geom

g = Geom(
		name="box1",
		type="box",
		size=[0.5, 0.5, 0.5],
		rgba=[0.8, 0.2, 0.2, 1.0],
		friction=[0.5, 0.1, 0.01],
)

print(g.to_xml_str())
```

If `friction` is provided, `condim` is emitted as its length, matching MuJoCo’s behavior.

## Testing

Run the unit tests with `pytest`.

```bash
pytest -q -s
```

## Status

This repository is under active development; expect minor API adjustments. A high-level `MujocoModel` aggregator is planned but not yet included.

## Roadmap

- [✅] **High-level Wrapper**: `MujocoModel` class to aggregate assets, worldbody, and other sections.
- [✅] **Body Elements**: Support for `joint`, `site`, `camera`.
- [=] **Sections**: Support for `actuator`, `sensor`, `equality`, `contact`, `tendon`.
- [❌] **IO**: Parsing existing XML files for round-trip editing.
- [❌] **Docs**: Comprehensive API documentation and more examples.

