$npx -y skills add graph-robots/open-robot-skills --skill curoboNVIDIA cuRobo motion planning — collision-free trajectories to
| 1 | # curobo |
| 2 | |
| 3 | Collision-aware cuRobo motion planning as in-process tools. Trajectories |
| 4 | in/out are gap `Trajectory` dicts (`waypoints: [{positions: |
| 5 | float64[dof]}]`); worlds are gap `WorldConfig` dicts (build one with |
| 6 | `geometry.build_world_config`). |
| 7 | |
| 8 | ## When to use |
| 9 | |
| 10 | - Tabletop pick: `geometry.top_down_grasp_candidates` → |
| 11 | `curobo.plan_to_grasp_poses` (pass the whole fan as the goalset; check |
| 12 | `goalset_index` for which one was reached). |
| 13 | - Transport after grasping: `curobo.plan_with_grasped_object` with the |
| 14 | object's mesh name from `build_world_config`. |
| 15 | - Drawers/doors: `curobo.plan_grasp_motion` (approach → grasp → lift/pull |
| 16 | with gripper commands interleaved), or `curobo.plan_directed_linear` for |
| 17 | a pull along one axis with orientation locked. |
| 18 | |
| 19 | ## Install |
| 20 | |
| 21 | cuRobo JIT-compiles CUDA extensions at install time — build isolation must |
| 22 | be off and `CUDA_HOME` must point at a toolkit matching your torch build: |
| 23 | |
| 24 | ```bash |
| 25 | export CUDA_HOME=/usr/local/cuda # toolkit matching torch's CUDA version |
| 26 | uv sync --extra curobo # (pip: pip install -e ".[curobo]" --no-build-isolation) |
| 27 | ``` |
| 28 | |
| 29 | If the import fails at tool-call time the tools raise a `ToolError` with |
| 30 | this recipe. First planner call per process pays JIT/warmup latency; the |
| 31 | MotionGen/planner instances are cached and reused (HyRL pattern — recreating |
| 32 | them per call corrupts CUDA graph state). |
| 33 | |
| 34 | ## Gotchas (carried over from the service + curobo_api) |
| 35 | |
| 36 | - **Frames**: grasp/target poses are in the robot-base frame (cuRobo treats |
| 37 | the robot base as world origin). With `grasp_pose_is_fingertip=True` |
| 38 | (default) grasp positions are fingertip-pad centers and converted to the |
| 39 | `panda_hand` frame solver-side (offset 0.1029 m along hand Z). |
| 40 | - **Ignore the grasp target**: pass its mesh name in |
| 41 | `ignore_obstacle_names` for `plan_to_grasp_poses` / |
| 42 | `batch_grasp_feasibility` — closing on the target is not a collision. |
| 43 | - `robot_collision_sphere_buffer` default −0.01 shrinks robot collision |
| 44 | spheres 1 cm; reduces IK_FAIL against dense perception meshes. Negative |
| 45 | is intentional. |
| 46 | - GPU access is serialised by a module lock (cuRobo is not thread-safe); |
| 47 | CUDA/"graph capture" errors invalidate the cached planners automatically |
| 48 | before raising `PlanningFailed`. |
| 49 | - `use_cuda_graph` must stay False for the validators |
| 50 | (`check_start_state` requirement) and for varying world/start setups. |
| 51 | - **curobo version split**: `plan_to_grasp_poses`, `plan_grasp_motion`, |
| 52 | `plan_directed_linear`, `plan_linear`, `plan_to_pose`, |
| 53 | `plan_with_grasped_object` target curobo v0.8 (MotionPlanner API); |
| 54 | `solve_ik` and `batch_grasp_feasibility` are built on the v0.7 |
| 55 | IKSolver API that v0.8 removed — on a v0.8-only install they raise |
| 56 | `PlanningFailed` ("not supported on cuRobo v0.8"); plan via the goalset |
| 57 | tools instead. The validators use the v0.7 MotionGen path too. |
| 58 | - `validate_joint_trajectory_grasped` always invalidates the planner cache |
| 59 | afterward so the attachment cannot leak; expect the next planning call to |
| 60 | re-create the planner. |
| 61 | - Planning failures return `success=False` (with `failure_reason` where the |
| 62 | RPC had one); infrastructure errors raise `PlanningFailed` / `ToolError`. |
| 63 | - Set `debug_out_dir` on the grasp/transport planners to dump world + robot |
| 64 | sphere OBJ/PLY debug artifacts on failure (default `./curobo_debug*`). |