← All ivy-nodes
IVYXSTUDIO · IVY NODE
C
Choose a grasp
ivy.node.choose-grasp · v0.1.0
ivyx✓
Decides how to take an object from its size: the jaw yaw across its narrow side and the approach height above it. A decision node: it computes, the robotics steps move.
#robotics#grasp#pick#decision
Inputs
| Field | Type | Description |
|---|---|---|
| sizerequired | object | The object's half extents in metres, as robotics.scene.locate answers them: x, y, z. |
| pose | object | The object's pose, passed through. |
| jawOpening | number | How wide the jaws open, metres; the grasp goes across the side that fits. |
| clearance | number | Metres between the object's top and the jaws on the approach. |
Outputs
| Field | Type | Description |
|---|---|---|
| yawrequired | number | The jaw yaw about the vertical, radians: 0 across x, pi/2 across y. |
| approachrequired | number | Metres above the object's centre the jaws arrive before coming down. |
| fitsrequired | boolean | True when a side of the object fits between the jaws. |
| pose | object | The object's pose, passed through. |
Source
python
# Input preparation
inp = __ivy_ctx__["nodes"][__ivy_node_id__]["input"]
# Compute
import math
class ChooseGrasp:
"""
Decides how to take an object from its half extents: the jaw yaw across
its narrower side and the height above its centre the jaws arrive at.
"""
def __init__(self, jaw_opening: float = 0.03, clearance: float = 0.03):
if jaw_opening <= 0:
raise ValueError("jawOpening must be a positive number of metres")
if clearance < 0:
raise ValueError("clearance must be zero or a positive number of metres")
self.jaw_opening = jaw_opening
self.clearance = clearance
def run(self, size: dict) -> dict:
hx = float(size.get("x", 0.0125))
hy = float(size.get("y", 0.0125))
hz = float(size.get("z", 0.0125))
across_x = 2 * hx
across_y = 2 * hy
# The jaws close across the narrower side: a yaw of 0 closes across x, pi/2 across y.
yaw = 0.0 if across_x <= across_y else math.pi / 2
return {
"yaw": yaw,
"approach": round(hz + self.clearance, 4),
"fits": min(across_x, across_y) <= self.jaw_opening,
}
result = ChooseGrasp(float(inp.get("jawOpening", 0.03)), float(inp.get("clearance", 0.03))).run(inp.get("size") or {})
result["pose"] = inp.get("pose")
# Output collection (the runner reads it here)
out = __ivy_ctx__["nodes"][__ivy_node_id__]["output"]
out.update(result)Tests
Requires: python:3.9
- cube-across-x
A cube is taken across x, the jaws arriving 4.25 cm above its centre, and it fits.
- bar-across-y
A bar wider in x than the jaws is taken across y.
- too-wide
A block wider than the jaws on both sides does not fit.