warp-lang 1.0.0b2__py3-none-manylinux2014_x86_64.whl → 1.0.0b6__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.
- docs/conf.py +17 -5
- examples/env/env_ant.py +1 -1
- examples/env/env_cartpole.py +1 -1
- examples/env/env_humanoid.py +1 -1
- examples/env/env_usd.py +4 -1
- examples/env/environment.py +8 -9
- examples/example_dem.py +34 -33
- examples/example_diffray.py +364 -337
- examples/example_fluid.py +32 -23
- examples/example_jacobian_ik.py +97 -93
- examples/example_marching_cubes.py +6 -16
- examples/example_mesh.py +6 -16
- examples/example_mesh_intersect.py +16 -14
- examples/example_nvdb.py +14 -16
- examples/example_raycast.py +14 -13
- examples/example_raymarch.py +16 -23
- examples/example_render_opengl.py +19 -10
- examples/example_sim_cartpole.py +82 -78
- examples/example_sim_cloth.py +45 -48
- examples/example_sim_fk_grad.py +51 -44
- examples/example_sim_fk_grad_torch.py +47 -40
- examples/example_sim_grad_bounce.py +108 -133
- examples/example_sim_grad_cloth.py +99 -113
- examples/example_sim_granular.py +5 -6
- examples/{example_sim_sdf_shape.py → example_sim_granular_collision_sdf.py} +37 -26
- examples/example_sim_neo_hookean.py +51 -55
- examples/example_sim_particle_chain.py +4 -4
- examples/example_sim_quadruped.py +126 -81
- examples/example_sim_rigid_chain.py +54 -61
- examples/example_sim_rigid_contact.py +66 -70
- examples/example_sim_rigid_fem.py +3 -3
- examples/example_sim_rigid_force.py +1 -1
- examples/example_sim_rigid_gyroscopic.py +3 -4
- examples/example_sim_rigid_kinematics.py +28 -39
- examples/example_sim_trajopt.py +112 -110
- examples/example_sph.py +9 -8
- examples/example_wave.py +7 -7
- examples/fem/bsr_utils.py +30 -17
- examples/fem/example_apic_fluid.py +85 -69
- examples/fem/example_convection_diffusion.py +97 -93
- examples/fem/example_convection_diffusion_dg.py +142 -149
- examples/fem/example_convection_diffusion_dg0.py +141 -136
- examples/fem/example_deformed_geometry.py +146 -0
- examples/fem/example_diffusion.py +115 -84
- examples/fem/example_diffusion_3d.py +116 -86
- examples/fem/example_diffusion_mgpu.py +102 -79
- examples/fem/example_mixed_elasticity.py +139 -100
- examples/fem/example_navier_stokes.py +175 -162
- examples/fem/example_stokes.py +143 -111
- examples/fem/example_stokes_transfer.py +186 -157
- examples/fem/mesh_utils.py +59 -97
- examples/fem/plot_utils.py +138 -17
- tools/ci/publishing/build_nodes_info.py +54 -0
- warp/__init__.py +4 -3
- warp/__init__.pyi +1 -0
- warp/bin/warp-clang.so +0 -0
- warp/bin/warp.so +0 -0
- warp/build.py +5 -3
- warp/build_dll.py +29 -9
- warp/builtins.py +836 -492
- warp/codegen.py +864 -553
- warp/config.py +3 -1
- warp/context.py +389 -172
- warp/fem/__init__.py +24 -6
- warp/fem/cache.py +318 -25
- warp/fem/dirichlet.py +7 -3
- warp/fem/domain.py +14 -0
- warp/fem/field/__init__.py +30 -38
- warp/fem/field/field.py +149 -0
- warp/fem/field/nodal_field.py +244 -138
- warp/fem/field/restriction.py +8 -6
- warp/fem/field/test.py +127 -59
- warp/fem/field/trial.py +117 -60
- warp/fem/geometry/__init__.py +5 -1
- warp/fem/geometry/deformed_geometry.py +271 -0
- warp/fem/geometry/element.py +24 -1
- warp/fem/geometry/geometry.py +86 -14
- warp/fem/geometry/grid_2d.py +112 -54
- warp/fem/geometry/grid_3d.py +134 -65
- warp/fem/geometry/hexmesh.py +953 -0
- warp/fem/geometry/partition.py +85 -33
- warp/fem/geometry/quadmesh_2d.py +532 -0
- warp/fem/geometry/tetmesh.py +451 -115
- warp/fem/geometry/trimesh_2d.py +197 -92
- warp/fem/integrate.py +534 -268
- warp/fem/operator.py +58 -31
- warp/fem/polynomial.py +11 -0
- warp/fem/quadrature/__init__.py +1 -1
- warp/fem/quadrature/pic_quadrature.py +150 -58
- warp/fem/quadrature/quadrature.py +209 -57
- warp/fem/space/__init__.py +230 -53
- warp/fem/space/basis_space.py +489 -0
- warp/fem/space/collocated_function_space.py +105 -0
- warp/fem/space/dof_mapper.py +49 -2
- warp/fem/space/function_space.py +90 -39
- warp/fem/space/grid_2d_function_space.py +149 -496
- warp/fem/space/grid_3d_function_space.py +173 -538
- warp/fem/space/hexmesh_function_space.py +352 -0
- warp/fem/space/partition.py +129 -76
- warp/fem/space/quadmesh_2d_function_space.py +369 -0
- warp/fem/space/restriction.py +46 -34
- warp/fem/space/shape/__init__.py +15 -0
- warp/fem/space/shape/cube_shape_function.py +738 -0
- warp/fem/space/shape/shape_function.py +103 -0
- warp/fem/space/shape/square_shape_function.py +611 -0
- warp/fem/space/shape/tet_shape_function.py +567 -0
- warp/fem/space/shape/triangle_shape_function.py +429 -0
- warp/fem/space/tetmesh_function_space.py +132 -1039
- warp/fem/space/topology.py +295 -0
- warp/fem/space/trimesh_2d_function_space.py +104 -742
- warp/fem/types.py +13 -11
- warp/fem/utils.py +335 -60
- warp/native/array.h +120 -34
- warp/native/builtin.h +101 -72
- warp/native/bvh.cpp +73 -325
- warp/native/bvh.cu +406 -23
- warp/native/bvh.h +22 -40
- warp/native/clang/clang.cpp +1 -0
- warp/native/crt.h +2 -0
- warp/native/cuda_util.cpp +8 -3
- warp/native/cuda_util.h +1 -0
- warp/native/exports.h +1522 -1243
- warp/native/intersect.h +19 -4
- warp/native/intersect_adj.h +8 -8
- warp/native/mat.h +76 -17
- warp/native/mesh.cpp +33 -108
- warp/native/mesh.cu +114 -18
- warp/native/mesh.h +395 -40
- warp/native/noise.h +272 -329
- warp/native/quat.h +51 -8
- warp/native/rand.h +44 -34
- warp/native/reduce.cpp +1 -1
- warp/native/sparse.cpp +4 -4
- warp/native/sparse.cu +163 -155
- warp/native/spatial.h +2 -2
- warp/native/temp_buffer.h +18 -14
- warp/native/vec.h +103 -21
- warp/native/warp.cpp +2 -1
- warp/native/warp.cu +28 -3
- warp/native/warp.h +4 -3
- warp/render/render_opengl.py +261 -109
- warp/sim/__init__.py +1 -2
- warp/sim/articulation.py +385 -185
- warp/sim/import_mjcf.py +59 -48
- warp/sim/import_urdf.py +15 -15
- warp/sim/import_usd.py +174 -102
- warp/sim/inertia.py +17 -18
- warp/sim/integrator_xpbd.py +4 -3
- warp/sim/model.py +330 -250
- warp/sim/render.py +1 -1
- warp/sparse.py +625 -152
- warp/stubs.py +341 -309
- warp/tape.py +9 -6
- warp/tests/__main__.py +3 -6
- warp/tests/assets/curlnoise_golden.npy +0 -0
- warp/tests/assets/pnoise_golden.npy +0 -0
- warp/tests/{test_class_kernel.py → aux_test_class_kernel.py} +9 -1
- warp/tests/aux_test_conditional_unequal_types_kernels.py +21 -0
- warp/tests/{test_dependent.py → aux_test_dependent.py} +2 -2
- warp/tests/{test_reference.py → aux_test_reference.py} +1 -1
- warp/tests/aux_test_unresolved_func.py +14 -0
- warp/tests/aux_test_unresolved_symbol.py +14 -0
- warp/tests/disabled_kinematics.py +239 -0
- warp/tests/run_coverage_serial.py +31 -0
- warp/tests/test_adam.py +103 -106
- warp/tests/test_arithmetic.py +94 -74
- warp/tests/test_array.py +82 -101
- warp/tests/test_array_reduce.py +57 -23
- warp/tests/test_atomic.py +64 -28
- warp/tests/test_bool.py +22 -12
- warp/tests/test_builtins_resolution.py +1292 -0
- warp/tests/test_bvh.py +18 -18
- warp/tests/test_closest_point_edge_edge.py +54 -57
- warp/tests/test_codegen.py +165 -134
- warp/tests/test_compile_consts.py +28 -20
- warp/tests/test_conditional.py +108 -24
- warp/tests/test_copy.py +10 -12
- warp/tests/test_ctypes.py +112 -88
- warp/tests/test_dense.py +21 -14
- warp/tests/test_devices.py +98 -0
- warp/tests/test_dlpack.py +75 -75
- warp/tests/test_examples.py +237 -0
- warp/tests/test_fabricarray.py +22 -24
- warp/tests/test_fast_math.py +15 -11
- warp/tests/test_fem.py +1034 -124
- warp/tests/test_fp16.py +23 -16
- warp/tests/test_func.py +187 -86
- warp/tests/test_generics.py +194 -49
- warp/tests/test_grad.py +123 -181
- warp/tests/test_grad_customs.py +176 -0
- warp/tests/test_hash_grid.py +35 -34
- warp/tests/test_import.py +10 -23
- warp/tests/test_indexedarray.py +24 -25
- warp/tests/test_intersect.py +18 -9
- warp/tests/test_large.py +141 -0
- warp/tests/test_launch.py +14 -41
- warp/tests/test_lerp.py +64 -65
- warp/tests/test_lvalue.py +493 -0
- warp/tests/test_marching_cubes.py +12 -13
- warp/tests/test_mat.py +517 -2898
- warp/tests/test_mat_lite.py +115 -0
- warp/tests/test_mat_scalar_ops.py +2889 -0
- warp/tests/test_math.py +103 -9
- warp/tests/test_matmul.py +304 -69
- warp/tests/test_matmul_lite.py +410 -0
- warp/tests/test_mesh.py +60 -22
- warp/tests/test_mesh_query_aabb.py +21 -25
- warp/tests/test_mesh_query_point.py +111 -22
- warp/tests/test_mesh_query_ray.py +12 -24
- warp/tests/test_mlp.py +30 -22
- warp/tests/test_model.py +92 -89
- warp/tests/test_modules_lite.py +39 -0
- warp/tests/test_multigpu.py +88 -114
- warp/tests/test_noise.py +12 -11
- warp/tests/test_operators.py +16 -20
- warp/tests/test_options.py +11 -11
- warp/tests/test_pinned.py +17 -18
- warp/tests/test_print.py +32 -11
- warp/tests/test_quat.py +275 -129
- warp/tests/test_rand.py +18 -16
- warp/tests/test_reload.py +38 -34
- warp/tests/test_rounding.py +50 -43
- warp/tests/test_runlength_encode.py +168 -20
- warp/tests/test_smoothstep.py +9 -11
- warp/tests/test_snippet.py +143 -0
- warp/tests/test_sparse.py +261 -63
- warp/tests/test_spatial.py +276 -243
- warp/tests/test_streams.py +110 -85
- warp/tests/test_struct.py +268 -63
- warp/tests/test_tape.py +39 -21
- warp/tests/test_torch.py +90 -86
- warp/tests/test_transient_module.py +10 -12
- warp/tests/test_types.py +363 -0
- warp/tests/test_utils.py +451 -0
- warp/tests/test_vec.py +354 -2050
- warp/tests/test_vec_lite.py +73 -0
- warp/tests/test_vec_scalar_ops.py +2099 -0
- warp/tests/test_volume.py +418 -376
- warp/tests/test_volume_write.py +124 -134
- warp/tests/unittest_serial.py +35 -0
- warp/tests/unittest_suites.py +291 -0
- warp/tests/unittest_utils.py +342 -0
- warp/tests/{test_misc.py → unused_test_misc.py} +13 -5
- warp/tests/{test_debug.py → walkthough_debug.py} +3 -17
- warp/thirdparty/appdirs.py +36 -45
- warp/thirdparty/unittest_parallel.py +589 -0
- warp/types.py +622 -211
- warp/utils.py +54 -393
- warp_lang-1.0.0b6.dist-info/METADATA +238 -0
- warp_lang-1.0.0b6.dist-info/RECORD +409 -0
- {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/WHEEL +1 -1
- examples/example_cache_management.py +0 -40
- examples/example_multigpu.py +0 -54
- examples/example_struct.py +0 -65
- examples/fem/example_stokes_transfer_3d.py +0 -210
- warp/fem/field/discrete_field.py +0 -80
- warp/fem/space/nodal_function_space.py +0 -233
- warp/tests/test_all.py +0 -223
- warp/tests/test_array_scan.py +0 -60
- warp/tests/test_base.py +0 -208
- warp/tests/test_unresolved_func.py +0 -7
- warp/tests/test_unresolved_symbol.py +0 -7
- warp_lang-1.0.0b2.dist-info/METADATA +0 -26
- warp_lang-1.0.0b2.dist-info/RECORD +0 -378
- /warp/tests/{test_compile_consts_dummy.py → aux_test_compile_consts_dummy.py} +0 -0
- /warp/tests/{test_reference_reference.py → aux_test_reference_reference.py} +0 -0
- /warp/tests/{test_square.py → aux_test_square.py} +0 -0
- {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/LICENSE.md +0 -0
- {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/top_level.txt +0 -0
warp/sim/model.py
CHANGED
|
@@ -99,11 +99,11 @@ class JointAxis:
|
|
|
99
99
|
|
|
100
100
|
Attributes:
|
|
101
101
|
|
|
102
|
-
axis (3D vector): The axis that this JointAxis object describes
|
|
102
|
+
axis (3D vector or JointAxis): The 3D axis that this JointAxis object describes, or alternatively another JointAxis object to copy from
|
|
103
103
|
limit_lower (float): The lower limit of the joint axis
|
|
104
104
|
limit_upper (float): The upper limit of the joint axis
|
|
105
|
-
limit_ke (float): The elastic stiffness of the joint axis limits, only respected by SemiImplicitIntegrator
|
|
106
|
-
limit_kd (float): The damping stiffness of the joint axis limits, only respected by SemiImplicitIntegrator
|
|
105
|
+
limit_ke (float): The elastic stiffness of the joint axis limits, only respected by :class:`SemiImplicitIntegrator`
|
|
106
|
+
limit_kd (float): The damping stiffness of the joint axis limits, only respected by :class:`SemiImplicitIntegrator`
|
|
107
107
|
target (float): The target position or velocity (depending on the mode, see `Joint modes`_) of the joint axis
|
|
108
108
|
target_ke (float): The proportional gain of the joint axis target drive PD controller
|
|
109
109
|
target_kd (float): The derivative gain of the joint axis target drive PD controller
|
|
@@ -113,8 +113,8 @@ class JointAxis:
|
|
|
113
113
|
def __init__(
|
|
114
114
|
self,
|
|
115
115
|
axis,
|
|
116
|
-
limit_lower=-
|
|
117
|
-
limit_upper=
|
|
116
|
+
limit_lower=-math.inf,
|
|
117
|
+
limit_upper=math.inf,
|
|
118
118
|
limit_ke=100.0,
|
|
119
119
|
limit_kd=10.0,
|
|
120
120
|
target=None,
|
|
@@ -122,38 +122,52 @@ class JointAxis:
|
|
|
122
122
|
target_kd=0.0,
|
|
123
123
|
mode=JOINT_MODE_TARGET_POSITION,
|
|
124
124
|
):
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
self.target = target
|
|
132
|
-
|
|
133
|
-
self.
|
|
125
|
+
if isinstance(axis, JointAxis):
|
|
126
|
+
self.axis = axis.axis
|
|
127
|
+
self.limit_lower = axis.limit_lower
|
|
128
|
+
self.limit_upper = axis.limit_upper
|
|
129
|
+
self.limit_ke = axis.limit_ke
|
|
130
|
+
self.limit_kd = axis.limit_kd
|
|
131
|
+
self.target = axis.target
|
|
132
|
+
self.target_ke = axis.target_ke
|
|
133
|
+
self.target_kd = axis.target_kd
|
|
134
|
+
self.mode = axis.mode
|
|
134
135
|
else:
|
|
135
|
-
self.
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
136
|
+
self.axis = wp.normalize(wp.vec3(axis))
|
|
137
|
+
self.limit_lower = limit_lower
|
|
138
|
+
self.limit_upper = limit_upper
|
|
139
|
+
self.limit_ke = limit_ke
|
|
140
|
+
self.limit_kd = limit_kd
|
|
141
|
+
if target is not None:
|
|
142
|
+
self.target = target
|
|
143
|
+
elif limit_lower > 0.0 or limit_upper < 0.0:
|
|
144
|
+
self.target = 0.5 * (limit_lower + limit_upper)
|
|
145
|
+
else:
|
|
146
|
+
self.target = 0.0
|
|
147
|
+
self.target_ke = target_ke
|
|
148
|
+
self.target_kd = target_kd
|
|
149
|
+
self.mode = mode
|
|
139
150
|
|
|
140
151
|
|
|
141
152
|
class SDF:
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
153
|
+
"""Describes a signed distance field for simulation
|
|
154
|
+
|
|
155
|
+
Attributes:
|
|
156
|
+
|
|
157
|
+
volume (Volume): The volume defining the SDF
|
|
158
|
+
I (Mat33): 3x3 inertia matrix of the SDF
|
|
159
|
+
mass (float): The total mass of the SDF
|
|
160
|
+
com (Vec3): The center of mass of the SDF
|
|
161
|
+
"""
|
|
162
|
+
def __init__(self, volume=None, I=wp.mat33(np.eye(3)), mass=1.0, com=wp.vec3()):
|
|
149
163
|
self.volume = volume
|
|
164
|
+
self.I = I
|
|
165
|
+
self.mass = mass
|
|
166
|
+
self.com = com
|
|
150
167
|
|
|
151
168
|
# Need to specify these for now
|
|
152
169
|
self.has_inertia = True
|
|
153
170
|
self.is_solid = True
|
|
154
|
-
self.mass = mass
|
|
155
|
-
self.com = com
|
|
156
|
-
self.I = I
|
|
157
171
|
|
|
158
172
|
def finalize(self, device=None):
|
|
159
173
|
return self.volume.id
|
|
@@ -164,12 +178,36 @@ class SDF:
|
|
|
164
178
|
|
|
165
179
|
class Mesh:
|
|
166
180
|
"""Describes a triangle collision mesh for simulation
|
|
181
|
+
|
|
182
|
+
Example mesh creation from a triangle OBJ mesh file:
|
|
183
|
+
====================================================
|
|
184
|
+
|
|
185
|
+
.. code-block:: python
|
|
186
|
+
|
|
187
|
+
import numpy as np
|
|
188
|
+
import warp as wp
|
|
189
|
+
import warp.sim
|
|
190
|
+
|
|
191
|
+
def load_mesh(self, filename, use_meshio=True):
|
|
192
|
+
if use_meshio:
|
|
193
|
+
import meshio
|
|
194
|
+
m = meshio.read(filename)
|
|
195
|
+
mesh_points = np.array(m.points)
|
|
196
|
+
mesh_indices = np.array(m.cells[0].data, dtype=np.int32).flatten()
|
|
197
|
+
else:
|
|
198
|
+
import openmesh
|
|
199
|
+
m = openmesh.read_trimesh(filename)
|
|
200
|
+
mesh_points = np.array(m.points())
|
|
201
|
+
mesh_indices = np.array(m.face_vertex_indices(), dtype=np.int32).flatten()
|
|
202
|
+
return wp.sim.Mesh(mesh_points, mesh_indices)
|
|
203
|
+
|
|
204
|
+
mesh = load_mesh("mesh.obj")
|
|
167
205
|
|
|
168
206
|
Attributes:
|
|
169
207
|
|
|
170
|
-
vertices (List[Vec3]): Mesh vertices
|
|
171
|
-
indices (List[int]): Mesh indices
|
|
172
|
-
I (Mat33):
|
|
208
|
+
vertices (List[Vec3]): Mesh 3D vertices points
|
|
209
|
+
indices (List[int]): Mesh indices as a flattened list of vertex indices describing triangles
|
|
210
|
+
I (Mat33): 3x3 inertia matrix of the mesh assuming density of 1.0 (around the center of mass)
|
|
173
211
|
mass (float): The total mass of the body assuming density of 1.0
|
|
174
212
|
com (Vec3): The center of mass of the body
|
|
175
213
|
"""
|
|
@@ -196,12 +234,20 @@ class Mesh:
|
|
|
196
234
|
if compute_inertia:
|
|
197
235
|
self.mass, self.com, self.I, _ = compute_mesh_inertia(1.0, vertices, indices, is_solid=is_solid)
|
|
198
236
|
else:
|
|
199
|
-
self.I = np.eye(3
|
|
237
|
+
self.I = wp.mat33(np.eye(3))
|
|
200
238
|
self.mass = 1.0
|
|
201
|
-
self.com =
|
|
239
|
+
self.com = wp.vec3()
|
|
202
240
|
|
|
203
|
-
# construct simulation ready buffers from points
|
|
204
241
|
def finalize(self, device=None):
|
|
242
|
+
"""
|
|
243
|
+
Constructs a simulation-ready :class:`Mesh` object from the mesh data and returns its ID.
|
|
244
|
+
|
|
245
|
+
Args:
|
|
246
|
+
device: The device on which to allocate the mesh buffers
|
|
247
|
+
|
|
248
|
+
Returns:
|
|
249
|
+
The ID of the simulation-ready :class:`Mesh`
|
|
250
|
+
"""
|
|
205
251
|
with wp.ScopedDevice(device):
|
|
206
252
|
pos = wp.array(self.vertices, dtype=wp.vec3)
|
|
207
253
|
vel = wp.zeros_like(pos)
|
|
@@ -211,6 +257,9 @@ class Mesh:
|
|
|
211
257
|
return self.mesh.id
|
|
212
258
|
|
|
213
259
|
def __hash__(self):
|
|
260
|
+
"""
|
|
261
|
+
Computes a hash of the mesh data for use in caching. The hash considers the mesh vertices, indices, and whether the mesh is solid or not.
|
|
262
|
+
"""
|
|
214
263
|
return hash((tuple(np.array(self.vertices).flatten()), tuple(np.array(self.indices).flatten()), self.is_solid))
|
|
215
264
|
|
|
216
265
|
|
|
@@ -228,13 +277,13 @@ class State:
|
|
|
228
277
|
particle_count (int): Number of particles
|
|
229
278
|
body_count (int): Number of rigid bodies
|
|
230
279
|
|
|
231
|
-
particle_q (
|
|
232
|
-
particle_qd (
|
|
233
|
-
particle_f (
|
|
280
|
+
particle_q (array): Tensor of particle positions
|
|
281
|
+
particle_qd (array): Tensor of particle velocities
|
|
282
|
+
particle_f (array): Tensor of particle forces
|
|
234
283
|
|
|
235
|
-
body_q (
|
|
236
|
-
body_qd (
|
|
237
|
-
body_f (
|
|
284
|
+
body_q (array): Tensor of body coordinates
|
|
285
|
+
body_qd (array): Tensor of body velocities
|
|
286
|
+
body_f (array): Tensor of body forces
|
|
238
287
|
|
|
239
288
|
"""
|
|
240
289
|
|
|
@@ -276,7 +325,7 @@ class State:
|
|
|
276
325
|
|
|
277
326
|
def compute_shape_mass(type, scale, src, density, is_solid, thickness):
|
|
278
327
|
if density == 0.0 or type == GEO_PLANE: # zero density means fixed
|
|
279
|
-
return 0.0,
|
|
328
|
+
return 0.0, wp.vec3(), wp.mat33()
|
|
280
329
|
|
|
281
330
|
if type == GEO_SPHERE:
|
|
282
331
|
solid = compute_sphere_inertia(density, scale[0])
|
|
@@ -286,7 +335,7 @@ def compute_shape_mass(type, scale, src, density, is_solid, thickness):
|
|
|
286
335
|
hollow = compute_sphere_inertia(density, scale[0] - thickness)
|
|
287
336
|
return solid[0] - hollow[0], solid[1], solid[2] - hollow[2]
|
|
288
337
|
elif type == GEO_BOX:
|
|
289
|
-
w, h, d =
|
|
338
|
+
w, h, d = scale * 2.0
|
|
290
339
|
solid = compute_box_inertia(density, w, h, d)
|
|
291
340
|
if is_solid:
|
|
292
341
|
return solid
|
|
@@ -321,13 +370,12 @@ def compute_shape_mass(type, scale, src, density, is_solid, thickness):
|
|
|
321
370
|
if src.has_inertia and src.mass > 0.0 and src.is_solid == is_solid:
|
|
322
371
|
m, c, I = src.mass, src.com, src.I
|
|
323
372
|
|
|
324
|
-
|
|
325
|
-
sx, sy, sz = s
|
|
373
|
+
sx, sy, sz = scale
|
|
326
374
|
|
|
327
375
|
mass_ratio = sx * sy * sz * density
|
|
328
376
|
m_new = m * mass_ratio
|
|
329
377
|
|
|
330
|
-
c_new = c
|
|
378
|
+
c_new = wp.cw_mul(c, scale)
|
|
331
379
|
|
|
332
380
|
Ixx = I[0, 0] * (sy**2 + sz**2) / 2 * mass_ratio
|
|
333
381
|
Iyy = I[1, 1] * (sx**2 + sz**2) / 2 * mass_ratio
|
|
@@ -336,12 +384,12 @@ def compute_shape_mass(type, scale, src, density, is_solid, thickness):
|
|
|
336
384
|
Ixz = I[0, 2] * sx * sz * mass_ratio
|
|
337
385
|
Iyz = I[1, 2] * sy * sz * mass_ratio
|
|
338
386
|
|
|
339
|
-
I_new =
|
|
387
|
+
I_new = wp.mat33([[Ixx, Ixy, Ixz], [Ixy, Iyy, Iyz], [Ixz, Iyz, Izz]])
|
|
340
388
|
|
|
341
389
|
return m_new, c_new, I_new
|
|
342
390
|
elif type == GEO_MESH:
|
|
343
391
|
# fall back to computing inertia from mesh geometry
|
|
344
|
-
vertices = np.array(src.vertices) * np.array(scale
|
|
392
|
+
vertices = np.array(src.vertices) * np.array(scale)
|
|
345
393
|
m, c, I, vol = compute_mesh_inertia(density, vertices, src.indices, is_solid, thickness)
|
|
346
394
|
return m, c, I
|
|
347
395
|
raise ValueError("Unsupported shape type: {}".format(type))
|
|
@@ -357,24 +405,24 @@ class Model:
|
|
|
357
405
|
requires_grad (float): Indicates whether the model was finalized with gradient computation enabled
|
|
358
406
|
num_envs (int): Number of articulation environments that were added to the ModelBuilder via `add_builder`
|
|
359
407
|
|
|
360
|
-
particle_q (
|
|
361
|
-
particle_qd (
|
|
362
|
-
particle_mass (
|
|
363
|
-
particle_inv_mass (
|
|
364
|
-
particle_radius (
|
|
408
|
+
particle_q (array): Particle positions, shape [particle_count, 3], float
|
|
409
|
+
particle_qd (array): Particle velocities, shape [particle_count, 3], float
|
|
410
|
+
particle_mass (array): Particle mass, shape [particle_count], float
|
|
411
|
+
particle_inv_mass (array): Particle inverse mass, shape [particle_count], float
|
|
412
|
+
particle_radius (array): Particle radius, shape [particle_count], float
|
|
365
413
|
particle_max_radius (float): Maximum particle radius (useful for HashGrid construction)
|
|
366
|
-
particle_ke (
|
|
367
|
-
particle_kd (
|
|
368
|
-
particle_kf (
|
|
369
|
-
particle_mu (
|
|
370
|
-
particle_cohesion (
|
|
371
|
-
particle_adhesion (
|
|
414
|
+
particle_ke (array): Particle normal contact stiffness (used by :class:`SemiImplicitIntegrator`), shape [particle_count], float
|
|
415
|
+
particle_kd (array): Particle normal contact damping (used by :class:`SemiImplicitIntegrator`), shape [particle_count], float
|
|
416
|
+
particle_kf (array): Particle friction force stiffness (used by :class:`SemiImplicitIntegrator`), shape [particle_count], float
|
|
417
|
+
particle_mu (array): Particle friction coefficient, shape [particle_count], float
|
|
418
|
+
particle_cohesion (array): Particle cohesion strength, shape [particle_count], float
|
|
419
|
+
particle_adhesion (array): Particle adhesion strength, shape [particle_count], float
|
|
372
420
|
particle_grid (HashGrid): HashGrid instance used for accelerated simulation of particle interactions
|
|
373
|
-
particle_flags (
|
|
421
|
+
particle_flags (array): Particle enabled state, shape [particle_count], bool
|
|
374
422
|
particle_max_velocity (float): Maximum particle velocity (to prevent instability)
|
|
375
423
|
|
|
376
|
-
shape_transform (
|
|
377
|
-
shape_body (
|
|
424
|
+
shape_transform (array): Rigid shape transforms, shape [shape_count, 7], float
|
|
425
|
+
shape_body (array): Rigid shape body index, shape [shape_count], int
|
|
378
426
|
body_shapes (dict): Mapping from body index to list of attached shape indices
|
|
379
427
|
shape_materials (ModelShapeMaterials): Rigid shape contact materials, shape [shape_count], float
|
|
380
428
|
shape_shape_geo (ModelShapeGeometry): Shape geometry properties (geo type, scale, thickness, etc.), shape [shape_count, 3], float
|
|
@@ -383,68 +431,68 @@ class Model:
|
|
|
383
431
|
shape_collision_group (list): Collision group of each shape, shape [shape_count], int
|
|
384
432
|
shape_collision_group_map (dict): Mapping from collision group to list of shape indices
|
|
385
433
|
shape_collision_filter_pairs (set): Pairs of shape indices that should not collide
|
|
386
|
-
shape_collision_radius (
|
|
434
|
+
shape_collision_radius (array): Collision radius of each shape used for bounding sphere broadphase collision checking, shape [shape_count], float
|
|
387
435
|
shape_ground_collision (list): Indicates whether each shape should collide with the ground, shape [shape_count], bool
|
|
388
|
-
shape_contact_pairs (
|
|
389
|
-
shape_ground_contact_pairs (
|
|
390
|
-
|
|
391
|
-
spring_indices (
|
|
392
|
-
spring_rest_length (
|
|
393
|
-
spring_stiffness (
|
|
394
|
-
spring_damping (
|
|
395
|
-
spring_control (
|
|
396
|
-
|
|
397
|
-
tri_indices (
|
|
398
|
-
tri_poses (
|
|
399
|
-
tri_activations (
|
|
400
|
-
tri_materials (
|
|
401
|
-
|
|
402
|
-
edge_indices (
|
|
403
|
-
edge_rest_angle (
|
|
404
|
-
edge_bending_properties (
|
|
405
|
-
|
|
406
|
-
tet_indices (
|
|
407
|
-
tet_poses (
|
|
408
|
-
tet_activations (
|
|
409
|
-
tet_materials (
|
|
410
|
-
|
|
411
|
-
body_q (
|
|
412
|
-
body_qd (
|
|
413
|
-
body_com (
|
|
414
|
-
body_inertia (
|
|
415
|
-
body_inv_inertia (
|
|
416
|
-
body_mass (
|
|
417
|
-
body_inv_mass (
|
|
436
|
+
shape_contact_pairs (array): Pairs of shape indices that may collide, shape [contact_pair_count, 2], int
|
|
437
|
+
shape_ground_contact_pairs (array): Pairs of shape, ground indices that may collide, shape [ground_contact_pair_count, 2], int
|
|
438
|
+
|
|
439
|
+
spring_indices (array): Particle spring indices, shape [spring_count*2], int
|
|
440
|
+
spring_rest_length (array): Particle spring rest length, shape [spring_count], float
|
|
441
|
+
spring_stiffness (array): Particle spring stiffness, shape [spring_count], float
|
|
442
|
+
spring_damping (array): Particle spring damping, shape [spring_count], float
|
|
443
|
+
spring_control (array): Particle spring activation, shape [spring_count], float
|
|
444
|
+
|
|
445
|
+
tri_indices (array): Triangle element indices, shape [tri_count*3], int
|
|
446
|
+
tri_poses (array): Triangle element rest pose, shape [tri_count, 2, 2], float
|
|
447
|
+
tri_activations (array): Triangle element activations, shape [tri_count], float
|
|
448
|
+
tri_materials (array): Triangle element materials, shape [tri_count, 5], float
|
|
449
|
+
|
|
450
|
+
edge_indices (array): Bending edge indices, shape [edge_count*4], int
|
|
451
|
+
edge_rest_angle (array): Bending edge rest angle, shape [edge_count], float
|
|
452
|
+
edge_bending_properties (array): Bending edge stiffness and damping parameters, shape [edge_count, 2], float
|
|
453
|
+
|
|
454
|
+
tet_indices (array): Tetrahedral element indices, shape [tet_count*4], int
|
|
455
|
+
tet_poses (array): Tetrahedral rest poses, shape [tet_count, 3, 3], float
|
|
456
|
+
tet_activations (array): Tetrahedral volumetric activations, shape [tet_count], float
|
|
457
|
+
tet_materials (array): Tetrahedral elastic parameters in form :math:`k_{mu}, k_{lambda}, k_{damp}`, shape [tet_count, 3]
|
|
458
|
+
|
|
459
|
+
body_q (array): Poses of rigid bodies used for state initialization, shape [body_count, 7], float
|
|
460
|
+
body_qd (array): Velocities of rigid bodies used for state initialization, shape [body_count, 6], float
|
|
461
|
+
body_com (array): Rigid body center of mass (in local frame), shape [body_count, 7], float
|
|
462
|
+
body_inertia (array): Rigid body inertia tensor (relative to COM), shape [body_count, 3, 3], float
|
|
463
|
+
body_inv_inertia (array): Rigid body inverse inertia tensor (relative to COM), shape [body_count, 3, 3], float
|
|
464
|
+
body_mass (array): Rigid body mass, shape [body_count], float
|
|
465
|
+
body_inv_mass (array): Rigid body inverse mass, shape [body_count], float
|
|
418
466
|
body_name (list): Rigid body names, shape [body_count], str
|
|
419
467
|
|
|
420
|
-
joint_q (
|
|
421
|
-
joint_qd (
|
|
422
|
-
joint_act (
|
|
423
|
-
joint_type (
|
|
424
|
-
joint_parent (
|
|
425
|
-
joint_child (
|
|
426
|
-
joint_X_p (
|
|
427
|
-
joint_X_c (
|
|
428
|
-
joint_axis (
|
|
429
|
-
joint_armature (
|
|
430
|
-
joint_target (
|
|
431
|
-
joint_target_ke (
|
|
432
|
-
joint_target_kd (
|
|
433
|
-
joint_axis_start (
|
|
434
|
-
joint_axis_dim (
|
|
435
|
-
joint_axis_mode (
|
|
436
|
-
joint_linear_compliance (
|
|
437
|
-
joint_angular_compliance (
|
|
438
|
-
joint_enabled (
|
|
439
|
-
joint_limit_lower (
|
|
440
|
-
joint_limit_upper (
|
|
441
|
-
joint_limit_ke (
|
|
442
|
-
joint_limit_kd (
|
|
443
|
-
joint_twist_lower (
|
|
444
|
-
joint_twist_upper (
|
|
445
|
-
joint_q_start (
|
|
446
|
-
joint_qd_start (
|
|
447
|
-
articulation_start (
|
|
468
|
+
joint_q (array): Generalized joint positions used for state initialization, shape [joint_coord_count], float
|
|
469
|
+
joint_qd (array): Generalized joint velocities used for state initialization, shape [joint_dof_count], float
|
|
470
|
+
joint_act (array): Generalized joint actuation force, shape [joint_dof_count], float
|
|
471
|
+
joint_type (array): Joint type, shape [joint_count], int
|
|
472
|
+
joint_parent (array): Joint parent body indices, shape [joint_count], int
|
|
473
|
+
joint_child (array): Joint child body indices, shape [joint_count], int
|
|
474
|
+
joint_X_p (array): Joint transform in parent frame, shape [joint_count, 7], float
|
|
475
|
+
joint_X_c (array): Joint mass frame in child frame, shape [joint_count, 7], float
|
|
476
|
+
joint_axis (array): Joint axis in child frame, shape [joint_axis_count, 3], float
|
|
477
|
+
joint_armature (array): Armature for each joint, shape [joint_count], float
|
|
478
|
+
joint_target (array): Joint target position/velocity (depending on joint axis mode), shape [joint_axis_count], float
|
|
479
|
+
joint_target_ke (array): Joint stiffness, shape [joint_axis_count], float
|
|
480
|
+
joint_target_kd (array): Joint damping, shape [joint_axis_count], float
|
|
481
|
+
joint_axis_start (array): Start index of the first axis per joint, shape [joint_count], int
|
|
482
|
+
joint_axis_dim (array): Number of linear and angular axes per joint, shape [joint_count, 2], int
|
|
483
|
+
joint_axis_mode (array): Joint axis mode, shape [joint_axis_count], int
|
|
484
|
+
joint_linear_compliance (array): Joint linear compliance, shape [joint_count], float
|
|
485
|
+
joint_angular_compliance (array): Joint linear compliance, shape [joint_count], float
|
|
486
|
+
joint_enabled (array): Joint enabled, shape [joint_count], int
|
|
487
|
+
joint_limit_lower (array): Joint lower position limits, shape [joint_count], float
|
|
488
|
+
joint_limit_upper (array): Joint upper position limits, shape [joint_count], float
|
|
489
|
+
joint_limit_ke (array): Joint position limit stiffness (used by SemiImplicitIntegrator), shape [joint_count], float
|
|
490
|
+
joint_limit_kd (array): Joint position limit damping (used by SemiImplicitIntegrator), shape [joint_count], float
|
|
491
|
+
joint_twist_lower (array): Joint lower twist limit, shape [joint_count], float
|
|
492
|
+
joint_twist_upper (array): Joint upper twist limit, shape [joint_count], float
|
|
493
|
+
joint_q_start (array): Start index of the first position coordinate per joint, shape [joint_count], int
|
|
494
|
+
joint_qd_start (array): Start index of the first velocity coordinate per joint, shape [joint_count], int
|
|
495
|
+
articulation_start (array): Articulation start index, shape [articulation_count], int
|
|
448
496
|
joint_name (list): Joint names, shape [joint_count], str
|
|
449
497
|
joint_attach_ke (float): Joint attachment force stiffness (used by SemiImplicitIntegrator)
|
|
450
498
|
joint_attach_kd (float): Joint attachment force damping (used by SemiImplicitIntegrator)
|
|
@@ -461,7 +509,7 @@ class Model:
|
|
|
461
509
|
rigid_contact_rolling_friction (float): Rolling friction coefficient for rigid body contacts (used by XPBDIntegrator)
|
|
462
510
|
|
|
463
511
|
ground (bool): Whether the ground plane and ground contacts are enabled
|
|
464
|
-
ground_plane (
|
|
512
|
+
ground_plane (array): Ground plane 3D normal and offset, shape [4], float
|
|
465
513
|
up_vector (np.ndarray): Up vector of the world, shape [3], float
|
|
466
514
|
up_axis (int): Up axis, 0 for x, 1 for y, 2 for z
|
|
467
515
|
gravity (np.ndarray): Gravity vector, shape [3], float
|
|
@@ -858,7 +906,7 @@ class Model:
|
|
|
858
906
|
|
|
859
907
|
@property
|
|
860
908
|
def particle_radius(self):
|
|
861
|
-
|
|
909
|
+
# Array of per-particle radii
|
|
862
910
|
return self._particle_radius
|
|
863
911
|
|
|
864
912
|
@particle_radius.setter
|
|
@@ -1082,8 +1130,8 @@ class ModelBuilder:
|
|
|
1082
1130
|
self.joint_coord_count = 0
|
|
1083
1131
|
self.joint_axis_total_count = 0
|
|
1084
1132
|
|
|
1085
|
-
self.up_vector =
|
|
1086
|
-
self.up_axis = np.argmax(np.abs(up_vector))
|
|
1133
|
+
self.up_vector = wp.vec3(up_vector)
|
|
1134
|
+
self.up_axis = wp.vec3(np.argmax(np.abs(up_vector)))
|
|
1087
1135
|
self.gravity = gravity
|
|
1088
1136
|
# indicates whether a ground plane has been created
|
|
1089
1137
|
self._ground_created = False
|
|
@@ -1174,10 +1222,10 @@ class ModelBuilder:
|
|
|
1174
1222
|
"""Copies a rigid articulation from `articulation`, another `ModelBuilder`.
|
|
1175
1223
|
|
|
1176
1224
|
Args:
|
|
1177
|
-
articulation: a model builder to add rigid articulation from.
|
|
1178
|
-
xform: offset transform applied to root bodies.
|
|
1179
|
-
update_num_env_count: if True, the number of environments is incremented by 1.
|
|
1180
|
-
separate_collision_group: if True, the shapes from the articulation will all be put into a single new collision group, otherwise, only the shapes in collision group > -1 will be moved to a new group.
|
|
1225
|
+
articulation (ModelBuilder): a model builder to add rigid articulation from.
|
|
1226
|
+
xform (:ref:`transform <transform>`): offset transform applied to root bodies.
|
|
1227
|
+
update_num_env_count (bool): if True, the number of environments is incremented by 1.
|
|
1228
|
+
separate_collision_group (bool): if True, the shapes from the articulation will all be put into a single new collision group, otherwise, only the shapes in collision group > -1 will be moved to a new group.
|
|
1181
1229
|
"""
|
|
1182
1230
|
|
|
1183
1231
|
start_body_idx = self.body_count
|
|
@@ -1317,8 +1365,8 @@ class ModelBuilder:
|
|
|
1317
1365
|
self,
|
|
1318
1366
|
origin: Transform = wp.transform(),
|
|
1319
1367
|
armature: float = 0.0,
|
|
1320
|
-
com: Vec3 =
|
|
1321
|
-
I_m: Mat33 =
|
|
1368
|
+
com: Vec3 = wp.vec3(),
|
|
1369
|
+
I_m: Mat33 = wp.mat33(),
|
|
1322
1370
|
m: float = 0.0,
|
|
1323
1371
|
name: str = None,
|
|
1324
1372
|
) -> int:
|
|
@@ -1343,7 +1391,7 @@ class ModelBuilder:
|
|
|
1343
1391
|
body_id = len(self.body_mass)
|
|
1344
1392
|
|
|
1345
1393
|
# body data
|
|
1346
|
-
inertia = I_m + np.eye(3) * armature
|
|
1394
|
+
inertia = I_m + wp.mat33(np.eye(3)) * armature
|
|
1347
1395
|
self.body_inertia.append(inertia)
|
|
1348
1396
|
self.body_mass.append(m)
|
|
1349
1397
|
self.body_com.append(com)
|
|
@@ -1353,8 +1401,8 @@ class ModelBuilder:
|
|
|
1353
1401
|
else:
|
|
1354
1402
|
self.body_inv_mass.append(0.0)
|
|
1355
1403
|
|
|
1356
|
-
if
|
|
1357
|
-
self.body_inv_inertia.append(
|
|
1404
|
+
if any(x for x in inertia):
|
|
1405
|
+
self.body_inv_inertia.append(wp.inverse(inertia))
|
|
1358
1406
|
else:
|
|
1359
1407
|
self.body_inv_inertia.append(inertia)
|
|
1360
1408
|
|
|
@@ -1390,16 +1438,19 @@ class ModelBuilder:
|
|
|
1390
1438
|
linear_axes: The linear axes (see :class:`JointAxis`) of the joint
|
|
1391
1439
|
angular_axes: The angular axes (see :class:`JointAxis`) of the joint
|
|
1392
1440
|
name: The name of the joint
|
|
1393
|
-
parent_xform: The transform of the joint in the parent body's local frame
|
|
1394
|
-
child_xform: The transform of the joint in the child body's local frame
|
|
1441
|
+
parent_xform (:ref:`transform <transform>`): The transform of the joint in the parent body's local frame
|
|
1442
|
+
child_xform (:ref:`transform <transform>`): The transform of the joint in the child body's local frame
|
|
1395
1443
|
linear_compliance: The linear compliance of the joint
|
|
1396
1444
|
angular_compliance: The angular compliance of the joint
|
|
1397
1445
|
collision_filter_parent: Whether to filter collisions between shapes of the parent and child bodies
|
|
1398
1446
|
enabled: Whether the joint is enabled
|
|
1399
1447
|
|
|
1400
1448
|
Returns:
|
|
1401
|
-
The index of the
|
|
1449
|
+
The index of the added joint
|
|
1402
1450
|
"""
|
|
1451
|
+
if len(self.articulation_start) == 0:
|
|
1452
|
+
# automatically add an articulation if none exists
|
|
1453
|
+
self.add_articulation()
|
|
1403
1454
|
self.joint_type.append(joint_type)
|
|
1404
1455
|
self.joint_parent.append(parent)
|
|
1405
1456
|
if child not in self.joint_parents:
|
|
@@ -1407,8 +1458,8 @@ class ModelBuilder:
|
|
|
1407
1458
|
else:
|
|
1408
1459
|
self.joint_parents[child].append(parent)
|
|
1409
1460
|
self.joint_child.append(child)
|
|
1410
|
-
self.joint_X_p.append(
|
|
1411
|
-
self.joint_X_c.append(
|
|
1461
|
+
self.joint_X_p.append(wp.transform(parent_xform))
|
|
1462
|
+
self.joint_X_c.append(wp.transform(child_xform))
|
|
1412
1463
|
self.joint_name.append(name or f"joint {self.joint_count}")
|
|
1413
1464
|
self.joint_axis_start.append(len(self.joint_axis))
|
|
1414
1465
|
self.joint_axis_dim.append((len(linear_axes), len(angular_axes)))
|
|
@@ -1451,7 +1502,7 @@ class ModelBuilder:
|
|
|
1451
1502
|
elif joint_type == JOINT_BALL:
|
|
1452
1503
|
dof_count = 3
|
|
1453
1504
|
coord_count = 4
|
|
1454
|
-
elif joint_type == JOINT_FREE:
|
|
1505
|
+
elif joint_type == JOINT_FREE or joint_type == JOINT_DISTANCE:
|
|
1455
1506
|
dof_count = 6
|
|
1456
1507
|
coord_count = 7
|
|
1457
1508
|
elif joint_type == JOINT_FIXED:
|
|
@@ -1463,10 +1514,6 @@ class ModelBuilder:
|
|
|
1463
1514
|
elif joint_type == JOINT_COMPOUND:
|
|
1464
1515
|
dof_count = 3
|
|
1465
1516
|
coord_count = 3
|
|
1466
|
-
elif joint_type == JOINT_DISTANCE:
|
|
1467
|
-
# todo use free joint dofs?
|
|
1468
|
-
dof_count = 0
|
|
1469
|
-
coord_count = 0
|
|
1470
1517
|
elif joint_type == JOINT_D6:
|
|
1471
1518
|
dof_count = len(linear_axes) + len(angular_axes)
|
|
1472
1519
|
coord_count = dof_count
|
|
@@ -1478,7 +1525,7 @@ class ModelBuilder:
|
|
|
1478
1525
|
self.joint_qd.append(0.0)
|
|
1479
1526
|
self.joint_act.append(0.0)
|
|
1480
1527
|
|
|
1481
|
-
if joint_type == JOINT_FREE or joint_type == JOINT_BALL:
|
|
1528
|
+
if joint_type == JOINT_FREE or joint_type == JOINT_DISTANCE or joint_type == JOINT_BALL:
|
|
1482
1529
|
# ensure that a valid quaternion is used for the angular dofs
|
|
1483
1530
|
self.joint_q[-1] = 1.0
|
|
1484
1531
|
|
|
@@ -1516,14 +1563,14 @@ class ModelBuilder:
|
|
|
1516
1563
|
collision_filter_parent: bool = True,
|
|
1517
1564
|
enabled: bool = True,
|
|
1518
1565
|
) -> int:
|
|
1519
|
-
"""Adds a revolute joint to the model
|
|
1566
|
+
"""Adds a revolute (hinge) joint to the model. It has one degree of freedom.
|
|
1520
1567
|
|
|
1521
1568
|
Args:
|
|
1522
1569
|
parent: The index of the parent body
|
|
1523
1570
|
child: The index of the child body
|
|
1524
|
-
parent_xform: The transform of the joint in the parent body's local frame
|
|
1525
|
-
child_xform: The transform of the joint in the child body's local frame
|
|
1526
|
-
axis: The axis of rotation in the parent body's local frame
|
|
1571
|
+
parent_xform (:ref:`transform <transform>`): The transform of the joint in the parent body's local frame
|
|
1572
|
+
child_xform (:ref:`transform <transform>`): The transform of the joint in the child body's local frame
|
|
1573
|
+
axis (3D vector or JointAxis): The axis of rotation in the parent body's local frame, can be a JointAxis object whose settings will be used instead of the other arguments
|
|
1527
1574
|
target: The target angle (in radians) of the joint
|
|
1528
1575
|
target_ke: The stiffness of the joint target
|
|
1529
1576
|
target_kd: The damping of the joint target
|
|
@@ -1538,7 +1585,7 @@ class ModelBuilder:
|
|
|
1538
1585
|
enabled: Whether the joint is enabled
|
|
1539
1586
|
|
|
1540
1587
|
Returns:
|
|
1541
|
-
The index of the
|
|
1588
|
+
The index of the added joint
|
|
1542
1589
|
|
|
1543
1590
|
"""
|
|
1544
1591
|
ax = JointAxis(
|
|
@@ -1587,14 +1634,14 @@ class ModelBuilder:
|
|
|
1587
1634
|
collision_filter_parent: bool = True,
|
|
1588
1635
|
enabled: bool = True,
|
|
1589
1636
|
) -> int:
|
|
1590
|
-
"""Adds a prismatic joint to the model
|
|
1637
|
+
"""Adds a prismatic (sliding) joint to the model. It has one degree of freedom.
|
|
1591
1638
|
|
|
1592
1639
|
Args:
|
|
1593
1640
|
parent: The index of the parent body
|
|
1594
1641
|
child: The index of the child body
|
|
1595
|
-
parent_xform: The transform of the joint in the parent body's local frame
|
|
1596
|
-
child_xform: The transform of the joint in the child body's local frame
|
|
1597
|
-
axis: The axis of rotation in the parent body's local frame
|
|
1642
|
+
parent_xform (:ref:`transform <transform>`): The transform of the joint in the parent body's local frame
|
|
1643
|
+
child_xform (:ref:`transform <transform>`): The transform of the joint in the child body's local frame
|
|
1644
|
+
axis (3D vector or JointAxis): The axis of rotation in the parent body's local frame, can be a JointAxis object whose settings will be used instead of the other arguments
|
|
1598
1645
|
target: The target position of the joint
|
|
1599
1646
|
target_ke: The stiffness of the joint target
|
|
1600
1647
|
target_kd: The damping of the joint target
|
|
@@ -1609,7 +1656,7 @@ class ModelBuilder:
|
|
|
1609
1656
|
enabled: Whether the joint is enabled
|
|
1610
1657
|
|
|
1611
1658
|
Returns:
|
|
1612
|
-
The index of the
|
|
1659
|
+
The index of the added joint
|
|
1613
1660
|
|
|
1614
1661
|
"""
|
|
1615
1662
|
ax = JointAxis(
|
|
@@ -1649,13 +1696,13 @@ class ModelBuilder:
|
|
|
1649
1696
|
collision_filter_parent: bool = True,
|
|
1650
1697
|
enabled: bool = True,
|
|
1651
1698
|
) -> int:
|
|
1652
|
-
"""Adds a ball joint to the model
|
|
1699
|
+
"""Adds a ball (spherical) joint to the model. Its position is defined by a 4D quaternion (xyzw) and its velocity is a 3D vector.
|
|
1653
1700
|
|
|
1654
1701
|
Args:
|
|
1655
1702
|
parent: The index of the parent body
|
|
1656
1703
|
child: The index of the child body
|
|
1657
|
-
parent_xform: The transform of the joint in the parent body's local frame
|
|
1658
|
-
|
|
1704
|
+
parent_xform (:ref:`transform <transform>`): The transform of the joint in the parent body's local frame
|
|
1705
|
+
child_xform (:ref:`transform <transform>`): The transform of the joint in the child body's local frame
|
|
1659
1706
|
linear_compliance: The linear compliance of the joint
|
|
1660
1707
|
angular_compliance: The angular compliance of the joint
|
|
1661
1708
|
name: The name of the joint
|
|
@@ -1663,7 +1710,7 @@ class ModelBuilder:
|
|
|
1663
1710
|
enabled: Whether the joint is enabled
|
|
1664
1711
|
|
|
1665
1712
|
Returns:
|
|
1666
|
-
The index of the
|
|
1713
|
+
The index of the added joint
|
|
1667
1714
|
|
|
1668
1715
|
"""
|
|
1669
1716
|
return self.add_joint(
|
|
@@ -1691,13 +1738,14 @@ class ModelBuilder:
|
|
|
1691
1738
|
collision_filter_parent: bool = True,
|
|
1692
1739
|
enabled: bool = True,
|
|
1693
1740
|
) -> int:
|
|
1694
|
-
"""Adds a fixed joint to the model
|
|
1741
|
+
"""Adds a fixed (static) joint to the model. It has no degrees of freedom.
|
|
1742
|
+
See :meth:`collapse_fixed_joints` for a helper function that removes these fixed joints and merges the connecting bodies to simplify the model and improve stability.
|
|
1695
1743
|
|
|
1696
1744
|
Args:
|
|
1697
1745
|
parent: The index of the parent body
|
|
1698
1746
|
child: The index of the child body
|
|
1699
|
-
parent_xform: The transform of the joint in the parent body's local frame
|
|
1700
|
-
|
|
1747
|
+
parent_xform (:ref:`transform <transform>`): The transform of the joint in the parent body's local frame
|
|
1748
|
+
child_xform (:ref:`transform <transform>`): The transform of the joint in the child body's local frame
|
|
1701
1749
|
linear_compliance: The linear compliance of the joint
|
|
1702
1750
|
angular_compliance: The angular compliance of the joint
|
|
1703
1751
|
name: The name of the joint
|
|
@@ -1705,7 +1753,7 @@ class ModelBuilder:
|
|
|
1705
1753
|
enabled: Whether the joint is enabled
|
|
1706
1754
|
|
|
1707
1755
|
Returns:
|
|
1708
|
-
The index of the
|
|
1756
|
+
The index of the added joint
|
|
1709
1757
|
|
|
1710
1758
|
"""
|
|
1711
1759
|
return self.add_joint(
|
|
@@ -1731,19 +1779,20 @@ class ModelBuilder:
|
|
|
1731
1779
|
collision_filter_parent: bool = True,
|
|
1732
1780
|
enabled: bool = True,
|
|
1733
1781
|
) -> int:
|
|
1734
|
-
"""Adds a free joint to the model
|
|
1782
|
+
"""Adds a free joint to the model.
|
|
1783
|
+
It has 7 positional degrees of freedom (first 3 linear and then 4 angular dimensions for the orientation quaternion in `xyzw` notation) and 6 velocity degrees of freedom (first 3 angular and then 3 linear velocity dimensions).
|
|
1735
1784
|
|
|
1736
1785
|
Args:
|
|
1737
|
-
parent: The index of the parent body
|
|
1738
1786
|
child: The index of the child body
|
|
1739
|
-
parent_xform: The transform of the joint in the parent body's local frame
|
|
1740
|
-
|
|
1787
|
+
parent_xform (:ref:`transform <transform>`): The transform of the joint in the parent body's local frame
|
|
1788
|
+
child_xform (:ref:`transform <transform>`): The transform of the joint in the child body's local frame
|
|
1789
|
+
parent: The index of the parent body (-1 by default to use the world frame, e.g. to make the child body and its children a floating-base mechanism)
|
|
1741
1790
|
name: The name of the joint
|
|
1742
1791
|
collision_filter_parent: Whether to filter collisions between shapes of the parent and child bodies
|
|
1743
1792
|
enabled: Whether the joint is enabled
|
|
1744
1793
|
|
|
1745
1794
|
Returns:
|
|
1746
|
-
The index of the
|
|
1795
|
+
The index of the added joint
|
|
1747
1796
|
|
|
1748
1797
|
"""
|
|
1749
1798
|
return self.add_joint(
|
|
@@ -1769,13 +1818,14 @@ class ModelBuilder:
|
|
|
1769
1818
|
collision_filter_parent: bool = True,
|
|
1770
1819
|
enabled: bool = True,
|
|
1771
1820
|
) -> int:
|
|
1772
|
-
"""Adds a distance joint to the model
|
|
1821
|
+
"""Adds a distance joint to the model. The distance joint constraints the distance between the joint anchor points on the two bodies (see :ref:`FK-IK`) it connects to the interval [`min_distance`, `max_distance`].
|
|
1822
|
+
It has 7 positional degrees of freedom (first 3 linear and then 4 angular dimensions for the orientation quaternion in `xyzw` notation) and 6 velocity degrees of freedom (first 3 angular and then 3 linear velocity dimensions).
|
|
1773
1823
|
|
|
1774
1824
|
Args:
|
|
1775
1825
|
parent: The index of the parent body
|
|
1776
1826
|
child: The index of the child body
|
|
1777
|
-
parent_xform: The transform of the joint in the parent body's local frame
|
|
1778
|
-
|
|
1827
|
+
parent_xform (:ref:`transform <transform>`): The transform of the joint in the parent body's local frame
|
|
1828
|
+
child_xform (:ref:`transform <transform>`): The transform of the joint in the child body's local frame
|
|
1779
1829
|
min_distance: The minimum distance between the bodies (no limit if negative)
|
|
1780
1830
|
max_distance: The maximum distance between the bodies (no limit if negative)
|
|
1781
1831
|
compliance: The compliance of the joint
|
|
@@ -1783,7 +1833,9 @@ class ModelBuilder:
|
|
|
1783
1833
|
enabled: Whether the joint is enabled
|
|
1784
1834
|
|
|
1785
1835
|
Returns:
|
|
1786
|
-
The index of the
|
|
1836
|
+
The index of the added joint
|
|
1837
|
+
|
|
1838
|
+
.. note:: Distance joints are currently only supported in the :class:`XPBDIntegrator` at the moment.
|
|
1787
1839
|
|
|
1788
1840
|
"""
|
|
1789
1841
|
ax = JointAxis(
|
|
@@ -1817,15 +1869,15 @@ class ModelBuilder:
|
|
|
1817
1869
|
collision_filter_parent: bool = True,
|
|
1818
1870
|
enabled: bool = True,
|
|
1819
1871
|
) -> int:
|
|
1820
|
-
"""Adds a universal joint to the model
|
|
1872
|
+
"""Adds a universal joint to the model. U-joints have two degrees of freedom, one for each axis.
|
|
1821
1873
|
|
|
1822
1874
|
Args:
|
|
1823
1875
|
parent: The index of the parent body
|
|
1824
1876
|
child: The index of the child body
|
|
1825
|
-
axis_0: The first axis of the joint
|
|
1826
|
-
axis_1: The second axis of the joint
|
|
1827
|
-
parent_xform: The transform of the joint in the parent body's local frame
|
|
1828
|
-
|
|
1877
|
+
axis_0 (3D vector or JointAxis): The first axis of the joint, can be a JointAxis object whose settings will be used instead of the other arguments
|
|
1878
|
+
axis_1 (3D vector or JointAxis): The second axis of the joint, can be a JointAxis object whose settings will be used instead of the other arguments
|
|
1879
|
+
parent_xform (:ref:`transform <transform>`): The transform of the joint in the parent body's local frame
|
|
1880
|
+
child_xform (:ref:`transform <transform>`): The transform of the joint in the child body's local frame
|
|
1829
1881
|
linear_compliance: The linear compliance of the joint
|
|
1830
1882
|
angular_compliance: The angular compliance of the joint
|
|
1831
1883
|
name: The name of the joint
|
|
@@ -1833,14 +1885,14 @@ class ModelBuilder:
|
|
|
1833
1885
|
enabled: Whether the joint is enabled
|
|
1834
1886
|
|
|
1835
1887
|
Returns:
|
|
1836
|
-
The index of the
|
|
1888
|
+
The index of the added joint
|
|
1837
1889
|
|
|
1838
1890
|
"""
|
|
1839
1891
|
return self.add_joint(
|
|
1840
1892
|
JOINT_UNIVERSAL,
|
|
1841
1893
|
parent,
|
|
1842
1894
|
child,
|
|
1843
|
-
angular_axes=[axis_0, axis_1],
|
|
1895
|
+
angular_axes=[JointAxis(axis_0), JointAxis(axis_1)],
|
|
1844
1896
|
parent_xform=parent_xform,
|
|
1845
1897
|
child_xform=child_xform,
|
|
1846
1898
|
linear_compliance=linear_compliance,
|
|
@@ -1863,29 +1915,32 @@ class ModelBuilder:
|
|
|
1863
1915
|
collision_filter_parent: bool = True,
|
|
1864
1916
|
enabled: bool = True,
|
|
1865
1917
|
) -> int:
|
|
1866
|
-
"""Adds a compound joint to the model
|
|
1918
|
+
"""Adds a compound joint to the model, which has 3 degrees of freedom, one for each axis.
|
|
1919
|
+
Similar to the ball joint (see :meth:`add_ball_joint`), the compound joint allows bodies to move in a 3D rotation relative to each other,
|
|
1920
|
+
except that the rotation is defined by 3 axes instead of a quaternion.
|
|
1921
|
+
Depending on the choice of axes, the orientation can be specified through Euler angles, e.g. `z-x-z` or `x-y-x`, or through a Tait-Bryan angle sequence, e.g. `z-y-x` or `x-y-z`.
|
|
1867
1922
|
|
|
1868
1923
|
Args:
|
|
1869
1924
|
parent: The index of the parent body
|
|
1870
1925
|
child: The index of the child body
|
|
1871
|
-
axis_0: The first axis of the joint
|
|
1872
|
-
axis_1: The second axis of the joint
|
|
1873
|
-
axis_2: The third axis of the joint
|
|
1874
|
-
parent_xform: The transform of the joint in the parent body's local frame
|
|
1875
|
-
|
|
1926
|
+
axis_0 (3D vector or JointAxis): The first axis of the joint, can be a JointAxis object whose settings will be used instead of the other arguments
|
|
1927
|
+
axis_1 (3D vector or JointAxis): The second axis of the joint, can be a JointAxis object whose settings will be used instead of the other arguments
|
|
1928
|
+
axis_2 (3D vector or JointAxis): The third axis of the joint, can be a JointAxis object whose settings will be used instead of the other arguments
|
|
1929
|
+
parent_xform (:ref:`transform <transform>`): The transform of the joint in the parent body's local frame
|
|
1930
|
+
child_xform (:ref:`transform <transform>`): The transform of the joint in the child body's local frame
|
|
1876
1931
|
name: The name of the joint
|
|
1877
1932
|
collision_filter_parent: Whether to filter collisions between shapes of the parent and child bodies
|
|
1878
1933
|
enabled: Whether the joint is enabled
|
|
1879
1934
|
|
|
1880
1935
|
Returns:
|
|
1881
|
-
The index of the
|
|
1936
|
+
The index of the added joint
|
|
1882
1937
|
|
|
1883
1938
|
"""
|
|
1884
1939
|
return self.add_joint(
|
|
1885
1940
|
JOINT_COMPOUND,
|
|
1886
1941
|
parent,
|
|
1887
1942
|
child,
|
|
1888
|
-
angular_axes=[axis_0, axis_1, axis_2],
|
|
1943
|
+
angular_axes=[JointAxis(axis_0), JointAxis(axis_1), JointAxis(axis_2)],
|
|
1889
1944
|
parent_xform=parent_xform,
|
|
1890
1945
|
child_xform=child_xform,
|
|
1891
1946
|
name=name,
|
|
@@ -1907,7 +1962,7 @@ class ModelBuilder:
|
|
|
1907
1962
|
collision_filter_parent: bool = True,
|
|
1908
1963
|
enabled: bool = True,
|
|
1909
1964
|
):
|
|
1910
|
-
"""Adds a generic joint with custom linear and angular axes.
|
|
1965
|
+
"""Adds a generic joint with custom linear and angular axes. The number of axes determines the number of degrees of freedom of the joint.
|
|
1911
1966
|
|
|
1912
1967
|
Args:
|
|
1913
1968
|
parent: The index of the parent body
|
|
@@ -1915,15 +1970,15 @@ class ModelBuilder:
|
|
|
1915
1970
|
linear_axes: A list of linear axes
|
|
1916
1971
|
angular_axes: A list of angular axes
|
|
1917
1972
|
name: The name of the joint
|
|
1918
|
-
parent_xform: The transform of the joint in the parent body's local frame
|
|
1919
|
-
|
|
1973
|
+
parent_xform (:ref:`transform <transform>`): The transform of the joint in the parent body's local frame
|
|
1974
|
+
child_xform (:ref:`transform <transform>`): The transform of the joint in the child body's local frame
|
|
1920
1975
|
linear_compliance: The linear compliance of the joint
|
|
1921
1976
|
angular_compliance: The angular compliance of the joint
|
|
1922
1977
|
collision_filter_parent: Whether to filter collisions between shapes of the parent and child bodies
|
|
1923
1978
|
enabled: Whether the joint is enabled
|
|
1924
1979
|
|
|
1925
1980
|
Returns:
|
|
1926
|
-
The index of the
|
|
1981
|
+
The index of the added joint
|
|
1927
1982
|
|
|
1928
1983
|
"""
|
|
1929
1984
|
return self.add_joint(
|
|
@@ -1932,8 +1987,8 @@ class ModelBuilder:
|
|
|
1932
1987
|
child,
|
|
1933
1988
|
parent_xform=parent_xform,
|
|
1934
1989
|
child_xform=child_xform,
|
|
1935
|
-
linear_axes=linear_axes,
|
|
1936
|
-
angular_axes=angular_axes,
|
|
1990
|
+
linear_axes=[JointAxis(a) for a in linear_axes],
|
|
1991
|
+
angular_axes=[JointAxis(a) for a in angular_axes],
|
|
1937
1992
|
linear_compliance=linear_compliance,
|
|
1938
1993
|
angular_compliance=angular_compliance,
|
|
1939
1994
|
name=name,
|
|
@@ -1942,7 +1997,7 @@ class ModelBuilder:
|
|
|
1942
1997
|
)
|
|
1943
1998
|
|
|
1944
1999
|
def collapse_fixed_joints(self, verbose=wp.config.verbose):
|
|
1945
|
-
"""Removes fixed joints from the model and merges the bodies they connect."""
|
|
2000
|
+
"""Removes fixed joints from the model and merges the bodies they connect. This is useful for simplifying the model for faster and more stable simulation."""
|
|
1946
2001
|
|
|
1947
2002
|
body_data = {}
|
|
1948
2003
|
body_children = {-1: []}
|
|
@@ -2191,7 +2246,7 @@ class ModelBuilder:
|
|
|
2191
2246
|
def add_muscle(
|
|
2192
2247
|
self, bodies: List[int], positions: List[Vec3], f0: float, lm: float, lt: float, lmax: float, pen: float
|
|
2193
2248
|
) -> float:
|
|
2194
|
-
"""Adds a muscle-tendon activation unit
|
|
2249
|
+
"""Adds a muscle-tendon activation unit.
|
|
2195
2250
|
|
|
2196
2251
|
Args:
|
|
2197
2252
|
bodies: A list of body indices for each waypoint
|
|
@@ -2204,6 +2259,8 @@ class ModelBuilder:
|
|
|
2204
2259
|
Returns:
|
|
2205
2260
|
The index of the muscle in the model
|
|
2206
2261
|
|
|
2262
|
+
.. note:: The simulation support for muscles is in progress and not yet fully functional.
|
|
2263
|
+
|
|
2207
2264
|
"""
|
|
2208
2265
|
|
|
2209
2266
|
n = len(bodies)
|
|
@@ -2239,7 +2296,7 @@ class ModelBuilder:
|
|
|
2239
2296
|
"""
|
|
2240
2297
|
Adds a plane collision shape.
|
|
2241
2298
|
If pos and rot are defined, the plane is assumed to have its normal as (0, 1, 0).
|
|
2242
|
-
Otherwise, the plane equation is used.
|
|
2299
|
+
Otherwise, the plane equation defined through the `plane` argument is used.
|
|
2243
2300
|
|
|
2244
2301
|
Args:
|
|
2245
2302
|
plane: The plane equation in form a*x + b*y + c*z + d = 0
|
|
@@ -2256,6 +2313,9 @@ class ModelBuilder:
|
|
|
2256
2313
|
thickness: The thickness of the plane (0 by default) for collision handling
|
|
2257
2314
|
has_ground_collision: If True, the mesh will collide with the ground plane if `Model.ground` is True
|
|
2258
2315
|
|
|
2316
|
+
Returns:
|
|
2317
|
+
The index of the added shape
|
|
2318
|
+
|
|
2259
2319
|
"""
|
|
2260
2320
|
if pos is None or rot is None:
|
|
2261
2321
|
# compute position and rotation from plane equation
|
|
@@ -2270,7 +2330,7 @@ class ModelBuilder:
|
|
|
2270
2330
|
angle = np.arcsin(np.linalg.norm(c))
|
|
2271
2331
|
axis = c / np.linalg.norm(c)
|
|
2272
2332
|
rot = wp.quat_from_axis_angle(axis, angle)
|
|
2273
|
-
scale = (width, length, 0.0)
|
|
2333
|
+
scale = wp.vec3(width, length, 0.0)
|
|
2274
2334
|
|
|
2275
2335
|
return self._add_shape(
|
|
2276
2336
|
body,
|
|
@@ -2308,7 +2368,7 @@ class ModelBuilder:
|
|
|
2308
2368
|
"""Adds a sphere collision shape to a body.
|
|
2309
2369
|
|
|
2310
2370
|
Args:
|
|
2311
|
-
body: The index of the parent body this shape belongs to
|
|
2371
|
+
body: The index of the parent body this shape belongs to (use -1 for static shapes)
|
|
2312
2372
|
pos: The location of the shape with respect to the parent frame
|
|
2313
2373
|
rot: The rotation of the shape with respect to the parent frame
|
|
2314
2374
|
radius: The radius of the sphere
|
|
@@ -2322,14 +2382,17 @@ class ModelBuilder:
|
|
|
2322
2382
|
thickness: Thickness to use for computing inertia of a hollow sphere, and for collision handling
|
|
2323
2383
|
has_ground_collision: If True, the mesh will collide with the ground plane if `Model.ground` is True
|
|
2324
2384
|
|
|
2385
|
+
Returns:
|
|
2386
|
+
The index of the added shape
|
|
2387
|
+
|
|
2325
2388
|
"""
|
|
2326
2389
|
|
|
2327
2390
|
return self._add_shape(
|
|
2328
2391
|
body,
|
|
2329
|
-
pos,
|
|
2330
|
-
rot,
|
|
2392
|
+
wp.vec3(pos),
|
|
2393
|
+
wp.quat(rot),
|
|
2331
2394
|
GEO_SPHERE,
|
|
2332
|
-
(radius, 0.0, 0.0
|
|
2395
|
+
wp.vec3(radius, 0.0, 0.0),
|
|
2333
2396
|
None,
|
|
2334
2397
|
density,
|
|
2335
2398
|
ke,
|
|
@@ -2363,7 +2426,7 @@ class ModelBuilder:
|
|
|
2363
2426
|
"""Adds a box collision shape to a body.
|
|
2364
2427
|
|
|
2365
2428
|
Args:
|
|
2366
|
-
body: The index of the parent body this shape belongs to
|
|
2429
|
+
body: The index of the parent body this shape belongs to (use -1 for static shapes)
|
|
2367
2430
|
pos: The location of the shape with respect to the parent frame
|
|
2368
2431
|
rot: The rotation of the shape with respect to the parent frame
|
|
2369
2432
|
hx: The half-extent along the x-axis
|
|
@@ -2379,14 +2442,17 @@ class ModelBuilder:
|
|
|
2379
2442
|
thickness: Thickness to use for computing inertia of a hollow box, and for collision handling
|
|
2380
2443
|
has_ground_collision: If True, the mesh will collide with the ground plane if `Model.ground` is True
|
|
2381
2444
|
|
|
2445
|
+
Returns:
|
|
2446
|
+
The index of the added shape
|
|
2447
|
+
|
|
2382
2448
|
"""
|
|
2383
2449
|
|
|
2384
2450
|
return self._add_shape(
|
|
2385
2451
|
body,
|
|
2386
|
-
pos,
|
|
2387
|
-
rot,
|
|
2452
|
+
wp.vec3(pos),
|
|
2453
|
+
wp.quat(rot),
|
|
2388
2454
|
GEO_BOX,
|
|
2389
|
-
(hx, hy, hz
|
|
2455
|
+
wp.vec3(hx, hy, hz),
|
|
2390
2456
|
None,
|
|
2391
2457
|
density,
|
|
2392
2458
|
ke,
|
|
@@ -2420,7 +2486,7 @@ class ModelBuilder:
|
|
|
2420
2486
|
"""Adds a capsule collision shape to a body.
|
|
2421
2487
|
|
|
2422
2488
|
Args:
|
|
2423
|
-
body: The index of the parent body this shape belongs to
|
|
2489
|
+
body: The index of the parent body this shape belongs to (use -1 for static shapes)
|
|
2424
2490
|
pos: The location of the shape with respect to the parent frame
|
|
2425
2491
|
rot: The rotation of the shape with respect to the parent frame
|
|
2426
2492
|
radius: The radius of the capsule
|
|
@@ -2436,21 +2502,24 @@ class ModelBuilder:
|
|
|
2436
2502
|
thickness: Thickness to use for computing inertia of a hollow capsule, and for collision handling
|
|
2437
2503
|
has_ground_collision: If True, the mesh will collide with the ground plane if `Model.ground` is True
|
|
2438
2504
|
|
|
2505
|
+
Returns:
|
|
2506
|
+
The index of the added shape
|
|
2507
|
+
|
|
2439
2508
|
"""
|
|
2440
2509
|
|
|
2441
|
-
q = rot
|
|
2510
|
+
q = wp.quat(rot)
|
|
2442
2511
|
sqh = math.sqrt(0.5)
|
|
2443
2512
|
if up_axis == 0:
|
|
2444
|
-
q = wp.mul(
|
|
2513
|
+
q = wp.mul(q, wp.quat(0.0, 0.0, -sqh, sqh))
|
|
2445
2514
|
elif up_axis == 2:
|
|
2446
|
-
q = wp.mul(
|
|
2515
|
+
q = wp.mul(q, wp.quat(sqh, 0.0, 0.0, sqh))
|
|
2447
2516
|
|
|
2448
2517
|
return self._add_shape(
|
|
2449
2518
|
body,
|
|
2450
|
-
pos,
|
|
2451
|
-
q,
|
|
2519
|
+
wp.vec3(pos),
|
|
2520
|
+
wp.quat(q),
|
|
2452
2521
|
GEO_CAPSULE,
|
|
2453
|
-
(radius, half_height, 0.0
|
|
2522
|
+
wp.vec3(radius, half_height, 0.0),
|
|
2454
2523
|
None,
|
|
2455
2524
|
density,
|
|
2456
2525
|
ke,
|
|
@@ -2484,7 +2553,7 @@ class ModelBuilder:
|
|
|
2484
2553
|
"""Adds a cylinder collision shape to a body.
|
|
2485
2554
|
|
|
2486
2555
|
Args:
|
|
2487
|
-
body: The index of the parent body this shape belongs to
|
|
2556
|
+
body: The index of the parent body this shape belongs to (use -1 for static shapes)
|
|
2488
2557
|
pos: The location of the shape with respect to the parent frame
|
|
2489
2558
|
rot: The rotation of the shape with respect to the parent frame
|
|
2490
2559
|
radius: The radius of the cylinder
|
|
@@ -2500,6 +2569,9 @@ class ModelBuilder:
|
|
|
2500
2569
|
thickness: Thickness to use for computing inertia of a hollow cylinder, and for collision handling
|
|
2501
2570
|
has_ground_collision: If True, the mesh will collide with the ground plane if `Model.ground` is True
|
|
2502
2571
|
|
|
2572
|
+
Returns:
|
|
2573
|
+
The index of the added shape
|
|
2574
|
+
|
|
2503
2575
|
"""
|
|
2504
2576
|
|
|
2505
2577
|
q = rot
|
|
@@ -2511,10 +2583,10 @@ class ModelBuilder:
|
|
|
2511
2583
|
|
|
2512
2584
|
return self._add_shape(
|
|
2513
2585
|
body,
|
|
2514
|
-
pos,
|
|
2515
|
-
q,
|
|
2586
|
+
wp.vec3(pos),
|
|
2587
|
+
wp.quat(q),
|
|
2516
2588
|
GEO_CYLINDER,
|
|
2517
|
-
(radius, half_height, 0.0
|
|
2589
|
+
wp.vec3(radius, half_height, 0.0),
|
|
2518
2590
|
None,
|
|
2519
2591
|
density,
|
|
2520
2592
|
ke,
|
|
@@ -2548,7 +2620,7 @@ class ModelBuilder:
|
|
|
2548
2620
|
"""Adds a cone collision shape to a body.
|
|
2549
2621
|
|
|
2550
2622
|
Args:
|
|
2551
|
-
body: The index of the parent body this shape belongs to
|
|
2623
|
+
body: The index of the parent body this shape belongs to (use -1 for static shapes)
|
|
2552
2624
|
pos: The location of the shape with respect to the parent frame
|
|
2553
2625
|
rot: The rotation of the shape with respect to the parent frame
|
|
2554
2626
|
radius: The radius of the cone
|
|
@@ -2564,6 +2636,9 @@ class ModelBuilder:
|
|
|
2564
2636
|
thickness: Thickness to use for computing inertia of a hollow cone, and for collision handling
|
|
2565
2637
|
has_ground_collision: If True, the mesh will collide with the ground plane if `Model.ground` is True
|
|
2566
2638
|
|
|
2639
|
+
Returns:
|
|
2640
|
+
The index of the added shape
|
|
2641
|
+
|
|
2567
2642
|
"""
|
|
2568
2643
|
|
|
2569
2644
|
q = rot
|
|
@@ -2575,10 +2650,10 @@ class ModelBuilder:
|
|
|
2575
2650
|
|
|
2576
2651
|
return self._add_shape(
|
|
2577
2652
|
body,
|
|
2578
|
-
pos,
|
|
2579
|
-
q,
|
|
2653
|
+
wp.vec3(pos),
|
|
2654
|
+
wp.quat(q),
|
|
2580
2655
|
GEO_CONE,
|
|
2581
|
-
(radius, half_height, 0.0
|
|
2656
|
+
wp.vec3(radius, half_height, 0.0),
|
|
2582
2657
|
None,
|
|
2583
2658
|
density,
|
|
2584
2659
|
ke,
|
|
@@ -2594,10 +2669,10 @@ class ModelBuilder:
|
|
|
2594
2669
|
def add_shape_mesh(
|
|
2595
2670
|
self,
|
|
2596
2671
|
body: int,
|
|
2597
|
-
pos: Vec3 = (0.0, 0.0, 0.0),
|
|
2598
|
-
rot: Quat = (0.0, 0.0, 0.0, 1.0),
|
|
2672
|
+
pos: Vec3 = wp.vec3(0.0, 0.0, 0.0),
|
|
2673
|
+
rot: Quat = wp.quat(0.0, 0.0, 0.0, 1.0),
|
|
2599
2674
|
mesh: Mesh = None,
|
|
2600
|
-
scale: Vec3 = (1.0, 1.0, 1.0),
|
|
2675
|
+
scale: Vec3 = wp.vec3(1.0, 1.0, 1.0),
|
|
2601
2676
|
density: float = default_shape_density,
|
|
2602
2677
|
ke: float = default_shape_ke,
|
|
2603
2678
|
kd: float = default_shape_kd,
|
|
@@ -2611,7 +2686,7 @@ class ModelBuilder:
|
|
|
2611
2686
|
"""Adds a triangle mesh collision shape to a body.
|
|
2612
2687
|
|
|
2613
2688
|
Args:
|
|
2614
|
-
body: The index of the parent body this shape belongs to
|
|
2689
|
+
body: The index of the parent body this shape belongs to (use -1 for static shapes)
|
|
2615
2690
|
pos: The location of the shape with respect to the parent frame
|
|
2616
2691
|
rot: The rotation of the shape with respect to the parent frame
|
|
2617
2692
|
mesh: The mesh object
|
|
@@ -2626,6 +2701,9 @@ class ModelBuilder:
|
|
|
2626
2701
|
thickness: Thickness to use for computing inertia of a hollow mesh, and for collision handling
|
|
2627
2702
|
has_ground_collision: If True, the mesh will collide with the ground plane if `Model.ground` is True
|
|
2628
2703
|
|
|
2704
|
+
Returns:
|
|
2705
|
+
The index of the added shape
|
|
2706
|
+
|
|
2629
2707
|
"""
|
|
2630
2708
|
|
|
2631
2709
|
return self._add_shape(
|
|
@@ -2633,7 +2711,7 @@ class ModelBuilder:
|
|
|
2633
2711
|
pos,
|
|
2634
2712
|
rot,
|
|
2635
2713
|
GEO_MESH,
|
|
2636
|
-
(scale[0], scale[1], scale[2]
|
|
2714
|
+
wp.vec3(scale[0], scale[1], scale[2]),
|
|
2637
2715
|
mesh,
|
|
2638
2716
|
density,
|
|
2639
2717
|
ke,
|
|
@@ -2665,7 +2743,7 @@ class ModelBuilder:
|
|
|
2665
2743
|
"""Adds SDF collision shape to a body.
|
|
2666
2744
|
|
|
2667
2745
|
Args:
|
|
2668
|
-
body: The index of the parent body this shape belongs to
|
|
2746
|
+
body: The index of the parent body this shape belongs to (use -1 for static shapes)
|
|
2669
2747
|
pos: The location of the shape with respect to the parent frame
|
|
2670
2748
|
rot: The rotation of the shape with respect to the parent frame
|
|
2671
2749
|
sdf: The sdf object
|
|
@@ -2680,13 +2758,16 @@ class ModelBuilder:
|
|
|
2680
2758
|
thickness: Thickness to use for computing inertia of a hollow mesh, and for collision handling
|
|
2681
2759
|
has_ground_collision: If True, the mesh will collide with the ground plane if `Model.ground` is True
|
|
2682
2760
|
|
|
2761
|
+
Returns:
|
|
2762
|
+
The index of the added shape
|
|
2763
|
+
|
|
2683
2764
|
"""
|
|
2684
2765
|
return self._add_shape(
|
|
2685
2766
|
body,
|
|
2686
|
-
pos,
|
|
2687
|
-
rot,
|
|
2767
|
+
wp.vec3(pos),
|
|
2768
|
+
wp.quat(rot),
|
|
2688
2769
|
GEO_SDF,
|
|
2689
|
-
(scale[0], scale[1], scale[2]
|
|
2770
|
+
wp.vec3(scale[0], scale[1], scale[2]),
|
|
2690
2771
|
sdf,
|
|
2691
2772
|
density,
|
|
2692
2773
|
ke,
|
|
@@ -2777,7 +2858,7 @@ class ModelBuilder:
|
|
|
2777
2858
|
|
|
2778
2859
|
(m, c, I) = compute_shape_mass(type, scale, src, density, is_solid, thickness)
|
|
2779
2860
|
|
|
2780
|
-
self._update_body_mass(body, m, I,
|
|
2861
|
+
self._update_body_mass(body, m, I, pos + c, rot)
|
|
2781
2862
|
return shape
|
|
2782
2863
|
|
|
2783
2864
|
# particles
|
|
@@ -2872,9 +2953,9 @@ class ModelBuilder:
|
|
|
2872
2953
|
|
|
2873
2954
|
"""
|
|
2874
2955
|
# compute basis for 2D rest pose
|
|
2875
|
-
p =
|
|
2876
|
-
q =
|
|
2877
|
-
r =
|
|
2956
|
+
p = self.particle_q[i]
|
|
2957
|
+
q = self.particle_q[j]
|
|
2958
|
+
r = self.particle_q[k]
|
|
2878
2959
|
|
|
2879
2960
|
qp = q - p
|
|
2880
2961
|
rp = r - p
|
|
@@ -3012,7 +3093,7 @@ class ModelBuilder:
|
|
|
3012
3093
|
The volume of the tetrahedron
|
|
3013
3094
|
|
|
3014
3095
|
Note:
|
|
3015
|
-
The tetrahedron is created with a rest-pose based on the particle's initial
|
|
3096
|
+
The tetrahedron is created with a rest-pose based on the particle's initial configuration
|
|
3016
3097
|
|
|
3017
3098
|
"""
|
|
3018
3099
|
# compute basis for 2D rest pose
|
|
@@ -3071,13 +3152,13 @@ class ModelBuilder:
|
|
|
3071
3152
|
"""
|
|
3072
3153
|
# compute rest angle
|
|
3073
3154
|
if rest is None:
|
|
3074
|
-
x1 =
|
|
3075
|
-
x2 =
|
|
3076
|
-
x3 =
|
|
3077
|
-
x4 =
|
|
3155
|
+
x1 = self.particle_q[i]
|
|
3156
|
+
x2 = self.particle_q[j]
|
|
3157
|
+
x3 = self.particle_q[k]
|
|
3158
|
+
x4 = self.particle_q[l]
|
|
3078
3159
|
|
|
3079
|
-
n1 = wp.normalize(
|
|
3080
|
-
n2 = wp.normalize(
|
|
3160
|
+
n1 = wp.normalize(wp.cross(x3 - x1, x4 - x1))
|
|
3161
|
+
n2 = wp.normalize(wp.cross(x4 - x2, x3 - x2))
|
|
3081
3162
|
e = wp.normalize(x4 - x3)
|
|
3082
3163
|
|
|
3083
3164
|
d = np.clip(np.dot(n2, n1), -1.0, 1.0)
|
|
@@ -3217,8 +3298,8 @@ class ModelBuilder:
|
|
|
3217
3298
|
|
|
3218
3299
|
for y in range(0, dim_y + 1):
|
|
3219
3300
|
for x in range(0, dim_x + 1):
|
|
3220
|
-
g =
|
|
3221
|
-
p =
|
|
3301
|
+
g = wp.vec3(x * cell_x, y * cell_y, 0.0)
|
|
3302
|
+
p = wp.quat_rotate(rot, g) + pos
|
|
3222
3303
|
m = mass
|
|
3223
3304
|
|
|
3224
3305
|
if x == 0 and fix_left:
|
|
@@ -3265,7 +3346,6 @@ class ModelBuilder:
|
|
|
3265
3346
|
self.add_triangle(*tri1, tri_ke, tri_ka, tri_kd, tri_drag, tri_lift)
|
|
3266
3347
|
self.add_triangle(*tri2, tri_ke, tri_ka, tri_kd, tri_drag, tri_lift)
|
|
3267
3348
|
|
|
3268
|
-
end_vertex = len(self.particle_q)
|
|
3269
3349
|
end_tri = len(self.tri_indices)
|
|
3270
3350
|
|
|
3271
3351
|
# bending constraints, could create these explicitly for a grid but this
|
|
@@ -3344,7 +3424,7 @@ class ModelBuilder:
|
|
|
3344
3424
|
|
|
3345
3425
|
# particles
|
|
3346
3426
|
for v in vertices:
|
|
3347
|
-
p =
|
|
3427
|
+
p = wp.quat_rotate(rot, v * scale) + pos
|
|
3348
3428
|
|
|
3349
3429
|
self.add_particle(p, vel, 0.0)
|
|
3350
3430
|
|
|
@@ -3417,13 +3497,14 @@ class ModelBuilder:
|
|
|
3417
3497
|
radius_mean: float = default_particle_radius,
|
|
3418
3498
|
radius_std: float = 0.0,
|
|
3419
3499
|
):
|
|
3500
|
+
rng = np.random.default_rng()
|
|
3420
3501
|
for z in range(dim_z):
|
|
3421
3502
|
for y in range(dim_y):
|
|
3422
3503
|
for x in range(dim_x):
|
|
3423
|
-
v =
|
|
3504
|
+
v = wp.vec3(x * cell_x, y * cell_y, z * cell_z)
|
|
3424
3505
|
m = mass
|
|
3425
3506
|
|
|
3426
|
-
p =
|
|
3507
|
+
p = wp.quat_rotate(rot, v) + pos + wp.vec3(rng.random(3) * jitter)
|
|
3427
3508
|
|
|
3428
3509
|
if radius_std > 0.0:
|
|
3429
3510
|
r = radius_mean + np.random.randn() * radius_std
|
|
@@ -3489,7 +3570,7 @@ class ModelBuilder:
|
|
|
3489
3570
|
for z in range(dim_z + 1):
|
|
3490
3571
|
for y in range(dim_y + 1):
|
|
3491
3572
|
for x in range(dim_x + 1):
|
|
3492
|
-
v =
|
|
3573
|
+
v = wp.vec3(x * cell_x, y * cell_y, z * cell_z)
|
|
3493
3574
|
m = mass
|
|
3494
3575
|
|
|
3495
3576
|
if fix_left and x == 0:
|
|
@@ -3504,7 +3585,7 @@ class ModelBuilder:
|
|
|
3504
3585
|
if fix_bottom and y == 0:
|
|
3505
3586
|
m = 0.0
|
|
3506
3587
|
|
|
3507
|
-
p =
|
|
3588
|
+
p = wp.quat_rotate(rot, v) + pos
|
|
3508
3589
|
|
|
3509
3590
|
self.add_particle(p, vel, m)
|
|
3510
3591
|
|
|
@@ -3594,7 +3675,6 @@ class ModelBuilder:
|
|
|
3594
3675
|
num_tets = int(len(indices) / 4)
|
|
3595
3676
|
|
|
3596
3677
|
start_vertex = len(self.particle_q)
|
|
3597
|
-
start_tri = len(self.tri_indices)
|
|
3598
3678
|
|
|
3599
3679
|
# dict of open faces
|
|
3600
3680
|
faces = {}
|
|
@@ -3672,8 +3752,8 @@ class ModelBuilder:
|
|
|
3672
3752
|
else:
|
|
3673
3753
|
self.body_inv_mass[i] = 0.0
|
|
3674
3754
|
|
|
3675
|
-
if
|
|
3676
|
-
self.body_inv_inertia[i] =
|
|
3755
|
+
if any(x for x in new_inertia):
|
|
3756
|
+
self.body_inv_inertia[i] = wp.inverse(new_inertia)
|
|
3677
3757
|
else:
|
|
3678
3758
|
self.body_inv_inertia[i] = new_inertia
|
|
3679
3759
|
|