Hello World#
SAPIEN provides APIs to build physical simulation environments.
In this tutorial, you will learn the following:
Create a simulation
SceneSetup 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()