warp-lang 1.5.1__py3-none-win_amd64.whl → 1.6.1__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 +5 -0
- warp/autograd.py +414 -191
- warp/bin/warp-clang.dll +0 -0
- warp/bin/warp.dll +0 -0
- warp/build.py +40 -12
- warp/build_dll.py +13 -6
- warp/builtins.py +1077 -481
- warp/codegen.py +250 -122
- warp/config.py +65 -21
- warp/context.py +500 -149
- warp/examples/assets/square_cloth.usd +0 -0
- warp/examples/benchmarks/benchmark_gemm.py +27 -18
- warp/examples/benchmarks/benchmark_interop_paddle.py +3 -3
- warp/examples/benchmarks/benchmark_interop_torch.py +3 -3
- warp/examples/core/example_marching_cubes.py +1 -1
- warp/examples/core/example_mesh.py +1 -1
- warp/examples/core/example_torch.py +18 -34
- warp/examples/core/example_wave.py +1 -1
- warp/examples/fem/example_apic_fluid.py +1 -0
- warp/examples/fem/example_mixed_elasticity.py +1 -1
- warp/examples/optim/example_bounce.py +1 -1
- warp/examples/optim/example_cloth_throw.py +1 -1
- warp/examples/optim/example_diffray.py +4 -15
- warp/examples/optim/example_drone.py +1 -1
- warp/examples/optim/example_softbody_properties.py +392 -0
- warp/examples/optim/example_trajectory.py +1 -3
- warp/examples/optim/example_walker.py +5 -0
- warp/examples/sim/example_cartpole.py +0 -2
- warp/examples/sim/example_cloth_self_contact.py +314 -0
- warp/examples/sim/example_granular_collision_sdf.py +4 -5
- warp/examples/sim/example_jacobian_ik.py +0 -2
- warp/examples/sim/example_quadruped.py +5 -2
- warp/examples/tile/example_tile_cholesky.py +79 -0
- warp/examples/tile/example_tile_convolution.py +2 -2
- warp/examples/tile/example_tile_fft.py +2 -2
- warp/examples/tile/example_tile_filtering.py +3 -3
- warp/examples/tile/example_tile_matmul.py +4 -4
- warp/examples/tile/example_tile_mlp.py +12 -12
- warp/examples/tile/example_tile_nbody.py +191 -0
- warp/examples/tile/example_tile_walker.py +319 -0
- warp/math.py +147 -0
- warp/native/array.h +12 -0
- warp/native/builtin.h +0 -1
- warp/native/bvh.cpp +149 -70
- warp/native/bvh.cu +287 -68
- warp/native/bvh.h +195 -85
- warp/native/clang/clang.cpp +6 -2
- warp/native/crt.h +1 -0
- warp/native/cuda_util.cpp +35 -0
- warp/native/cuda_util.h +5 -0
- warp/native/exports.h +40 -40
- warp/native/intersect.h +17 -0
- warp/native/mat.h +57 -3
- warp/native/mathdx.cpp +19 -0
- warp/native/mesh.cpp +25 -8
- warp/native/mesh.cu +153 -101
- warp/native/mesh.h +482 -403
- warp/native/quat.h +40 -0
- warp/native/solid_angle.h +7 -0
- warp/native/sort.cpp +85 -0
- warp/native/sort.cu +34 -0
- warp/native/sort.h +3 -1
- warp/native/spatial.h +11 -0
- warp/native/tile.h +1189 -664
- warp/native/tile_reduce.h +8 -6
- warp/native/vec.h +41 -0
- warp/native/warp.cpp +8 -1
- warp/native/warp.cu +263 -40
- warp/native/warp.h +19 -5
- warp/optim/linear.py +22 -4
- warp/render/render_opengl.py +132 -59
- warp/render/render_usd.py +10 -2
- warp/sim/__init__.py +6 -1
- warp/sim/collide.py +289 -32
- warp/sim/import_urdf.py +20 -5
- warp/sim/integrator_euler.py +25 -7
- warp/sim/integrator_featherstone.py +147 -35
- warp/sim/integrator_vbd.py +842 -40
- warp/sim/model.py +173 -112
- warp/sim/render.py +2 -2
- warp/stubs.py +249 -116
- warp/tape.py +28 -30
- warp/tests/aux_test_module_unload.py +15 -0
- warp/tests/{test_sim_grad.py → flaky_test_sim_grad.py} +104 -63
- warp/tests/test_array.py +100 -0
- warp/tests/test_assert.py +242 -0
- warp/tests/test_codegen.py +14 -61
- warp/tests/test_collision.py +8 -8
- warp/tests/test_examples.py +16 -1
- warp/tests/test_grad_debug.py +87 -2
- warp/tests/test_hash_grid.py +1 -1
- warp/tests/test_ipc.py +116 -0
- warp/tests/test_launch.py +77 -26
- warp/tests/test_mat.py +213 -168
- warp/tests/test_math.py +47 -1
- warp/tests/test_matmul.py +11 -7
- warp/tests/test_matmul_lite.py +4 -4
- warp/tests/test_mesh.py +84 -60
- warp/tests/test_mesh_query_aabb.py +165 -0
- warp/tests/test_mesh_query_point.py +328 -286
- warp/tests/test_mesh_query_ray.py +134 -121
- warp/tests/test_mlp.py +2 -2
- warp/tests/test_operators.py +43 -0
- warp/tests/test_overwrite.py +6 -5
- warp/tests/test_quat.py +77 -0
- warp/tests/test_reload.py +29 -0
- warp/tests/test_sim_grad_bounce_linear.py +204 -0
- warp/tests/test_static.py +16 -0
- warp/tests/test_tape.py +25 -0
- warp/tests/test_tile.py +134 -191
- warp/tests/test_tile_load.py +399 -0
- warp/tests/test_tile_mathdx.py +61 -8
- warp/tests/test_tile_mlp.py +17 -17
- warp/tests/test_tile_reduce.py +24 -18
- warp/tests/test_tile_shared_memory.py +66 -17
- warp/tests/test_tile_view.py +165 -0
- warp/tests/test_torch.py +35 -0
- warp/tests/test_utils.py +36 -24
- warp/tests/test_vec.py +110 -0
- warp/tests/unittest_suites.py +29 -4
- warp/tests/unittest_utils.py +30 -11
- warp/thirdparty/unittest_parallel.py +5 -2
- warp/types.py +419 -111
- warp/utils.py +9 -5
- {warp_lang-1.5.1.dist-info → warp_lang-1.6.1.dist-info}/METADATA +86 -45
- {warp_lang-1.5.1.dist-info → warp_lang-1.6.1.dist-info}/RECORD +129 -118
- {warp_lang-1.5.1.dist-info → warp_lang-1.6.1.dist-info}/WHEEL +1 -1
- warp/examples/benchmarks/benchmark_tile.py +0 -179
- warp/native/tile_gemm.h +0 -341
- {warp_lang-1.5.1.dist-info → warp_lang-1.6.1.dist-info}/LICENSE.md +0 -0
- {warp_lang-1.5.1.dist-info → warp_lang-1.6.1.dist-info}/top_level.txt +0 -0
warp/sim/model.py
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
"""A module for building simulation models and state."""
|
|
9
9
|
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
10
12
|
import copy
|
|
11
13
|
import math
|
|
12
14
|
from typing import List, Optional, Tuple
|
|
@@ -262,47 +264,51 @@ class Mesh:
|
|
|
262
264
|
|
|
263
265
|
|
|
264
266
|
class State:
|
|
265
|
-
"""
|
|
267
|
+
"""Time-varying state data for a :class:`Model`.
|
|
266
268
|
|
|
267
|
-
Time-varying data includes particle positions, velocities, rigid body states, and
|
|
269
|
+
Time-varying state data includes particle positions, velocities, rigid body states, and
|
|
268
270
|
anything that is output from the integrator as derived data, e.g.: forces.
|
|
269
271
|
|
|
270
272
|
The exact attributes depend on the contents of the model. State objects should
|
|
271
273
|
generally be created using the :func:`Model.state()` function.
|
|
274
|
+
"""
|
|
272
275
|
|
|
273
|
-
|
|
276
|
+
def __init__(self):
|
|
277
|
+
self.particle_q: Optional[wp.array] = None
|
|
278
|
+
"""Array of 3D particle positions with shape ``(particle_count,)`` and type :class:`vec3`."""
|
|
274
279
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
particle_f (array): Array of 3D particle forces, shape [particle_count], :class:`vec3`
|
|
280
|
+
self.particle_qd: Optional[wp.array] = None
|
|
281
|
+
"""Array of 3D particle velocities with shape ``(particle_count,)`` and type :class:`vec3`."""
|
|
278
282
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
body_f (array): Array of body forces in maximal coordinates (first 3 entries represent torque, last 3 entries represent linear force), shape [body_count], :class:`spatial_vector`
|
|
283
|
+
self.particle_f: Optional[wp.array] = None
|
|
284
|
+
"""Array of 3D particle forces with shape ``(particle_count,)`` and type :class:`vec3`."""
|
|
282
285
|
|
|
283
|
-
|
|
286
|
+
self.body_q: Optional[wp.array] = None
|
|
287
|
+
"""Array of body coordinates (7-dof transforms) in maximal coordinates with shape ``(body_count,)`` and type :class:`transform`."""
|
|
284
288
|
|
|
285
|
-
|
|
289
|
+
self.body_qd: Optional[wp.array] = None
|
|
290
|
+
"""Array of body velocities in maximal coordinates (first three entries represent angular velocity,
|
|
291
|
+
last three entries represent linear velocity) with shape ``(body_count,)`` and type :class:`spatial_vector`.
|
|
292
|
+
"""
|
|
286
293
|
|
|
287
|
-
|
|
288
|
-
|
|
294
|
+
self.body_f: Optional[wp.array] = None
|
|
295
|
+
"""Array of body forces in maximal coordinates (first three entries represent torque, last three
|
|
296
|
+
entries represent linear force) with shape ``(body_count,)`` and type :class:`spatial_vector`.
|
|
289
297
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
self.particle_f = None
|
|
298
|
+
.. note::
|
|
299
|
+
:attr:`body_f` represents external wrenches in world frame and denotes wrenches measured w.r.t.
|
|
300
|
+
to the body's center of mass for all integrators except :class:`FeatherstoneIntegrator`, which
|
|
301
|
+
assumes the wrenches are measured w.r.t. world origin.
|
|
302
|
+
"""
|
|
296
303
|
|
|
297
|
-
self.
|
|
298
|
-
|
|
299
|
-
self.body_f = None
|
|
304
|
+
self.joint_q: Optional[wp.array] = None
|
|
305
|
+
"""Array of generalized joint coordinates with shape ``(joint_coord_count,)`` and type ``float``."""
|
|
300
306
|
|
|
301
|
-
self.
|
|
302
|
-
|
|
307
|
+
self.joint_qd: Optional[wp.array] = None
|
|
308
|
+
"""Array of generalized joint velocities with shape ``(joint_dof_count,)`` and type ``float``."""
|
|
303
309
|
|
|
304
|
-
def clear_forces(self):
|
|
305
|
-
"""
|
|
310
|
+
def clear_forces(self) -> None:
|
|
311
|
+
"""Clear all forces (for particles and bodies) in the state object."""
|
|
306
312
|
with wp.ScopedTimer("clear_forces", False):
|
|
307
313
|
if self.particle_count:
|
|
308
314
|
self.particle_f.zero_()
|
|
@@ -311,7 +317,7 @@ class State:
|
|
|
311
317
|
self.body_f.zero_()
|
|
312
318
|
|
|
313
319
|
@property
|
|
314
|
-
def requires_grad(self):
|
|
320
|
+
def requires_grad(self) -> bool:
|
|
315
321
|
"""Indicates whether the state arrays have gradient computation enabled."""
|
|
316
322
|
if self.particle_q:
|
|
317
323
|
return self.particle_q.requires_grad
|
|
@@ -320,28 +326,28 @@ class State:
|
|
|
320
326
|
return False
|
|
321
327
|
|
|
322
328
|
@property
|
|
323
|
-
def body_count(self):
|
|
329
|
+
def body_count(self) -> int:
|
|
324
330
|
"""The number of bodies represented in the state."""
|
|
325
331
|
if self.body_q is None:
|
|
326
332
|
return 0
|
|
327
333
|
return len(self.body_q)
|
|
328
334
|
|
|
329
335
|
@property
|
|
330
|
-
def particle_count(self):
|
|
336
|
+
def particle_count(self) -> int:
|
|
331
337
|
"""The number of particles represented in the state."""
|
|
332
338
|
if self.particle_q is None:
|
|
333
339
|
return 0
|
|
334
340
|
return len(self.particle_q)
|
|
335
341
|
|
|
336
342
|
@property
|
|
337
|
-
def joint_coord_count(self):
|
|
343
|
+
def joint_coord_count(self) -> int:
|
|
338
344
|
"""The number of generalized joint position coordinates represented in the state."""
|
|
339
345
|
if self.joint_q is None:
|
|
340
346
|
return 0
|
|
341
347
|
return len(self.joint_q)
|
|
342
348
|
|
|
343
349
|
@property
|
|
344
|
-
def joint_dof_count(self):
|
|
350
|
+
def joint_dof_count(self) -> int:
|
|
345
351
|
"""The number of generalized joint velocity coordinates represented in the state."""
|
|
346
352
|
if self.joint_qd is None:
|
|
347
353
|
return 0
|
|
@@ -349,37 +355,34 @@ class State:
|
|
|
349
355
|
|
|
350
356
|
|
|
351
357
|
class Control:
|
|
358
|
+
"""Time-varying control data for a :class:`Model`.
|
|
359
|
+
|
|
360
|
+
Time-varying control data includes joint control inputs, muscle activations,
|
|
361
|
+
and activation forces for triangle and tetrahedral elements.
|
|
362
|
+
|
|
363
|
+
The exact attributes depend on the contents of the model. Control objects
|
|
364
|
+
should generally be created using the :func:`Model.control()` function.
|
|
352
365
|
"""
|
|
353
|
-
The Control object holds all *time-varying* control data for a model.
|
|
354
366
|
|
|
355
|
-
|
|
367
|
+
def __init__(self, model: Model):
|
|
368
|
+
self.model: Model = model
|
|
369
|
+
"""Model to use as a reference for the control inputs."""
|
|
356
370
|
|
|
357
|
-
|
|
371
|
+
self.joint_act: Optional[wp.array] = None
|
|
372
|
+
"""Array of joint control inputs with shape ``(joint_axis_count,)`` and type ``float``."""
|
|
358
373
|
|
|
359
|
-
|
|
374
|
+
self.tri_activations: Optional[wp.array] = None
|
|
375
|
+
"""Array of triangle element activations with shape ``(tri_count,)`` and type ``float``."""
|
|
360
376
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
tet_activations (array): Array of tetrahedral element activations, shape [tet_count], float
|
|
364
|
-
muscle_activations (array): Array of muscle activations, shape [muscle_count], float
|
|
377
|
+
self.tet_activations: Optional[wp.array] = None
|
|
378
|
+
"""Array of tetrahedral element activations with shape with shape ``(tet_count,) and type ``float``."""
|
|
365
379
|
|
|
366
|
-
|
|
380
|
+
self.muscle_activations: Optional[wp.array] = None
|
|
381
|
+
"""Array of muscle activations with shape ``(muscle_count,)`` and type ``float``."""
|
|
367
382
|
|
|
368
|
-
def
|
|
369
|
-
"""
|
|
370
|
-
Args:
|
|
371
|
-
model (Model): The model to use as a reference for the control inputs
|
|
372
|
-
"""
|
|
373
|
-
self.model = model
|
|
374
|
-
self.joint_act = None
|
|
375
|
-
self.tri_activations = None
|
|
376
|
-
self.tet_activations = None
|
|
377
|
-
self.muscle_activations = None
|
|
383
|
+
def reset(self) -> None:
|
|
384
|
+
"""Reset the control inputs to their initial state defined in :attr:`model`."""
|
|
378
385
|
|
|
379
|
-
def reset(self):
|
|
380
|
-
"""
|
|
381
|
-
Resets the control inputs to their initial state defined in :class:`Model`.
|
|
382
|
-
"""
|
|
383
386
|
if self.joint_act is not None:
|
|
384
387
|
self.joint_act.assign(self.model.joint_act)
|
|
385
388
|
if self.tri_activations is not None:
|
|
@@ -591,6 +594,7 @@ class Model:
|
|
|
591
594
|
joint_attach_ke (float): Joint attachment force stiffness (used by :class:`SemiImplicitIntegrator`)
|
|
592
595
|
joint_attach_kd (float): Joint attachment force damping (used by :class:`SemiImplicitIntegrator`)
|
|
593
596
|
|
|
597
|
+
soft_contact_radius (float): Contact radius used for self-collisions in the VBD integrator.
|
|
594
598
|
soft_contact_margin (float): Contact margin for generation of soft contacts
|
|
595
599
|
soft_contact_ke (float): Stiffness of soft contacts (used by the Euler integrators)
|
|
596
600
|
soft_contact_kd (float): Damping of soft contacts (used by the Euler integrators)
|
|
@@ -761,6 +765,7 @@ class Model:
|
|
|
761
765
|
self.joint_attach_ke = 1.0e3
|
|
762
766
|
self.joint_attach_kd = 1.0e2
|
|
763
767
|
|
|
768
|
+
self.soft_contact_radius = 0.2
|
|
764
769
|
self.soft_contact_margin = 0.2
|
|
765
770
|
self.soft_contact_ke = 1.0e3
|
|
766
771
|
self.soft_contact_kd = 10.0
|
|
@@ -1046,6 +1051,8 @@ class Model:
|
|
|
1046
1051
|
@property
|
|
1047
1052
|
def soft_contact_max(self):
|
|
1048
1053
|
"""Maximum number of soft contacts that can be registered"""
|
|
1054
|
+
if self.soft_contact_particle is None:
|
|
1055
|
+
return 0
|
|
1049
1056
|
return len(self.soft_contact_particle)
|
|
1050
1057
|
|
|
1051
1058
|
|
|
@@ -1392,6 +1399,8 @@ class ModelBuilder:
|
|
|
1392
1399
|
# apply offset transform to root bodies
|
|
1393
1400
|
if xform is not None:
|
|
1394
1401
|
self.shape_transform.append(xform * builder.shape_transform[s])
|
|
1402
|
+
else:
|
|
1403
|
+
self.shape_transform.append(builder.shape_transform[s])
|
|
1395
1404
|
|
|
1396
1405
|
for b, shapes in builder.body_shapes.items():
|
|
1397
1406
|
self.body_shapes[b + start_body_idx] = [s + start_shape_idx for s in shapes]
|
|
@@ -1414,18 +1423,16 @@ class ModelBuilder:
|
|
|
1414
1423
|
|
|
1415
1424
|
# offset the indices
|
|
1416
1425
|
self.articulation_start.extend([a + self.joint_count for a in builder.articulation_start])
|
|
1417
|
-
self.joint_parent.extend([p + self.
|
|
1418
|
-
self.joint_child.extend([c + self.
|
|
1426
|
+
self.joint_parent.extend([p + self.body_count if p != -1 else -1 for p in builder.joint_parent])
|
|
1427
|
+
self.joint_child.extend([c + self.body_count for c in builder.joint_child])
|
|
1419
1428
|
|
|
1420
1429
|
self.joint_q_start.extend([c + self.joint_coord_count for c in builder.joint_q_start])
|
|
1421
1430
|
self.joint_qd_start.extend([c + self.joint_dof_count for c in builder.joint_qd_start])
|
|
1422
1431
|
|
|
1423
1432
|
self.joint_axis_start.extend([a + self.joint_axis_total_count for a in builder.joint_axis_start])
|
|
1424
1433
|
|
|
1425
|
-
joint_children = set(builder.joint_child)
|
|
1426
1434
|
for i in range(builder.body_count):
|
|
1427
|
-
if xform is not None
|
|
1428
|
-
# rigid body is not attached to a joint, so apply input transform directly
|
|
1435
|
+
if xform is not None:
|
|
1429
1436
|
self.body_q.append(xform * builder.body_q[i])
|
|
1430
1437
|
else:
|
|
1431
1438
|
self.body_q.append(builder.body_q[i])
|
|
@@ -1747,8 +1754,8 @@ class ModelBuilder:
|
|
|
1747
1754
|
mode: int = JOINT_MODE_FORCE,
|
|
1748
1755
|
limit_lower: float = -2 * math.pi,
|
|
1749
1756
|
limit_upper: float = 2 * math.pi,
|
|
1750
|
-
limit_ke: float =
|
|
1751
|
-
limit_kd: float =
|
|
1757
|
+
limit_ke: float = None,
|
|
1758
|
+
limit_kd: float = None,
|
|
1752
1759
|
linear_compliance: float = 0.0,
|
|
1753
1760
|
angular_compliance: float = 0.0,
|
|
1754
1761
|
armature: float = 1e-2,
|
|
@@ -1769,8 +1776,8 @@ class ModelBuilder:
|
|
|
1769
1776
|
target_kd: The damping of the joint target
|
|
1770
1777
|
limit_lower: The lower limit of the joint
|
|
1771
1778
|
limit_upper: The upper limit of the joint
|
|
1772
|
-
limit_ke: The stiffness of the joint limit
|
|
1773
|
-
limit_kd: The damping of the joint limit
|
|
1779
|
+
limit_ke: The stiffness of the joint limit (None to use the default value :attr:`default_joint_limit_ke`)
|
|
1780
|
+
limit_kd: The damping of the joint limit (None to use the default value :attr:`default_joint_limit_kd`)
|
|
1774
1781
|
linear_compliance: The linear compliance of the joint
|
|
1775
1782
|
angular_compliance: The angular compliance of the joint
|
|
1776
1783
|
armature: Artificial inertia added around the joint axis
|
|
@@ -1788,6 +1795,9 @@ class ModelBuilder:
|
|
|
1788
1795
|
if child_xform is None:
|
|
1789
1796
|
child_xform = wp.transform()
|
|
1790
1797
|
|
|
1798
|
+
limit_ke = limit_ke if limit_ke is not None else self.default_joint_limit_ke
|
|
1799
|
+
limit_kd = limit_kd if limit_kd is not None else self.default_joint_limit_kd
|
|
1800
|
+
|
|
1791
1801
|
action = 0.0
|
|
1792
1802
|
if target is None and mode == JOINT_MODE_TARGET_POSITION:
|
|
1793
1803
|
action = 0.5 * (limit_lower + limit_upper)
|
|
@@ -1834,8 +1844,8 @@ class ModelBuilder:
|
|
|
1834
1844
|
mode: int = JOINT_MODE_FORCE,
|
|
1835
1845
|
limit_lower: float = -1e4,
|
|
1836
1846
|
limit_upper: float = 1e4,
|
|
1837
|
-
limit_ke: float =
|
|
1838
|
-
limit_kd: float =
|
|
1847
|
+
limit_ke: float = None,
|
|
1848
|
+
limit_kd: float = None,
|
|
1839
1849
|
linear_compliance: float = 0.0,
|
|
1840
1850
|
angular_compliance: float = 0.0,
|
|
1841
1851
|
armature: float = 1e-2,
|
|
@@ -1856,8 +1866,8 @@ class ModelBuilder:
|
|
|
1856
1866
|
target_kd: The damping of the joint target
|
|
1857
1867
|
limit_lower: The lower limit of the joint
|
|
1858
1868
|
limit_upper: The upper limit of the joint
|
|
1859
|
-
limit_ke: The stiffness of the joint limit
|
|
1860
|
-
limit_kd: The damping of the joint limit
|
|
1869
|
+
limit_ke: The stiffness of the joint limit (None to use the default value :attr:`default_joint_limit_ke`)
|
|
1870
|
+
limit_kd: The damping of the joint limit (None to use the default value :attr:`default_joint_limit_ke`)
|
|
1861
1871
|
linear_compliance: The linear compliance of the joint
|
|
1862
1872
|
angular_compliance: The angular compliance of the joint
|
|
1863
1873
|
armature: Artificial inertia added around the joint axis
|
|
@@ -1875,6 +1885,9 @@ class ModelBuilder:
|
|
|
1875
1885
|
if child_xform is None:
|
|
1876
1886
|
child_xform = wp.transform()
|
|
1877
1887
|
|
|
1888
|
+
limit_ke = limit_ke if limit_ke is not None else self.default_joint_limit_ke
|
|
1889
|
+
limit_kd = limit_kd if limit_kd is not None else self.default_joint_limit_kd
|
|
1890
|
+
|
|
1878
1891
|
action = 0.0
|
|
1879
1892
|
if target is None and mode == JOINT_MODE_TARGET_POSITION:
|
|
1880
1893
|
action = 0.5 * (limit_lower + limit_upper)
|
|
@@ -2523,7 +2536,7 @@ class ModelBuilder:
|
|
|
2523
2536
|
last_dynamic_body_name = self.body_name[last_dynamic_body] if last_dynamic_body > -1 else "world"
|
|
2524
2537
|
if verbose:
|
|
2525
2538
|
print(
|
|
2526
|
-
f
|
|
2539
|
+
f"Remove fixed joint {joint['name']} between {parent_name} and {child_name}, "
|
|
2527
2540
|
f"merging {child_name} into {last_dynamic_body_name}"
|
|
2528
2541
|
)
|
|
2529
2542
|
child_id = body_data[child_body]["original_id"]
|
|
@@ -2775,7 +2788,7 @@ class ModelBuilder:
|
|
|
2775
2788
|
c = np.cross(normal, (0.0, 1.0, 0.0))
|
|
2776
2789
|
angle = np.arcsin(np.linalg.norm(c))
|
|
2777
2790
|
axis = np.abs(c) / np.linalg.norm(c)
|
|
2778
|
-
rot = wp.quat_from_axis_angle(axis, angle)
|
|
2791
|
+
rot = wp.quat_from_axis_angle(wp.vec3(*axis), wp.float32(angle))
|
|
2779
2792
|
scale = wp.vec3(width, length, 0.0)
|
|
2780
2793
|
|
|
2781
2794
|
return self._add_shape(
|
|
@@ -3501,11 +3514,11 @@ class ModelBuilder:
|
|
|
3501
3514
|
i: int,
|
|
3502
3515
|
j: int,
|
|
3503
3516
|
k: int,
|
|
3504
|
-
tri_ke: float =
|
|
3505
|
-
tri_ka: float =
|
|
3506
|
-
tri_kd: float =
|
|
3507
|
-
tri_drag: float =
|
|
3508
|
-
tri_lift: float =
|
|
3517
|
+
tri_ke: float = None,
|
|
3518
|
+
tri_ka: float = None,
|
|
3519
|
+
tri_kd: float = None,
|
|
3520
|
+
tri_drag: float = None,
|
|
3521
|
+
tri_lift: float = None,
|
|
3509
3522
|
) -> float:
|
|
3510
3523
|
"""Adds a triangular FEM element between three particles in the system.
|
|
3511
3524
|
|
|
@@ -3525,6 +3538,11 @@ class ModelBuilder:
|
|
|
3525
3538
|
between the particles in their initial configuration.
|
|
3526
3539
|
"""
|
|
3527
3540
|
# TODO: Expose elastic parameters on a per-element basis
|
|
3541
|
+
tri_ke = tri_ke if tri_ke is not None else self.default_tri_ke
|
|
3542
|
+
tri_ka = tri_ka if tri_ka is not None else self.default_tri_ka
|
|
3543
|
+
tri_kd = tri_kd if tri_kd is not None else self.default_tri_kd
|
|
3544
|
+
tri_drag = tri_drag if tri_drag is not None else self.default_tri_drag
|
|
3545
|
+
tri_lift = tri_lift if tri_lift is not None else self.default_tri_lift
|
|
3528
3546
|
|
|
3529
3547
|
# compute basis for 2D rest pose
|
|
3530
3548
|
p = self.particle_q[i]
|
|
@@ -3705,8 +3723,8 @@ class ModelBuilder:
|
|
|
3705
3723
|
k: int,
|
|
3706
3724
|
l: int,
|
|
3707
3725
|
rest: float = None,
|
|
3708
|
-
edge_ke: float =
|
|
3709
|
-
edge_kd: float =
|
|
3726
|
+
edge_ke: float = None,
|
|
3727
|
+
edge_kd: float = None,
|
|
3710
3728
|
):
|
|
3711
3729
|
"""Adds a bending edge element between four particles in the system.
|
|
3712
3730
|
|
|
@@ -3727,6 +3745,9 @@ class ModelBuilder:
|
|
|
3727
3745
|
winding: (i, k, l), (j, l, k).
|
|
3728
3746
|
|
|
3729
3747
|
"""
|
|
3748
|
+
edge_ke = edge_ke if edge_ke is not None else self.default_edge_ke
|
|
3749
|
+
edge_kd = edge_kd if edge_kd is not None else self.default_edge_kd
|
|
3750
|
+
|
|
3730
3751
|
# compute rest angle
|
|
3731
3752
|
if rest is None:
|
|
3732
3753
|
x1 = self.particle_q[i]
|
|
@@ -3834,17 +3855,17 @@ class ModelBuilder:
|
|
|
3834
3855
|
fix_right: bool = False,
|
|
3835
3856
|
fix_top: bool = False,
|
|
3836
3857
|
fix_bottom: bool = False,
|
|
3837
|
-
tri_ke: float =
|
|
3838
|
-
tri_ka: float =
|
|
3839
|
-
tri_kd: float =
|
|
3840
|
-
tri_drag: float =
|
|
3841
|
-
tri_lift: float =
|
|
3842
|
-
edge_ke: float =
|
|
3843
|
-
edge_kd: float =
|
|
3858
|
+
tri_ke: float = None,
|
|
3859
|
+
tri_ka: float = None,
|
|
3860
|
+
tri_kd: float = None,
|
|
3861
|
+
tri_drag: float = None,
|
|
3862
|
+
tri_lift: float = None,
|
|
3863
|
+
edge_ke: float = None,
|
|
3864
|
+
edge_kd: float = None,
|
|
3844
3865
|
add_springs: bool = False,
|
|
3845
|
-
spring_ke: float =
|
|
3846
|
-
spring_kd: float =
|
|
3847
|
-
particle_radius: float =
|
|
3866
|
+
spring_ke: float = None,
|
|
3867
|
+
spring_kd: float = None,
|
|
3868
|
+
particle_radius: float = None,
|
|
3848
3869
|
):
|
|
3849
3870
|
"""Helper to create a regular planar cloth grid
|
|
3850
3871
|
|
|
@@ -3866,6 +3887,16 @@ class ModelBuilder:
|
|
|
3866
3887
|
fix_top: Make the top-most edge of particles kinematic
|
|
3867
3888
|
fix_bottom: Make the bottom-most edge of particles kinematic
|
|
3868
3889
|
"""
|
|
3890
|
+
tri_ke = tri_ke if tri_ke is not None else self.default_tri_ke
|
|
3891
|
+
tri_ka = tri_ka if tri_ka is not None else self.default_tri_ka
|
|
3892
|
+
tri_kd = tri_kd if tri_kd is not None else self.default_tri_kd
|
|
3893
|
+
tri_drag = tri_drag if tri_drag is not None else self.default_tri_drag
|
|
3894
|
+
tri_lift = tri_lift if tri_lift is not None else self.default_tri_lift
|
|
3895
|
+
edge_ke = edge_ke if edge_ke is not None else self.default_edge_ke
|
|
3896
|
+
edge_kd = edge_kd if edge_kd is not None else self.default_edge_kd
|
|
3897
|
+
spring_ke = spring_ke if spring_ke is not None else self.default_spring_ke
|
|
3898
|
+
spring_kd = spring_kd if spring_kd is not None else self.default_spring_kd
|
|
3899
|
+
particle_radius = particle_radius if particle_radius is not None else self.default_particle_radius
|
|
3869
3900
|
|
|
3870
3901
|
def grid_index(x, y, dim_x):
|
|
3871
3902
|
return y * dim_x + x
|
|
@@ -3968,17 +3999,17 @@ class ModelBuilder:
|
|
|
3968
3999
|
density: float,
|
|
3969
4000
|
edge_callback=None,
|
|
3970
4001
|
face_callback=None,
|
|
3971
|
-
tri_ke: float =
|
|
3972
|
-
tri_ka: float =
|
|
3973
|
-
tri_kd: float =
|
|
3974
|
-
tri_drag: float =
|
|
3975
|
-
tri_lift: float =
|
|
3976
|
-
edge_ke: float =
|
|
3977
|
-
edge_kd: float =
|
|
4002
|
+
tri_ke: float = None,
|
|
4003
|
+
tri_ka: float = None,
|
|
4004
|
+
tri_kd: float = None,
|
|
4005
|
+
tri_drag: float = None,
|
|
4006
|
+
tri_lift: float = None,
|
|
4007
|
+
edge_ke: float = None,
|
|
4008
|
+
edge_kd: float = None,
|
|
3978
4009
|
add_springs: bool = False,
|
|
3979
|
-
spring_ke: float =
|
|
3980
|
-
spring_kd: float =
|
|
3981
|
-
particle_radius: float =
|
|
4010
|
+
spring_ke: float = None,
|
|
4011
|
+
spring_kd: float = None,
|
|
4012
|
+
particle_radius: float = None,
|
|
3982
4013
|
):
|
|
3983
4014
|
"""Helper to create a cloth model from a regular triangle mesh
|
|
3984
4015
|
|
|
@@ -3999,6 +4030,17 @@ class ModelBuilder:
|
|
|
3999
4030
|
|
|
4000
4031
|
The mesh should be two manifold.
|
|
4001
4032
|
"""
|
|
4033
|
+
tri_ke = tri_ke if tri_ke is not None else self.default_tri_ke
|
|
4034
|
+
tri_ka = tri_ka if tri_ka is not None else self.default_tri_ka
|
|
4035
|
+
tri_kd = tri_kd if tri_kd is not None else self.default_tri_kd
|
|
4036
|
+
tri_drag = tri_drag if tri_drag is not None else self.default_tri_drag
|
|
4037
|
+
tri_lift = tri_lift if tri_lift is not None else self.default_tri_lift
|
|
4038
|
+
edge_ke = edge_ke if edge_ke is not None else self.default_edge_ke
|
|
4039
|
+
edge_kd = edge_kd if edge_kd is not None else self.default_edge_kd
|
|
4040
|
+
spring_ke = spring_ke if spring_ke is not None else self.default_spring_ke
|
|
4041
|
+
spring_kd = spring_kd if spring_kd is not None else self.default_spring_kd
|
|
4042
|
+
particle_radius = particle_radius if particle_radius is not None else self.default_particle_radius
|
|
4043
|
+
|
|
4002
4044
|
num_tris = int(len(indices) / 3)
|
|
4003
4045
|
|
|
4004
4046
|
start_vertex = len(self.particle_q)
|
|
@@ -4076,9 +4118,11 @@ class ModelBuilder:
|
|
|
4076
4118
|
cell_z: float,
|
|
4077
4119
|
mass: float,
|
|
4078
4120
|
jitter: float,
|
|
4079
|
-
radius_mean: float =
|
|
4121
|
+
radius_mean: float = None,
|
|
4080
4122
|
radius_std: float = 0.0,
|
|
4081
4123
|
):
|
|
4124
|
+
radius_mean = radius_mean if radius_mean is not None else self.default_particle_radius
|
|
4125
|
+
|
|
4082
4126
|
rng = np.random.default_rng(42)
|
|
4083
4127
|
for z in range(dim_z):
|
|
4084
4128
|
for y in range(dim_y):
|
|
@@ -4113,11 +4157,11 @@ class ModelBuilder:
|
|
|
4113
4157
|
fix_right: bool = False,
|
|
4114
4158
|
fix_top: bool = False,
|
|
4115
4159
|
fix_bottom: bool = False,
|
|
4116
|
-
tri_ke: float =
|
|
4117
|
-
tri_ka: float =
|
|
4118
|
-
tri_kd: float =
|
|
4119
|
-
tri_drag: float =
|
|
4120
|
-
tri_lift: float =
|
|
4160
|
+
tri_ke: float = None,
|
|
4161
|
+
tri_ka: float = None,
|
|
4162
|
+
tri_kd: float = None,
|
|
4163
|
+
tri_drag: float = None,
|
|
4164
|
+
tri_lift: float = None,
|
|
4121
4165
|
):
|
|
4122
4166
|
"""Helper to create a rectangular tetrahedral FEM grid
|
|
4123
4167
|
|
|
@@ -4144,6 +4188,11 @@ class ModelBuilder:
|
|
|
4144
4188
|
fix_top: Make the top-most edge of particles kinematic
|
|
4145
4189
|
fix_bottom: Make the bottom-most edge of particles kinematic
|
|
4146
4190
|
"""
|
|
4191
|
+
tri_ke = tri_ke if tri_ke is not None else self.default_tri_ke
|
|
4192
|
+
tri_ka = tri_ka if tri_ka is not None else self.default_tri_ka
|
|
4193
|
+
tri_kd = tri_kd if tri_kd is not None else self.default_tri_kd
|
|
4194
|
+
tri_drag = tri_drag if tri_drag is not None else self.default_tri_drag
|
|
4195
|
+
tri_lift = tri_lift if tri_lift is not None else self.default_tri_lift
|
|
4147
4196
|
|
|
4148
4197
|
start_vertex = len(self.particle_q)
|
|
4149
4198
|
|
|
@@ -4235,11 +4284,11 @@ class ModelBuilder:
|
|
|
4235
4284
|
k_mu: float,
|
|
4236
4285
|
k_lambda: float,
|
|
4237
4286
|
k_damp: float,
|
|
4238
|
-
tri_ke: float =
|
|
4239
|
-
tri_ka: float =
|
|
4240
|
-
tri_kd: float =
|
|
4241
|
-
tri_drag: float =
|
|
4242
|
-
tri_lift: float =
|
|
4287
|
+
tri_ke: float = None,
|
|
4288
|
+
tri_ka: float = None,
|
|
4289
|
+
tri_kd: float = None,
|
|
4290
|
+
tri_drag: float = None,
|
|
4291
|
+
tri_lift: float = None,
|
|
4243
4292
|
):
|
|
4244
4293
|
"""Helper to create a tetrahedral model from an input tetrahedral mesh
|
|
4245
4294
|
|
|
@@ -4254,6 +4303,12 @@ class ModelBuilder:
|
|
|
4254
4303
|
k_lambda: The second elastic Lame parameter
|
|
4255
4304
|
k_damp: The damping stiffness
|
|
4256
4305
|
"""
|
|
4306
|
+
tri_ke = tri_ke if tri_ke is not None else self.default_tri_ke
|
|
4307
|
+
tri_ka = tri_ka if tri_ka is not None else self.default_tri_ka
|
|
4308
|
+
tri_kd = tri_kd if tri_kd is not None else self.default_tri_kd
|
|
4309
|
+
tri_drag = tri_drag if tri_drag is not None else self.default_tri_drag
|
|
4310
|
+
tri_lift = tri_lift if tri_lift is not None else self.default_tri_lift
|
|
4311
|
+
|
|
4257
4312
|
num_tets = int(len(indices) / 4)
|
|
4258
4313
|
|
|
4259
4314
|
start_vertex = len(self.particle_q)
|
|
@@ -4344,16 +4399,22 @@ class ModelBuilder:
|
|
|
4344
4399
|
self,
|
|
4345
4400
|
normal=None,
|
|
4346
4401
|
offset=0.0,
|
|
4347
|
-
ke: float =
|
|
4348
|
-
kd: float =
|
|
4349
|
-
kf: float =
|
|
4350
|
-
mu: float =
|
|
4351
|
-
restitution: float =
|
|
4402
|
+
ke: float = None,
|
|
4403
|
+
kd: float = None,
|
|
4404
|
+
kf: float = None,
|
|
4405
|
+
mu: float = None,
|
|
4406
|
+
restitution: float = None,
|
|
4352
4407
|
):
|
|
4353
4408
|
"""
|
|
4354
4409
|
Creates a ground plane for the world. If the normal is not specified,
|
|
4355
4410
|
the up_vector of the ModelBuilder is used.
|
|
4356
4411
|
"""
|
|
4412
|
+
ke = ke if ke is not None else self.default_shape_ke
|
|
4413
|
+
kd = kd if kd is not None else self.default_shape_kd
|
|
4414
|
+
kf = kf if kf is not None else self.default_shape_kf
|
|
4415
|
+
mu = mu if mu is not None else self.default_shape_mu
|
|
4416
|
+
restitution = restitution if restitution is not None else self.default_shape_restitution
|
|
4417
|
+
|
|
4357
4418
|
if normal is None:
|
|
4358
4419
|
normal = self.up_vector
|
|
4359
4420
|
self._ground_params = {
|
warp/sim/render.py
CHANGED
|
@@ -213,7 +213,7 @@ def CreateSimRenderer(renderer):
|
|
|
213
213
|
pos=p,
|
|
214
214
|
rot=q,
|
|
215
215
|
scale=geo_scale,
|
|
216
|
-
colors=
|
|
216
|
+
colors=color,
|
|
217
217
|
parent_body=body,
|
|
218
218
|
is_template=True,
|
|
219
219
|
)
|
|
@@ -328,7 +328,7 @@ def CreateSimRenderer(renderer):
|
|
|
328
328
|
"surface",
|
|
329
329
|
particle_q,
|
|
330
330
|
self.model.tri_indices.numpy().flatten(),
|
|
331
|
-
colors=(
|
|
331
|
+
colors=(0.75, 0.25, 0.0),
|
|
332
332
|
)
|
|
333
333
|
|
|
334
334
|
# render springs
|