Create Actors
SAPIEN simulates rigid body dynamics. In SAPIEN, actor is an alias of rigid body.
In this tutorial, you will learn the following:
Create
Actor
using primitives (box, sphere, capsule)Create
Actor
using mesh filesUse
Pose
to set the pose of an actor
The full script can be downloaded here create_actors.py
Create an actor by a single primitive
The primitives supported by SAPIEN include box, sphere and capsule. Here we show an example about how to create a box. Examples to create a sphere and a capsule can be found in the code provided.
def create_box(
scene: sapien.Scene,
pose: sapien.Pose,
half_size,
color=None,
name='',
) -> sapien.Actor:
"""Create a box.
Args:
scene: sapien.Scene to create a box.
pose: 6D pose of the box.
half_size: [3], half size along x, y, z axes.
color: [3] or [4], rgb or rgba
name: name of the actor.
Returns:
sapien.Actor
"""
half_size = np.array(half_size)
builder: sapien.ActorBuilder = scene.create_actor_builder()
builder.add_box_collision(half_size=half_size) # Add collision shape
builder.add_box_visual(half_size=half_size, color=color) # Add visual shape
box: sapien.Actor = builder.build(name=name)
# Or you can set_name after building the actor
# box.set_name(name)
box.set_pose(pose)
return box
Actor
(or rigid body) is created through ActorBuilder
in SAPIEN.
An actor consists of both collision shapes (used for physical simulation) and visual shapes (used for rendering).
You can call add_box_collision
and add_box_visual
to add collision and visual shapes of an box respectively.
Note
Collision shapes do not necessarily correspond to visual shapes. For example, you might have a simple collision shape for fast simulation, but a complicated visual shape for realistic rendering.
Then, you might create a box as follows:
box = create_box(
scene,
sapien.Pose(p=[0, 0, 1.0 + 0.05]),
half_size=[0.05, 0.05, 0.05],
color=[1., 0., 0.],
name='box',
)
The pose of the box in the world frame can be specified by Pose
.
Pose
describes a 6D pose, consisting of a 3-dim position vector p
and a 4-dim quaternion q
(to represent the rotation, in the wxyz convention).
Create an actor by multiple primitives
Next, we show an example to create an actor (table) by multiple boxes (a tabletop with four legs).
def create_table(
scene: sapien.Scene,
pose: sapien.Pose,
size,
height,
thickness=0.1,
color=(0.8, 0.6, 0.4),
name='table',
) -> sapien.Actor:
"""Create a table (a collection of collision and visual shapes)."""
builder = scene.create_actor_builder()
# Tabletop
tabletop_pose = sapien.Pose([0., 0., -thickness / 2]) # Make the top surface's z equal to 0
tabletop_half_size = [size / 2, size / 2, thickness / 2]
builder.add_box_collision(pose=tabletop_pose, half_size=tabletop_half_size)
builder.add_box_visual(pose=tabletop_pose, half_size=tabletop_half_size, color=color)
# Table legs (x4)
for i in [-1, 1]:
for j in [-1, 1]:
x = i * (size - thickness) / 2
y = j * (size - thickness) / 2
table_leg_pose = sapien.Pose([x, y, -height / 2])
table_leg_half_size = [thickness / 2, thickness / 2, height / 2]
builder.add_box_collision(pose=table_leg_pose, half_size=table_leg_half_size)
builder.add_box_visual(pose=table_leg_pose, half_size=table_leg_half_size, color=color)
table = builder.build(name=name)
table.set_pose(pose)
return table
We can call add_box_collision(pose=Pose(...), ...)
to set the pose of a collision shape in the actor frame.
Similarly, we can call add_box_visual(pose=Pose(...), ...)
for a visual shape.
Note that table.set_pose(pose)
sets the pose of the actor in the world frame.
Create an actor by a mesh file
Apart from primitives, actors can also be created from mesh files.
builder = scene.create_actor_builder()
builder.add_collision_from_file(filename='../assets/banana/collision_meshes/collision.obj')
builder.add_visual_from_file(filename='../assets/banana/visual_meshes/visual.dae')
mesh = builder.build(name='mesh')
mesh.set_pose(sapien.Pose(p=[-0.2, 0, 1.0 + 0.05]))
Note
Any collision shape in SAPIEN is required to be convex. To this end, a mesh will be “cooked” into a convex mesh before being used in the simulation. The converted convex mesh is cached at the same directory of the original mesh file. Thus, if the mesh file is changed, please remove the cache.
Remove an actor
After an actor is built with actor = builder.build()
, You can call
scene.remove_actor(actor)
to remove it. Using a removed actor will result in
undefined behavior (usually a crash).