Skip to content

Fix MJCF XSD schema metadata gaps - #3410

Open
devshahofficial wants to merge 8 commits into
google-deepmind:mainfrom
devshahofficial:agent/pr3237-mjcf-xsd-schema-gaps
Open

Fix MJCF XSD schema metadata gaps#3410
devshahofficial wants to merge 8 commits into
google-deepmind:mainfrom
devshahofficial:agent/pr3237-mjcf-xsd-schema-gaps

Conversation

@devshahofficial

Copy link
Copy Markdown
Contributor

Draft stacked follow-up for #3237, based on the MJCF XSD generator work from @julien-blanchon.

This branch is rebased onto current origin/main, includes #3237's schema generator commits, and adds one final metadata patch for concrete validation misses reported in the #3237 thread. It is not meant to take credit for or replace the original schema PR; it is a proof/patch branch maintainers can use if they want these fixes folded into #3237.

Fixes in the final commit:

  • adds compiler conflict to the XSD metadata table using conflict_map
  • adds replicate prefix as a string attribute
  • changes top-level composite size from exact 3 values to up-to-3 values, matching ReadAttr(..., exact=false)

Also verified after rebasing that flexcomp dof="2d" is now covered via the current fdof_map from origin/main.

Local validation:

  • git diff --check
  • cmake -S . -B /tmp/mujoco-pr3237-build -DMUJOCO_BUILD_TESTS=OFF -DMUJOCO_TEST_PYTHON_UTIL=OFF -DCMAKE_BUILD_TYPE=Release
  • cmake --build /tmp/mujoco-pr3237-build --target xmlschema -j2
  • /tmp/mujoco-pr3237-build/bin/xmlschema /tmp/mujoco-pr3237-raw.xsd
  • xmllint --noout --schema /tmp/mujoco-pr3237-raw.xsd - with a snippet covering compiler conflict="merge", replicate prefix, composite size="1", and flexcomp dof="2d"
  • python3 doc/mjcf_schema_enrich.py --in /tmp/mujoco-pr3237-raw.xsd --rst doc/XMLreference.rst --out /tmp/mujoco-pr3237-enriched.xsd --report

Note: the enrichment script succeeds without --strict; --strict --report exits nonzero on pre-existing documentation drift unrelated to this patch.

julien-blanchon and others added 6 commits July 16, 2026 15:05
Four local refactors to the MJCF XSD generator; all preserve the schema
semantics (same validating behaviour, same set of declared types).

1. Move the ~600-line kMjXAttrTable (and the mjXAttr/mjXAttrKind type
   declarations) into xml_native_reader.cc / xml_native_reader.h, next
   to MJCF[] and the enum maps. Reverts the earlier `extern const mjMap`
   sprinkling: the maps go back to internal linkage, and the schema
   generator just consumes kMjXAttrTable through its declarations.
   xml_native_schema.cc shrinks from 1653 to 532 lines.

2. Drop the manual kGeomTypesSz / kNDYN / etc. shadow constants; reference
   the authoritative mjNGEOMTYPES / mjNDYN / ... enum values directly from
   mjmodel.h / user_composite.h / user_flexcomp.h. No more silent drift.

3. Replace the O(N) linear Lookup() over kMjXAttrTable with a file-static
   unordered_map<(string_view, string_view), const mjXAttr*>, populated
   on first call. Schema emission drops from O(N^2) to O(N).

4. Replace the ListTypeName / EmitListType string round-tripping with a
   ListType struct (kind + size). EmitListType takes the struct directly,
   no stoi/find_last_of parsing of type names.

5. Deduplicate <xs:simpleType> enum declarations by mjMap* identity: the
   first (element, attr) pair that references a given map sets the
   canonical enum type name; every subsequent attribute using the same
   map reuses it. The generated XSD shrinks from 183 enum simpleTypes
   (many byte-identical copies of bool / interp / enable enums) down to
   39 distinct ones.
Drop the plain python3 shebang in favor of `uv run --script`, add the
inline script metadata block pinning requires-python >=3.10, mark the
file executable, and update the pipeline snippets in CONTRIBUTING.md
and xml_native_schema.cc to invoke it directly.

With this change the only prerequisite for regenerating doc/mjcf.xsd
is uv on PATH — uv provisions a Python interpreter that actually has
expat, which the Homebrew python3 builds lack.
@yuvaltassa

Copy link
Copy Markdown
Collaborator

WDYT @devshahofficial , how useful is this? Are you using it?

@julien-blanchon

julien-blanchon commented Jul 17, 2026

Copy link
Copy Markdown

@yuvaltassa for context this is related to julien-blanchon/mujoco-schema#1 and my PR here #3237.

I'm using the schema for example in this project https://github.com/julien-blanchon/mujoco-viewer, to provide validation and documentation for every field inside the extension.

The schema can also be used independantly to enrich mujoco IDE support (see my julien-blanchon/mujoco-schema#1 screenshot)

@devshahofficial

Copy link
Copy Markdown
Contributor Author

I’m not relying on the XSD in a production workflow today. The concrete value I see is editor/LLM tooling: completion, inline docs, and catching obvious MJCF typos before handing the file to MuJoCo. Julien’s viewer integration is the stronger real-world usage signal here.

I’d treat it as a convenience layer, not a replacement for compiler validation. If that scope is useful to the project, I’m happy to keep the metadata-gap patch focused and adapt the hosting/update path to whatever maintainers prefer.

@devshahofficial
devshahofficial marked this pull request as ready for review July 20, 2026 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants