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.
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
¶
(time, reason) when the simulation stopped before the end of the
cycle — the track holds its last state from there — else None.
landmarks
property
¶
Landmark name to vertex index: a T-shirt's cuff_left,
hem_right, shoulder_left…; a sheet's corner_nw, edge_s,
center….
times
property
¶
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.
warnings
property
¶
What the pass noticed without stopping: a gripper that closed on nothing, a step it took in parts.
positions
method descriptor
¶
World position of every vertex at t, blended between the samples
around it.