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:

    # 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.