Creating a soft-body simulation#
This tutorial shows how to create a soft-body simulation using SimulationManager. It covers the setup of the simulation context, adding a deformable mesh (soft object), and running the simulation loop.
The Code#
The tutorial corresponds to the create_softbody.py script in the scripts/tutorials/sim directory.
Code for create_softbody.py
1# ----------------------------------------------------------------------------
2# Copyright (c) 2021-2025 DexForce Technology Co., Ltd.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15# ----------------------------------------------------------------------------
16
17"""
18This script demonstrates how to create a simulation scene using SimulationManager.
19It shows the basic setup of simulation context, adding objects, lighting, and sensors.
20"""
21
22import argparse
23import time
24from dexsim.utility.path import get_resources_data_path
25from embodichain.lab.sim import SimulationManager, SimulationManagerCfg
26from embodichain.lab.sim.cfg import (
27 SoftbodyVoxelAttributesCfg,
28 SoftbodyPhysicalAttributesCfg,
29)
30from embodichain.lab.sim.shapes import MeshCfg
31from embodichain.lab.sim.objects import (
32 SoftObject,
33 SoftObjectCfg,
34)
35
36
37def main():
38 """Main function to create and run the simulation scene."""
39
40 # Parse command line arguments
41 parser = argparse.ArgumentParser(
42 description="Create a simulation scene with SimulationManager"
43 )
44 parser.add_argument(
45 "--headless",
46 action="store_true",
47 default=False,
48 help="Run simulation in headless mode",
49 )
50 parser.add_argument(
51 "--num_envs", type=int, default=4, help="Number of parallel environments"
52 )
53 parser.add_argument(
54 "--enable_rt",
55 action="store_true",
56 default=False,
57 help="Enable ray tracing for better visuals",
58 )
59 args = parser.parse_args()
60
61 # Configure the simulation
62 sim_cfg = SimulationManagerCfg(
63 width=1920,
64 height=1080,
65 headless=True,
66 physics_dt=1.0 / 100.0, # Physics timestep (100 Hz)
67 sim_device="cuda", # soft simulation only supports cuda device
68 enable_rt=args.enable_rt, # Enable ray tracing for better visuals
69 )
70
71 # Create the simulation instance
72 sim = SimulationManager(sim_cfg)
73
74 print("[INFO]: Scene setup complete!")
75
76 # add softbody to the scene
77 cow: SoftObject = sim.add_soft_object(
78 cfg=SoftObjectCfg(
79 uid="cow",
80 shape=MeshCfg(
81 fpath=get_resources_data_path("Model", "cow", "cow.obj"),
82 ),
83 init_pos=[0.0, 0.0, 3.0],
84 voxel_attr=SoftbodyVoxelAttributesCfg(
85 simulation_mesh_resolution=8,
86 maximal_edge_length=0.5,
87 ),
88 physical_attr=SoftbodyPhysicalAttributesCfg(
89 youngs=1e6,
90 poissons=0.45,
91 density=100,
92 dynamic_friction=0.1,
93 min_position_iters=30,
94 ),
95 ),
96 )
97 print("[INFO]: Add soft object complete!")
98
99 # Open window when the scene has been set up
100 if not args.headless:
101 sim.open_window()
102
103 print(f"[INFO]: Running simulation with {args.num_envs} environment(s)")
104 print("[INFO]: Press Ctrl+C to stop the simulation")
105
106 # Run the simulation
107 run_simulation(sim, cow)
108
109
110def run_simulation(sim: SimulationManager, soft_obj: SoftObject) -> None:
111 """Run the simulation loop.
112
113 Args:
114 sim: The SimulationManager instance to run
115 soft_obj: soft object
116 """
117
118 # Initialize GPU physics
119 sim.init_gpu_physics()
120
121 step_count = 0
122
123 try:
124 last_time = time.time()
125 last_step = 0
126 while True:
127 # Update physics simulation
128 sim.update(step=1)
129 step_count += 1
130
131 # Print FPS every second
132 if step_count % 100 == 0:
133 current_time = time.time()
134 elapsed = current_time - last_time
135 fps = (
136 sim.num_envs * (step_count - last_step) / elapsed
137 if elapsed > 0
138 else 0
139 )
140 print(f"[INFO]: Simulation step: {step_count}, FPS: {fps:.2f}")
141 last_time = current_time
142 last_step = step_count
143 if step_count % 500 == 0:
144 soft_obj.reset()
145
146 except KeyboardInterrupt:
147 print("\n[INFO]: Stopping simulation...")
148 finally:
149 # Clean up resources
150 sim.destroy()
151 print("[INFO]: Simulation terminated successfully")
152
153
154if __name__ == "__main__":
155 main()
The Code Explained#
Configuring the simulation#
The first step is to configure the simulation environment. This is done using the SimulationManagerCfg data class, which allows you to specify parameters like window dimensions, headless mode, physics timestep, simulation device (CPU/GPU), and rendering options like ray tracing. Reminded that soft body simulation can only run on cuda deive.
# Configure the simulation
sim_cfg = SimulationManagerCfg(
width=1920,
height=1080,
headless=True,
physics_dt=1.0 / 100.0, # Physics timestep (100 Hz)
sim_device="cuda", # soft simulation only supports cuda device
enable_rt=args.enable_rt, # Enable ray tracing for better visuals
)
# Create the simulation instance
sim = SimulationManager(sim_cfg)
print("[INFO]: Scene setup complete!")
Adding a soft body to the scene#
With the simulation context created, we can add a soft (deformable) object. This tutorial demonstrates adding a soft-body cow mesh to the scene using the SimulationManager.add_soft_object() method. The object’s geometry and physical parameters are defined through configuration objects:
cfg.MeshCfgfor the mesh shape (cow.obj)cfg.SoftbodyVoxelAttributesCfgfor voxelization and simulation mesh resolutioncfg.SoftbodyPhysicalAttributesCfgfor material properties (Young’s modulus, Poisson’s ratio, density, frictions, solver iterations)
# add softbody to the scene
cow: SoftObject = sim.add_soft_object(
cfg=SoftObjectCfg(
uid="cow",
shape=MeshCfg(
fpath=get_resources_data_path("Model", "cow", "cow.obj"),
),
init_pos=[0.0, 0.0, 3.0],
voxel_attr=SoftbodyVoxelAttributesCfg(
simulation_mesh_resolution=8,
maximal_edge_length=0.5,
),
physical_attr=SoftbodyPhysicalAttributesCfg(
youngs=1e6,
poissons=0.45,
density=100,
dynamic_friction=0.1,
min_position_iters=30,
),
),
)
print("[INFO]: Add soft object complete!")
The Code Execution#
To run the script and see the result, execute the following command:
python scripts/tutorials/sim/create_softbody.py
A window should appear showing a soft-body cow mesh falling onto a ground plane. To stop the simulation, you can either close the window or press Ctrl+C in the terminal.
You can also pass arguments to customize the simulation. For example, to run in headless mode with n parallel environments using the specified device:
python scripts/tutorials/sim/create_softbody.py --headless --num_envs <n> --device <cuda/cpu>
Now that we have a basic understanding of how to create a soft-body scene, let’s move on to more advanced topics.