-
Notifications
You must be signed in to change notification settings - Fork 252
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[QUESTION] Granular collision SDF example has changed #409
Comments
Thanks for reporting this issue. It seems that when 02d8d33 adjusted the scale and orientation of the example assets, the granular collision SDF was not fully updated. This led to the rock collision geometry being a factor of 100x smaller than what's shown in the example gallery image. Try out this updated example: # Copyright (c) 2022 NVIDIA CORPORATION. All rights reserved.
# NVIDIA CORPORATION and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto. Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION is strictly prohibited.
###########################################################################
# Example Sim Granular Collision SDF
#
# Shows how to set up a particle-based granular material model using the
# wp.sim.ModelBuilder(). This version shows how to create collision geometry
# objects from SDFs.
#
# Note: requires a CUDA-capable device
###########################################################################
import os
import numpy as np
import warp as wp
import warp.examples
import warp.sim
import warp.sim.render
class Example:
def __init__(self, stage_path="example_granular_collision_sdf.usd"):
fps = 60
self.frame_dt = 1.0 / fps
self.sim_substeps = 64
self.sim_dt = self.frame_dt / self.sim_substeps
self.sim_time = 0.0
self.radius = 0.1
builder = wp.sim.ModelBuilder()
builder.default_particle_radius = self.radius
builder.add_particle_grid(
dim_x=16,
dim_y=32,
dim_z=16,
cell_x=self.radius * 2.0,
cell_y=self.radius * 2.0,
cell_z=self.radius * 2.0,
pos=wp.vec3(0.0, 20.0, 0.0),
rot=wp.quat_identity(),
vel=wp.vec3(2.0, 0.0, 0.0),
mass=0.1,
jitter=self.radius * 0.1,
)
with open(os.path.join(warp.examples.get_asset_directory(), "rocks.nvdb"), "rb") as rock_file:
rock_vdb = wp.Volume.load_from_nvdb(rock_file.read())
rock_sdf = wp.sim.SDF(rock_vdb)
builder.add_shape_sdf(
ke=1.0e4,
kd=1000.0,
kf=1000.0,
mu=0.5,
sdf=rock_sdf,
body=-1,
pos=wp.vec3(0.0, 0.0, 0.0),
rot=wp.quat(0.0, 0.0, 0.0, 1.0),
scale=wp.vec3(1.0, 1.0, 1.0),
)
mins = np.array([-3.0, -3.0, -3.0])
voxel_size = 0.2
maxs = np.array([3.0, 3.0, 3.0])
nums = np.ceil((maxs - mins) / (voxel_size)).astype(dtype=int)
center = np.array([0.0, 0.0, 0.0])
rad = 2.5
sphere_sdf_np = np.zeros(tuple(nums))
for x in range(nums[0]):
for y in range(nums[1]):
for z in range(nums[2]):
pos = mins + voxel_size * np.array([x, y, z])
dis = np.linalg.norm(pos - center)
sphere_sdf_np[x, y, z] = dis - rad
sphere_vdb = wp.Volume.load_from_numpy(sphere_sdf_np, mins, voxel_size, rad + 3.0 * voxel_size)
sphere_sdf = wp.sim.SDF(sphere_vdb)
self.sphere_pos = wp.vec3(3.0, 15.0, 0.0)
self.sphere_scale = 1.0
self.sphere_radius = rad
builder.add_shape_sdf(
ke=1.0e4,
kd=1000.0,
kf=1000.0,
mu=0.5,
sdf=sphere_sdf,
body=-1,
pos=self.sphere_pos,
scale=wp.vec3(self.sphere_scale, self.sphere_scale, self.sphere_scale),
)
self.model = builder.finalize()
self.model.particle_kf = 25.0
self.model.soft_contact_kd = 100.0
self.model.soft_contact_kf *= 2.0
self.state_0 = self.model.state()
self.state_1 = self.model.state()
self.integrator = wp.sim.SemiImplicitIntegrator()
if stage_path:
self.renderer = wp.sim.render.SimRenderer(self.model, stage_path, scaling=20.0)
else:
self.renderer = None
self.use_cuda_graph = wp.get_device().is_cuda
if self.use_cuda_graph:
with wp.ScopedCapture() as capture:
self.simulate()
self.graph = capture.graph
def simulate(self):
for _ in range(self.sim_substeps):
self.state_0.clear_forces()
wp.sim.collide(self.model, self.state_0)
self.integrator.simulate(self.model, self.state_0, self.state_1, self.sim_dt)
# swap states
(self.state_0, self.state_1) = (self.state_1, self.state_0)
def step(self):
with wp.ScopedTimer("step"):
self.model.particle_grid.build(self.state_0.particle_q, self.radius * 2.0)
if self.use_cuda_graph:
wp.capture_launch(self.graph)
else:
self.simulate()
self.sim_time += self.frame_dt
def render(self):
if self.renderer is None:
return
with wp.ScopedTimer("render"):
self.renderer.begin_frame(self.sim_time)
self.renderer.render_ref(
name="collision",
path=os.path.join(warp.examples.get_asset_directory(), "rocks.usd"),
pos=wp.vec3(0.0, 0.0, 0.0),
rot=wp.quat(0.0, 0.0, 0.0, 1.0),
scale=wp.vec3(1.0, 1.0, 1.0),
color=(0.35, 0.55, 0.9),
)
self.renderer.render_sphere(
name="sphere",
pos=self.sphere_pos,
radius=self.sphere_scale * self.sphere_radius,
rot=wp.quat(0.0, 0.0, 0.0, 1.0),
)
self.renderer.render(self.state_0)
self.renderer.end_frame()
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
parser.add_argument(
"--stage_path",
type=lambda x: None if x == "None" else str(x),
default="example_granular_collision_sdf.usd",
help="Path to the output USD file.",
)
parser.add_argument("--num_frames", type=int, default=400, help="Total number of frames.")
args = parser.parse_known_args()[0]
with wp.ScopedDevice(args.device):
example = Example(stage_path=args.stage_path)
for _ in range(args.num_frames):
example.step()
example.render()
if example.renderer:
example.renderer.save() |
@shi-eric Thank you so much for your patient reply! The new code displays the normal size of the rock. However, when I imported the result into Blender and clicked the play button, nothing happened. The entire result is static, and the granules can’t fall onto the rock. Is there something I did wrong? |
I don't think you did anything wrong; it could be an issue with Blender's USD import. Here's a screenshot from opening the file in usdview: @christophercrouzet Do you have any insight about the Blender issue? |
Hi @sxn22012023, I managed to visualize the expected result in USD View, Omniverse, and Houdini, but I can repro your issue in Blender 4.3.2. From what I can tell, everything is set correctly during the import, and the frame range is correct, so this should work. My first guess would also be some possible shortcomings with Blender's USD importer. |
Hi! I am re-running granular collision sdf example. But when I imported the calculated usd file into Blender, there is no collision between rock and particles? Can you tell me how I should visualize the calculated result?
These are the results I imported into Blender.
This is the result from the official documentation.
The text was updated successfully, but these errors were encountered: