fix: IS 4.5.0 -> 5.0.0 migration — USD metadata, DomeLight, scene reuse
- Fix USD metersPerUnit/upAxis for IS 5.0.0 (no longer auto-compensated) - Batch fix all Aligned_obj.usd, table, and art USD files with backups - Fix DomeLight rotation to Z-axis only (prevent tilted environment map) - Fix scene reuse across episodes (arena_file caching, task clearing, prim guard) - Add migration tools: scan_usd_metadata.py, fix_usd_metadata.py - Add migration guide: migerate/migerate.md - Add nvidia-curobo to .gitignore - Fix sort_the_rubbish config: obj_0 -> obj_1 (obj_0 does not exist) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -29,7 +29,7 @@ tasks:
|
||||
objects:
|
||||
-
|
||||
name: pick_object_left
|
||||
path: task/sort_the_rubbish/non_recyclable_garbage/obj_0/Aligned_obj.usd
|
||||
path: task/sort_the_rubbish/non_recyclable_garbage/obj_1/Aligned_obj.usd
|
||||
target_class: RigidObject
|
||||
dataset: oo3d
|
||||
category: bottle
|
||||
|
||||
@@ -249,6 +249,12 @@ class TemplateController(BaseController):
|
||||
obstacles = self.usd_help.get_obstacles_from_stage(
|
||||
ignore_substring=self.ignore_substring, reference_prim_path=self.reference_prim_path
|
||||
).get_collision_check_world()
|
||||
# Diagnostic: print what curobo sees as the collision world
|
||||
n_cuboid = len(obstacles.cuboid) if obstacles.cuboid else 0
|
||||
n_mesh = len(obstacles.mesh) if obstacles.mesh else 0
|
||||
mesh_names = [m.name for m in obstacles.mesh] if obstacles.mesh else []
|
||||
print(f"[CUROBO_WORLD] cuboids={n_cuboid}, meshes={n_mesh}, "
|
||||
f"mesh_names={mesh_names[:5]}{'...' if n_mesh > 5 else ''}", flush=True)
|
||||
if self.motion_gen is not None:
|
||||
self.motion_gen.update_world(obstacles)
|
||||
self.world_cfg = obstacles
|
||||
@@ -277,6 +283,10 @@ class TemplateController(BaseController):
|
||||
self.T_world_base_init = get_relative_transform(
|
||||
get_prim_at_path(self.robot_base_path), get_prim_at_path(self.task.root_prim_path)
|
||||
)
|
||||
print(f"[TRANSFORM_DBG] robot_base_path={self.robot_base_path}", flush=True)
|
||||
print(f"[TRANSFORM_DBG] root_prim_path={self.task.root_prim_path}", flush=True)
|
||||
print(f"[TRANSFORM_DBG] T_world_base_init translation={self.T_world_base_init[:3, 3]}", flush=True)
|
||||
print(f"[TRANSFORM_DBG] T_world_base_init full=\n{self.T_world_base_init}", flush=True)
|
||||
self.T_world_ee_init = self.T_world_base_init @ self.T_base_ee_init
|
||||
self._ee_trans, self._ee_ori = self.get_ee_pose()
|
||||
self._ee_trans = self.tensor_args.to_device(self._ee_trans)
|
||||
|
||||
@@ -47,6 +47,21 @@ class RigidObject(RigidPrim):
|
||||
self.base_prim_path = prim_path
|
||||
rigid_prim_path = os.path.join(self.base_prim_path, cfg["prim_path_child"])
|
||||
self.mesh_prim_path = str(get_prim_at_path(rigid_prim_path).GetChildren()[0].GetPrimPath())
|
||||
# [LOAD_DBG] Print xformOps right after create_prim, before physics
|
||||
try:
|
||||
from pxr import UsdGeom
|
||||
_xf = UsdGeom.Xformable(get_prim_at_path(rigid_prim_path))
|
||||
for _op in _xf.GetOrderedXformOps():
|
||||
print(f"[LOAD_DBG] {cfg_name} after_create_prim: {_op.GetName()} = {_op.Get()}", flush=True)
|
||||
_l2w = _xf.ComputeLocalToWorldTransform(0)
|
||||
print(f"[LOAD_DBG] {cfg_name} after_create_prim l2w=({_l2w[3][0]:.6f}, {_l2w[3][1]:.6f}, {_l2w[3][2]:.6f})", flush=True)
|
||||
# Also check the USD file's own metersPerUnit
|
||||
_ref_stage = get_prim_at_path(prim_path).GetStage()
|
||||
_mpu = UsdGeom.GetStageMetersPerUnit(_ref_stage)
|
||||
_up = UsdGeom.GetStageUpAxis(_ref_stage)
|
||||
print(f"[LOAD_DBG] {cfg_name} stage metersPerUnit={_mpu} upAxis={_up}", flush=True)
|
||||
except Exception as _e:
|
||||
print(f"[LOAD_DBG] {cfg_name} error: {_e}", flush=True)
|
||||
super().__init__(prim_path=rigid_prim_path, name=cfg["name"], *args, **kwargs)
|
||||
|
||||
def get_observations(self):
|
||||
|
||||
@@ -284,8 +284,49 @@ class Pick(BaseSkill):
|
||||
if frame == "body":
|
||||
return self.T_obj_ee
|
||||
|
||||
T_world_obj = tf_matrix_from_pose(*self.pick_obj.get_local_pose())
|
||||
local_pose = self.pick_obj.get_local_pose()
|
||||
world_pose = self.pick_obj.get_world_pose()
|
||||
print(f"[PICK_DBG] prim_path={self.pick_obj.prim_path}", flush=True)
|
||||
print(f"[PICK_DBG] local_pose trans={local_pose[0]}", flush=True)
|
||||
print(f"[PICK_DBG] world_pose trans={world_pose[0]}", flush=True)
|
||||
print(f"[PICK_DBG] local_pose ori={local_pose[1]}", flush=True)
|
||||
print(f"[PICK_DBG] world_pose ori={world_pose[1]}", flush=True)
|
||||
parent_prim = get_prim_at_path(self.pick_obj.prim_path).GetParent()
|
||||
print(f"[PICK_DBG] parent_prim_path={parent_prim.GetPrimPath()}", flush=True)
|
||||
grandparent_prim = parent_prim.GetParent()
|
||||
print(f"[PICK_DBG] grandparent_prim_path={grandparent_prim.GetPrimPath()}", flush=True)
|
||||
try:
|
||||
from pxr import UsdGeom
|
||||
obj_prim = get_prim_at_path(self.pick_obj.prim_path)
|
||||
obj_xf = UsdGeom.Xformable(obj_prim)
|
||||
xform_ops = obj_xf.GetOrderedXformOps()
|
||||
print(f"[PICK_DBG] obj_xformOps_count={len(xform_ops)}", flush=True)
|
||||
for op in xform_ops:
|
||||
print(f"[PICK_DBG] obj_xformOp: {op.GetName()} val={op.Get()}", flush=True)
|
||||
obj_l2w = obj_xf.ComputeLocalToWorldTransform(0)
|
||||
print(f"[PICK_DBG] obj_USD_l2w=({obj_l2w[3][0]:.6f}, {obj_l2w[3][1]:.6f}, {obj_l2w[3][2]:.6f})", flush=True)
|
||||
parent_xf = UsdGeom.Xformable(parent_prim)
|
||||
parent_l2w = parent_xf.ComputeLocalToWorldTransform(0)
|
||||
print(f"[PICK_DBG] parent_l2w_translate=({parent_l2w[3][0]}, {parent_l2w[3][1]}, {parent_l2w[3][2]})", flush=True)
|
||||
gp_xf = UsdGeom.Xformable(grandparent_prim)
|
||||
gp_l2w = gp_xf.ComputeLocalToWorldTransform(0)
|
||||
print(f"[PICK_DBG] grandparent_l2w_translate=({gp_l2w[3][0]}, {gp_l2w[3][1]}, {gp_l2w[3][2]})", flush=True)
|
||||
stage = parent_prim.GetStage()
|
||||
mpu = UsdGeom.GetStageMetersPerUnit(stage)
|
||||
print(f"[PICK_DBG] stage_metersPerUnit={mpu}", flush=True)
|
||||
# Check get_local_pose source
|
||||
glp_method = type(self.pick_obj).get_local_pose
|
||||
print(f"[PICK_DBG] get_local_pose_from={glp_method.__qualname__}", flush=True)
|
||||
except Exception as e:
|
||||
import traceback
|
||||
print(f"[PICK_DBG] UsdGeom error: {e}", flush=True)
|
||||
traceback.print_exc()
|
||||
print(f"[PICK_DBG] root_prim_path={self.task.root_prim_path}", flush=True)
|
||||
print(f"[PICK_DBG] reference_prim_path={self.controller.reference_prim_path}", flush=True)
|
||||
T_world_obj = tf_matrix_from_pose(*local_pose)
|
||||
print(f"[PICK_DBG] T_world_obj translation={T_world_obj[:3,3]}", flush=True)
|
||||
T_world_ee = T_world_obj[None] @ self.T_obj_ee
|
||||
print(f"[PICK_DBG] T_world_ee[0] translation={T_world_ee[0,:3,3]}", flush=True)
|
||||
|
||||
if frame == "world":
|
||||
return T_world_ee
|
||||
@@ -294,8 +335,11 @@ class Pick(BaseSkill):
|
||||
T_world_base = get_relative_transform(
|
||||
get_prim_at_path(self.controller.reference_prim_path), get_prim_at_path(self.task.root_prim_path)
|
||||
)
|
||||
print(f"[PICK_DBG] T_world_base translation={T_world_base[:3,3]}", flush=True)
|
||||
T_base_world = np.linalg.inv(T_world_base)
|
||||
print(f"[PICK_DBG] T_base_world translation={T_base_world[:3,3]}", flush=True)
|
||||
T_base_ee = T_base_world[None] @ T_world_ee
|
||||
print(f"[PICK_DBG] T_base_ee[0] translation={T_base_ee[0,:3,3]}", flush=True)
|
||||
return T_base_ee
|
||||
|
||||
def get_contact(self, contact_threshold=0.0):
|
||||
|
||||
@@ -143,6 +143,8 @@ class Track(BaseSkill):
|
||||
def cal_table_2_base(self):
|
||||
tgt = self.task.fixtures["table"]
|
||||
bbox_tgt = compute_bbox(tgt.prim)
|
||||
print(f"[BBOX_DBG] table bbox min={list(bbox_tgt.min)}, max={list(bbox_tgt.max)}", flush=True)
|
||||
print(f"[BBOX_DBG] T_base_2_world translation={self.T_base_2_world[:3, 3]}", flush=True)
|
||||
table_center = (np.asarray(bbox_tgt.min) + np.asarray(bbox_tgt.max)) / 2
|
||||
tgt_z_max = bbox_tgt.max[2]
|
||||
table_center[2] = tgt_z_max
|
||||
|
||||
@@ -335,6 +335,14 @@ class BananaBaseTask(BaseTask):
|
||||
orientation = get_orientation(cfg.get("euler"), cfg.get("quaternion"))
|
||||
obj.set_local_pose(translation=cfg.get("translation"), orientation=orientation)
|
||||
obj.set_local_scale(cfg.get("scale", [1.0, 1.0, 1.0]))
|
||||
# [LOAD_DBG] Print after set_local_pose
|
||||
try:
|
||||
from pxr import UsdGeom
|
||||
_xf = UsdGeom.Xformable(get_prim_at_path(obj.prim_path))
|
||||
for _op in _xf.GetOrderedXformOps():
|
||||
print(f"[LOAD_DBG] {cfg['name']} after_set_local_pose: {_op.GetName()} = {_op.Get()}", flush=True)
|
||||
except Exception as _e:
|
||||
print(f"[LOAD_DBG] {cfg['name']} after_set_local_pose error: {_e}", flush=True)
|
||||
obj.set_visibility(cfg.get("visible", True))
|
||||
|
||||
# Extra behavior per type
|
||||
@@ -490,7 +498,7 @@ class BananaBaseTask(BaseTask):
|
||||
if cfg.get("apply_randomization", False):
|
||||
envmap_id = random.randint(0, len(envmap_hdr_path_list) - 1)
|
||||
intensity = random.uniform(cfg["intensity_range"][0], cfg["intensity_range"][1])
|
||||
rotation = [random.uniform(cfg["rotation_range"][0], cfg["rotation_range"][1]) for _ in range(3)]
|
||||
rotation = [0.0, 0.0, random.uniform(cfg["rotation_range"][0], cfg["rotation_range"][1])]
|
||||
else:
|
||||
envmap_id = 0
|
||||
intensity = 1000.0
|
||||
|
||||
Reference in New Issue
Block a user