-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Fix inconsistent asset paths in mj_saveLastXML: canonicalize includes… #2954
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
… and set output dir during write (fixes google-deepmind#2941)
|
@yuvaltassa please check this pr |
havess
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi! Thanks for taking a look at this, left a few comments. I'd like to see some unit tests that validate the behaviour if you don't mind.
|
i will fix it asap |
|
Hi @Adityakk9031, thanks so much for opening this PR addressing the issue I posted. Just wanted to check whether you’re still planning to finish it up. If you’re busy, I’d be happy to help or take over the remaining work to get it across the finish line -- whatever works best for you! |
|
i wiil fix it today |
|
@havess Check now |
havess
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once again I don't believe this will work by changing the spec modelfiledir this way. I could be wrong, but please include a unit test as requested in my first review.
|
ok |
Fixes: #2941
Problem
Users observed inconsistent behavior of
mj_saveLastXMLwith respect to asset file paths:xmls/xmls/...and broken loading,Root cause
The problem was caused by two interacting issues:
IncludeXMLin xml.cpp) mixed different filename forms when checking and recording included files: it checked theincludedset against the rawfilenamebut then inserted a dir-prefixedfilename(i.e.dir + filename) intoincluded. This inconsistent canonicalization caused themjSpecto contain a mix of relative and dir-prefixed paths, which the writer later serialized incorrectly.spec->modelfilediras the base. When saving to a new target file, the writer had no information about the output directory and thus could not deterministically produce paths relative to the output file — causing inconsistent absolute/relative outputs.What this PR does
Parser canonicalization (
xml.cc):fullname = dir + filename) and usefullnameconsistently forincludedchecks and insertions and for subsequent processing.mjSpecand avoids doubled prefixes when the writer later emits file paths.Output-dir awareness at write time (
xml_api.cc):spec->modelfiledirwith the directory of the output file when calling the writer viaGetGlobalModel().ToXML(...). This is implemented in a backward-compatible way (temporary override + restore).mj_saveLastXMLcase.Why this fixes #2941
mjSpec, preventing double-prefix issues likexmls/xmls/....spec->modelfiledirto the output directory ensures the writer computes relative/absolute paths consistently w.r.t. the output location, so the saved XML can be loaded reliably.Testing
Run the three cases reported in #2941 and verify saved XML loads in each case:
model = mujoco.MjModel.from_xml_path("xmls/panda_2f85/panda_2f85.xml")mujoco.mj_saveLastXML("test.xml", model)mj_loadXML("test.xml")should succeed.model = mujoco.MjModel.from_xml_path("xmls/scene.xml")mujoco.mj_saveLastXML("test.xml", model)mj_loadXML("test.xml")should succeed (noxmls/xmls/...errors).model = mujoco.MjModel.from_xml_path(os.path.abspath("xmls/scene.xml"))mujoco.mj_saveLastXML("test.xml", model)mj_loadXML("test.xml")should succeed.Additional tests:
mj_saveXMLandmj_saveXMLStringcallers (consider parity later).Files changed
src/xml/xml.cc(parser include canonicalization)src/xml/xml_api.cc(temporary modelfiledir override for writer calls, helper DirnameOfPath)