warp-lang 0.11.0__py3-none-manylinux2014_x86_64.whl → 1.0.0__py3-none-manylinux2014_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of warp-lang might be problematic. Click here for more details.

Files changed (170) hide show
  1. warp/__init__.py +8 -0
  2. warp/bin/warp-clang.so +0 -0
  3. warp/bin/warp.so +0 -0
  4. warp/build.py +7 -6
  5. warp/build_dll.py +70 -79
  6. warp/builtins.py +10 -6
  7. warp/codegen.py +51 -19
  8. warp/config.py +7 -8
  9. warp/constants.py +3 -0
  10. warp/context.py +948 -245
  11. warp/dlpack.py +198 -113
  12. warp/examples/assets/bunny.usd +0 -0
  13. warp/examples/assets/cartpole.urdf +110 -0
  14. warp/examples/assets/crazyflie.usd +0 -0
  15. warp/examples/assets/cube.usda +42 -0
  16. warp/examples/assets/nv_ant.xml +92 -0
  17. warp/examples/assets/nv_humanoid.xml +183 -0
  18. warp/examples/assets/quadruped.urdf +268 -0
  19. warp/examples/assets/rocks.nvdb +0 -0
  20. warp/examples/assets/rocks.usd +0 -0
  21. warp/examples/assets/sphere.usda +56 -0
  22. warp/examples/assets/torus.usda +105 -0
  23. warp/examples/benchmarks/benchmark_api.py +383 -0
  24. warp/examples/benchmarks/benchmark_cloth.py +279 -0
  25. warp/examples/benchmarks/benchmark_cloth_cupy.py +88 -0
  26. warp/examples/benchmarks/benchmark_cloth_jax.py +100 -0
  27. warp/examples/benchmarks/benchmark_cloth_numba.py +142 -0
  28. warp/examples/benchmarks/benchmark_cloth_numpy.py +77 -0
  29. warp/examples/benchmarks/benchmark_cloth_pytorch.py +86 -0
  30. warp/examples/benchmarks/benchmark_cloth_taichi.py +112 -0
  31. warp/examples/benchmarks/benchmark_cloth_warp.py +146 -0
  32. warp/examples/benchmarks/benchmark_launches.py +295 -0
  33. warp/examples/core/example_dem.py +221 -0
  34. warp/examples/core/example_fluid.py +267 -0
  35. warp/examples/core/example_graph_capture.py +129 -0
  36. warp/examples/core/example_marching_cubes.py +177 -0
  37. warp/examples/core/example_mesh.py +154 -0
  38. warp/examples/core/example_mesh_intersect.py +193 -0
  39. warp/examples/core/example_nvdb.py +169 -0
  40. warp/examples/core/example_raycast.py +89 -0
  41. warp/examples/core/example_raymarch.py +178 -0
  42. warp/examples/core/example_render_opengl.py +141 -0
  43. warp/examples/core/example_sph.py +389 -0
  44. warp/examples/core/example_torch.py +181 -0
  45. warp/examples/core/example_wave.py +249 -0
  46. warp/examples/fem/bsr_utils.py +380 -0
  47. warp/examples/fem/example_apic_fluid.py +391 -0
  48. warp/examples/fem/example_convection_diffusion.py +168 -0
  49. warp/examples/fem/example_convection_diffusion_dg.py +209 -0
  50. warp/examples/fem/example_convection_diffusion_dg0.py +194 -0
  51. warp/examples/fem/example_deformed_geometry.py +159 -0
  52. warp/examples/fem/example_diffusion.py +173 -0
  53. warp/examples/fem/example_diffusion_3d.py +152 -0
  54. warp/examples/fem/example_diffusion_mgpu.py +214 -0
  55. warp/examples/fem/example_mixed_elasticity.py +222 -0
  56. warp/examples/fem/example_navier_stokes.py +243 -0
  57. warp/examples/fem/example_stokes.py +192 -0
  58. warp/examples/fem/example_stokes_transfer.py +249 -0
  59. warp/examples/fem/mesh_utils.py +109 -0
  60. warp/examples/fem/plot_utils.py +287 -0
  61. warp/examples/optim/example_bounce.py +248 -0
  62. warp/examples/optim/example_cloth_throw.py +210 -0
  63. warp/examples/optim/example_diffray.py +535 -0
  64. warp/examples/optim/example_drone.py +850 -0
  65. warp/examples/optim/example_inverse_kinematics.py +169 -0
  66. warp/examples/optim/example_inverse_kinematics_torch.py +170 -0
  67. warp/examples/optim/example_spring_cage.py +234 -0
  68. warp/examples/optim/example_trajectory.py +201 -0
  69. warp/examples/sim/example_cartpole.py +128 -0
  70. warp/examples/sim/example_cloth.py +184 -0
  71. warp/examples/sim/example_granular.py +113 -0
  72. warp/examples/sim/example_granular_collision_sdf.py +185 -0
  73. warp/examples/sim/example_jacobian_ik.py +213 -0
  74. warp/examples/sim/example_particle_chain.py +106 -0
  75. warp/examples/sim/example_quadruped.py +179 -0
  76. warp/examples/sim/example_rigid_chain.py +191 -0
  77. warp/examples/sim/example_rigid_contact.py +176 -0
  78. warp/examples/sim/example_rigid_force.py +126 -0
  79. warp/examples/sim/example_rigid_gyroscopic.py +97 -0
  80. warp/examples/sim/example_rigid_soft_contact.py +124 -0
  81. warp/examples/sim/example_soft_body.py +178 -0
  82. warp/fabric.py +29 -20
  83. warp/fem/cache.py +0 -1
  84. warp/fem/dirichlet.py +0 -2
  85. warp/fem/integrate.py +0 -1
  86. warp/jax.py +45 -0
  87. warp/jax_experimental.py +339 -0
  88. warp/native/builtin.h +12 -0
  89. warp/native/bvh.cu +18 -18
  90. warp/native/clang/clang.cpp +8 -3
  91. warp/native/cuda_util.cpp +94 -5
  92. warp/native/cuda_util.h +35 -6
  93. warp/native/cutlass_gemm.cpp +1 -1
  94. warp/native/cutlass_gemm.cu +4 -1
  95. warp/native/error.cpp +66 -0
  96. warp/native/error.h +27 -0
  97. warp/native/mesh.cu +2 -2
  98. warp/native/reduce.cu +4 -4
  99. warp/native/runlength_encode.cu +2 -2
  100. warp/native/scan.cu +2 -2
  101. warp/native/sparse.cu +0 -1
  102. warp/native/temp_buffer.h +2 -2
  103. warp/native/warp.cpp +95 -60
  104. warp/native/warp.cu +1053 -218
  105. warp/native/warp.h +49 -32
  106. warp/optim/linear.py +33 -16
  107. warp/render/render_opengl.py +202 -101
  108. warp/render/render_usd.py +82 -40
  109. warp/sim/__init__.py +13 -4
  110. warp/sim/articulation.py +4 -5
  111. warp/sim/collide.py +320 -175
  112. warp/sim/import_mjcf.py +25 -30
  113. warp/sim/import_urdf.py +94 -63
  114. warp/sim/import_usd.py +51 -36
  115. warp/sim/inertia.py +3 -2
  116. warp/sim/integrator.py +233 -0
  117. warp/sim/integrator_euler.py +447 -469
  118. warp/sim/integrator_featherstone.py +1991 -0
  119. warp/sim/integrator_xpbd.py +1420 -640
  120. warp/sim/model.py +765 -487
  121. warp/sim/particles.py +2 -1
  122. warp/sim/render.py +35 -13
  123. warp/sim/utils.py +222 -11
  124. warp/stubs.py +8 -0
  125. warp/tape.py +16 -1
  126. warp/tests/aux_test_grad_customs.py +23 -0
  127. warp/tests/test_array.py +190 -1
  128. warp/tests/test_async.py +656 -0
  129. warp/tests/test_bool.py +50 -0
  130. warp/tests/test_dlpack.py +164 -11
  131. warp/tests/test_examples.py +166 -74
  132. warp/tests/test_fem.py +8 -1
  133. warp/tests/test_generics.py +15 -5
  134. warp/tests/test_grad.py +1 -1
  135. warp/tests/test_grad_customs.py +172 -12
  136. warp/tests/test_jax.py +254 -0
  137. warp/tests/test_large.py +29 -6
  138. warp/tests/test_launch.py +25 -0
  139. warp/tests/test_linear_solvers.py +20 -3
  140. warp/tests/test_matmul.py +61 -16
  141. warp/tests/test_matmul_lite.py +13 -13
  142. warp/tests/test_mempool.py +186 -0
  143. warp/tests/test_multigpu.py +3 -0
  144. warp/tests/test_options.py +16 -2
  145. warp/tests/test_peer.py +137 -0
  146. warp/tests/test_print.py +3 -1
  147. warp/tests/test_quat.py +23 -0
  148. warp/tests/test_sim_kinematics.py +97 -0
  149. warp/tests/test_snippet.py +126 -3
  150. warp/tests/test_streams.py +108 -79
  151. warp/tests/test_torch.py +16 -8
  152. warp/tests/test_utils.py +32 -27
  153. warp/tests/test_verify_fp.py +65 -0
  154. warp/tests/test_volume.py +1 -1
  155. warp/tests/unittest_serial.py +2 -0
  156. warp/tests/unittest_suites.py +12 -0
  157. warp/tests/unittest_utils.py +14 -7
  158. warp/thirdparty/unittest_parallel.py +15 -3
  159. warp/torch.py +10 -8
  160. warp/types.py +363 -246
  161. warp/utils.py +143 -19
  162. warp_lang-1.0.0.dist-info/LICENSE.md +126 -0
  163. warp_lang-1.0.0.dist-info/METADATA +394 -0
  164. {warp_lang-0.11.0.dist-info → warp_lang-1.0.0.dist-info}/RECORD +167 -86
  165. warp/sim/optimizer.py +0 -138
  166. warp_lang-0.11.0.dist-info/LICENSE.md +0 -36
  167. warp_lang-0.11.0.dist-info/METADATA +0 -238
  168. /warp/tests/{walkthough_debug.py → walkthrough_debug.py} +0 -0
  169. {warp_lang-0.11.0.dist-info → warp_lang-1.0.0.dist-info}/WHEEL +0 -0
  170. {warp_lang-0.11.0.dist-info → warp_lang-1.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,201 @@
1
+ # Copyright (c) 2022 NVIDIA CORPORATION. All rights reserved.
2
+ # NVIDIA CORPORATION and its licensors retain all intellectual property
3
+ # and proprietary rights in and to this software, related documentation
4
+ # and any modifications thereto. Any use, reproduction, disclosure or
5
+ # distribution of this software and related documentation without an express
6
+ # license agreement from NVIDIA CORPORATION is strictly prohibited.
7
+
8
+ ###########################################################################
9
+ # Example Trajectory Optimization
10
+ #
11
+ # Shows how to optimize torque trajectories for a simple planar environment
12
+ # using Warp's provided Adam optimizer.
13
+ #
14
+ ###########################################################################
15
+
16
+
17
+ import os
18
+
19
+ import numpy as np
20
+
21
+ import warp as wp
22
+ import warp.sim
23
+ import warp.sim.render
24
+ from warp.optim import Adam
25
+
26
+ wp.init()
27
+
28
+
29
+ @wp.kernel
30
+ def loss_l2(
31
+ states: wp.array2d(dtype=wp.float32), targets: wp.array2d(dtype=wp.float32), loss: wp.array(dtype=wp.float32)
32
+ ):
33
+ i, j = wp.tid()
34
+ diff = states[i, j] - targets[i, j]
35
+ l = diff * diff
36
+ wp.atomic_add(loss, 0, l)
37
+
38
+
39
+ @wp.kernel
40
+ def apply_torque(torques: wp.array(dtype=wp.float32), start_index: int, body_f: wp.array(dtype=wp.spatial_vector)):
41
+ fx = torques[start_index + 0]
42
+ fz = torques[start_index + 1]
43
+ body_f[0] = wp.spatial_vector(0.0, 0.0, 0.0, fx, 0.0, fz)
44
+
45
+
46
+ @wp.kernel
47
+ def save_state(body_q: wp.array(dtype=wp.transform), write_index: int, states: wp.array2d(dtype=wp.float32)):
48
+ pos = wp.transform_get_translation(body_q[0])
49
+ states[write_index, 0] = pos[0]
50
+ states[write_index, 1] = pos[2]
51
+
52
+
53
+ class Example:
54
+ def __init__(self, stage, verbose=False):
55
+ self.verbose = verbose
56
+ self.frame_dt = 1.0 / 60.0
57
+ self.episode_frames = 100
58
+
59
+ self.sim_substeps = 1
60
+ self.sim_dt = self.frame_dt / self.sim_substeps
61
+
62
+ self.render_time = 0.0
63
+
64
+ self.iter = 0
65
+
66
+ builder = wp.sim.ModelBuilder()
67
+
68
+ # add planar joints
69
+ builder = wp.sim.ModelBuilder(gravity=0.0)
70
+ builder.add_articulation()
71
+ b = builder.add_body(origin=wp.transform())
72
+ builder.add_shape_sphere(pos=wp.vec3(0.0, 0.0, 0.0), radius=0.1, density=100.0, body=b)
73
+
74
+ # compute reference trajectory
75
+ rad = np.linspace(0.0, np.pi * 2, self.episode_frames)
76
+ self.ref_traj = np.stack([np.cos(rad), np.sin(rad)], axis=1)
77
+
78
+ # set initial joint configuration to first reference state
79
+ builder.body_q[0] = wp.transform(p=[self.ref_traj[0][0], 0.0, self.ref_traj[0][1]])
80
+
81
+ self.ref_traj = wp.array(self.ref_traj, dtype=wp.float32, requires_grad=True)
82
+ self.last_traj = wp.empty_like(self.ref_traj)
83
+
84
+ # finalize model
85
+ self.model = builder.finalize(requires_grad=True)
86
+
87
+ self.builder = builder
88
+ self.model.ground = False
89
+
90
+ self.dof_q = self.model.joint_coord_count
91
+ self.dof_qd = self.model.joint_dof_count
92
+ self.num_bodies = self.model.body_count
93
+
94
+ self.action_dim = 2
95
+ self.state_dim = 2
96
+
97
+ assert self.ref_traj.shape == (self.episode_frames, self.state_dim)
98
+
99
+ self.integrator = wp.sim.SemiImplicitIntegrator()
100
+
101
+ # initial guess
102
+ self.actions = wp.array(
103
+ np.zeros(self.episode_frames * self.action_dim) * 100.0, dtype=wp.float32, requires_grad=True
104
+ )
105
+
106
+ self.optimizer = Adam([self.actions], lr=1e2)
107
+ self.loss = wp.zeros(1, dtype=wp.float32, requires_grad=True)
108
+
109
+ self.renderer = None
110
+ if stage:
111
+ self.renderer = wp.sim.render.SimRenderer(self.model, stage, scaling=100.0)
112
+
113
+ # allocate sim states for trajectory
114
+ self.states = []
115
+ for _ in range(self.episode_frames + 1):
116
+ self.states.append(self.model.state())
117
+
118
+ def forward(self):
119
+ """
120
+ Advances the system dynamics given the rigid-body state in maximal coordinates and generalized joint torques
121
+ [body_q, body_qd, tau].
122
+ """
123
+
124
+ self.last_traj.zero_()
125
+
126
+ for i in range(self.episode_frames):
127
+ state = self.states[i]
128
+
129
+ for _ in range(self.sim_substeps):
130
+ next_state = self.model.state(requires_grad=True)
131
+
132
+ wp.sim.collide(self.model, state)
133
+
134
+ # apply generalized torques to rigid body here, instead of planar joints
135
+ wp.launch(apply_torque, 1, inputs=[self.actions, i * self.action_dim], outputs=[state.body_f])
136
+
137
+ state = self.integrator.simulate(self.model, state, next_state, self.sim_dt)
138
+
139
+ self.states[i + 1] = state
140
+
141
+ # save state
142
+ wp.launch(save_state, dim=1, inputs=[self.states[i + 1].body_q, i], outputs=[self.last_traj])
143
+
144
+ # compute loss
145
+ wp.launch(loss_l2, dim=self.last_traj.shape, inputs=[self.last_traj, self.ref_traj], outputs=[self.loss])
146
+
147
+ def step(self):
148
+ """Runs a single optimizer iteration"""
149
+ self.loss.zero_()
150
+ tape = wp.Tape()
151
+ with tape:
152
+ self.forward()
153
+ tape.backward(loss=self.loss)
154
+
155
+ if self.verbose and (self.iter + 1) % 10 == 0:
156
+ print(f"Iter {self.iter+1} Loss: {self.loss.numpy()[0]:.3f}")
157
+
158
+ assert not np.isnan(self.actions.grad.numpy()).any(), "NaN in gradient"
159
+
160
+ self.optimizer.step([self.actions.grad])
161
+ tape.zero()
162
+ self.iter = self.iter + 1
163
+
164
+ def render(self):
165
+ if self.renderer is None:
166
+ return
167
+
168
+ for i in range(self.episode_frames):
169
+ self.renderer.begin_frame(self.render_time)
170
+ self.renderer.render(self.states[i + 1])
171
+ self.renderer.end_frame()
172
+ self.render_time += self.frame_dt
173
+
174
+
175
+ if __name__ == "__main__":
176
+ import matplotlib.pyplot as plt
177
+
178
+ stage_path = os.path.join(os.path.dirname(__file__), "example_trajectory.usd")
179
+
180
+ example = Example(stage_path, verbose=True)
181
+
182
+ # Optimize
183
+ num_iter = 250
184
+
185
+ for i in range(num_iter):
186
+ example.step()
187
+
188
+ if i % 25 == 0:
189
+ example.render()
190
+
191
+ if example.renderer:
192
+ example.renderer.save()
193
+
194
+ np_states = example.last_traj.numpy()
195
+ np_ref = example.ref_traj.numpy()
196
+ plt.plot(np_ref[:, 0], np_ref[:, 1], label="Reference Trajectory")
197
+ plt.plot(np_states[:, 0], np_states[:, 1], label="Optimized Trajectory")
198
+ plt.grid()
199
+ plt.legend()
200
+ plt.axis("equal")
201
+ plt.show()
@@ -0,0 +1,128 @@
1
+ # Copyright (c) 2022 NVIDIA CORPORATION. All rights reserved.
2
+ # NVIDIA CORPORATION and its licensors retain all intellectual property
3
+ # and proprietary rights in and to this software, related documentation
4
+ # and any modifications thereto. Any use, reproduction, disclosure or
5
+ # distribution of this software and related documentation without an express
6
+ # license agreement from NVIDIA CORPORATION is strictly prohibited.
7
+
8
+ ###########################################################################
9
+ # Example Sim Cartpole
10
+ #
11
+ # Shows how to set up a simulation of a rigid-body cartpole articulation
12
+ # from a URDF using the wp.sim.ModelBuilder().
13
+ # Note this example does not include a trained policy.
14
+ #
15
+ ###########################################################################
16
+
17
+ import math
18
+ import os
19
+
20
+ import numpy as np
21
+
22
+ import warp as wp
23
+ import warp.sim
24
+ import warp.sim.render
25
+
26
+ wp.init()
27
+
28
+
29
+ class Example:
30
+ def __init__(self, stage=None, num_envs=1, print_timers=True):
31
+ builder = wp.sim.ModelBuilder()
32
+
33
+ self.num_envs = num_envs
34
+
35
+ articulation_builder = wp.sim.ModelBuilder()
36
+
37
+ wp.sim.parse_urdf(
38
+ os.path.join(os.path.dirname(__file__), "../assets/cartpole.urdf"),
39
+ articulation_builder,
40
+ xform=wp.transform(wp.vec3(), wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), -math.pi * 0.5)),
41
+ floating=False,
42
+ density=100,
43
+ armature=0.1,
44
+ stiffness=0.0,
45
+ damping=0.0,
46
+ limit_ke=1.0e4,
47
+ limit_kd=1.0e1,
48
+ enable_self_collisions=False,
49
+ )
50
+
51
+ builder = wp.sim.ModelBuilder()
52
+
53
+ self.sim_time = 0.0
54
+ self.frame_dt = 1.0 / 60.0
55
+
56
+ episode_duration = 20.0 # seconds
57
+ self.episode_frames = int(episode_duration / self.frame_dt)
58
+
59
+ self.sim_substeps = 10
60
+ self.sim_dt = self.frame_dt / self.sim_substeps
61
+
62
+ for i in range(num_envs):
63
+ builder.add_builder(
64
+ articulation_builder, xform=wp.transform(np.array((i * 2.0, 4.0, 0.0)), wp.quat_identity())
65
+ )
66
+
67
+ # joint initial positions
68
+ builder.joint_q[-3:] = [0.0, 0.3, 0.0]
69
+
70
+ # finalize model
71
+ self.model = builder.finalize()
72
+ self.model.ground = False
73
+
74
+ self.model.joint_attach_ke = 1600.0
75
+ self.model.joint_attach_kd = 20.0
76
+
77
+ self.integrator = wp.sim.SemiImplicitIntegrator()
78
+
79
+ self.renderer = None
80
+ if stage:
81
+ self.renderer = wp.sim.render.SimRenderer(path=stage, model=self.model, scaling=15.0)
82
+
83
+ self.print_timers = print_timers
84
+
85
+ self.state = self.model.state()
86
+
87
+ wp.sim.eval_fk(self.model, self.model.joint_q, self.model.joint_qd, None, self.state)
88
+
89
+ self.use_graph = wp.get_device().is_cuda
90
+ if self.use_graph:
91
+ with wp.ScopedCapture() as capture:
92
+ self.simulate()
93
+ self.graph = capture.graph
94
+
95
+ def simulate(self):
96
+ for _ in range(self.sim_substeps):
97
+ self.state.clear_forces()
98
+ self.state = self.integrator.simulate(self.model, self.state, self.state, self.sim_dt)
99
+
100
+ def step(self):
101
+ with wp.ScopedTimer("step", active=True, print=self.print_timers):
102
+ if self.use_graph:
103
+ wp.capture_launch(self.graph)
104
+ else:
105
+ self.simulate()
106
+ self.sim_time += self.frame_dt
107
+
108
+ def render(self):
109
+ if self.renderer is None:
110
+ return
111
+
112
+ with wp.ScopedTimer("render", active=True, print=self.print_timers):
113
+ self.renderer.begin_frame(self.sim_time)
114
+ self.renderer.render(self.state)
115
+ self.renderer.end_frame()
116
+
117
+
118
+ if __name__ == "__main__":
119
+ stage = os.path.join(os.path.dirname(__file__), "example_cartpole.usd")
120
+
121
+ example = Example(stage, num_envs=10)
122
+
123
+ for _ in range(example.episode_frames):
124
+ example.step()
125
+ example.render()
126
+
127
+ if example.renderer:
128
+ example.renderer.save()
@@ -0,0 +1,184 @@
1
+ # Copyright (c) 2022 NVIDIA CORPORATION. All rights reserved.
2
+ # NVIDIA CORPORATION and its licensors retain all intellectual property
3
+ # and proprietary rights in and to this software, related documentation
4
+ # and any modifications thereto. Any use, reproduction, disclosure or
5
+ # distribution of this software and related documentation without an express
6
+ # license agreement from NVIDIA CORPORATION is strictly prohibited.
7
+
8
+ ###########################################################################
9
+ # Example Sim Cloth
10
+ #
11
+ # Shows a simulation of an FEM cloth model colliding against a static
12
+ # rigid body mesh using the wp.sim.ModelBuilder().
13
+ #
14
+ ###########################################################################
15
+
16
+ import argparse
17
+ import math
18
+ import os
19
+ from enum import Enum
20
+
21
+ import numpy as np
22
+ from pxr import Usd, UsdGeom
23
+
24
+ import warp as wp
25
+ import warp.sim
26
+ import warp.sim.render
27
+
28
+ wp.init()
29
+
30
+
31
+ class IntegratorType(Enum):
32
+ EULER = "euler"
33
+ XPBD = "xpbd"
34
+
35
+ def __str__(self):
36
+ return self.value
37
+
38
+
39
+ class Example:
40
+ def __init__(self, stage, integrator=IntegratorType.EULER):
41
+ self.integrator_type = integrator
42
+
43
+ self.sim_width = 64
44
+ self.sim_height = 32
45
+
46
+ self.sim_fps = 60.0
47
+ self.sim_substeps = 32
48
+ self.sim_duration = 5.0
49
+ self.sim_frames = int(self.sim_duration * self.sim_fps)
50
+ self.frame_dt = 1.0 / self.sim_fps
51
+ self.sim_dt = self.frame_dt / self.sim_substeps
52
+ self.sim_time = 0.0
53
+ self.profiler = {}
54
+
55
+ builder = wp.sim.ModelBuilder()
56
+
57
+ if self.integrator_type == IntegratorType.EULER:
58
+ builder.add_cloth_grid(
59
+ pos=wp.vec3(0.0, 4.0, 0.0),
60
+ rot=wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), math.pi * 0.5),
61
+ vel=wp.vec3(0.0, 0.0, 0.0),
62
+ dim_x=self.sim_width,
63
+ dim_y=self.sim_height,
64
+ cell_x=0.1,
65
+ cell_y=0.1,
66
+ mass=0.1,
67
+ fix_left=True,
68
+ tri_ke=1.0e3,
69
+ tri_ka=1.0e3,
70
+ tri_kd=1.0e1,
71
+ )
72
+ else:
73
+ builder.add_cloth_grid(
74
+ pos=wp.vec3(0.0, 4.0, 0.0),
75
+ rot=wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), math.pi * 0.5),
76
+ vel=wp.vec3(0.0, 0.0, 0.0),
77
+ dim_x=self.sim_width,
78
+ dim_y=self.sim_height,
79
+ cell_x=0.1,
80
+ cell_y=0.1,
81
+ mass=0.1,
82
+ fix_left=True,
83
+ edge_ke=1.0e2,
84
+ add_springs=True,
85
+ spring_ke=1.0e3,
86
+ spring_kd=0.0,
87
+ )
88
+
89
+ usd_stage = Usd.Stage.Open(os.path.join(os.path.dirname(__file__), "../assets/bunny.usd"))
90
+ usd_geom = UsdGeom.Mesh(usd_stage.GetPrimAtPath("/bunny/bunny"))
91
+
92
+ mesh_points = np.array(usd_geom.GetPointsAttr().Get())
93
+ mesh_indices = np.array(usd_geom.GetFaceVertexIndicesAttr().Get())
94
+
95
+ mesh = wp.sim.Mesh(mesh_points, mesh_indices)
96
+
97
+ builder.add_shape_mesh(
98
+ body=-1,
99
+ mesh=mesh,
100
+ pos=wp.vec3(1.0, 0.0, 1.0),
101
+ rot=wp.quat_from_axis_angle(wp.vec3(0.0, 1.0, 0.0), math.pi * 0.5),
102
+ scale=wp.vec3(2.0, 2.0, 2.0),
103
+ ke=1.0e2,
104
+ kd=1.0e2,
105
+ kf=1.0e1,
106
+ )
107
+
108
+ if self.integrator_type == IntegratorType.EULER:
109
+ self.integrator = wp.sim.SemiImplicitIntegrator()
110
+ else:
111
+ self.integrator = wp.sim.XPBDIntegrator(iterations=1)
112
+
113
+ self.model = builder.finalize()
114
+ self.model.ground = True
115
+ self.model.soft_contact_ke = 1.0e4
116
+ self.model.soft_contact_kd = 1.0e2
117
+
118
+ self.state_0 = self.model.state()
119
+ self.state_1 = self.model.state()
120
+
121
+ self.renderer = None
122
+ if stage:
123
+ self.renderer = wp.sim.render.SimRenderer(self.model, stage, scaling=40.0)
124
+
125
+ self.use_graph = wp.get_device().is_cuda
126
+ if self.use_graph:
127
+ with wp.ScopedCapture() as capture:
128
+ self.simulate()
129
+ self.graph = capture.graph
130
+
131
+ def simulate(self):
132
+ wp.sim.collide(self.model, self.state_0)
133
+
134
+ for _ in range(self.sim_substeps):
135
+ self.state_0.clear_forces()
136
+
137
+ self.integrator.simulate(self.model, self.state_0, self.state_1, self.sim_dt)
138
+
139
+ # swap states
140
+ (self.state_0, self.state_1) = (self.state_1, self.state_0)
141
+
142
+ def step(self):
143
+ with wp.ScopedTimer("step", dict=self.profiler):
144
+ if self.use_graph:
145
+ wp.capture_launch(self.graph)
146
+ else:
147
+ self.simulate()
148
+ self.sim_time += self.frame_dt
149
+
150
+ def render(self):
151
+ if self.renderer is None:
152
+ return
153
+
154
+ with wp.ScopedTimer("render", active=True):
155
+ self.renderer.begin_frame(self.sim_time)
156
+ self.renderer.render(self.state_0)
157
+ self.renderer.end_frame()
158
+
159
+
160
+ if __name__ == "__main__":
161
+ parser = argparse.ArgumentParser()
162
+ parser.add_argument(
163
+ "--integrator",
164
+ help="Type of integrator",
165
+ type=IntegratorType,
166
+ choices=list(IntegratorType),
167
+ default=IntegratorType.EULER,
168
+ )
169
+
170
+ args = parser.parse_args()
171
+
172
+ stage_path = os.path.join(os.path.dirname(__file__), "example_cloth.usd")
173
+
174
+ example = Example(stage_path, integrator=args.integrator)
175
+
176
+ for i in range(example.sim_frames):
177
+ example.step()
178
+ example.render()
179
+
180
+ frame_times = example.profiler["step"]
181
+ print("\nAverage frame sim time: {:.2f} ms".format(sum(frame_times) / len(frame_times)))
182
+
183
+ if example.renderer:
184
+ example.renderer.save()
@@ -0,0 +1,113 @@
1
+ # Copyright (c) 2022 NVIDIA CORPORATION. All rights reserved.
2
+ # NVIDIA CORPORATION and its licensors retain all intellectual property
3
+ # and proprietary rights in and to this software, related documentation
4
+ # and any modifications thereto. Any use, reproduction, disclosure or
5
+ # distribution of this software and related documentation without an express
6
+ # license agreement from NVIDIA CORPORATION is strictly prohibited.
7
+
8
+ ###########################################################################
9
+ # Example Sim Granular
10
+ #
11
+ # Shows how to set up a particle-based granular material model using the
12
+ # wp.sim.ModelBuilder().
13
+ #
14
+ ###########################################################################
15
+
16
+ import os
17
+
18
+ import warp as wp
19
+ import warp.sim
20
+ import warp.sim.render
21
+
22
+ wp.init()
23
+
24
+
25
+ class Example:
26
+ def __init__(self, stage):
27
+ self.frame_dt = 1.0 / 60
28
+ self.frame_count = 400
29
+
30
+ self.sim_substeps = 64
31
+ self.sim_dt = self.frame_dt / self.sim_substeps
32
+ self.sim_steps = self.frame_count * self.sim_substeps
33
+ self.sim_time = 0.0
34
+
35
+ self.radius = 0.1
36
+
37
+ builder = wp.sim.ModelBuilder()
38
+ builder.default_particle_radius = self.radius
39
+
40
+ builder.add_particle_grid(
41
+ dim_x=16,
42
+ dim_y=32,
43
+ dim_z=16,
44
+ cell_x=self.radius * 2.0,
45
+ cell_y=self.radius * 2.0,
46
+ cell_z=self.radius * 2.0,
47
+ pos=wp.vec3(0.0, 1.0, 0.0),
48
+ rot=wp.quat_identity(),
49
+ vel=wp.vec3(5.0, 0.0, 0.0),
50
+ mass=0.1,
51
+ jitter=self.radius * 0.1,
52
+ )
53
+
54
+ self.model = builder.finalize()
55
+ self.model.particle_kf = 25.0
56
+
57
+ self.model.soft_contact_kd = 100.0
58
+ self.model.soft_contact_kf *= 2.0
59
+
60
+ self.state_0 = self.model.state()
61
+ self.state_1 = self.model.state()
62
+
63
+ self.integrator = wp.sim.SemiImplicitIntegrator()
64
+
65
+ self.renderer = None
66
+ if stage:
67
+ self.renderer = wp.sim.render.SimRenderer(self.model, stage, scaling=20.0)
68
+
69
+ self.use_graph = wp.get_device().is_cuda
70
+ if self.use_graph:
71
+ with wp.ScopedCapture() as capture:
72
+ self.simulate()
73
+ self.graph = capture.graph
74
+
75
+ def simulate(self):
76
+ for _ in range(self.sim_substeps):
77
+ self.state_0.clear_forces()
78
+ self.integrator.simulate(self.model, self.state_0, self.state_1, self.sim_dt)
79
+
80
+ # swap states
81
+ (self.state_0, self.state_1) = (self.state_1, self.state_0)
82
+
83
+ def step(self):
84
+ with wp.ScopedTimer("step", active=True):
85
+ self.model.particle_grid.build(self.state_0.particle_q, self.radius * 2.0)
86
+ if self.use_graph:
87
+ wp.capture_launch(self.graph)
88
+ else:
89
+ self.simulate()
90
+
91
+ self.sim_time += self.frame_dt
92
+
93
+ def render(self):
94
+ if self.renderer is None:
95
+ return
96
+
97
+ with wp.ScopedTimer("render", active=True):
98
+ self.renderer.begin_frame(self.sim_time)
99
+ self.renderer.render(self.state_0)
100
+ self.renderer.end_frame()
101
+
102
+
103
+ if __name__ == "__main__":
104
+ stage_path = os.path.join(os.path.dirname(__file__), "example_granular.usd")
105
+
106
+ example = Example(stage_path)
107
+
108
+ for _ in range(example.frame_count):
109
+ example.step()
110
+ example.render()
111
+
112
+ if example.renderer:
113
+ example.renderer.save()