Skip to content

Cloth (bt.cloth)

A T-shirt or a sheet on a table, handled by the robots' grippers and simulated against the baked cycle. See the cloth guide for what it answers and how a fold is taught.

shirt = bt.cloth.tshirt("shirt", on="table/top")
marks = bt.cloth.landmarks(scene, shirt)
bt.cloth.add(scene, shirt, grippers=[bt.cloth.gripper("grip", radius=0.05)])
timeline = scene.simulate_sequence("fold")
timeline.cloth("shirt").position("cuff_left", timeline.duration)

Reference

cloth

Cloth in a cell: a T-shirt or a sheet handled by the robots' grippers.

The cloth is simulated after a bake, against the finished cycle: each gripper's tool point follows its robot through the cycle and closes while a signal is on. The cloth never pushes a robot back, and the robots plan as if it were not there.

shirt = bt.cloth.tshirt("shirt", on="table/top", spacing=0.02)
marks = bt.cloth.landmarks(scene, shirt)   # frames shirt/cuff_left, ...
# ... teach motions against the landmarks; set a signal where a gripper closes ...
bt.cloth.add(scene, shirt, grippers=[bt.cloth.gripper("grip", radius=0.04)])
tl = scene.simulate_sequence("fold")       # the cloth rides every bake
tl.cloth("shirt").position("cuff_left", 3.0)

A cloth lies flat on a level support surface: the frame named by on (a table's <name>/top) gives its centre, the support height and its heading; position gives the centre and the height without a frame. At yaw=0 the width runs along +x and the length — a T-shirt's hem to its shoulders — along -y.

tshirt

tshirt(
    name: str,
    *,
    on: Optional[str] = None,
    position: Optional[Sequence[float]] = None,
    yaw: float = 0.0,
    spacing: float = 0.02,
    layers: str = "sewn",
    neck: str = "notch",
    seams: str = "shared",
    body: Optional[Tuple[float, float]] = None,
    sleeve: Optional[Tuple[float, float]] = None,
    thickness: Optional[float] = None,
    band: Optional[float] = None,
    friction: Optional[float] = None,
    density: Optional[float] = None,
    workers: Optional[int] = None,
    max_iterations: Optional[int] = None,
) -> Dict[str, Any]

A T-shirt lying flat, front up.

layers is "sewn" (a front and a back joined along the outline) or "single" (one panel); neck "notch" or "round"; seams "shared" or "stitched". body is (width, length) (0.50 x 0.70 m by default) and sleeve (length, width) (0.22 x 0.20 m). spacing is the mesh cell: 0.02 m is the full-size shirt (about two thousand vertices, minutes to simulate); 0.05 m a coarse one that runs in seconds.

Landmarks: cuff_left/right, hem_left/right/center, shoulder_left/right, underarm_left/right, neck_front/back, chest.

sheet

sheet(
    name: str,
    size: Tuple[float, float],
    *,
    on: Optional[str] = None,
    position: Optional[Sequence[float]] = None,
    yaw: float = 0.0,
    spacing: float = 0.02,
    thickness: Optional[float] = None,
    band: Optional[float] = None,
    friction: Optional[float] = None,
    density: Optional[float] = None,
    workers: Optional[int] = None,
    max_iterations: Optional[int] = None,
) -> Dict[str, Any]

A rectangular sheet size = (width, length) lying flat.

Landmarks, as it lies at yaw=0 (north is +y, east +x): corner_nw/ne/sw/se, edge_n/s/w/e, center.

gripper

gripper(
    signal: str,
    *,
    robot: Optional[str] = None,
    group: Optional[str] = None,
    link: Optional[str] = None,
    radius: float = 0.04,
    compliance: float = 0.0,
    soften: int = 0,
    pad: Optional[Sequence[float]] = None,
    pad_offset: Sequence[float] = (0.0, 0.0, 0.0),
) -> Dict[str, Any]

A gripper that handles cloth: it holds while signal is on.

Its tool point is link's frame, else the tip of group (one arm of a dual-arm robot), else the robot's TCP. When the signal turns on, the gripper takes the cloth vertices within radius of the tool point, through every layer — or takes over the patch another gripper holds there, which is a hand-over. When it turns off it lets go.

compliance 0 pins the patch; a positive value (m/N) holds it on springs, which a flap folded by two grippers needs (0.02 for a T-shirt's hem). soften is the number of cloth steps over which the hold weakens before it opens, so a taut flap settles instead of snapping free.

pad gives the gripper a box (full extents, in the tool frame, centred at pad_offset) that pushes cloth it does not hold; without one it passes through cloth.

landmarks

landmarks(
    scene, cloth: Dict[str, Any], frames: bool = True
) -> Dict[str, Tuple[float, float, float]]

Where the cloth's landmarks lie before anything moves it.

With frames (the default) each is also registered as the frame <cloth name>/<landmark>, so motions and toolpaths can be taught against it. Nothing is simulated.

add

add(
    scene,
    cloth: Dict[str, Any],
    grippers: Iterable[Dict[str, Any]] = (),
    step: float = 0.1,
) -> None

Puts the cloth in the cell: every bake from here on — a simulate_sequence call or the studio's simulate button — is followed by the cloth's simulation against the baked cycle, and its timeline carries the track (timeline.cloth(name)). Adding a cloth of the same name replaces it.

step is the cloth's time step (s); 0.1 is what the solver is qualified at.

remove

remove(scene, name: str) -> bool

Takes a cloth out of the cell; False if it was not there.

animate

animate(
    scene,
    timeline,
    cloth: Dict[str, Any],
    grippers: Iterable[Dict[str, Any]] = (),
    step: float = 0.1,
)

Simulates the cloth against an already baked timeline and returns the timeline with its track, without putting the cloth in the cell — for trying cloth settings on one cycle without baking it again.

ClothTrack

Returned by SequenceTimeline.cloth(name): one cloth over the baked cycle.

ClothTrack

One cloth over a baked cycle: where every vertex was, on the cloth's own clock (times), and which vertices a gripper held.

failure property

failure

(time, reason) when the simulation stopped before the end of the cycle — the track holds its last state from there — else None.

landmarks property

landmarks

Landmark name to vertex index: a T-shirt's cuff_left, hem_right, shoulder_left…; a sheet's corner_nw, edge_s, center….

name property

name

times property

times

Sample times (s): a step of the cloth solver apart while the cloth moves, the two ends only of a span in which it lies still.

triangles property

triangles

Triangles over the vertex indices.

warnings property

warnings

What the pass noticed without stopping: a gripper that closed on nothing, a step it took in parts.

held method descriptor

held(t)

The vertices a gripper holds at t.

position method descriptor

position(landmark, t)

World position of one landmark at t.

positions method descriptor

positions(t)

World position of every vertex at t, blended between the samples around it.