Hello World¶
SAPIEN provides APIs to build physical simulation environments.
In this tutorial, you will learn the following:
Create a simulation engine
Engine
Create a simulation scene
Scene
Setup a renderer to visualize
Run a simulation loop
The full script can be downloaded here hello_world.py
Simulation engine and scene¶
To simulate with SAPIEN, you need to first create a simulation engine, and then create a simulation scene by the engine.
engine = sapien.Engine() # Create a physical simulation engine
renderer = sapien.VulkanRenderer() # Create a Vulkan renderer
engine.set_renderer(renderer) # Bind the renderer and the engine
scene = engine.create_scene() # Create an instance of simulation world (aka scene)
scene.set_timestep(1 / 100.0) # Set the simulation frequency
Engine
is the physical simulation engine connected to the PhysX backend.
One engine per process is allowed.
Scene
is an instance of the simulation world.
Multiple scenes can be created through create_scene
, and run independently.
VulkanRenderer
is the rendering engine connected to our vulkan-based renderer.
The renderer should be bound with an engine, and then all the scenes created by the engine will be bound with the renderer.
Add rigid bodies¶
So far, our scene is empty.
Actor
(rigid body) is simulated in SAPIEN.
Let’s add two actors, a ground and a box, to the scene.
How to create actors 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], color=[1., 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.
How to use the GUI will be elaborated in Viewer.
# Add some lights so that you can observe the scene
scene.set_ambient_light([0.5, 0.5, 0.5])
scene.add_directional_light([0, 1, -1], [0.5, 0.5, 0.5])
viewer = Viewer(renderer) # Create a viewer (window)
viewer.set_scene(scene) # Bind the viewer and the scene
# 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 physical simulation, 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¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | import sapien.core as sapien
from sapien.utils import Viewer
import numpy as np
def main():
engine = sapien.Engine() # Create a physical simulation engine
renderer = sapien.VulkanRenderer() # Create a Vulkan renderer
engine.set_renderer(renderer) # Bind the renderer and the engine
scene = engine.create_scene() # Create an instance of simulation world (aka scene)
scene.set_timestep(1 / 100.0) # Set the simulation frequency
# NOTE: How to build actors (rigid bodies) is elaborated in create_actors.py
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], color=[1., 0., 0.])
box = actor_builder.build(name='box') # Add a box
box.set_pose(sapien.Pose(p=[0, 0, 0.5]))
# Add some lights so that you can observe the scene
scene.set_ambient_light([0.5, 0.5, 0.5])
scene.add_directional_light([0, 1, -1], [0.5, 0.5, 0.5])
viewer = Viewer(renderer) # Create a viewer (window)
viewer.set_scene(scene) # Bind the viewer and the scene
# 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)
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()
if __name__ == '__main__':
main()
|