google-deepmind / google-deepmind/mujoco
Expected behavior of mj_saveLastXML regarding asset file path: absolute vs relative?
- 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
Assessment
This issue has not been assessed yet.