google-deepmind / google-deepmind/mujoco

Expected behavior of mj_saveLastXML regarding asset file path: absolute vs relative?

Open
#2,941 0 comments 0 reactions 1 assignee Claimed by @havess View on GitHub
bug
Dominant language
C++
Stars
15.2k
Forks
1.8k
Avg merge
10d 16h
Merged PRs (30d)
25

Description

### Intro

Hi!

I am a PhD student at MIT, using mujoco for dexterous manipulation research.

I'm curious what's actually the expected behavior of `mj_saveLastXML` regarding the asset file paths; is it supposed to save with **absolute paths** for all the files, or **relative paths** based on the original XML file that `MjModel` was loaded with (using `from_xml_path`)? I am observing both behaviors in different scenarios, which I cannot find the pattern of its behavior.

### My setup

I'm on macOS using the latest mujoco version (3.3.7) installed via `pip install mujoco`

### What's happening? What did you expect?

I basically have this directory structure, which I attached as a zip file.

[saveLastXML_bug.zip](https://github.com/user-attachments/files/23487004/saveLastXML_bug.zip)

```
xmls/
|_ panda_2f85/
|_ xxx.obj
|_ xxx.obj
|_ panda_2f85.xml
|_ scene.xml
```

where `scene.xml` is nothing but an XML model defined with some mocap bodies and ground floors, where the panda model is included using the `` tag.

```






```
Everything loads properly when I load it directly via mujoco GUI.

**Now, depending on what XML you load, and how you load it, the outcome of `mj_saveLastXML` is different**.

### Case 1. Load `xmls/panda_2f85/panda_2f85.xml`

```python
model = mujoco.MjModel.from_xml_path(f"xmls/panda_2f85/panda_2f85.xml")
mujoco.mj_saveLastXML("test.xml", model)
with open("test.xml", "r") as f:
xml_content = f.read()
check_if_file_paths_are_absolute(xml_content)
```

Then `mj_saveLastXML` returns every file path as its relative path.
```
Number of relative paths : 75
Number of absolute paths : 0
```

### Case 2. Load `xmls/scene.xml` (using relative path)

```python
model = mujoco.MjModel.from_xml_path("xmls/scene.xml")
mujoco.mj_saveLastXML("test.xml", model)
with open("test.xml", "r") as f:
xml_content = f.read()
check_if_file_paths_are_absolute(xml_content)
```

Then I cannot load the model; it parses the asset path in a weird way.
```
Error opening file 'xmls/xmls/panda_2f85/base.stl': No such file or directory
```

### Case 3. Load `xmls/scene.xml` (using absolute path)

```python
model = mujoco.MjModel.from_xml_path(os.path.abspath("xmls/scene.xml"))
mujoco.mj_saveLastXML("test.xml", model)
with open("test.xml", "r") as f:
xml_content = f.read()
file_paths = check_file_paths(xml_content)
```

Then everything loads properly, and `mj_saveLastXML` writes everything in absolute path.

```bash
Number of relative paths : 0
Number of absolute paths : 75
```

----

### Expected behavior

For every case above,

1. `MjModel.from_xml_path` successfully loads the model
2. `mj_saveLastXML` returns an XML with every file path being absolute path.

### Steps for reproduction

[saveLastXML_bug.zip](https://github.com/user-attachments/files/23487004/saveLastXML_bug.zip)

Unzip the file, and launch

```bash
pip install mujoco
python test.py
```

### Minimal model for reproduction

_No response_

### Code required for reproduction

_No response_

### Confirmations

- [x] I searched the [latest documentation](https://mujoco.readthedocs.io/en/latest/overview.html) thoroughly before posting.
- [x] I searched previous [Issues](https://github.com/google-deepmind/mujoco/issues) and [Discussions](https://github.com/google-deepmind/mujoco/discussions), I am certain this has not been raised before.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.