Physics¶
Since SAPIEN is a physical simulation framework, we would like to showcase how to change physical properties which lead to different behaviors.
In this tutorial, you will learn the following:
Use
SceneConfig
to initialize default physical propertiesUse
PhysicalMaterial
to set different physical materialsCreate kinematic actors
Enable damping for actors
Get kinematic quantities (pose, velocity, angular velocity) of an actor
The example illustrates an object sliding down the slope.
You can run the script with different arguments.
transforms3d
is required to compute poses, which can be installed by pip install transforms3d
.
The full script can be downloaded here physics.py
Set default physical properties¶
Default physical properties can be specified when a scene is created. Those properties include gravity, static and dynamic friction, as well as restitution (elasticity of collision).
def main():
args = parse_args()
engine = sapien.Engine()
renderer = sapien.VulkanRenderer()
engine.set_renderer(renderer)
scene_config = sapien.SceneConfig()
# The default physical properties can be modified through sapien.SceneConfig
print(scene_config.gravity)
print(scene_config.default_static_friction)
print(scene_config.default_dynamic_friction)
print(scene_config.default_restitution)
scene_config.gravity = np.array([0.0, 0.0, args.gravity])
scene = engine.create_scene(scene_config)
scene.set_timestep(1 / 100.0)
SceneConfig
describes default physical properties, and can be passed to Scene
.
Set physical materials¶
PhysicalMaterial
describes physical (contact) properties (friction and restitution) of the material of an actor.
It can be specified when an actor is created.
If not provided, the default physical material, induced by the scene’s default physical properties, will be used.
Note that PhysicalMaterial
can only be created by create_physical_material(...)
.
physical_material: sapien.PhysicalMaterial = scene.create_physical_material(
static_friction=args.static_friction,
dynamic_friction=args.dynamic_friction,
restitution=args.restitution,
)
Some other physical properties, like density, are directly provided to collision shapes. We update create_sphere
function in Create Actors.
def create_sphere(
scene: sapien.Scene,
pose: sapien.Pose,
radius,
color=None,
density=1000.0,
physical_material: sapien.PhysicalMaterial = None,
name='',
) -> sapien.Actor:
"""Create a sphere."""
builder = scene.create_actor_builder()
builder.add_sphere_collision(radius=radius, material=physical_material, density=density)
builder.add_sphere_visual(radius=radius, color=color)
sphere = builder.build(name=name)
sphere.set_pose(pose)
return sphere
Note
The rolling restitution (friction) is not modeled in SAPIEN currently.
Create a kinematic actor¶
Now, let’s create a slope.
The slope should be a kinematic object, rather than a dynamic object.
In other words, it can not be affected by external forces.
We can set is_kinematic=True
when building the actor.
def create_box(
scene: sapien.Scene,
pose: sapien.Pose,
half_size,
color=None,
is_kinematic=False,
density=1000.0,
physical_material: sapien.PhysicalMaterial = 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.
is_kinematic: whether an object is kinematic (can not be affected by forces).
density: float, the density of the box.
physical_material: physical material of the actor.
name: name of the actor.
Returns:
sapien.Actor
"""
half_size = np.array(half_size)
builder = scene.create_actor_builder()
builder.add_box_collision(half_size=half_size, material=physical_material, density=density) # Add collision shape
builder.add_box_visual(half_size=half_size, color=color) # Add visual shape
if is_kinematic:
box = builder.build_kinematic(name=name)
else:
box = builder.build(name=name)
box.set_pose(pose)
return box
Set damping for the actor¶
Sometimes, you might model some restitution proportional to (linear or angular) velocity, like air restitution. It can be achieved by setting the damping of an actor.
actor.set_damping(linear=args.linear_damping, angular=args.angular_damping)
Get kinematic quantities (pose, velocity) of an actor¶
We can acquire kinematic quantities (pose, linear velocity, angular velocity) of an actor through get_pose()
, get_velocity()
, get_angular_velocity()
.
print('Pose', actor.get_pose())
print('Velocity', actor.get_velocity())
print('Angular velocity', actor.get_angular_velocity())