warp-lang 1.9.0__py3-none-win_amd64.whl → 1.10.0rc2__py3-none-win_amd64.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.
- warp/__init__.py +301 -287
- warp/__init__.pyi +2220 -313
- warp/_src/__init__.py +14 -0
- warp/_src/autograd.py +1075 -0
- warp/_src/build.py +618 -0
- warp/_src/build_dll.py +640 -0
- warp/{builtins.py → _src/builtins.py} +1497 -226
- warp/_src/codegen.py +4359 -0
- warp/{config.py → _src/config.py} +178 -169
- warp/_src/constants.py +57 -0
- warp/_src/context.py +8294 -0
- warp/_src/dlpack.py +462 -0
- warp/_src/fabric.py +355 -0
- warp/_src/fem/__init__.py +14 -0
- warp/_src/fem/adaptivity.py +508 -0
- warp/_src/fem/cache.py +687 -0
- warp/_src/fem/dirichlet.py +188 -0
- warp/{fem → _src/fem}/domain.py +40 -30
- warp/_src/fem/field/__init__.py +131 -0
- warp/_src/fem/field/field.py +701 -0
- warp/{fem → _src/fem}/field/nodal_field.py +30 -15
- warp/{fem → _src/fem}/field/restriction.py +1 -1
- warp/{fem → _src/fem}/field/virtual.py +53 -27
- warp/_src/fem/geometry/__init__.py +32 -0
- warp/{fem → _src/fem}/geometry/adaptive_nanogrid.py +77 -163
- warp/_src/fem/geometry/closest_point.py +97 -0
- warp/{fem → _src/fem}/geometry/deformed_geometry.py +14 -22
- warp/{fem → _src/fem}/geometry/element.py +32 -10
- warp/{fem → _src/fem}/geometry/geometry.py +48 -20
- warp/{fem → _src/fem}/geometry/grid_2d.py +12 -23
- warp/{fem → _src/fem}/geometry/grid_3d.py +12 -23
- warp/{fem → _src/fem}/geometry/hexmesh.py +40 -63
- warp/{fem → _src/fem}/geometry/nanogrid.py +255 -248
- warp/{fem → _src/fem}/geometry/partition.py +121 -63
- warp/{fem → _src/fem}/geometry/quadmesh.py +26 -45
- warp/{fem → _src/fem}/geometry/tetmesh.py +40 -63
- warp/{fem → _src/fem}/geometry/trimesh.py +26 -45
- warp/{fem → _src/fem}/integrate.py +164 -158
- warp/_src/fem/linalg.py +383 -0
- warp/_src/fem/operator.py +396 -0
- warp/_src/fem/polynomial.py +229 -0
- warp/{fem → _src/fem}/quadrature/pic_quadrature.py +15 -20
- warp/{fem → _src/fem}/quadrature/quadrature.py +95 -47
- warp/_src/fem/space/__init__.py +248 -0
- warp/{fem → _src/fem}/space/basis_function_space.py +20 -11
- warp/_src/fem/space/basis_space.py +679 -0
- warp/{fem → _src/fem}/space/dof_mapper.py +3 -3
- warp/{fem → _src/fem}/space/function_space.py +14 -13
- warp/{fem → _src/fem}/space/grid_2d_function_space.py +4 -7
- warp/{fem → _src/fem}/space/grid_3d_function_space.py +4 -4
- warp/{fem → _src/fem}/space/hexmesh_function_space.py +4 -10
- warp/{fem → _src/fem}/space/nanogrid_function_space.py +3 -9
- warp/{fem → _src/fem}/space/partition.py +117 -60
- warp/{fem → _src/fem}/space/quadmesh_function_space.py +4 -10
- warp/{fem → _src/fem}/space/restriction.py +66 -33
- warp/_src/fem/space/shape/__init__.py +152 -0
- warp/{fem → _src/fem}/space/shape/cube_shape_function.py +9 -9
- warp/{fem → _src/fem}/space/shape/shape_function.py +8 -9
- warp/{fem → _src/fem}/space/shape/square_shape_function.py +6 -6
- warp/{fem → _src/fem}/space/shape/tet_shape_function.py +3 -3
- warp/{fem → _src/fem}/space/shape/triangle_shape_function.py +3 -3
- warp/{fem → _src/fem}/space/tetmesh_function_space.py +3 -9
- warp/_src/fem/space/topology.py +459 -0
- warp/{fem → _src/fem}/space/trimesh_function_space.py +3 -9
- warp/_src/fem/types.py +112 -0
- warp/_src/fem/utils.py +486 -0
- warp/_src/jax.py +186 -0
- warp/_src/jax_experimental/__init__.py +14 -0
- warp/_src/jax_experimental/custom_call.py +387 -0
- warp/_src/jax_experimental/ffi.py +1284 -0
- warp/_src/jax_experimental/xla_ffi.py +656 -0
- warp/_src/marching_cubes.py +708 -0
- warp/_src/math.py +414 -0
- warp/_src/optim/__init__.py +14 -0
- warp/_src/optim/adam.py +163 -0
- warp/_src/optim/linear.py +1606 -0
- warp/_src/optim/sgd.py +112 -0
- warp/_src/paddle.py +406 -0
- warp/_src/render/__init__.py +14 -0
- warp/_src/render/imgui_manager.py +289 -0
- warp/_src/render/render_opengl.py +3636 -0
- warp/_src/render/render_usd.py +937 -0
- warp/_src/render/utils.py +160 -0
- warp/_src/sparse.py +2716 -0
- warp/_src/tape.py +1206 -0
- warp/{thirdparty → _src/thirdparty}/unittest_parallel.py +9 -2
- warp/_src/torch.py +391 -0
- warp/_src/types.py +5870 -0
- warp/_src/utils.py +1693 -0
- warp/autograd.py +12 -1054
- warp/bin/warp-clang.dll +0 -0
- warp/bin/warp.dll +0 -0
- warp/build.py +8 -588
- warp/build_dll.py +6 -471
- warp/codegen.py +6 -4246
- warp/constants.py +6 -39
- warp/context.py +12 -7851
- warp/dlpack.py +6 -444
- warp/examples/distributed/example_jacobi_mpi.py +4 -5
- warp/examples/fem/example_adaptive_grid.py +1 -1
- warp/examples/fem/example_apic_fluid.py +1 -1
- warp/examples/fem/example_burgers.py +8 -8
- warp/examples/fem/example_diffusion.py +1 -1
- warp/examples/fem/example_distortion_energy.py +1 -1
- warp/examples/fem/example_mixed_elasticity.py +2 -2
- warp/examples/fem/example_navier_stokes.py +1 -1
- warp/examples/fem/example_nonconforming_contact.py +7 -7
- warp/examples/fem/example_stokes.py +1 -1
- warp/examples/fem/example_stokes_transfer.py +1 -1
- warp/examples/fem/utils.py +2 -2
- warp/examples/interop/example_jax_callable.py +1 -1
- warp/examples/interop/example_jax_ffi_callback.py +1 -1
- warp/examples/interop/example_jax_kernel.py +3 -2
- warp/examples/tile/example_tile_mcgp.py +191 -0
- warp/fabric.py +6 -337
- warp/fem/__init__.py +159 -97
- warp/fem/adaptivity.py +7 -489
- warp/fem/cache.py +9 -648
- warp/fem/dirichlet.py +6 -184
- warp/fem/field/__init__.py +8 -109
- warp/fem/field/field.py +7 -652
- warp/fem/geometry/__init__.py +7 -18
- warp/fem/geometry/closest_point.py +11 -77
- warp/fem/linalg.py +18 -366
- warp/fem/operator.py +11 -369
- warp/fem/polynomial.py +9 -209
- warp/fem/space/__init__.py +5 -211
- warp/fem/space/basis_space.py +6 -662
- warp/fem/space/shape/__init__.py +41 -118
- warp/fem/space/topology.py +6 -437
- warp/fem/types.py +6 -81
- warp/fem/utils.py +11 -444
- warp/jax.py +8 -165
- warp/jax_experimental/__init__.py +14 -1
- warp/jax_experimental/custom_call.py +8 -342
- warp/jax_experimental/ffi.py +17 -853
- warp/jax_experimental/xla_ffi.py +5 -596
- warp/marching_cubes.py +5 -689
- warp/math.py +16 -393
- warp/native/array.h +385 -37
- warp/native/builtin.h +316 -39
- warp/native/bvh.cpp +43 -9
- warp/native/bvh.cu +62 -27
- warp/native/bvh.h +310 -309
- warp/native/clang/clang.cpp +102 -97
- warp/native/coloring.cpp +0 -1
- warp/native/crt.h +208 -0
- warp/native/exports.h +156 -0
- warp/native/hashgrid.cu +2 -0
- warp/native/intersect.h +24 -1
- warp/native/intersect_tri.h +44 -35
- warp/native/mat.h +1456 -276
- warp/native/mesh.cpp +4 -4
- warp/native/mesh.cu +4 -2
- warp/native/mesh.h +176 -61
- warp/native/quat.h +0 -52
- warp/native/scan.cu +2 -0
- warp/native/sort.cu +22 -13
- warp/native/sort.h +2 -0
- warp/native/sparse.cu +7 -3
- warp/native/spatial.h +12 -0
- warp/native/tile.h +837 -70
- warp/native/tile_radix_sort.h +1 -1
- warp/native/tile_reduce.h +394 -46
- warp/native/tile_scan.h +4 -4
- warp/native/vec.h +469 -53
- warp/native/version.h +23 -0
- warp/native/volume.cpp +1 -1
- warp/native/volume.cu +1 -0
- warp/native/volume.h +1 -1
- warp/native/volume_builder.cu +2 -0
- warp/native/warp.cpp +60 -32
- warp/native/warp.cu +313 -201
- warp/native/warp.h +14 -11
- warp/optim/__init__.py +6 -3
- warp/optim/adam.py +6 -145
- warp/optim/linear.py +14 -1585
- warp/optim/sgd.py +6 -94
- warp/paddle.py +6 -388
- warp/render/__init__.py +8 -4
- warp/render/imgui_manager.py +7 -267
- warp/render/render_opengl.py +6 -3616
- warp/render/render_usd.py +6 -918
- warp/render/utils.py +6 -142
- warp/sparse.py +37 -2563
- warp/tape.py +6 -1188
- warp/tests/__main__.py +1 -1
- warp/tests/cuda/test_async.py +4 -4
- warp/tests/cuda/test_conditional_captures.py +1 -1
- warp/tests/cuda/test_multigpu.py +1 -1
- warp/tests/cuda/test_streams.py +58 -1
- warp/tests/geometry/test_bvh.py +157 -22
- warp/tests/geometry/test_hash_grid.py +38 -0
- warp/tests/geometry/test_marching_cubes.py +0 -1
- warp/tests/geometry/test_mesh.py +5 -3
- warp/tests/geometry/test_mesh_query_aabb.py +5 -12
- warp/tests/geometry/test_mesh_query_point.py +5 -2
- warp/tests/geometry/test_mesh_query_ray.py +15 -3
- warp/tests/geometry/test_volume_write.py +5 -5
- warp/tests/interop/test_dlpack.py +14 -14
- warp/tests/interop/test_jax.py +1382 -79
- warp/tests/interop/test_paddle.py +1 -1
- warp/tests/test_adam.py +0 -1
- warp/tests/test_arithmetic.py +9 -9
- warp/tests/test_array.py +529 -100
- warp/tests/test_array_reduce.py +3 -3
- warp/tests/test_atomic.py +12 -8
- warp/tests/test_atomic_bitwise.py +209 -0
- warp/tests/test_atomic_cas.py +4 -4
- warp/tests/test_bool.py +2 -2
- warp/tests/test_builtins_resolution.py +5 -571
- warp/tests/test_codegen.py +34 -15
- warp/tests/test_conditional.py +1 -1
- warp/tests/test_context.py +6 -6
- warp/tests/test_copy.py +242 -161
- warp/tests/test_ctypes.py +3 -3
- warp/tests/test_devices.py +24 -2
- warp/tests/test_examples.py +16 -84
- warp/tests/test_fabricarray.py +35 -35
- warp/tests/test_fast_math.py +0 -2
- warp/tests/test_fem.py +60 -14
- warp/tests/test_fixedarray.py +3 -3
- warp/tests/test_func.py +8 -5
- warp/tests/test_generics.py +1 -1
- warp/tests/test_indexedarray.py +24 -24
- warp/tests/test_intersect.py +39 -9
- warp/tests/test_large.py +1 -1
- warp/tests/test_lerp.py +3 -1
- warp/tests/test_linear_solvers.py +1 -1
- warp/tests/test_map.py +49 -4
- warp/tests/test_mat.py +52 -62
- warp/tests/test_mat_constructors.py +4 -5
- warp/tests/test_mat_lite.py +1 -1
- warp/tests/test_mat_scalar_ops.py +121 -121
- warp/tests/test_math.py +34 -0
- warp/tests/test_module_aot.py +4 -4
- warp/tests/test_modules_lite.py +28 -2
- warp/tests/test_print.py +11 -11
- warp/tests/test_quat.py +93 -58
- warp/tests/test_runlength_encode.py +1 -1
- warp/tests/test_scalar_ops.py +38 -10
- warp/tests/test_smoothstep.py +1 -1
- warp/tests/test_sparse.py +126 -15
- warp/tests/test_spatial.py +105 -87
- warp/tests/test_special_values.py +6 -6
- warp/tests/test_static.py +7 -7
- warp/tests/test_struct.py +13 -2
- warp/tests/test_triangle_closest_point.py +48 -1
- warp/tests/test_tuple.py +96 -0
- warp/tests/test_types.py +82 -9
- warp/tests/test_utils.py +52 -52
- warp/tests/test_vec.py +29 -29
- warp/tests/test_vec_constructors.py +5 -5
- warp/tests/test_vec_scalar_ops.py +97 -97
- warp/tests/test_version.py +75 -0
- warp/tests/tile/test_tile.py +239 -0
- warp/tests/tile/test_tile_atomic_bitwise.py +403 -0
- warp/tests/tile/test_tile_cholesky.py +7 -4
- warp/tests/tile/test_tile_load.py +26 -2
- warp/tests/tile/test_tile_mathdx.py +3 -3
- warp/tests/tile/test_tile_matmul.py +1 -1
- warp/tests/tile/test_tile_mlp.py +2 -4
- warp/tests/tile/test_tile_reduce.py +214 -13
- warp/tests/unittest_suites.py +6 -14
- warp/tests/unittest_utils.py +10 -9
- warp/tests/walkthrough_debug.py +3 -1
- warp/torch.py +6 -373
- warp/types.py +29 -5750
- warp/utils.py +10 -1659
- {warp_lang-1.9.0.dist-info → warp_lang-1.10.0rc2.dist-info}/METADATA +47 -103
- warp_lang-1.10.0rc2.dist-info/RECORD +468 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/Gaia-LICENSE.txt +6 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/appdirs-LICENSE.txt +22 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/asset_pixel_jpg-LICENSE.txt +3 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/cuda-LICENSE.txt +1582 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/dlpack-LICENSE.txt +201 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/fp16-LICENSE.txt +28 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/libmathdx-LICENSE.txt +220 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/llvm-LICENSE.txt +279 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/moller-LICENSE.txt +16 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/nanovdb-LICENSE.txt +2 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/nvrtc-LICENSE.txt +1592 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/svd-LICENSE.txt +23 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/unittest_parallel-LICENSE.txt +21 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/usd-LICENSE.txt +213 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/windingnumber-LICENSE.txt +21 -0
- warp/examples/assets/cartpole.urdf +0 -110
- warp/examples/assets/crazyflie.usd +0 -0
- warp/examples/assets/nv_ant.xml +0 -92
- warp/examples/assets/nv_humanoid.xml +0 -183
- warp/examples/assets/quadruped.urdf +0 -268
- warp/examples/optim/example_bounce.py +0 -266
- warp/examples/optim/example_cloth_throw.py +0 -228
- warp/examples/optim/example_drone.py +0 -870
- warp/examples/optim/example_inverse_kinematics.py +0 -182
- warp/examples/optim/example_inverse_kinematics_torch.py +0 -191
- warp/examples/optim/example_softbody_properties.py +0 -400
- warp/examples/optim/example_spring_cage.py +0 -245
- warp/examples/optim/example_trajectory.py +0 -227
- warp/examples/sim/example_cartpole.py +0 -143
- warp/examples/sim/example_cloth.py +0 -225
- warp/examples/sim/example_cloth_self_contact.py +0 -316
- warp/examples/sim/example_granular.py +0 -130
- warp/examples/sim/example_granular_collision_sdf.py +0 -202
- warp/examples/sim/example_jacobian_ik.py +0 -244
- warp/examples/sim/example_particle_chain.py +0 -124
- warp/examples/sim/example_quadruped.py +0 -203
- warp/examples/sim/example_rigid_chain.py +0 -203
- warp/examples/sim/example_rigid_contact.py +0 -195
- warp/examples/sim/example_rigid_force.py +0 -133
- warp/examples/sim/example_rigid_gyroscopic.py +0 -115
- warp/examples/sim/example_rigid_soft_contact.py +0 -140
- warp/examples/sim/example_soft_body.py +0 -196
- warp/examples/tile/example_tile_walker.py +0 -327
- warp/sim/__init__.py +0 -74
- warp/sim/articulation.py +0 -793
- warp/sim/collide.py +0 -2570
- warp/sim/graph_coloring.py +0 -307
- warp/sim/import_mjcf.py +0 -791
- warp/sim/import_snu.py +0 -227
- warp/sim/import_urdf.py +0 -579
- warp/sim/import_usd.py +0 -898
- warp/sim/inertia.py +0 -357
- warp/sim/integrator.py +0 -245
- warp/sim/integrator_euler.py +0 -2000
- warp/sim/integrator_featherstone.py +0 -2101
- warp/sim/integrator_vbd.py +0 -2487
- warp/sim/integrator_xpbd.py +0 -3295
- warp/sim/model.py +0 -4821
- warp/sim/particles.py +0 -121
- warp/sim/render.py +0 -431
- warp/sim/utils.py +0 -431
- warp/tests/sim/disabled_kinematics.py +0 -244
- warp/tests/sim/test_cloth.py +0 -863
- warp/tests/sim/test_collision.py +0 -743
- warp/tests/sim/test_coloring.py +0 -347
- warp/tests/sim/test_inertia.py +0 -161
- warp/tests/sim/test_model.py +0 -226
- warp/tests/sim/test_sim_grad.py +0 -287
- warp/tests/sim/test_sim_grad_bounce_linear.py +0 -212
- warp/tests/sim/test_sim_kinematics.py +0 -98
- warp/thirdparty/__init__.py +0 -0
- warp_lang-1.9.0.dist-info/RECORD +0 -456
- /warp/{fem → _src/fem}/quadrature/__init__.py +0 -0
- /warp/{tests/sim → _src/thirdparty}/__init__.py +0 -0
- /warp/{thirdparty → _src/thirdparty}/appdirs.py +0 -0
- /warp/{thirdparty → _src/thirdparty}/dlpack.py +0 -0
- {warp_lang-1.9.0.dist-info → warp_lang-1.10.0rc2.dist-info}/WHEEL +0 -0
- {warp_lang-1.9.0.dist-info → warp_lang-1.10.0rc2.dist-info}/licenses/LICENSE.md +0 -0
- {warp_lang-1.9.0.dist-info → warp_lang-1.10.0rc2.dist-info}/top_level.txt +0 -0
|
@@ -1,400 +0,0 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
-
# SPDX-License-Identifier: Apache-2.0
|
|
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
|
-
# Example FEM Bounce
|
|
18
|
-
#
|
|
19
|
-
# Shows how to use Warp to optimize for the material parameters of a soft body,
|
|
20
|
-
# such that it bounces off the wall and floor in order to hit a target.
|
|
21
|
-
#
|
|
22
|
-
# This example uses the built-in wp.Tape() object to compute gradients of
|
|
23
|
-
# the distance to target (loss) w.r.t the material parameters, followed by
|
|
24
|
-
# a simple gradient-descent optimization step.
|
|
25
|
-
#
|
|
26
|
-
###########################################################################
|
|
27
|
-
|
|
28
|
-
import numpy as np
|
|
29
|
-
|
|
30
|
-
import warp as wp
|
|
31
|
-
import warp.optim
|
|
32
|
-
import warp.sim
|
|
33
|
-
import warp.sim.render
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
@wp.kernel
|
|
37
|
-
def assign_param(params: wp.array(dtype=wp.float32), tet_materials: wp.array2d(dtype=wp.float32)):
|
|
38
|
-
tid = wp.tid()
|
|
39
|
-
params_idx = 2 * wp.tid() % params.shape[0]
|
|
40
|
-
tet_materials[tid, 0] = params[params_idx]
|
|
41
|
-
tet_materials[tid, 1] = params[params_idx + 1]
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
@wp.kernel
|
|
45
|
-
def com_kernel(particle_q: wp.array(dtype=wp.vec3), com: wp.array(dtype=wp.vec3)):
|
|
46
|
-
tid = wp.tid()
|
|
47
|
-
point = particle_q[tid]
|
|
48
|
-
a = point / wp.float32(particle_q.shape[0])
|
|
49
|
-
|
|
50
|
-
# Atomically add the point coordinates to the accumulator
|
|
51
|
-
wp.atomic_add(com, 0, a)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
@wp.kernel
|
|
55
|
-
def loss_kernel(
|
|
56
|
-
target: wp.vec3,
|
|
57
|
-
com: wp.array(dtype=wp.vec3),
|
|
58
|
-
pos_error: wp.array(dtype=float),
|
|
59
|
-
loss: wp.array(dtype=float),
|
|
60
|
-
):
|
|
61
|
-
diff = com[0] - target
|
|
62
|
-
pos_error[0] = wp.dot(diff, diff)
|
|
63
|
-
norm = pos_error[0]
|
|
64
|
-
loss[0] = norm
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
@wp.kernel
|
|
68
|
-
def enforce_constraint_kernel(lower_bound: wp.float32, upper_bound: wp.float32, x: wp.array(dtype=wp.float32)):
|
|
69
|
-
tid = wp.tid()
|
|
70
|
-
if x[tid] < lower_bound:
|
|
71
|
-
x[tid] = lower_bound
|
|
72
|
-
elif x[tid] > upper_bound:
|
|
73
|
-
x[tid] = upper_bound
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
class Example:
|
|
77
|
-
def __init__(
|
|
78
|
-
self,
|
|
79
|
-
stage_path="example_softbody_properties.usd",
|
|
80
|
-
material_behavior="anisotropic",
|
|
81
|
-
verbose=False,
|
|
82
|
-
):
|
|
83
|
-
self.verbose = verbose
|
|
84
|
-
self.material_behavior = material_behavior
|
|
85
|
-
|
|
86
|
-
# seconds
|
|
87
|
-
sim_duration = 1.0
|
|
88
|
-
|
|
89
|
-
# control frequency
|
|
90
|
-
fps = 60
|
|
91
|
-
self.frame_dt = 1.0 / fps
|
|
92
|
-
frame_steps = int(sim_duration / self.frame_dt)
|
|
93
|
-
|
|
94
|
-
# sim frequency
|
|
95
|
-
self.sim_substeps = 16
|
|
96
|
-
self.sim_steps = frame_steps * self.sim_substeps
|
|
97
|
-
self.sim_dt = self.frame_dt / self.sim_substeps
|
|
98
|
-
|
|
99
|
-
self.iter = 0
|
|
100
|
-
self.render_time = 0.0
|
|
101
|
-
|
|
102
|
-
self.train_rate = 1e7
|
|
103
|
-
|
|
104
|
-
self.losses = []
|
|
105
|
-
|
|
106
|
-
self.hard_lower_bound = wp.float32(500.0)
|
|
107
|
-
self.hard_upper_bound = wp.float32(4e6)
|
|
108
|
-
|
|
109
|
-
# Create FEM model.
|
|
110
|
-
self.cell_dim = 2
|
|
111
|
-
self.cell_size = 0.1
|
|
112
|
-
center = self.cell_size * self.cell_dim * 0.5
|
|
113
|
-
self.grid_origin = wp.vec3(-0.5, 1.0, -center)
|
|
114
|
-
self.create_model()
|
|
115
|
-
|
|
116
|
-
self.integrator = wp.sim.SemiImplicitIntegrator()
|
|
117
|
-
|
|
118
|
-
self.target = wp.vec3(-1.0, 1.5, 0.0)
|
|
119
|
-
# Initialize material parameters
|
|
120
|
-
if self.material_behavior == "anisotropic":
|
|
121
|
-
# Different Lame parameters for each tet
|
|
122
|
-
self.material_params = wp.array(
|
|
123
|
-
self.model.tet_materials.numpy()[:, :2].flatten(),
|
|
124
|
-
dtype=wp.float32,
|
|
125
|
-
requires_grad=True,
|
|
126
|
-
)
|
|
127
|
-
else:
|
|
128
|
-
# Same Lame parameters for all tets
|
|
129
|
-
self.material_params = wp.array(
|
|
130
|
-
self.model.tet_materials.numpy()[0, :2].flatten(),
|
|
131
|
-
dtype=wp.float32,
|
|
132
|
-
requires_grad=True,
|
|
133
|
-
)
|
|
134
|
-
|
|
135
|
-
self.optimizer = wp.optim.SGD(
|
|
136
|
-
[self.material_params],
|
|
137
|
-
lr=self.train_rate,
|
|
138
|
-
nesterov=False,
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
self.com = wp.array([wp.vec3(0.0, 0.0, 0.0)], dtype=wp.vec3, requires_grad=True)
|
|
142
|
-
self.pos_error = wp.zeros(1, dtype=wp.float32, requires_grad=True)
|
|
143
|
-
self.loss = wp.zeros(1, dtype=wp.float32, requires_grad=True)
|
|
144
|
-
|
|
145
|
-
# allocate sim states for trajectory
|
|
146
|
-
self.states = []
|
|
147
|
-
for _i in range(self.sim_steps + 1):
|
|
148
|
-
self.states.append(self.model.state())
|
|
149
|
-
|
|
150
|
-
if stage_path:
|
|
151
|
-
self.renderer = wp.sim.render.SimRenderer(self.model, stage_path, scaling=1.0)
|
|
152
|
-
else:
|
|
153
|
-
self.renderer = None
|
|
154
|
-
|
|
155
|
-
# capture forward/backward passes
|
|
156
|
-
self.use_cuda_graph = wp.get_device().is_cuda
|
|
157
|
-
if self.use_cuda_graph:
|
|
158
|
-
with wp.ScopedCapture() as capture:
|
|
159
|
-
self.tape = wp.Tape()
|
|
160
|
-
with self.tape:
|
|
161
|
-
self.forward()
|
|
162
|
-
self.tape.backward(self.loss)
|
|
163
|
-
self.graph = capture.graph
|
|
164
|
-
|
|
165
|
-
def create_model(self):
|
|
166
|
-
builder = wp.sim.ModelBuilder()
|
|
167
|
-
builder.default_particle_radius = 0.0005
|
|
168
|
-
|
|
169
|
-
total_mass = 0.2
|
|
170
|
-
num_particles = (self.cell_dim + 1) ** 3
|
|
171
|
-
particle_mass = total_mass / num_particles
|
|
172
|
-
particle_density = particle_mass / (self.cell_size**3)
|
|
173
|
-
if self.verbose:
|
|
174
|
-
print(f"Particle density: {particle_density}")
|
|
175
|
-
|
|
176
|
-
young_mod = 1.5 * 1e4
|
|
177
|
-
poisson_ratio = 0.3
|
|
178
|
-
k_mu = 0.5 * young_mod / (1.0 + poisson_ratio)
|
|
179
|
-
k_lambda = young_mod * poisson_ratio / ((1 + poisson_ratio) * (1 - 2 * poisson_ratio))
|
|
180
|
-
|
|
181
|
-
builder.add_soft_grid(
|
|
182
|
-
pos=self.grid_origin,
|
|
183
|
-
rot=wp.quat_identity(),
|
|
184
|
-
vel=wp.vec3(5.0, -5.0, 0.0),
|
|
185
|
-
dim_x=self.cell_dim,
|
|
186
|
-
dim_y=self.cell_dim,
|
|
187
|
-
dim_z=self.cell_dim,
|
|
188
|
-
cell_x=self.cell_size,
|
|
189
|
-
cell_y=self.cell_size,
|
|
190
|
-
cell_z=self.cell_size,
|
|
191
|
-
density=particle_density,
|
|
192
|
-
k_mu=k_mu,
|
|
193
|
-
k_lambda=k_lambda,
|
|
194
|
-
k_damp=0.0,
|
|
195
|
-
tri_ke=1e-4,
|
|
196
|
-
tri_ka=1e-4,
|
|
197
|
-
tri_kd=1e-4,
|
|
198
|
-
tri_drag=0.0,
|
|
199
|
-
tri_lift=0.0,
|
|
200
|
-
fix_bottom=False,
|
|
201
|
-
)
|
|
202
|
-
|
|
203
|
-
ke = 1.0e3
|
|
204
|
-
kf = 0.0
|
|
205
|
-
kd = 1.0e0
|
|
206
|
-
mu = 0.2
|
|
207
|
-
builder.add_shape_box(
|
|
208
|
-
body=-1,
|
|
209
|
-
pos=wp.vec3(2.0, 1.0, 0.0),
|
|
210
|
-
hx=0.25,
|
|
211
|
-
hy=1.0,
|
|
212
|
-
hz=1.0,
|
|
213
|
-
ke=ke,
|
|
214
|
-
kf=kf,
|
|
215
|
-
kd=kd,
|
|
216
|
-
mu=mu,
|
|
217
|
-
)
|
|
218
|
-
|
|
219
|
-
# use `requires_grad=True` to create a model for differentiable simulation
|
|
220
|
-
self.model = builder.finalize(requires_grad=True)
|
|
221
|
-
self.model.ground = True
|
|
222
|
-
|
|
223
|
-
self.model.soft_contact_ke = ke
|
|
224
|
-
self.model.soft_contact_kf = kf
|
|
225
|
-
self.model.soft_contact_kd = kd
|
|
226
|
-
self.model.soft_contact_mu = mu
|
|
227
|
-
self.model.soft_contact_margin = 0.001
|
|
228
|
-
self.model.soft_contact_restitution = 1.0
|
|
229
|
-
|
|
230
|
-
def forward(self):
|
|
231
|
-
wp.launch(
|
|
232
|
-
kernel=assign_param,
|
|
233
|
-
dim=self.model.tet_count,
|
|
234
|
-
inputs=(self.material_params,),
|
|
235
|
-
outputs=(self.model.tet_materials,),
|
|
236
|
-
)
|
|
237
|
-
# run control loop
|
|
238
|
-
for i in range(self.sim_steps):
|
|
239
|
-
wp.sim.collide(self.model, self.states[i])
|
|
240
|
-
self.states[i].clear_forces()
|
|
241
|
-
|
|
242
|
-
self.integrator.simulate(self.model, self.states[i], self.states[i + 1], self.sim_dt)
|
|
243
|
-
|
|
244
|
-
# Update loss
|
|
245
|
-
# Compute the center of mass for the last time step.
|
|
246
|
-
wp.launch(
|
|
247
|
-
kernel=com_kernel,
|
|
248
|
-
dim=self.model.particle_count,
|
|
249
|
-
inputs=(self.states[-1].particle_q,),
|
|
250
|
-
outputs=(self.com,),
|
|
251
|
-
)
|
|
252
|
-
|
|
253
|
-
# calculate loss
|
|
254
|
-
wp.launch(
|
|
255
|
-
kernel=loss_kernel,
|
|
256
|
-
dim=1,
|
|
257
|
-
inputs=(
|
|
258
|
-
self.target,
|
|
259
|
-
self.com,
|
|
260
|
-
),
|
|
261
|
-
outputs=(self.pos_error, self.loss),
|
|
262
|
-
)
|
|
263
|
-
|
|
264
|
-
return self.loss
|
|
265
|
-
|
|
266
|
-
def step(self):
|
|
267
|
-
with wp.ScopedTimer("step"):
|
|
268
|
-
if self.use_cuda_graph:
|
|
269
|
-
wp.capture_launch(self.graph)
|
|
270
|
-
else:
|
|
271
|
-
self.tape = wp.Tape()
|
|
272
|
-
with self.tape:
|
|
273
|
-
self.forward()
|
|
274
|
-
self.tape.backward(loss=self.loss)
|
|
275
|
-
|
|
276
|
-
if self.verbose:
|
|
277
|
-
self.log_step()
|
|
278
|
-
|
|
279
|
-
self.optimizer.step([self.material_params.grad])
|
|
280
|
-
|
|
281
|
-
wp.launch(
|
|
282
|
-
kernel=enforce_constraint_kernel,
|
|
283
|
-
dim=self.material_params.shape[0],
|
|
284
|
-
inputs=(
|
|
285
|
-
self.hard_lower_bound,
|
|
286
|
-
self.hard_upper_bound,
|
|
287
|
-
),
|
|
288
|
-
outputs=(self.material_params,),
|
|
289
|
-
)
|
|
290
|
-
|
|
291
|
-
self.losses.append(self.loss.numpy()[0])
|
|
292
|
-
|
|
293
|
-
# clear grads for next iteration
|
|
294
|
-
self.tape.zero()
|
|
295
|
-
self.loss.zero_()
|
|
296
|
-
self.com.zero_()
|
|
297
|
-
self.pos_error.zero_()
|
|
298
|
-
|
|
299
|
-
self.iter = self.iter + 1
|
|
300
|
-
|
|
301
|
-
def log_step(self):
|
|
302
|
-
x = self.material_params.numpy().reshape(-1, 2)
|
|
303
|
-
x_grad = self.material_params.grad.numpy().reshape(-1, 2)
|
|
304
|
-
|
|
305
|
-
print(f"Iter: {self.iter} Loss: {self.loss.numpy()[0]}")
|
|
306
|
-
|
|
307
|
-
print(f"Pos error: {np.sqrt(self.pos_error.numpy()[0])}")
|
|
308
|
-
|
|
309
|
-
print(
|
|
310
|
-
f"Max Mu: {np.max(x[:, 0])}, Min Mu: {np.min(x[:, 0])}, "
|
|
311
|
-
f"Max Lambda: {np.max(x[:, 1])}, Min Lambda: {np.min(x[:, 1])}"
|
|
312
|
-
)
|
|
313
|
-
|
|
314
|
-
print(
|
|
315
|
-
f"Max Mu Grad: {np.max(x_grad[:, 0])}, Min Mu Grad: {np.min(x_grad[:, 0])}, "
|
|
316
|
-
f"Max Lambda Grad: {np.max(x_grad[:, 1])}, Min Lambda Grad: {np.min(x_grad[:, 1])}"
|
|
317
|
-
)
|
|
318
|
-
|
|
319
|
-
def render(self):
|
|
320
|
-
if self.renderer is None:
|
|
321
|
-
return
|
|
322
|
-
|
|
323
|
-
with wp.ScopedTimer("render"):
|
|
324
|
-
# draw trajectory
|
|
325
|
-
traj_verts = [np.mean(self.states[0].particle_q.numpy(), axis=0).tolist()]
|
|
326
|
-
for i in range(0, self.sim_steps, self.sim_substeps):
|
|
327
|
-
traj_verts.append(np.mean(self.states[i].particle_q.numpy(), axis=0).tolist())
|
|
328
|
-
|
|
329
|
-
self.renderer.begin_frame(self.render_time)
|
|
330
|
-
self.renderer.render(self.states[i])
|
|
331
|
-
self.renderer.render_box(
|
|
332
|
-
pos=self.target,
|
|
333
|
-
rot=wp.quat_identity(),
|
|
334
|
-
extents=(0.1, 0.1, 0.1),
|
|
335
|
-
name="target",
|
|
336
|
-
color=(0.0, 0.0, 0.0),
|
|
337
|
-
)
|
|
338
|
-
self.renderer.render_line_strip(
|
|
339
|
-
vertices=traj_verts,
|
|
340
|
-
color=wp.render.bourke_color_map(0.0, self.losses[0], self.losses[-1]),
|
|
341
|
-
radius=0.02,
|
|
342
|
-
name=f"traj_{self.iter - 1}",
|
|
343
|
-
)
|
|
344
|
-
self.renderer.end_frame()
|
|
345
|
-
|
|
346
|
-
from pxr import Gf, UsdGeom
|
|
347
|
-
|
|
348
|
-
particles_prim = self.renderer.stage.GetPrimAtPath("/root/particles")
|
|
349
|
-
particles = UsdGeom.Points.Get(self.renderer.stage, particles_prim.GetPath())
|
|
350
|
-
particles.CreateDisplayColorAttr().Set([Gf.Vec3f(1.0, 1.0, 1.0)], time=self.renderer.time)
|
|
351
|
-
|
|
352
|
-
self.render_time += self.frame_dt
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
if __name__ == "__main__":
|
|
356
|
-
import argparse
|
|
357
|
-
|
|
358
|
-
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
359
|
-
parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
|
|
360
|
-
parser.add_argument(
|
|
361
|
-
"--stage_path",
|
|
362
|
-
type=lambda x: None if x == "None" else str(x),
|
|
363
|
-
default="example_softbody_properties.usd",
|
|
364
|
-
help="Path to the output USD file.",
|
|
365
|
-
)
|
|
366
|
-
parser.add_argument(
|
|
367
|
-
"--train_iters",
|
|
368
|
-
type=int,
|
|
369
|
-
default=300,
|
|
370
|
-
help="Total number of training iterations.",
|
|
371
|
-
)
|
|
372
|
-
parser.add_argument(
|
|
373
|
-
"--material_behavior",
|
|
374
|
-
default="anisotropic",
|
|
375
|
-
choices=["anisotropic", "isotropic"],
|
|
376
|
-
help="Set material behavior to be Anisotropic or Isotropic.",
|
|
377
|
-
)
|
|
378
|
-
parser.add_argument(
|
|
379
|
-
"--verbose",
|
|
380
|
-
action="store_true",
|
|
381
|
-
help="Print out additional status messages during execution.",
|
|
382
|
-
)
|
|
383
|
-
|
|
384
|
-
args = parser.parse_known_args()[0]
|
|
385
|
-
|
|
386
|
-
with wp.ScopedDevice(args.device):
|
|
387
|
-
example = Example(
|
|
388
|
-
stage_path=args.stage_path,
|
|
389
|
-
material_behavior=args.material_behavior,
|
|
390
|
-
verbose=args.verbose,
|
|
391
|
-
)
|
|
392
|
-
|
|
393
|
-
# replay and optimize
|
|
394
|
-
for i in range(args.train_iters):
|
|
395
|
-
example.step()
|
|
396
|
-
if i == 0 or i % 50 == 0 or i == args.train_iters - 1:
|
|
397
|
-
example.render()
|
|
398
|
-
|
|
399
|
-
if example.renderer:
|
|
400
|
-
example.renderer.save()
|
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
-
# SPDX-License-Identifier: Apache-2.0
|
|
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
|
-
# Example Diff Sim Spring Cage
|
|
18
|
-
#
|
|
19
|
-
# A single particle is attached with springs to each point of a cage.
|
|
20
|
-
# The objective is to optimize the rest length of the springs in order
|
|
21
|
-
# for the particle to be pulled towards a target position.
|
|
22
|
-
#
|
|
23
|
-
###########################################################################
|
|
24
|
-
|
|
25
|
-
import numpy as np
|
|
26
|
-
|
|
27
|
-
import warp as wp
|
|
28
|
-
import warp.sim
|
|
29
|
-
import warp.sim.render
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
@wp.kernel
|
|
33
|
-
def compute_loss_kernel(
|
|
34
|
-
pos: wp.array(dtype=wp.vec3),
|
|
35
|
-
target_pos: wp.vec3,
|
|
36
|
-
loss: wp.array(dtype=float),
|
|
37
|
-
):
|
|
38
|
-
loss[0] = wp.length_sq(pos[0] - target_pos)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
@wp.kernel(enable_backward=False)
|
|
42
|
-
def apply_gradient_kernel(
|
|
43
|
-
spring_rest_lengths_grad: wp.array(dtype=float),
|
|
44
|
-
train_rate: float,
|
|
45
|
-
spring_rest_lengths: wp.array(dtype=float),
|
|
46
|
-
):
|
|
47
|
-
tid = wp.tid()
|
|
48
|
-
|
|
49
|
-
spring_rest_lengths[tid] -= spring_rest_lengths_grad[tid] * train_rate
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
class Example:
|
|
53
|
-
def __init__(self, stage_path="example_spring_cage.usd", num_frames=30, train_iters=25):
|
|
54
|
-
# Number of frames per second.
|
|
55
|
-
self.fps = 30
|
|
56
|
-
|
|
57
|
-
# Duration of a single simulation iteration in number of frames.
|
|
58
|
-
self.num_frames = num_frames
|
|
59
|
-
|
|
60
|
-
# Number of simulation steps to take per frame.
|
|
61
|
-
self.sim_substep_count = 1
|
|
62
|
-
|
|
63
|
-
# Delta time between each simulation substep.
|
|
64
|
-
self.sim_dt = 1.0 / (self.fps * self.sim_substep_count)
|
|
65
|
-
|
|
66
|
-
# Target position that we want the main particle to reach by optimising
|
|
67
|
-
# the rest lengths of the springs.
|
|
68
|
-
self.target_pos = (0.125, 0.25, 0.375)
|
|
69
|
-
|
|
70
|
-
# Number of training iterations.
|
|
71
|
-
self.train_iters = train_iters
|
|
72
|
-
|
|
73
|
-
# Factor by which the rest lengths of the springs are adjusted after each
|
|
74
|
-
# iteration, relatively to the corresponding gradients. Lower values
|
|
75
|
-
# converge more slowly but have less chances to miss the local minimum.
|
|
76
|
-
self.train_rate = 0.5
|
|
77
|
-
|
|
78
|
-
# Initialize the helper to build a physics scene.
|
|
79
|
-
builder = wp.sim.ModelBuilder()
|
|
80
|
-
|
|
81
|
-
# Define the main particle at the origin.
|
|
82
|
-
particle_mass = 1.0
|
|
83
|
-
builder.add_particle((0.0, 0.0, 0.0), (0.0, 0.0, 0.0), particle_mass)
|
|
84
|
-
|
|
85
|
-
# Define the cage made of points that will be pulling our main particle
|
|
86
|
-
# using springs.
|
|
87
|
-
# fmt: off
|
|
88
|
-
builder.add_particle((-0.7, 0.8, 0.2), (0.0, 0.0, 0.0), 0.0)
|
|
89
|
-
builder.add_particle(( 0.0, 0.2, 1.1), (0.0, 0.0, 0.0), 0.0)
|
|
90
|
-
builder.add_particle(( 0.1, 0.1, -1.2), (0.0, 0.0, 0.0), 0.0)
|
|
91
|
-
builder.add_particle(( 0.6, 0.4, 0.4), (0.0, 0.0, 0.0), 0.0)
|
|
92
|
-
builder.add_particle(( 0.7, -0.9, -0.2), (0.0, 0.0, 0.0), 0.0)
|
|
93
|
-
builder.add_particle((-0.8, -0.8, 0.1), (0.0, 0.0, 0.0), 0.0)
|
|
94
|
-
builder.add_particle((-0.9, 0.2, -0.8), (0.0, 0.0, 0.0), 0.0)
|
|
95
|
-
builder.add_particle(( 1.0, 0.4, -0.1), (0.0, 0.0, 0.0), 0.0)
|
|
96
|
-
# fmt: on
|
|
97
|
-
|
|
98
|
-
# Define the spring constraints between the main particle and the cage points.
|
|
99
|
-
spring_elastic_stiffness = 100.0
|
|
100
|
-
spring_elastic_damping = 10.0
|
|
101
|
-
for i in range(1, builder.particle_count):
|
|
102
|
-
builder.add_spring(0, i, spring_elastic_stiffness, spring_elastic_damping, 0)
|
|
103
|
-
|
|
104
|
-
# Build the model and set-up its properties.
|
|
105
|
-
self.model = builder.finalize(requires_grad=True)
|
|
106
|
-
self.model.gravity = np.array((0.0, 0.0, 0.0))
|
|
107
|
-
self.model.ground = False
|
|
108
|
-
|
|
109
|
-
# Use the Euler integrator for stepping through the simulation.
|
|
110
|
-
self.integrator = wp.sim.SemiImplicitIntegrator()
|
|
111
|
-
|
|
112
|
-
# Initialize a state for each simulation step.
|
|
113
|
-
self.states = tuple(self.model.state() for _ in range(self.num_frames * self.sim_substep_count + 1))
|
|
114
|
-
|
|
115
|
-
# Initialize a loss value that will represent the distance of the main
|
|
116
|
-
# particle to the target position. It needs to be defined as an array
|
|
117
|
-
# so that it can be written out by a kernel.
|
|
118
|
-
self.loss = wp.zeros(1, dtype=float, requires_grad=True)
|
|
119
|
-
|
|
120
|
-
if stage_path:
|
|
121
|
-
# Helper to render the physics scene as a USD file.
|
|
122
|
-
self.renderer = warp.sim.render.SimRenderer(self.model, stage_path, fps=self.fps, scaling=10.0)
|
|
123
|
-
|
|
124
|
-
# Allows rendering one simulation to USD every N training iterations.
|
|
125
|
-
self.render_iteration_steps = 2
|
|
126
|
-
|
|
127
|
-
# Frame number used to render the simulation iterations onto the USD file.
|
|
128
|
-
self.render_frame = 0
|
|
129
|
-
else:
|
|
130
|
-
self.renderer = None
|
|
131
|
-
|
|
132
|
-
self.use_cuda_graph = wp.get_device().is_cuda
|
|
133
|
-
if self.use_cuda_graph:
|
|
134
|
-
# Capture all the kernel launches into a CUDA graph so that they can
|
|
135
|
-
# all be run in a single graph launch, which helps with performance.
|
|
136
|
-
with wp.ScopedCapture() as capture:
|
|
137
|
-
self.tape = wp.Tape()
|
|
138
|
-
with self.tape:
|
|
139
|
-
self.forward()
|
|
140
|
-
self.tape.backward(loss=self.loss)
|
|
141
|
-
self.graph = capture.graph
|
|
142
|
-
|
|
143
|
-
def forward(self):
|
|
144
|
-
for i in range(1, len(self.states)):
|
|
145
|
-
prev = self.states[i - 1]
|
|
146
|
-
curr = self.states[i]
|
|
147
|
-
prev.clear_forces()
|
|
148
|
-
self.integrator.simulate(
|
|
149
|
-
self.model,
|
|
150
|
-
prev,
|
|
151
|
-
curr,
|
|
152
|
-
self.sim_dt,
|
|
153
|
-
)
|
|
154
|
-
|
|
155
|
-
last_state = self.states[-1]
|
|
156
|
-
wp.launch(
|
|
157
|
-
compute_loss_kernel,
|
|
158
|
-
dim=1,
|
|
159
|
-
inputs=(
|
|
160
|
-
last_state.particle_q,
|
|
161
|
-
self.target_pos,
|
|
162
|
-
),
|
|
163
|
-
outputs=(self.loss,),
|
|
164
|
-
)
|
|
165
|
-
|
|
166
|
-
def step(self):
|
|
167
|
-
with wp.ScopedTimer("step"):
|
|
168
|
-
if self.use_cuda_graph:
|
|
169
|
-
wp.capture_launch(self.graph)
|
|
170
|
-
else:
|
|
171
|
-
self.tape = wp.Tape()
|
|
172
|
-
with self.tape:
|
|
173
|
-
self.forward()
|
|
174
|
-
self.tape.backward(loss=self.loss)
|
|
175
|
-
|
|
176
|
-
wp.launch(
|
|
177
|
-
apply_gradient_kernel,
|
|
178
|
-
dim=self.model.spring_count,
|
|
179
|
-
inputs=(
|
|
180
|
-
self.model.spring_rest_length.grad,
|
|
181
|
-
self.train_rate,
|
|
182
|
-
),
|
|
183
|
-
outputs=(self.model.spring_rest_length,),
|
|
184
|
-
)
|
|
185
|
-
|
|
186
|
-
self.tape.zero()
|
|
187
|
-
|
|
188
|
-
def render(self):
|
|
189
|
-
if self.renderer is None:
|
|
190
|
-
return
|
|
191
|
-
|
|
192
|
-
with wp.ScopedTimer("render"):
|
|
193
|
-
self.renderer.begin_frame(0.0)
|
|
194
|
-
self.renderer.render_box(
|
|
195
|
-
name="target",
|
|
196
|
-
pos=self.target_pos,
|
|
197
|
-
rot=wp.quat_identity(),
|
|
198
|
-
extents=(0.1, 0.1, 0.1),
|
|
199
|
-
color=(1.0, 0.0, 0.0),
|
|
200
|
-
)
|
|
201
|
-
self.renderer.end_frame()
|
|
202
|
-
|
|
203
|
-
for frame in range(self.num_frames):
|
|
204
|
-
self.renderer.begin_frame(self.render_frame / self.fps)
|
|
205
|
-
self.renderer.render(self.states[frame * self.sim_substep_count])
|
|
206
|
-
self.renderer.end_frame()
|
|
207
|
-
|
|
208
|
-
self.render_frame += 1
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
if __name__ == "__main__":
|
|
212
|
-
import argparse
|
|
213
|
-
|
|
214
|
-
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
215
|
-
parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
|
|
216
|
-
parser.add_argument(
|
|
217
|
-
"--stage_path",
|
|
218
|
-
type=lambda x: None if x == "None" else str(x),
|
|
219
|
-
default="example_spring_cage.usd",
|
|
220
|
-
help="Path to the output USD file.",
|
|
221
|
-
)
|
|
222
|
-
parser.add_argument("--num_frames", type=int, default=30, help="Total number of frames per training iteration.")
|
|
223
|
-
parser.add_argument("--train_iters", type=int, default=25, help="Total number of training iterations.")
|
|
224
|
-
parser.add_argument("--verbose", action="store_true", help="Print out additional status messages during execution.")
|
|
225
|
-
|
|
226
|
-
args = parser.parse_known_args()[0]
|
|
227
|
-
|
|
228
|
-
with wp.ScopedDevice(args.device):
|
|
229
|
-
example = Example(stage_path=args.stage_path, num_frames=args.num_frames, train_iters=args.train_iters)
|
|
230
|
-
|
|
231
|
-
for iteration in range(args.train_iters):
|
|
232
|
-
example.step()
|
|
233
|
-
|
|
234
|
-
loss = example.loss.numpy()[0]
|
|
235
|
-
|
|
236
|
-
if args.verbose:
|
|
237
|
-
print(f"[{iteration:3d}] loss={loss:.8f}")
|
|
238
|
-
|
|
239
|
-
if example.renderer and (
|
|
240
|
-
iteration == example.train_iters - 1 or iteration % example.render_iteration_steps == 0
|
|
241
|
-
):
|
|
242
|
-
example.render()
|
|
243
|
-
|
|
244
|
-
if example.renderer:
|
|
245
|
-
example.renderer.save()
|