agentsclimarketplace

Grasping short axis

Skill graph-robots/open-robot-skills/skills/grasping-short-axis

Skill and tool bundles for gap (graph as policy) — Anthropic Agent Skills format, discovered by path

Install
npx -y skills add graph-robots/open-robot-skills --skill grasping-short-axis

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

What its author says it does

Copied from the file, not written here

Deterministic short-axis-aligned grasp with CuRobo. The grasp pose is computed geometrically (NOT sampled/scored) — the gripper approaches straight down with its finger-opening axis locked to the OBB's SHORTER horizontal axis, so the jaws close ACROSS the narrow dimension of an elongated target. Use for pan/pot handles, bottles, tools, utensils — anywhere the OBB centroid is graspable but orientation is the thing that matters. An optional offset_from_base node slides the grasp outward along the handle, clear of the heavier object body, when a second OBB of that body is wired in. A scored/sampled pose often holds at close but shears out under the lift; the short-axis pose grips the bar squarely so it survives lift + transport.

SKILL.md

13.5 KB, as published. Nobody here has run it

grasping-short-axis

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_obb for 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.
  • curobo not 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:

  1. opentype: tool, tool: "robot.open_gripper", inputs: { settle_steps: 40 }.
  2. compute_grasptype: script, file scripts/<sg>/short_axis_grasp_pose.py (canonical — do NOT re-emit a ```python block; the bundle materializes it). Inputs: target_obb = Ref("in.target_obb"). Optional z_offset (default −0.04: descend the fingertip 4 cm into the OBB top). Returns {grasp_pose: Se3Pose}.
  3. offset_from_basetype: script, file scripts/<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 and base_obb declared as a subgraph input — base_obb = Ref("in.base_obb"). Returns {adjusted_grasp: Se3Pose}. Safe no-op when base_obb is absent.
  4. approachtype: script, file scripts/<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").
  5. observetype: tool, tool: "robot.get_observation".
  6. build_worldtype: script, file scripts/<sg>/build_world.py (canonical). Inputs: observation = Ref("observe"), target_mask = Ref("in.target_mask"), target_obb = Ref("in.target_obb"), target_name = "target".
  7. plantype: script, file scripts/<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.py auto-wraps the single bare Se3Pose into a one-element list. All four inputs are required.
  8. executetype: tool, tool: "robot.execute_trajectory", inputs: { trajectory: Ref("plan.trajectory"), subsample: 4 }.
  9. finalizetype: script, file scripts/<sg>/finalize_trajectory.py (canonical). Inputs: trajectory = Ref("plan.trajectory"). MANDATORY — see the execute → finalize → close hard_rule. Edges: execute → finalize, finalize → close.
  10. closetype: tool, tool: "robot.close_gripper", inputs: { settle_steps: 60 }. Edge directly from close to the grasped success 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 stateMeaning
graspedGripper has closed on the object after the descend. Route to the next subgraph (typically transporting-objects).
failedAny 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 its approach/build_world/plan/finalize tail (the scripts are bundled here so the skill is self-contained).

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.