update curobo sphere fit - #468
Conversation
…j/update-curobo-sphere-fit
Greptile SummaryThe PR replaces cuRobo’s configurable sphere/world fitting with DexSim MorphIt robot spheres and tensor-backed ESDF voxel worlds, and adds collision-model visualization.
Confidence Score: 5/5The PR appears safe to merge because the previously reported benchmark configuration failure is resolved and no blocking failure remains. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| embodichain/lab/sim/planners/curobo/curobo_planner.py | Integrates versioned voxel-scene generation and caching, runtime robot configuration, scene cloning, and collision-model visualization; the previously incompatible benchmark option has been removed from the suites. |
| embodichain/lab/sim/planners/curobo/curobo_yaml.py | Replaces cuRobo sphere/world fitting with DexSim MorphIt and VisACD-backed voxel generation and adds visualization helpers. |
| scripts/benchmark/motion_generation/suites/smoke.yaml | Removes the obsolete fit_type value while preserving supported sphere-fitting settings. |
| scripts/benchmark/motion_generation/suites/coverage.yaml | Removes the obsolete fit_type value while preserving supported sphere-fitting settings. |
| tests/sim/planners/test_curobo_planner.py | Updates planner tests for fixed MorphIt fitting, voxel collision scenes, cache behavior, and visualization. |
| tests/sim/planners/test_curobo_integration.py | Updates integration coverage for the revised cuRobo collision-model pipeline. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
A[Robot URDF and link meshes] --> B[DexSim MorphIt sphere fitting]
B --> C[Versioned robot YAML cache]
D[RigidObject meshes and poses] --> E[VisACD convex decomposition]
E --> F[ESDF voxel generation]
F --> G[Versioned tensor cache]
C --> H[cuRobo MotionPlanner]
G --> H
H --> I[Collision-aware trajectory]
C --> J[Collision-model visualization]
G --> J
Reviews (3): Last reviewed commit: "update" | Re-trigger Greptile
There was a problem hiding this comment.
Pull request overview
This PR updates EmbodiChain’s cuRobo planner integration to use DexSim’s MorphIt sphere fitting for both robot-link and world obstacle collision spheres, and adds runtime support for cuRobo V2 sphere obstacles by registering an analytic sphere SDF into cuRobo’s Warp-based collision checker. It also adds cached collision-model visualization utilities, updates documentation, and expands the test suite to cover the new behavior (including temporarily disabling cuRobo self-collision checking).
Changes:
- Switch sphere fitting for robot/world YAML generation from cuRobo’s fitter to DexSim MorphIt with fixed convex-hull limits.
- Add analytic sphere obstacle storage + cuRobo runtime hooks so sphere scene obstacles are actually checked at runtime.
- Add visualization helpers for cached robot/world collision spheres and extend tests/docs accordingly.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/sim/planners/test_curobo_planner.py | Adds tests for DexSim MorphIt fitting, runtime sphere registration/validation, self-collision disabling, and visualization. |
| examples/sim/planners/curobo_planner.py | Updates the demo to use sphere obstacle representation and optionally visualize cached collision models. |
| embodichain/lab/sim/planners/curobo/curobo_yaml.py | Switches YAML generation sphere fitting to DexSim + Open3D and adds collision-model visualization utilities. |
| embodichain/lab/sim/planners/curobo/curobo_sphere_data.py | Introduces analytic sphere obstacle storage and Warp SDF helpers for cuRobo’s generic collision checker. |
| embodichain/lab/sim/planners/curobo/curobo_planner.py | Wires in runtime sphere support registration, disables self-collision checks, validates runtime sphere loading, and adds visualization entrypoint. |
| docs/source/overview/sim/planners/curobo_planner.md | Documents DexSim MorphIt usage, runtime sphere support, visualization, and the temporary self-collision disablement. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| inv_pose = torch.zeros( | ||
| (num_envs, max_n, 8), | ||
| dtype=device_cfg.dtype, | ||
| device=device_cfg.device, | ||
| ) | ||
| inv_pose[..., 3] = 1.0 |
| # if robot_type == "w1": | ||
| # Keep the W1-specific IK diagnostic batched so it remains useful when | ||
| # checking solver and cuRobo reachability across multiple environments. | ||
| # import ipdb; ipdb.set_trace() | ||
| init_qpos = torch.tensor( | ||
| robot.cfg.init_qpos, dtype=torch.float32, device=robot.device | ||
| ) | ||
| arm_init_qpos = ( | ||
| init_qpos[robot.get_joint_ids(control_part)] | ||
| .unsqueeze(0) | ||
| .expand(num_envs, -1) | ||
| .clone() | ||
| ) | ||
| is_success, ik_qpos = robot.compute_ik( | ||
| pose=target_xpos, name=control_part, joint_seed=arm_init_qpos | ||
| ) | ||
| print(f"robot target xpos ik success: {is_success}, ik_qpos: {ik_qpos}") |
| ``"sphere"`` (default) fits spheres with DexSim's MorphIt implementation | ||
| (approximate, and requires CUDA + Open3D). cuRobo V2 can parse sphere | ||
| obstacles but omits their collision storage; EmbodiChain registers an |
| world=CuroboWorldCfg( | ||
| rigid_objects=obstacles, | ||
| obstacle_representation="cuboid", | ||
| obstacle_representation=("sphere"), |
…j/update-curobo-sphere-fit
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.
Suppressed comments (2)
examples/sim/planners/curobo_planner.py:465
- The comment block says this is a "W1-specific IK diagnostic", but the
compute_ik(...)call now runs unconditionally for all robots, so the comment is misleading. Also, leaving commented-out debugger lines (ipdb.set_trace) in an example reads like leftover debug scaffolding.
# if robot_type == "w1":
# Keep the W1-specific IK diagnostic batched so it remains useful when
# checking solver and cuRobo reachability across multiple environments.
# import ipdb; ipdb.set_trace()
init_qpos = torch.tensor(
embodichain/lab/sim/planners/curobo/curobo_planner.py:1563
torch.load(..., weights_only=True)is used without a compatibility fallback. Elsewhere in the codebase (e.g.embodichain/lab/sim/planners/neural_planner.py:_safe_torch_load) the project falls back toweights_only=Falsewhen running on older PyTorch versions or whenweights_only=Truecannot deserialize the file. Without a fallback, loading an existing world cache will raise on those setups and break planner init.
cache_path = os.path.join(cache_dir, f"world_{cache_key}.pt")
if not auto.force and os.path.exists(cache_path):
logger.log_info(f"cuRobo voxel world cache hit: {cache_path}")
scene_data = torch.load(cache_path, map_location="cpu", weights_only=True)
else:
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.
Suppressed comments (5)
examples/sim/planners/curobo_planner.py:467
- Commented-out debug code (
ipdb.set_trace()) and a commented conditional were added to the example. Leaving these in the repo makes the example harder to follow and risks reintroducing debug statements later.
# if robot_type == "w1":
# Keep the W1-specific IK diagnostic batched so it remains useful when
# checking solver and cuRobo reachability across multiple environments.
# import ipdb; ipdb.set_trace()
init_qpos = torch.tensor(
robot.cfg.init_qpos, dtype=torch.float32, device=robot.device
)
embodichain/lab/sim/planners/curobo/curobo_planner.py:1563
torch.load(..., weights_only=True)is used without a compatibility fallback. Because EmbodiChain does not pin a minimum PyTorch version (and older versions don't supportweights_only), this can raiseTypeErrorand break cuRobo world-cache reuse. The codebase already uses a try/fallback pattern (e.g.embodichain/lab/sim/planners/neural_planner.py:_safe_torch_load).
if not auto.force and os.path.exists(cache_path):
logger.log_info(f"cuRobo voxel world cache hit: {cache_path}")
scene_data = torch.load(cache_path, map_location="cpu", weights_only=True)
else:
embodichain/lab/sim/planners/curobo/curobo_planner.py:1581
deepcopy(scene_data)will deep-copy the cached voxel tensors, which can be extremely expensive in CPU memory/time before they are moved to GPU. Since you only need a device-mapped runtime view, prefer a shallow copy of the dict and rebuild the per-voxel entries while movingfeature_tensortoself._curobo_device.
runtime_data = deepcopy(scene_data)
for voxel in runtime_data.get("voxel", {}).values():
voxel["feature_tensor"] = voxel["feature_tensor"].to(
device=self._curobo_device, dtype=torch.float16
)
return self._bindings.Scene.create(runtime_data)
docs/source/overview/sim/planners/curobo_planner.md:242
- The documentation says
planner.visualize_collision_models(...)shows an "Open3D overlay" and instructs readers to close an Open3D window, but the implementation overlays temporary actors in the DexSim scene and blocks on a terminalinput()prompt. This mismatch will confuse users.
For an Open3D overlay of the live robot/obstacle meshes and the exact spheres
read back from those YAML caches, call
`planner.visualize_collision_models(control_part)`. Robot sphere centers are
transformed by the simulator's live link poses. The interactive cuRobo example
calls this once after planner initialization; close the Open3D window to continue.
embodichain/lab/sim/planners/curobo/curobo_yaml.py:179
- The
generate_curobo_robot_yamldocstring lists ImportError only for DexSim/Open3D, but the function also imports cuRobo (UrdfRobotParser) and will raise ImportError if cuRobo is missing. The raised-exception documentation should match actual imports.
Raises:
ImportError: If DexSim or Open3D is not installed.
RuntimeError: If CUDA is unavailable or no spheres could be fitted.
Description
visualization:
motion_generator.planner.visualize_collision_models(control_part)(only support curobo)TODO:
Type of change
Checklist
black .command to format the code base.