Download scripts/robotwin_urdf_convert.py from yqi19/mp_yam_code: direct link, hf CLI and curl.
- Browser
- Download file 3.81 kB
-
https://huggingface.co/yqi19/mp_yam_code/resolve/main/scripts/robotwin_urdf_convert.py
- Command line
-
hf download hf://yqi19/mp_yam_code/scripts/robotwin_urdf_convert.py
-
curl -L -o robotwin_urdf_convert.py https://huggingface.co/yqi19/mp_yam_code/resolve/main/scripts/robotwin_urdf_convert.py
3.81 kB
| """Convert an ARTICULATED RoboTwin object (SAPIEN-style URDF) to USD. | |
| Most RoboTwin categories ship a single fused GLB, but some also ship articulated variants under | |
| numbered sub-directories with a `mobility.urdf` and a `semantics.txt`. `060_kitchenpot/100015`, | |
| for instance, is `link_0 = lid` on a PRISMATIC joint plus `link_1 = pot_body` -- i.e. a pot whose | |
| lid genuinely lifts off, which the fused GLB cannot do. | |
| ROBOTWIN_SRC=... ROBOTWIN_USD=... \ | |
| python scripts/robotwin_urdf_convert.py --headless --jobs 060_kitchenpot/100015 | |
| """ | |
| import argparse, os, sys | |
| from isaaclab.app import AppLauncher | |
| p = argparse.ArgumentParser() | |
| p.add_argument("--jobs", default="060_kitchenpot/100015", | |
| help="comma-separated <category>/<instance> dirs holding a mobility.urdf") | |
| p.add_argument("--fix_base", action="store_true", help="pin the base in place (a static fixture)") | |
| AppLauncher.add_app_launcher_args(p) | |
| a = p.parse_args(); a.headless = True | |
| app = AppLauncher(a).app | |
| from isaaclab.sim.converters import UrdfConverter, UrdfConverterCfg | |
| SRC = os.environ.get("ROBOTWIN_SRC", "/home/yu/internship_yu/robotwin_object/objects") | |
| OUT = os.environ.get("ROBOTWIN_USD", "/home/yu/internship_yu/robotwin_usd") | |
| os.makedirs(OUT, exist_ok=True) | |
| for job in [j for j in a.jobs.split(",") if j]: | |
| cat, inst = job.split("/") | |
| urdf = f"{SRC}/{cat}/{inst}/mobility.urdf" | |
| if not os.path.exists(urdf): | |
| print(f"[urdf] MISSING {urdf}", flush=True); continue | |
| sem = f"{SRC}/{cat}/{inst}/semantics.txt" | |
| if os.path.exists(sem): | |
| print(f"[urdf] {cat}/{inst} parts: {open(sem).read().strip().splitlines()}", flush=True) | |
| # `fix_base` and the joint drive's PD gains are required fields in this Isaac Lab version -- | |
| # a lid on a prismatic joint needs a soft drive so the arm can pull it open rather than | |
| # fighting a stiff actuator. | |
| cfg = UrdfConverterCfg( | |
| asset_path=urdf, usd_dir=f"{OUT}/{cat}", usd_file_name=f"{inst}.usd", | |
| force_usd_conversion=True, fix_base=a.fix_base, | |
| # THE default here is "convex_hull", and it is wrong for every one of these fixtures: it | |
| # collapses a whole microwave into a single box, swallowing the door, and the door's | |
| # collider then interpenetrates the body's so the hinge cannot move at all. It also makes | |
| # the asset RENDER as a featureless cube. Decomposition keeps the parts apart. | |
| collider_type="convex_decomposition", | |
| joint_drive=UrdfConverterCfg.JointDriveCfg( | |
| target_type="none", | |
| gains=UrdfConverterCfg.JointDriveCfg.PDGainsCfg(stiffness=0.0, damping=2.0), | |
| ), | |
| ) | |
| try: | |
| conv = UrdfConverter(cfg) | |
| # The importer swallows its own failures: a hyphen in a mesh filename makes it die with | |
| # "Used null prim", write a 492-byte stub, and return normally. Size-check the result so | |
| # a broken conversion is caught here instead of as a missing ArticulationRootAPI later. | |
| size = os.path.getsize(conv.usd_path) if os.path.exists(conv.usd_path) else 0 | |
| payload = sum(os.path.getsize(os.path.join(r, f)) | |
| for r, _d, fs in os.walk(os.path.dirname(conv.usd_path)) for f in fs) | |
| if payload < 12_000: | |
| print(f"[urdf] FAIL {cat}/{inst}: importer produced an EMPTY asset " | |
| f"({size} B stub, {payload} B total). Almost always a USD-illegal character in " | |
| f"a mesh/link name -- run scripts/sanitize_urdf_asset.py {cat}/{inst} first.", | |
| flush=True) | |
| else: | |
| print(f"[urdf] OK {cat}/{inst} -> {conv.usd_path} ({payload//1024} KB)", flush=True) | |
| except Exception as e: | |
| print(f"[urdf] FAIL {cat}/{inst}: {type(e).__name__}: {e}", flush=True) | |
| app.close(); print("URDF_CONVERT_DONE", flush=True) | |