grasping-short-axis
SkillDev toolsDeterministic short-axis-aligned grasp with CuRobo. The grasp
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the grasping-short-axis skill
What this skill tells your AI
The instructions your AI receives, as published by graph-robots/open-robot-skills in skills/grasping-short-axis/SKILL.md and read by ahel’s review.
Deterministic, geometry-locked grasping with CuRobo. The grasp pose is computed directly from the target OBB — the gripper descends along world −Z with its finger-opening axis snapped to the OBB's shorter horizontal axis, so the jaws close across the narrow dimension of the bar. An optional node then slides the grasp outward along the handle, clear of a heavier attached body. The subgraph builds a per-observation collision world (target excluded), plans a CuRobo trajectory, executes it, finalizes the last waypoint, closes the gripper, and outputs the EE pose at grasp.
Install
This skill depends on the curobo and geometry tool bundles:
export CUDA_HOME=/usr/local/cuda
uv sync --extra curobo --extra geometry # (pip: pip install -e "open-robot-skills[curobo,geometry]" --no-build-isolation)
When to use
- Elongated targets where grasp orientation matters: pan / pot handles, bottles, tools, utensils.
- A subpart (handle) that protrudes from a heavier body — wire
base_obbfor the outward slide. - When a sampled/scored grasp pose holds at close but the object slips during the lift (marginal off-axis contact patch).
When NOT to use
- Symmetric objects (boxes, cans) where any yaw works — use
grasping-with-planner. curobonot deployed.- You genuinely want multiple sampled candidates for the planner to
choose from — use
grasping-with-planner.
Recommended subgraph state flow
10 states, in order:
open → compute_grasp → offset_from_base → approach → observe
→ build_world → plan → execute → finalize → 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: script, filescripts/<sg>/short_axis_grasp_pose.py(canonical — do NOT re-emit a```pythonblock; the bundle materializes it). Inputs:target_obb = Ref("in.target_obb"). Optionalz_offset(default −0.04: descend the fingertip 4 cm into the OBB top). Returns{grasp_pose: Se3Pose}.offset_from_base—type: script, filescripts/<sg>/offset_grasp_from_base.py(canonical). Inputs:handle_obb = Ref("in.target_obb"),grasp_pose = Ref("compute_grasp.grasp_pose"), and — ONLY when a body perception was authored andbase_obbdeclared as a subgraph input —base_obb = Ref("in.base_obb"). Returns{adjusted_grasp: Se3Pose}. Safe no-op whenbase_obbis absent.approach—type: script, filescripts/<sg>/approach_above.py(canonical). Inputs:target_position = Ref("offset_from_base.adjusted_grasp.position"),rotation = Ref("offset_from_base.adjusted_grasp.rotation"),target_obb = Ref("in.target_obb").observe—type: tool,tool: "robot.get_observation".build_world—type: script, filescripts/<sg>/build_world.py(canonical). Inputs:observation = Ref("observe"),target_mask = Ref("in.target_mask"),target_obb = Ref("in.target_obb"),target_name = "target".plan—type: script, filescripts/<sg>/plan_grasp.py(canonical). Inputs:world_config = Ref("build_world.config"),observation = Ref("observe"),grasp_poses = Ref("offset_from_base.adjusted_grasp"),target_name = "target".plan_grasp.pyauto-wraps the single bare Se3Pose into a one-element list. All four inputs are required.execute—type: tool,tool: "robot.execute_trajectory",inputs: { trajectory: Ref("plan.trajectory"), subsample: 4 }.finalize—type: script, filescripts/<sg>/finalize_trajectory.py(canonical). Inputs:trajectory = Ref("plan.trajectory"). MANDATORY — see theexecute → finalize → closehard_rule. Edges:execute → finalize,finalize → close.close—type: tool,tool: "robot.close_gripper",inputs: { settle_steps: 60 }. Edge directly fromcloseto thegraspedsuccess marker.
The cross-subgraph output binding:
sg.set_outputs(
ee_pose_at_grasp=Ref("observe.arms.0.ee_pose"),
grasp_pose=Ref("offset_from_base.adjusted_grasp"),
)
Wire the exit:
sg.add_edge("close", "grasped")
sg.add_edge("grasped", END)
sg.add_exit("grasped")
sg.set_on_error("failed")
Required end states
| End state | Meaning |
|---|---|
grasped | Gripper has closed on the object after the descend. Route to the next subgraph (typically transporting-objects). |
failed | Any grasp-attempt failure: collision-aware planning failure or trajectory execution error (a raise to on_error). Lives only in on_error — never declare a failed node. |
Checkpoints
Express grasp success as a validate=True postcondition checkpoint
target_held on the close state (the gripper is holding the target
after close). Do not add a re-check-and-raise node.
See also
../grasping-with-planner/SKILL.md— the sampled-candidate OBB counterpart; this skill mirrors itsapproach/build_world/plan/finalizetail (the scripts are bundled here so the skill is self-contained).
Signals
- GitHub stars
- 41
- Forks
- 7
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
grasping-short-axis- Source
- github.com/graph-robots/open-robot-skills