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    # Build multiple arenas if requested
 75    if args.num_envs > 1:
 76        sim.build_multiple_arenas(args.num_envs, space=3.0)
 77    print("[INFO]: Scene setup complete!")
 78
 79    # add softbody to the scene
 80    cow: SoftObject = sim.add_soft_object(
 81        cfg=SoftObjectCfg(
 82            uid="cow",
 83            shape=MeshCfg(
 84                fpath=get_resources_data_path("Model", "cow", "cow.obj"),
 85            ),
 86            init_pos=[0.0, 0.0, 3.0],
 87            voxel_attr=SoftbodyVoxelAttributesCfg(
 88                simulation_mesh_resolution=8,
 89                maximal_edge_length=0.5,
 90            ),
 91            physical_attr=SoftbodyPhysicalAttributesCfg(
 92                youngs=1e6,
 93                poissons=0.45,
 94                density=100,
 95                dynamic_friction=0.1,
 96                min_position_iters=30,
 97            ),
 98        ),
 99    )
100    print("[INFO]: Add soft object complete!")
101
102    # Open window when the scene has been set up
103    if not args.headless:
104        sim.open_window()
105
106    print(f"[INFO]: Running simulation with {args.num_envs} environment(s)")
107    print("[INFO]: Press Ctrl+C to stop the simulation")
108
109    # Run the simulation
110    run_simulation(sim, cow)
111
112
113def run_simulation(sim: SimulationManager, soft_obj: SoftObject) -> None:
114    """Run the simulation loop.
115
116    Args:
117        sim: The SimulationManager instance to run
118        soft_obj: soft object
119    """
120
121    # Initialize GPU physics
122    sim.init_gpu_physics()
123
124    step_count = 0
125
126    try:
127        last_time = time.time()
128        last_step = 0
129        while True:
130            # Update physics simulation
131            sim.update(step=1)
132            step_count += 1
133
134            # Print FPS every second
135            if step_count % 100 == 0:
136                current_time = time.time()
137                elapsed = current_time - last_time
138                fps = (
139                    sim.num_envs * (step_count - last_step) / elapsed
140                    if elapsed > 0
141                    else 0
142                )
143                print(f"[INFO]: Simulation step: {step_count}, FPS: {fps:.2f}")
144                last_time = current_time
145                last_step = step_count
146                if step_count % 500 == 0:
147                    soft_obj.reset()
148
149    except KeyboardInterrupt:
150        print("\n[INFO]: Stopping simulation...")
151    finally:
152        # Clean up resources
153        sim.destroy()
154        print("[INFO]: Simulation terminated successfully")
155
156
157if __name__ == "__main__":
158    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)

    # Build multiple arenas if requested
    if args.num_envs > 1:
        sim.build_multiple_arenas(args.num_envs, space=3.0)
    print("[INFO]: Scene setup complete!")

If num_envs is greater than 1, SimulationManager.build_multiple_arenas() should be used to create multiple simulation arenas.

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.