Grasping direct ik
Skill graph-robots/open-robot-skills/skills/grasping-direct-ik
Direct IK align-then-descend grasping. The gripper pre-rotates to the grasp orientation at a safe height ABOVE the target before descending straight down, avoiding the twist-while-closing failure mode of a blended rotate+descend. Use when no trajectory planner (curobo) is deployed or the scene is uncluttered enough that a straight-line approach is safe.From its SKILL.md
npx -y skills add graph-robots/open-robot-skills --skill grasping-direct-ikAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
SKILL.md
5.5 KB, 981 tokens by cl100k_base, as published. Nobody here has run it
grasping-direct-ik
Direct-IK grasp: rotate the gripper to grasp orientation at a safe height above the target, then descend straight down, then close. No trajectory planner — works on platforms where CuRobo is not deployed, or in uncluttered scenes where planning is overkill.
When to use
- The
curobotool bundle is not deployed (no collision-aware planner available). - The scene is uncluttered enough that a straight-line approach is safe.
When NOT to use
- Cluttered scenes where the arm must thread between obstacles. Prefer
grasping-with-plannerif available.
Recommended subgraph state flow
The subgraph state machine the agent generates should look like (6 states):
open → compute_grasp → compute_align → rotate_align → descend → close → grasped
(grasped is the success-marker noop from sg.add_exit("grasped"),
with an edge to END.)
State details:
-
open—type: tool,tool: "robot.open_gripper",inputs: { settle_steps: 40 }. -
compute_grasp—type: tool,tool: "geometry.top_down_grasp_candidates",inputs: { obb: Ref("in.target_obb") }. -
compute_align—type: script, filescripts/<sg>/compute_align_pose.py(from this bundle'scanonical_scripts). Inputs:grasp_pose = Ref("compute_grasp.candidates.poses.0"),target_obb = Ref("in.target_obb"). Returnsalign_pose. -
rotate_align—type: tool,tool: "robot.go_to_pose",inputs: { pose: Ref("compute_align.align_pose") }. -
descend—type: tool,tool: "robot.go_to_pose",inputs: { pose: Ref("compute_grasp.candidates.poses.0") }. -
close—type: tool,tool: "robot.close_gripper",inputs: { settle_steps: 60 }. Edge directly fromcloseto thegraspedsuccess marker; the subgraph'son_error: "failed"catches any raise from earlier steps. Whether the gripper actually closed on the object is checked by thetarget_heldpostcondition checkpoint (see## Checkpoints), NOT by a re-check-and-raise node (none such exists)."edges": [ ..., ["close", "grasped"], ["grasped", "END"] ], "conditional_edges": {}, "exit": { "router_field": null, "success_values": ["grasped"] }, "on_error": "failed"The lift onto a safe carry height is handled by the next
transporting-objectssubgraph (itswaypoint_movescript lifts before lateral motion); do NOT add a lift step here.
Hard rules
- Use
geometry.top_down_grasp_candidates(returnscandidates: {poses: list[Se3Pose]}), notgeometry.top_down_grasp_from_obb(single bare pose). The align-pose construction in step 3 assumescompute_grasp.candidates.poses.0exists. - The
align_posedescends straight down with the gripper pre-rotated. Do NOT skip thecompute_align+rotate_alignstates — a directrobot.go_to_poseto the grasp pose blends rotation and descent and twists the gripper against the object.
Required end states
| End state | Meaning |
|---|---|
grasped | Gripper has closed on the object after the descend. Route to next subgraph (typically transporting-objects). |
failed | Any grasp-attempt failure: planning failure or trajectory execution error (a raise to on_error). Coordinator routes to abort. Lives only in on_error — never declare a failed node. |
See also
references/design_align_then_descend.md— why pre-rotate-then-descend beats blended rotate+descend.scripts/compute_align_pose.py— the canonical align-pose construction.
What ships with it: 3 files
4.6 KB alongside SKILL.md, 2 of them executable
references/
scripts/
- compute_align_pose.pyruns1.3 KB
- plan_to_pose.pyruns1.3 KB