Hello World#
SAPIEN provides APIs to build physical simulation environments.
In this tutorial, you will learn the following:
Create a simulation
Scene
Setup visualization
Run a simulation loop
The full script can be downloaded here hello_world.py
Simulation scene#
To simulate with SAPIEN, you need to first create a scene.
scene = sapien.Scene() # Create an instance of simulation world (aka scene)
scene.set_timestep(1 / 100.0) # Set the simulation frequency
Scene
is an instance of the simulation world.
Multiple scenes can be created by calling the constructor sapien.Scene
, and they are independent.
By default, SAPIEN uses PhysX 5 to simulate
rigid bodies. scene.set_timestep
sets how many seconds the physical
simulator will advance when scene.step
is called.
Add rigid bodies#
So far, our scene is empty.
In SAPIEN, a scene contains a list of Entity
. The behavior of an Entity
is determined by a list of Component
attached to the Entity
. In SAPIEN,
we refer to an Entity
with physical behavior as an Actor. For example, an
Entity
with an attached rigid body component is an Actor. Let’s add two
actors, a ground and a box, to the scene. Actor creation will be elaborated in
Create Actors.
scene.add_ground(altitude=0) # Add a ground
actor_builder = scene.create_actor_builder()
actor_builder.add_box_collision(half_size=[0.5, 0.5, 0.5])
actor_builder.add_box_visual(half_size=[0.5, 0.5, 0.5], material=[1.0, 0.0, 0.0])
box = actor_builder.build(name="box") # Add a box
box.set_pose(sapien.Pose(p=[0, 0, 0.5]))
Viewer#
Viewer
creates a window (GUI) to render the simulation world. It is only
available with a connected display. The display can be physical (e.g., monitor)
or virtual (e.g., VNC). Usage of the GUI will be elaborated in Viewer.
viewer = scene.create_viewer() # Create a viewer (window)
# The coordinate frame in Sapien is: x(forward), y(left), z(upward)
# The principle axis of the camera is the x-axis
viewer.set_camera_xyz(x=-4, y=0, z=2)
# The rotation of the free camera is represented as [roll(x), pitch(-y), yaw(-z)]
# The camera now looks at the origin
viewer.set_camera_rpy(r=0, p=-np.arctan2(2, 4), y=0)
viewer.window.set_camera_parameters(near=0.05, far=100, fovy=1)
Note
The GUI is not necessary when you only need simulation and rendering, e.g. collecting experiences for policy learning.
Simulation loop#
After setting up the simulation world, the actual simulation happens in a loop.
For each iteration, the scene simulates for one step and updates the world to the renderer.
The viewer calls render
to update the results on the screen.
while not viewer.closed: # Press key q to quit
scene.step() # Simulate the world
scene.update_render() # Update the world to the renderer
viewer.render()
Full script#
1import sapien as sapien
2from sapien.utils import Viewer
3import numpy as np
4
5
6def main():
7 scene = sapien.Scene() # Create an instance of simulation world (aka scene)
8 scene.set_timestep(1 / 100.0) # Set the simulation frequency
9
10 # NOTE: How to build (rigid bodies) is elaborated in create_actors.py
11 scene.add_ground(altitude=0) # Add a ground
12 actor_builder = scene.create_actor_builder()
13 actor_builder.add_box_collision(half_size=[0.5, 0.5, 0.5])
14 actor_builder.add_box_visual(half_size=[0.5, 0.5, 0.5], material=[1.0, 0.0, 0.0])
15 box = actor_builder.build(name="box") # Add a box
16 box.set_pose(sapien.Pose(p=[0, 0, 0.5]))
17
18 # Add some lights so that you can observe the scene
19 scene.set_ambient_light([0.5, 0.5, 0.5])
20 scene.add_directional_light([0, 1, -1], [0.5, 0.5, 0.5])
21
22 viewer = scene.create_viewer() # Create a viewer (window)
23
24 # The coordinate frame in Sapien is: x(forward), y(left), z(upward)
25 # The principle axis of the camera is the x-axis
26 viewer.set_camera_xyz(x=-4, y=0, z=2)
27 # The rotation of the free camera is represented as [roll(x), pitch(-y), yaw(-z)]
28 # The camera now looks at the origin
29 viewer.set_camera_rpy(r=0, p=-np.arctan2(2, 4), y=0)
30 viewer.window.set_camera_parameters(near=0.05, far=100, fovy=1)
31
32 while not viewer.closed: # Press key q to quit
33 scene.step() # Simulate the world
34 scene.update_render() # Update the world to the renderer
35 viewer.render()
36
37
38if __name__ == "__main__":
39 main()