Onboarding a URDF
Adding a new articulated object to MetaFine is a deliberate four-step pipeline: drop the URDF in, auto-derive a capabilities file from joint names + a synonym table, run an interactive QA pass, and you're registered. The skill registry picks up the new asset automatically — no re-imports, no per-skill edits.
1 · Drop the URDF in
Create a new directory under assets/ and drop in your urdf.xml + meshes:
assets/my_kettle/
urdf.xml
meshes/
base.obj
lid.obj
textures/...
The URDF should already have named links and joints — base, lid, handle, etc. — because the next step uses those names as synonym keys.
2 · Auto-derive capabilities.json
utils.derive_capabilities walks the URDF, inspects each link's joint type (fixed / revolute / prismatic / continuous) and matches the link name against an internal synonym table to seed an initial affordance set per part.
$ python -m utils.derive_capabilities --asset my_kettle
This writes assets/my_kettle/capabilities.json with a best-guess mapping. Example output:
{
"parts": {
"base": ["graspable", "liftable"],
"lid": ["graspable", "rotatable", "openable"],
"handle": ["graspable"]
},
"aliases": {
"cap": "lid",
"body": "base"
}
}
3 · Interactive QA
utils.review_capabilities is a small interactive shell that walks every part, lets you toggle affordances on / off, add aliases so task-graph YAMLs can refer to parts by friendly names, and confirm the final mapping.
$ python -m utils.review_capabilities --asset my_kettle # Interactive prompts (illustrative): part [lid] has affordances: graspable, rotatable, openable commands: list / toggle <aff> / alias <name> / walk / confirm > toggle insertable > alias cap > confirm
The walk command pops up a SAPIEN viewer that visually highlights the part being reviewed — invaluable when joint names are cryptic.
4 · Registered automatically
Once capabilities.json is confirmed, the asset is live. The skill registry indexes the asset on next import; every skill whose required affordances are a subset of the asset's offered affordances is now applicable to it.
>>> from core.skill_registry import SKILL_REGISTRY >>> SKILL_REGISTRY.applicable_skills("my_kettle", part="lid") ['grasp_part', 'pure_rotate', 'lift_lid', 'lid_opening']
From here, drop the asset id into any task-graph YAML and record demos with python record.py.