Closed honglin-c closed 5 months ago
I was using the following code (with libigl python binding) to load the tetmesh, which was unsuccessful so far.
V, T, F = igl.read_mesh("./data/tetmesh/spot.mesh")
V = Vt.Vec3fArray.FromNumpy(V)
T = Vt.IntArray.FromNumpy(T)
builder.add_soft_mesh(
pos=wp.vec3(0.0, 2.0, 0.0),
rot=wp.quat_identity(),
scale=0.1,
vel=wp.vec3(0.0, 0.0, 0.0),
vertices=V,
indices=T,
density=100.0,
k_mu=2000.0,
k_lambda=2000.0,
k_damp=2.0,
tri_ke=0.0,
tri_ka=1e4,
tri_kd=0.0,
tri_drag=0.0,
tri_lift=0.0,
)
Hi @honglin-c, could you provide the .mesh file for this example so we can reproduce?
Thanks, Miles
I'm guessing it's this mesh: https://github.com/honglin-c/INSR-PDE/blob/main/elasticity/data/spot.mesh
download link: spot.zip
I tried writing a minimal reproducer with @honglin-c 's approach
import os
import math
import warp as wp
import warp.examples
import warp.sim
import warp.optim
import warp.sim.render
import igl
import scipy as sp
import numpy as np
from pxr import Usd, UsdGeom, Vt
wp.init()
# sim model
builder = wp.sim.ModelBuilder()
V, T, F = igl.read_mesh("/path/to/meshes/spot.mesh")
V = Vt.Vec3fArray.FromNumpy(V)
T = Vt.IntArray.FromNumpy(T)
builder.add_soft_mesh(
pos=wp.vec3(0.0, 0.0, 0.0),
rot=wp.quat_identity(),
scale=2.0,
vel=wp.vec3(0.0, 0.0, 0.0),
vertices=V,
indices=T,
density=1.0,
k_mu=2000.0,
k_lambda=2000.0,
k_damp=2.0,
tri_ke=0.0,
tri_ka=1e-8,
tri_kd=0.0,
tri_drag=0.0,
tri_lift=0.0,
)
# finalize model
model = builder.finalize(requires_grad=False)
model.soft_contact_ke = 2.0e3
model.soft_contact_kd = 0.1
model.soft_contact_kf = 10.0
model.soft_contact_mu = 0.7
model.ground = True
state = model.state(requires_grad=False)
# rendering
renderer = wp.sim.render.SimRenderer(model, "spot.usd")
renderer.begin_frame(0)
renderer.render(state)
renderer.end_frame()
renderer.save()
and it seemed to work:
But I'm very new to using warp, so I might be doing something wrong!
Nice! Thank you @samuelpmish! @honglin-c does this solve your problem?
Wowww thank you so much @samuelpmish!! :)))
Nice! Thank you @samuelpmish! @honglin-c does this solve your problem?
Sort of but not fully 👀
Actually, I realized the problem was with the simulation and the scale of the tetmesh.
For instance, I will have this problem for the code below. But if I simply change scale=5.0
to scale=10.0
in the parameter list of builder.add_soft_mesh()
, the simulation will run without problem.
Still trying to figure out what's going wrong here... 🤔
import math
import os
import warp as wp
import warp.sim
import warp.sim.render
import numpy as np
from pxr import Usd, UsdGeom, Vt
import igl
wp.init()
class Example:
def __init__(self, stage):
sim_fps = 60.0
self.sim_substeps = 64
sim_duration = 5.0
self.sim_frames = int(sim_duration * sim_fps)
self.frame_dt = 1.0 / sim_fps
self.sim_dt = (1.0 / sim_fps) / self.sim_substeps
self.sim_time = 0.0
# bunny
builder = wp.sim.ModelBuilder()
V, T, F = igl.read_mesh("./data/tetmesh/spot.mesh")
# don't know why warp needs this
V = Vt.Vec3fArray.FromNumpy(V)
T = Vt.IntArray.FromNumpy(T)
builder.add_soft_mesh(
pos=wp.vec3(0.0, 10.0, 0.0),
rot=wp.quat_identity(),
scale=5.0,
vel=wp.vec3(0.0, 0.0, 0.0),
vertices=V,
indices=T,
density=100.0,
k_mu=100000.0,
k_lambda=100000.0,
k_damp=2.0,
tri_ke=0.0,
tri_ka=1e4,
tri_kd=0.0,
tri_drag=0.0,
tri_lift=0.0,
)
self.model = builder.finalize()
self.model.ground = True
self.model.soft_contact_ke = 2.0e3
self.model.soft_contact_kd = 0.1
self.model.soft_contact_kf = 10.0
self.model.soft_contact_mu = 0.7
self.integrator = wp.sim.SemiImplicitIntegrator()
self.rest = self.model.state()
self.state_0 = self.model.state()
self.state_1 = self.model.state()
self.volume = wp.zeros(1, dtype=wp.float32)
self.renderer = None
if stage:
self.renderer = wp.sim.render.SimRenderer(self.model, stage)
self.use_graph = wp.get_device().is_cuda
if self.use_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()
# self.state_1.clear_forces()
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"):
if self.use_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(self.state_0)
self.renderer.end_frame()
if __name__ == "__main__":
stage_path = os.path.join(os.path.dirname(__file__), "outputs/example_soft_spot.usd")
example = Example(stage_path)
for i in range(example.sim_frames):
example.step()
example.render()
if example.renderer:
example.renderer.save()
This is with scale = 5.0
:
Without the simulation (I commented out example.step()
) , the rendering looks fine:
But if I simply change scale=5.0
to scale=10.0
in builder.add_soft_mesh()
, the simulation just runs perfectly! :0
I'm having a mesh colliding with the ground and then bouncing back :
This is probably just a classic example of simulation stability being dependent on the scale, e.g.: by scaling everything down then everything gets lighter while stiffness is staying the same, i.e.: the problem got a lot stiffer, which means you need smaller time-steps to be stable.
If you are reducing scale you generally need to reduce the time-step size (dt) or take more substeps as well.
Cheers, Miles
Thank you so much for the explanations! Now I finally understand. :)
Resolved by @samuelpmish
Would it be possible to provide an example where the user reads a tetmesh from a .mesh file? Thank you! :)