warp-lang 0.10.1__py3-none-win_amd64.whl → 0.11.0__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 +10 -4
- warp/__init__.pyi +1 -0
- warp/bin/warp-clang.dll +0 -0
- warp/bin/warp.dll +0 -0
- warp/build.py +5 -3
- warp/build_dll.py +29 -9
- warp/builtins.py +868 -507
- warp/codegen.py +1074 -638
- warp/config.py +3 -3
- warp/constants.py +6 -0
- warp/context.py +715 -222
- warp/fabric.py +326 -0
- warp/fem/__init__.py +27 -0
- warp/fem/cache.py +389 -0
- warp/fem/dirichlet.py +181 -0
- warp/fem/domain.py +263 -0
- warp/fem/field/__init__.py +101 -0
- warp/fem/field/field.py +149 -0
- warp/fem/field/nodal_field.py +299 -0
- warp/fem/field/restriction.py +21 -0
- warp/fem/field/test.py +181 -0
- warp/fem/field/trial.py +183 -0
- warp/fem/geometry/__init__.py +19 -0
- warp/fem/geometry/closest_point.py +70 -0
- warp/fem/geometry/deformed_geometry.py +271 -0
- warp/fem/geometry/element.py +744 -0
- warp/fem/geometry/geometry.py +186 -0
- warp/fem/geometry/grid_2d.py +373 -0
- warp/fem/geometry/grid_3d.py +435 -0
- warp/fem/geometry/hexmesh.py +953 -0
- warp/fem/geometry/partition.py +376 -0
- warp/fem/geometry/quadmesh_2d.py +532 -0
- warp/fem/geometry/tetmesh.py +840 -0
- warp/fem/geometry/trimesh_2d.py +577 -0
- warp/fem/integrate.py +1616 -0
- warp/fem/operator.py +191 -0
- warp/fem/polynomial.py +213 -0
- warp/fem/quadrature/__init__.py +2 -0
- warp/fem/quadrature/pic_quadrature.py +245 -0
- warp/fem/quadrature/quadrature.py +294 -0
- warp/fem/space/__init__.py +292 -0
- warp/fem/space/basis_space.py +489 -0
- warp/fem/space/collocated_function_space.py +105 -0
- warp/fem/space/dof_mapper.py +236 -0
- warp/fem/space/function_space.py +145 -0
- warp/fem/space/grid_2d_function_space.py +267 -0
- warp/fem/space/grid_3d_function_space.py +306 -0
- warp/fem/space/hexmesh_function_space.py +352 -0
- warp/fem/space/partition.py +350 -0
- warp/fem/space/quadmesh_2d_function_space.py +369 -0
- warp/fem/space/restriction.py +160 -0
- 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 +292 -0
- warp/fem/space/topology.py +295 -0
- warp/fem/space/trimesh_2d_function_space.py +221 -0
- warp/fem/types.py +77 -0
- warp/fem/utils.py +495 -0
- warp/native/array.h +147 -44
- warp/native/builtin.h +122 -149
- warp/native/bvh.cpp +73 -325
- warp/native/bvh.cu +406 -23
- warp/native/bvh.h +34 -43
- warp/native/clang/clang.cpp +13 -8
- warp/native/crt.h +2 -0
- warp/native/cuda_crt.h +5 -0
- warp/native/cuda_util.cpp +15 -3
- warp/native/cuda_util.h +3 -1
- warp/native/cutlass/tools/library/scripts/conv2d_operation.py +463 -0
- warp/native/cutlass/tools/library/scripts/conv3d_operation.py +321 -0
- warp/native/cutlass/tools/library/scripts/gemm_operation.py +988 -0
- warp/native/cutlass/tools/library/scripts/generator.py +4625 -0
- warp/native/cutlass/tools/library/scripts/library.py +799 -0
- warp/native/cutlass/tools/library/scripts/manifest.py +402 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/docs/source/conf.py +96 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/profile/conv/conv2d_f16_sm80.py +106 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/profile/gemm/gemm_f32_sm80.py +91 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/setup.py +80 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/__init__.py +48 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/arguments.py +118 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/c_types.py +241 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/compiler.py +432 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/conv2d_operation.py +631 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/epilogue.py +1026 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/frontend.py +104 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/gemm_operation.py +1276 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/library.py +744 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/memory_manager.py +74 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/operation.py +110 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/parser.py +619 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/reduction_operation.py +398 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/tensor_ref.py +70 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/__init__.py +4 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/conv2d_testbed.py +646 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/gemm_grouped_testbed.py +235 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/gemm_testbed.py +557 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/profiler.py +70 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/type_hint.py +39 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/__init__.py +1 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/device.py +76 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/reference_model.py +255 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/__init__.py +0 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +201 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +177 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +98 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +95 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_few_channels_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_sm80.py +163 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_fixed_channels_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_sm80.py +187 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +309 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +54 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +96 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +107 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_strided_dgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +253 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +97 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +242 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +96 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +107 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/run_all_tests.py +10 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/frontend/test_frontend.py +146 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/__init__.py +0 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_bf16_sm80.py +96 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f16_sm80.py +447 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f32_sm80.py +146 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f64_sm80.py +102 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_grouped_sm80.py +203 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_s8_sm80.py +229 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/run_all_tests.py +9 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/unit/test_sm80.py +453 -0
- warp/native/cutlass/tools/library/scripts/rank_2k_operation.py +398 -0
- warp/native/cutlass/tools/library/scripts/rank_k_operation.py +387 -0
- warp/native/cutlass/tools/library/scripts/rt.py +796 -0
- warp/native/cutlass/tools/library/scripts/symm_operation.py +400 -0
- warp/native/cutlass/tools/library/scripts/trmm_operation.py +407 -0
- warp/native/cutlass_gemm.cu +5 -3
- warp/native/exports.h +1240 -952
- warp/native/fabric.h +228 -0
- warp/native/hashgrid.cpp +4 -4
- warp/native/hashgrid.h +22 -2
- warp/native/intersect.h +22 -7
- warp/native/intersect_adj.h +8 -8
- warp/native/intersect_tri.h +1 -1
- warp/native/marching.cu +157 -161
- warp/native/mat.h +80 -19
- warp/native/matnn.h +2 -2
- warp/native/mesh.cpp +33 -108
- warp/native/mesh.cu +114 -23
- warp/native/mesh.h +446 -46
- warp/native/noise.h +272 -329
- warp/native/quat.h +51 -8
- warp/native/rand.h +45 -35
- warp/native/range.h +6 -2
- warp/native/reduce.cpp +1 -1
- warp/native/reduce.cu +10 -12
- warp/native/runlength_encode.cu +6 -10
- warp/native/scan.cu +8 -11
- warp/native/sparse.cpp +4 -4
- warp/native/sparse.cu +164 -154
- warp/native/spatial.h +2 -2
- warp/native/temp_buffer.h +14 -30
- warp/native/vec.h +107 -23
- warp/native/volume.h +120 -0
- warp/native/warp.cpp +560 -30
- warp/native/warp.cu +431 -44
- warp/native/warp.h +13 -4
- warp/optim/__init__.py +1 -0
- warp/optim/linear.py +922 -0
- warp/optim/sgd.py +92 -0
- warp/render/render_opengl.py +335 -119
- warp/render/render_usd.py +11 -11
- warp/sim/__init__.py +2 -2
- warp/sim/articulation.py +385 -185
- warp/sim/collide.py +8 -0
- warp/sim/import_mjcf.py +297 -106
- warp/sim/import_urdf.py +389 -210
- warp/sim/import_usd.py +198 -97
- warp/sim/inertia.py +17 -18
- warp/sim/integrator_euler.py +14 -8
- warp/sim/integrator_xpbd.py +158 -16
- warp/sim/model.py +795 -291
- warp/sim/render.py +3 -3
- warp/sim/utils.py +3 -0
- warp/sparse.py +640 -150
- warp/stubs.py +606 -267
- warp/tape.py +61 -10
- 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 +128 -74
- warp/tests/test_array.py +212 -97
- warp/tests/test_array_reduce.py +57 -23
- warp/tests/test_atomic.py +64 -28
- warp/tests/test_bool.py +99 -0
- warp/tests/test_builtins_resolution.py +1292 -0
- warp/tests/test_bvh.py +42 -18
- warp/tests/test_closest_point_edge_edge.py +54 -57
- warp/tests/test_codegen.py +208 -130
- 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 +277 -0
- warp/tests/test_fabricarray.py +955 -0
- warp/tests/test_fast_math.py +15 -11
- warp/tests/test_fem.py +1271 -0
- warp/tests/test_fp16.py +53 -19
- warp/tests/test_func.py +187 -86
- warp/tests/test_generics.py +194 -49
- warp/tests/test_grad.py +178 -109
- warp/tests/test_grad_customs.py +176 -0
- warp/tests/test_hash_grid.py +52 -37
- warp/tests/test_import.py +10 -23
- warp/tests/test_indexedarray.py +32 -31
- 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_linear_solvers.py +154 -0
- 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 +305 -69
- warp/tests/test_matmul_lite.py +410 -0
- warp/tests/test_mesh.py +71 -14
- warp/tests/test_mesh_query_aabb.py +41 -25
- warp/tests/test_mesh_query_point.py +140 -22
- warp/tests/test_mesh_query_ray.py +39 -22
- 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 +118 -89
- warp/tests/test_transient_module.py +12 -13
- warp/tests/test_types.py +614 -0
- warp/tests/test_utils.py +494 -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 +457 -293
- warp/tests/test_volume_write.py +124 -134
- warp/tests/unittest_serial.py +35 -0
- warp/tests/unittest_suites.py +341 -0
- warp/tests/unittest_utils.py +568 -0
- warp/tests/unused_test_misc.py +71 -0
- warp/tests/{test_debug.py → walkthough_debug.py} +3 -17
- warp/thirdparty/appdirs.py +36 -45
- warp/thirdparty/unittest_parallel.py +549 -0
- warp/torch.py +9 -6
- warp/types.py +1089 -366
- warp/utils.py +93 -387
- warp_lang-0.11.0.dist-info/METADATA +238 -0
- warp_lang-0.11.0.dist-info/RECORD +332 -0
- {warp_lang-0.10.1.dist-info → warp_lang-0.11.0.dist-info}/WHEEL +1 -1
- warp/tests/test_all.py +0 -219
- 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-0.10.1.dist-info/METADATA +0 -21
- warp_lang-0.10.1.dist-info/RECORD +0 -188
- /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-0.10.1.dist-info → warp_lang-0.11.0.dist-info}/LICENSE.md +0 -0
- {warp_lang-0.10.1.dist-info → warp_lang-0.11.0.dist-info}/top_level.txt +0 -0
warp/sim/articulation.py
CHANGED
|
@@ -7,7 +7,161 @@
|
|
|
7
7
|
|
|
8
8
|
import warp as wp
|
|
9
9
|
|
|
10
|
-
from .utils import quat_decompose, quat_twist
|
|
10
|
+
from .utils import quat_decompose, quat_twist
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@wp.func
|
|
14
|
+
def compute_2d_rotational_dofs(
|
|
15
|
+
axis_0: wp.vec3,
|
|
16
|
+
axis_1: wp.vec3,
|
|
17
|
+
q0: float,
|
|
18
|
+
q1: float,
|
|
19
|
+
qd0: float,
|
|
20
|
+
qd1: float,
|
|
21
|
+
):
|
|
22
|
+
"""
|
|
23
|
+
Computes the rotation quaternion and 3D angular velocity given the joint axes, coordinates and velocities.
|
|
24
|
+
"""
|
|
25
|
+
q_off = wp.quat_from_matrix(wp.mat33(axis_0, axis_1, wp.cross(axis_0, axis_1)))
|
|
26
|
+
|
|
27
|
+
# body local axes
|
|
28
|
+
local_0 = wp.quat_rotate(q_off, wp.vec3(1.0, 0.0, 0.0))
|
|
29
|
+
local_1 = wp.quat_rotate(q_off, wp.vec3(0.0, 1.0, 0.0))
|
|
30
|
+
|
|
31
|
+
axis_0 = local_0
|
|
32
|
+
q_0 = wp.quat_from_axis_angle(axis_0, q0)
|
|
33
|
+
|
|
34
|
+
axis_1 = wp.quat_rotate(q_0, local_1)
|
|
35
|
+
q_1 = wp.quat_from_axis_angle(axis_1, q1)
|
|
36
|
+
|
|
37
|
+
rot = q_1 * q_0
|
|
38
|
+
|
|
39
|
+
vel = axis_0 * qd0 + axis_1 * qd1
|
|
40
|
+
|
|
41
|
+
return rot, vel
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@wp.func
|
|
45
|
+
def invert_2d_rotational_dofs(
|
|
46
|
+
axis_0: wp.vec3,
|
|
47
|
+
axis_1: wp.vec3,
|
|
48
|
+
q_p: wp.quat,
|
|
49
|
+
q_c: wp.quat,
|
|
50
|
+
w_err: wp.vec3,
|
|
51
|
+
):
|
|
52
|
+
"""
|
|
53
|
+
Computes generalized joint position and velocity coordinates for a 2D rotational joint given the joint axes, relative orientations and angular velocity differences between the two bodies the joint connects.
|
|
54
|
+
"""
|
|
55
|
+
q_off = wp.quat_from_matrix(wp.mat33(axis_0, axis_1, wp.cross(axis_0, axis_1)))
|
|
56
|
+
q_pc = wp.quat_inverse(q_off) * wp.quat_inverse(q_p) * q_c * q_off
|
|
57
|
+
|
|
58
|
+
# decompose to a compound rotation each axis
|
|
59
|
+
angles = quat_decompose(q_pc)
|
|
60
|
+
|
|
61
|
+
# find rotation axes
|
|
62
|
+
local_0 = wp.quat_rotate(q_off, wp.vec3(1.0, 0.0, 0.0))
|
|
63
|
+
local_1 = wp.quat_rotate(q_off, wp.vec3(0.0, 1.0, 0.0))
|
|
64
|
+
local_2 = wp.quat_rotate(q_off, wp.vec3(0.0, 0.0, 1.0))
|
|
65
|
+
|
|
66
|
+
axis_0 = local_0
|
|
67
|
+
q_0 = wp.quat_from_axis_angle(axis_0, angles[0])
|
|
68
|
+
|
|
69
|
+
axis_1 = wp.quat_rotate(q_0, local_1)
|
|
70
|
+
q_1 = wp.quat_from_axis_angle(axis_1, angles[1])
|
|
71
|
+
|
|
72
|
+
axis_2 = wp.quat_rotate(q_1 * q_0, local_2)
|
|
73
|
+
|
|
74
|
+
# convert angular velocity to local space
|
|
75
|
+
w_err_p = wp.quat_rotate_inv(q_p, w_err)
|
|
76
|
+
|
|
77
|
+
# given joint axes and angular velocity error, solve for joint velocities
|
|
78
|
+
c12 = wp.cross(axis_1, axis_2)
|
|
79
|
+
c02 = wp.cross(axis_0, axis_2)
|
|
80
|
+
|
|
81
|
+
vel = wp.vec2(wp.dot(w_err_p, c12) / wp.dot(axis_0, c12), wp.dot(w_err_p, c02) / wp.dot(axis_1, c02))
|
|
82
|
+
|
|
83
|
+
return wp.vec2(angles[0], angles[1]), vel
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@wp.func
|
|
87
|
+
def compute_3d_rotational_dofs(
|
|
88
|
+
axis_0: wp.vec3,
|
|
89
|
+
axis_1: wp.vec3,
|
|
90
|
+
axis_2: wp.vec3,
|
|
91
|
+
q0: float,
|
|
92
|
+
q1: float,
|
|
93
|
+
q2: float,
|
|
94
|
+
qd0: float,
|
|
95
|
+
qd1: float,
|
|
96
|
+
qd2: float,
|
|
97
|
+
):
|
|
98
|
+
"""
|
|
99
|
+
Computes the rotation quaternion and 3D angular velocity given the joint axes, coordinates and velocities.
|
|
100
|
+
"""
|
|
101
|
+
q_off = wp.quat_from_matrix(wp.mat33(axis_0, axis_1, axis_2))
|
|
102
|
+
|
|
103
|
+
# body local axes
|
|
104
|
+
local_0 = wp.quat_rotate(q_off, wp.vec3(1.0, 0.0, 0.0))
|
|
105
|
+
local_1 = wp.quat_rotate(q_off, wp.vec3(0.0, 1.0, 0.0))
|
|
106
|
+
local_2 = wp.quat_rotate(q_off, wp.vec3(0.0, 0.0, 1.0))
|
|
107
|
+
|
|
108
|
+
# reconstruct rotation axes, todo: can probably use fact that rz'*ry'*rx' == rx*ry*rz to avoid some work here
|
|
109
|
+
axis_0 = local_0
|
|
110
|
+
q_0 = wp.quat_from_axis_angle(axis_0, q0)
|
|
111
|
+
|
|
112
|
+
axis_1 = wp.quat_rotate(q_0, local_1)
|
|
113
|
+
q_1 = wp.quat_from_axis_angle(axis_1, q1)
|
|
114
|
+
|
|
115
|
+
axis_2 = wp.quat_rotate(q_1 * q_0, local_2)
|
|
116
|
+
q_2 = wp.quat_from_axis_angle(axis_2, q2)
|
|
117
|
+
|
|
118
|
+
rot = q_2 * q_1 * q_0
|
|
119
|
+
vel = axis_0 * qd0 + axis_1 * qd1 + axis_2 * qd2
|
|
120
|
+
|
|
121
|
+
return rot, vel
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
@wp.func
|
|
125
|
+
def invert_3d_rotational_dofs(
|
|
126
|
+
axis_0: wp.vec3, axis_1: wp.vec3, axis_2: wp.vec3, q_p: wp.quat, q_c: wp.quat, w_err: wp.vec3
|
|
127
|
+
):
|
|
128
|
+
"""
|
|
129
|
+
Computes generalized joint position and velocity coordinates for a 3D rotational joint given the joint axes, relative orientations and angular velocity differences between the two bodies the joint connects.
|
|
130
|
+
"""
|
|
131
|
+
q_off = wp.quat_from_matrix(wp.mat33(axis_0, axis_1, axis_2))
|
|
132
|
+
q_pc = wp.quat_inverse(q_off) * wp.quat_inverse(q_p) * q_c * q_off
|
|
133
|
+
|
|
134
|
+
# decompose to a compound rotation each axis
|
|
135
|
+
angles = quat_decompose(q_pc)
|
|
136
|
+
|
|
137
|
+
# find rotation axes
|
|
138
|
+
local_0 = wp.quat_rotate(q_off, wp.vec3(1.0, 0.0, 0.0))
|
|
139
|
+
local_1 = wp.quat_rotate(q_off, wp.vec3(0.0, 1.0, 0.0))
|
|
140
|
+
local_2 = wp.quat_rotate(q_off, wp.vec3(0.0, 0.0, 1.0))
|
|
141
|
+
|
|
142
|
+
axis_0 = local_0
|
|
143
|
+
q_0 = wp.quat_from_axis_angle(axis_0, angles[0])
|
|
144
|
+
|
|
145
|
+
axis_1 = wp.quat_rotate(q_0, local_1)
|
|
146
|
+
q_1 = wp.quat_from_axis_angle(axis_1, angles[1])
|
|
147
|
+
|
|
148
|
+
axis_2 = wp.quat_rotate(q_1 * q_0, local_2)
|
|
149
|
+
|
|
150
|
+
# convert angular velocity to local space
|
|
151
|
+
w_err_p = wp.quat_rotate_inv(q_p, w_err)
|
|
152
|
+
|
|
153
|
+
# given joint axes and angular velocity error, solve for joint velocities
|
|
154
|
+
c12 = wp.cross(axis_1, axis_2)
|
|
155
|
+
c02 = wp.cross(axis_0, axis_2)
|
|
156
|
+
c01 = wp.cross(axis_0, axis_1)
|
|
157
|
+
|
|
158
|
+
velocities = wp.vec3(
|
|
159
|
+
wp.dot(w_err_p, c12) / wp.dot(axis_0, c12),
|
|
160
|
+
wp.dot(w_err_p, c02) / wp.dot(axis_1, c02),
|
|
161
|
+
wp.dot(w_err_p, c01) / wp.dot(axis_2, c01),
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
return angles, velocities
|
|
11
165
|
|
|
12
166
|
|
|
13
167
|
@wp.kernel
|
|
@@ -46,12 +200,6 @@ def eval_articulation_fk(
|
|
|
46
200
|
for i in range(joint_start, joint_end):
|
|
47
201
|
parent = joint_parent[i]
|
|
48
202
|
child = joint_child[i]
|
|
49
|
-
X_wp = wp.transform_identity()
|
|
50
|
-
v_wp = wp.spatial_vector()
|
|
51
|
-
|
|
52
|
-
if parent >= 0:
|
|
53
|
-
X_wp = body_q[parent]
|
|
54
|
-
v_wp = body_qd[parent]
|
|
55
203
|
|
|
56
204
|
# compute transform across the joint
|
|
57
205
|
type = joint_type[i]
|
|
@@ -59,14 +207,28 @@ def eval_articulation_fk(
|
|
|
59
207
|
X_pj = joint_X_p[i]
|
|
60
208
|
X_cj = joint_X_c[i]
|
|
61
209
|
|
|
210
|
+
# parent anchor frame in world space
|
|
211
|
+
X_wpj = X_pj
|
|
212
|
+
# velocity of parent anchor point in world space
|
|
213
|
+
v_wpj = wp.spatial_vector()
|
|
214
|
+
if parent >= 0:
|
|
215
|
+
X_wp = body_q[parent]
|
|
216
|
+
X_wpj = X_wp * X_wpj
|
|
217
|
+
r_p = wp.transform_get_translation(X_wpj) - wp.transform_point(X_wp, body_com[parent])
|
|
218
|
+
|
|
219
|
+
v_wp = body_qd[parent]
|
|
220
|
+
w_p = wp.spatial_top(v_wp)
|
|
221
|
+
v_p = wp.spatial_bottom(v_wp) + wp.cross(w_p, r_p)
|
|
222
|
+
v_wpj = wp.spatial_vector(w_p, v_p)
|
|
223
|
+
|
|
62
224
|
q_start = joint_q_start[i]
|
|
63
225
|
qd_start = joint_qd_start[i]
|
|
64
226
|
axis_start = joint_axis_start[i]
|
|
65
227
|
lin_axis_count = joint_axis_dim[i, 0]
|
|
66
228
|
ang_axis_count = joint_axis_dim[i, 1]
|
|
67
229
|
|
|
68
|
-
|
|
69
|
-
|
|
230
|
+
X_j = wp.transform_identity()
|
|
231
|
+
v_j = wp.spatial_vector(wp.vec3(), wp.vec3())
|
|
70
232
|
|
|
71
233
|
if type == wp.sim.JOINT_PRISMATIC:
|
|
72
234
|
axis = joint_axis[axis_start]
|
|
@@ -74,8 +236,8 @@ def eval_articulation_fk(
|
|
|
74
236
|
q = joint_q[q_start]
|
|
75
237
|
qd = joint_qd[qd_start]
|
|
76
238
|
|
|
77
|
-
|
|
78
|
-
|
|
239
|
+
X_j = wp.transform(axis * q, wp.quat_identity())
|
|
240
|
+
v_j = wp.spatial_vector(wp.vec3(), axis * qd)
|
|
79
241
|
|
|
80
242
|
if type == wp.sim.JOINT_REVOLUTE:
|
|
81
243
|
axis = joint_axis[axis_start]
|
|
@@ -83,20 +245,18 @@ def eval_articulation_fk(
|
|
|
83
245
|
q = joint_q[q_start]
|
|
84
246
|
qd = joint_qd[qd_start]
|
|
85
247
|
|
|
86
|
-
|
|
87
|
-
|
|
248
|
+
X_j = wp.transform(wp.vec3(), wp.quat_from_axis_angle(axis, q))
|
|
249
|
+
v_j = wp.spatial_vector(axis * qd, wp.vec3())
|
|
88
250
|
|
|
89
251
|
if type == wp.sim.JOINT_BALL:
|
|
90
252
|
r = wp.quat(joint_q[q_start + 0], joint_q[q_start + 1], joint_q[q_start + 2], joint_q[q_start + 3])
|
|
91
253
|
|
|
92
254
|
w = wp.vec3(joint_qd[qd_start + 0], joint_qd[qd_start + 1], joint_qd[qd_start + 2])
|
|
93
255
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
X_jc = wp.transform(wp.vec3(), r)
|
|
97
|
-
v_jc = wp.spatial_vector(w, wp.vec3())
|
|
256
|
+
X_j = wp.transform(wp.vec3(), r)
|
|
257
|
+
v_j = wp.spatial_vector(w, wp.vec3())
|
|
98
258
|
|
|
99
|
-
if type == wp.sim.JOINT_FREE:
|
|
259
|
+
if type == wp.sim.JOINT_FREE or type == wp.sim.JOINT_DISTANCE:
|
|
100
260
|
t = wp.transform(
|
|
101
261
|
wp.vec3(joint_q[q_start + 0], joint_q[q_start + 1], joint_q[q_start + 2]),
|
|
102
262
|
wp.quat(joint_q[q_start + 3], joint_q[q_start + 4], joint_q[q_start + 5], joint_q[q_start + 6]),
|
|
@@ -107,46 +267,43 @@ def eval_articulation_fk(
|
|
|
107
267
|
wp.vec3(joint_qd[qd_start + 3], joint_qd[qd_start + 4], joint_qd[qd_start + 5]),
|
|
108
268
|
)
|
|
109
269
|
|
|
110
|
-
|
|
111
|
-
|
|
270
|
+
X_j = t
|
|
271
|
+
v_j = v
|
|
112
272
|
|
|
113
273
|
if type == wp.sim.JOINT_COMPOUND:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
q_2 = wp.quat_from_axis_angle(axis_2, joint_q[q_start + 2])
|
|
125
|
-
|
|
126
|
-
t = wp.transform(wp.vec3(), q_2 * q_1 * q_0)
|
|
127
|
-
|
|
128
|
-
v = wp.spatial_vector(
|
|
129
|
-
axis_0 * joint_qd[qd_start + 0] + axis_1 * joint_qd[qd_start + 1] + axis_2 * joint_qd[qd_start + 2],
|
|
130
|
-
wp.vec3(),
|
|
274
|
+
rot, vel_w = compute_3d_rotational_dofs(
|
|
275
|
+
joint_axis[axis_start],
|
|
276
|
+
joint_axis[axis_start + 1],
|
|
277
|
+
joint_axis[axis_start + 2],
|
|
278
|
+
joint_q[q_start + 0],
|
|
279
|
+
joint_q[q_start + 1],
|
|
280
|
+
joint_q[q_start + 2],
|
|
281
|
+
joint_qd[qd_start + 0],
|
|
282
|
+
joint_qd[qd_start + 1],
|
|
283
|
+
joint_qd[qd_start + 2],
|
|
131
284
|
)
|
|
132
285
|
|
|
133
|
-
|
|
134
|
-
|
|
286
|
+
t = wp.transform(wp.vec3(0.0, 0.0, 0.0), rot)
|
|
287
|
+
v = wp.spatial_vector(vel_w, wp.vec3(0.0, 0.0, 0.0))
|
|
135
288
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
axis_0 = joint_axis[axis_start]
|
|
139
|
-
q_0 = wp.quat_from_axis_angle(axis_0, joint_q[q_start + 0])
|
|
140
|
-
|
|
141
|
-
axis_1 = joint_axis[axis_start + 1]
|
|
142
|
-
q_1 = wp.quat_from_axis_angle(axis_1, joint_q[q_start + 1])
|
|
289
|
+
X_j = t
|
|
290
|
+
v_j = v
|
|
143
291
|
|
|
144
|
-
|
|
292
|
+
if type == wp.sim.JOINT_UNIVERSAL:
|
|
293
|
+
rot, vel_w = compute_2d_rotational_dofs(
|
|
294
|
+
joint_axis[axis_start],
|
|
295
|
+
joint_axis[axis_start + 1],
|
|
296
|
+
joint_q[q_start + 0],
|
|
297
|
+
joint_q[q_start + 1],
|
|
298
|
+
joint_qd[qd_start + 0],
|
|
299
|
+
joint_qd[qd_start + 1],
|
|
300
|
+
)
|
|
145
301
|
|
|
146
|
-
|
|
302
|
+
t = wp.transform(wp.vec3(0.0, 0.0, 0.0), rot)
|
|
303
|
+
v = wp.spatial_vector(vel_w, wp.vec3(0.0, 0.0, 0.0))
|
|
147
304
|
|
|
148
|
-
|
|
149
|
-
|
|
305
|
+
X_j = t
|
|
306
|
+
v_j = v
|
|
150
307
|
|
|
151
308
|
if type == wp.sim.JOINT_D6:
|
|
152
309
|
pos = wp.vec3(0.0)
|
|
@@ -170,34 +327,49 @@ def eval_articulation_fk(
|
|
|
170
327
|
pos += axis * joint_q[q_start + 2]
|
|
171
328
|
vel_v += axis * joint_qd[qd_start + 2]
|
|
172
329
|
|
|
173
|
-
|
|
330
|
+
ia = axis_start + lin_axis_count
|
|
331
|
+
iq = q_start + lin_axis_count
|
|
332
|
+
iqd = qd_start + lin_axis_count
|
|
333
|
+
if ang_axis_count == 1:
|
|
174
334
|
axis = joint_axis[axis_start + lin_axis_count + 0]
|
|
175
335
|
qi = wp.quat_from_axis_angle(axis, joint_q[q_start + lin_axis_count + 0])
|
|
176
336
|
rot = qi * rot
|
|
177
|
-
vel_w
|
|
178
|
-
if ang_axis_count
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
337
|
+
vel_w = joint_qd[qd_start + lin_axis_count + 0] * axis
|
|
338
|
+
if ang_axis_count == 2:
|
|
339
|
+
rot, vel_w = compute_2d_rotational_dofs(
|
|
340
|
+
joint_axis[ia + 0],
|
|
341
|
+
joint_axis[ia + 1],
|
|
342
|
+
joint_q[iq + 0],
|
|
343
|
+
joint_q[iq + 1],
|
|
344
|
+
joint_qd[iqd + 0],
|
|
345
|
+
joint_qd[iqd + 1],
|
|
346
|
+
)
|
|
347
|
+
if ang_axis_count == 3:
|
|
348
|
+
rot, vel_w = compute_3d_rotational_dofs(
|
|
349
|
+
joint_axis[ia + 0],
|
|
350
|
+
joint_axis[ia + 1],
|
|
351
|
+
joint_axis[ia + 2],
|
|
352
|
+
joint_q[iq + 0],
|
|
353
|
+
joint_q[iq + 1],
|
|
354
|
+
joint_q[iq + 2],
|
|
355
|
+
joint_qd[iqd + 0],
|
|
356
|
+
joint_qd[iqd + 1],
|
|
357
|
+
joint_qd[iqd + 2],
|
|
358
|
+
)
|
|
359
|
+
|
|
360
|
+
X_j = wp.transform(pos, rot)
|
|
361
|
+
v_j = wp.spatial_vector(vel_w, vel_v)
|
|
362
|
+
|
|
363
|
+
# transform from world to joint anchor frame at child body
|
|
364
|
+
X_wcj = X_wpj * X_j
|
|
365
|
+
# transform from world to child body frame
|
|
366
|
+
X_wc = X_wcj * wp.transform_inverse(X_cj)
|
|
195
367
|
|
|
196
368
|
# transform velocity across the joint to world space
|
|
197
|
-
angular_vel = wp.transform_vector(
|
|
198
|
-
linear_vel = wp.transform_vector(
|
|
369
|
+
angular_vel = wp.transform_vector(X_wpj, wp.spatial_top(v_j))
|
|
370
|
+
linear_vel = wp.transform_vector(X_wpj, wp.spatial_bottom(v_j))
|
|
199
371
|
|
|
200
|
-
v_wc =
|
|
372
|
+
v_wc = v_wpj + wp.spatial_vector(angular_vel, linear_vel)
|
|
201
373
|
|
|
202
374
|
body_q[child] = X_wc
|
|
203
375
|
body_qd[child] = v_wc
|
|
@@ -205,6 +377,16 @@ def eval_articulation_fk(
|
|
|
205
377
|
|
|
206
378
|
# updates state body information based on joint coordinates
|
|
207
379
|
def eval_fk(model, joint_q, joint_qd, mask, state):
|
|
380
|
+
"""
|
|
381
|
+
Evaluates the model's forward kinematics given the joint coordinates and updates the state's body information (:attr:`State.body_q` and :attr:`State.body_qd`).
|
|
382
|
+
|
|
383
|
+
Args:
|
|
384
|
+
model (Model): The model to evaluate.
|
|
385
|
+
joint_q (array): Generalized joint position coordinates, shape [joint_coord_count], float
|
|
386
|
+
joint_qd (array): Generalized joint velocity coordinates, shape [joint_dof_count], float
|
|
387
|
+
mask (array): The mask to use to enable / disable FK for an articulation. If None then treat all as enabled, shape [articulation_count], int
|
|
388
|
+
state (State): The state to update.
|
|
389
|
+
"""
|
|
208
390
|
wp.launch(
|
|
209
391
|
kernel=eval_articulation_fk,
|
|
210
392
|
dim=model.articulation_count,
|
|
@@ -233,6 +415,29 @@ def eval_fk(model, joint_q, joint_qd, mask, state):
|
|
|
233
415
|
)
|
|
234
416
|
|
|
235
417
|
|
|
418
|
+
@wp.func
|
|
419
|
+
def reconstruct_angular_q_qd(q_pc: wp.quat, w_err: wp.vec3, X_wp: wp.transform, axis: wp.vec3):
|
|
420
|
+
"""
|
|
421
|
+
Reconstructs the angular joint coordinates and velocities given the relative rotation and angular velocity
|
|
422
|
+
between a parent and child body.
|
|
423
|
+
|
|
424
|
+
Args:
|
|
425
|
+
q_pc (quat): The relative rotation between the parent and child body.
|
|
426
|
+
w_err (vec3): The angular velocity between the parent and child body.
|
|
427
|
+
X_wp (transform): The parent body's transform in world space.
|
|
428
|
+
axis (vec3): The joint axis in the frame of the parent body.
|
|
429
|
+
|
|
430
|
+
Returns:
|
|
431
|
+
q (float): The joint position coordinate.
|
|
432
|
+
qd (float): The joint velocity coordinate.
|
|
433
|
+
"""
|
|
434
|
+
axis_p = wp.transform_vector(X_wp, axis)
|
|
435
|
+
twist = quat_twist(axis, q_pc)
|
|
436
|
+
q = wp.acos(twist[3]) * 2.0 * wp.sign(wp.dot(axis, wp.vec3(twist[0], twist[1], twist[2])))
|
|
437
|
+
qd = wp.dot(w_err, axis_p)
|
|
438
|
+
return q, qd
|
|
439
|
+
|
|
440
|
+
|
|
236
441
|
@wp.kernel
|
|
237
442
|
def eval_articulation_ik(
|
|
238
443
|
body_q: wp.array(dtype=wp.transform),
|
|
@@ -253,46 +458,46 @@ def eval_articulation_ik(
|
|
|
253
458
|
):
|
|
254
459
|
tid = wp.tid()
|
|
255
460
|
|
|
256
|
-
|
|
257
|
-
|
|
461
|
+
parent = joint_parent[tid]
|
|
462
|
+
child = joint_child[tid]
|
|
258
463
|
|
|
259
464
|
X_pj = joint_X_p[tid]
|
|
260
465
|
X_cj = joint_X_c[tid]
|
|
261
466
|
|
|
262
|
-
X_wp = X_pj
|
|
263
|
-
r_p = wp.vec3()
|
|
264
467
|
w_p = wp.vec3()
|
|
265
468
|
v_p = wp.vec3()
|
|
469
|
+
v_wp = wp.spatial_vector()
|
|
266
470
|
|
|
267
|
-
# parent
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
471
|
+
# parent anchor frame in world space
|
|
472
|
+
X_wpj = X_pj
|
|
473
|
+
if parent >= 0:
|
|
474
|
+
X_wp = body_q[parent]
|
|
475
|
+
X_wpj = X_wp * X_pj
|
|
476
|
+
r_p = wp.transform_get_translation(X_wpj) - wp.transform_point(X_wp, body_com[parent])
|
|
271
477
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
v_p = wp.spatial_bottom(twist_p) + wp.cross(w_p, r_wp)
|
|
478
|
+
v_wp = body_qd[parent]
|
|
479
|
+
w_p = wp.spatial_top(v_wp)
|
|
480
|
+
v_p = wp.spatial_bottom(v_wp) + wp.cross(w_p, r_p)
|
|
276
481
|
|
|
277
482
|
# child transform and moment arm
|
|
278
|
-
X_wc = body_q[
|
|
279
|
-
|
|
483
|
+
X_wc = body_q[child]
|
|
484
|
+
X_wcj = X_wc * X_cj
|
|
280
485
|
|
|
281
|
-
|
|
486
|
+
v_wc = body_qd[child]
|
|
282
487
|
|
|
283
|
-
w_c = wp.spatial_top(
|
|
284
|
-
v_c = wp.spatial_bottom(
|
|
488
|
+
w_c = wp.spatial_top(v_wc)
|
|
489
|
+
v_c = wp.spatial_bottom(v_wc)
|
|
285
490
|
|
|
286
491
|
# joint properties
|
|
287
492
|
type = joint_type[tid]
|
|
288
493
|
|
|
289
|
-
|
|
290
|
-
|
|
494
|
+
# compute position and orientation differences between anchor frames
|
|
495
|
+
x_p = wp.transform_get_translation(X_wpj)
|
|
496
|
+
x_c = wp.transform_get_translation(X_wcj)
|
|
291
497
|
|
|
292
|
-
q_p = wp.transform_get_rotation(
|
|
293
|
-
q_c = wp.transform_get_rotation(
|
|
498
|
+
q_p = wp.transform_get_rotation(X_wpj)
|
|
499
|
+
q_c = wp.transform_get_rotation(X_wcj)
|
|
294
500
|
|
|
295
|
-
# translational error
|
|
296
501
|
x_err = x_c - x_p
|
|
297
502
|
v_err = v_c - v_p
|
|
298
503
|
w_err = w_c - w_p
|
|
@@ -307,7 +512,7 @@ def eval_articulation_ik(
|
|
|
307
512
|
axis = joint_axis[axis_start]
|
|
308
513
|
|
|
309
514
|
# world space joint axis
|
|
310
|
-
axis_p = wp.
|
|
515
|
+
axis_p = wp.quat_rotate(q_p, axis)
|
|
311
516
|
|
|
312
517
|
# evaluate joint coordinates
|
|
313
518
|
q = wp.dot(x_err, axis_p)
|
|
@@ -320,16 +525,9 @@ def eval_articulation_ik(
|
|
|
320
525
|
|
|
321
526
|
if type == wp.sim.JOINT_REVOLUTE:
|
|
322
527
|
axis = joint_axis[axis_start]
|
|
323
|
-
|
|
324
|
-
axis_p = wp.transform_vector(X_wp, axis)
|
|
325
|
-
axis_c = wp.transform_vector(X_wc, axis)
|
|
326
|
-
|
|
327
|
-
# swing twist decomposition
|
|
328
528
|
q_pc = wp.quat_inverse(q_p) * q_c
|
|
329
|
-
twist = quat_twist(axis, q_pc)
|
|
330
529
|
|
|
331
|
-
q =
|
|
332
|
-
qd = wp.dot(w_err, axis_p)
|
|
530
|
+
q, qd = reconstruct_angular_q_qd(q_pc, w_err, X_wpj, axis)
|
|
333
531
|
|
|
334
532
|
joint_q[q_start] = q
|
|
335
533
|
joint_qd[qd_start] = qd
|
|
@@ -344,125 +542,127 @@ def eval_articulation_ik(
|
|
|
344
542
|
joint_q[q_start + 2] = q_pc[2]
|
|
345
543
|
joint_q[q_start + 3] = q_pc[3]
|
|
346
544
|
|
|
347
|
-
|
|
348
|
-
joint_qd[qd_start +
|
|
349
|
-
joint_qd[qd_start +
|
|
545
|
+
ang_vel = wp.transform_vector(wp.transform_inverse(X_wpj), w_err)
|
|
546
|
+
joint_qd[qd_start + 0] = ang_vel[0]
|
|
547
|
+
joint_qd[qd_start + 1] = ang_vel[1]
|
|
548
|
+
joint_qd[qd_start + 2] = ang_vel[2]
|
|
350
549
|
|
|
351
550
|
return
|
|
352
551
|
|
|
353
552
|
if type == wp.sim.JOINT_FIXED:
|
|
354
553
|
return
|
|
355
554
|
|
|
356
|
-
if type == wp.sim.JOINT_FREE:
|
|
555
|
+
if type == wp.sim.JOINT_FREE or type == wp.sim.JOINT_DISTANCE:
|
|
357
556
|
q_pc = wp.quat_inverse(q_p) * q_c
|
|
358
557
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
558
|
+
x_err_c = wp.quat_rotate_inv(q_p, x_err)
|
|
559
|
+
v_err_c = wp.quat_rotate_inv(q_p, v_err)
|
|
560
|
+
w_err_c = wp.quat_rotate_inv(q_p, w_err)
|
|
561
|
+
|
|
562
|
+
joint_q[q_start + 0] = x_err_c[0]
|
|
563
|
+
joint_q[q_start + 1] = x_err_c[1]
|
|
564
|
+
joint_q[q_start + 2] = x_err_c[2]
|
|
362
565
|
|
|
363
566
|
joint_q[q_start + 3] = q_pc[0]
|
|
364
567
|
joint_q[q_start + 4] = q_pc[1]
|
|
365
568
|
joint_q[q_start + 5] = q_pc[2]
|
|
366
569
|
joint_q[q_start + 6] = q_pc[3]
|
|
367
570
|
|
|
368
|
-
joint_qd[qd_start + 0] =
|
|
369
|
-
joint_qd[qd_start + 1] =
|
|
370
|
-
joint_qd[qd_start + 2] =
|
|
371
|
-
|
|
372
|
-
joint_qd[qd_start + 3] = v_err[0]
|
|
373
|
-
joint_qd[qd_start + 4] = v_err[1]
|
|
374
|
-
joint_qd[qd_start + 5] = v_err[2]
|
|
375
|
-
|
|
376
|
-
if type == wp.sim.JOINT_COMPOUND:
|
|
377
|
-
q_off = wp.transform_get_rotation(X_cj)
|
|
378
|
-
q_pc = wp.quat_inverse(q_off) * wp.quat_inverse(q_p) * q_c * q_off
|
|
379
|
-
|
|
380
|
-
# decompose to a compound rotation each axis
|
|
381
|
-
angles = quat_decompose(q_pc)
|
|
382
|
-
|
|
383
|
-
# reconstruct rotation axes
|
|
384
|
-
axis_0 = wp.vec3(1.0, 0.0, 0.0)
|
|
385
|
-
q_0 = wp.quat_from_axis_angle(axis_0, angles[0])
|
|
571
|
+
joint_qd[qd_start + 0] = w_err_c[0]
|
|
572
|
+
joint_qd[qd_start + 1] = w_err_c[1]
|
|
573
|
+
joint_qd[qd_start + 2] = w_err_c[2]
|
|
386
574
|
|
|
387
|
-
|
|
388
|
-
|
|
575
|
+
joint_qd[qd_start + 3] = v_err_c[0]
|
|
576
|
+
joint_qd[qd_start + 4] = v_err_c[1]
|
|
577
|
+
joint_qd[qd_start + 5] = v_err_c[2]
|
|
389
578
|
|
|
390
|
-
|
|
391
|
-
q_2 = wp.quat_from_axis_angle(axis_2, angles[2])
|
|
392
|
-
|
|
393
|
-
q_w = q_p * q_off
|
|
394
|
-
|
|
395
|
-
joint_q[q_start + 0] = angles[0]
|
|
396
|
-
joint_q[q_start + 1] = angles[1]
|
|
397
|
-
joint_q[q_start + 2] = angles[2]
|
|
579
|
+
return
|
|
398
580
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
581
|
+
if type == wp.sim.JOINT_COMPOUND:
|
|
582
|
+
axis_0 = joint_axis[axis_start + 0]
|
|
583
|
+
axis_1 = joint_axis[axis_start + 1]
|
|
584
|
+
axis_2 = joint_axis[axis_start + 2]
|
|
585
|
+
qs, qds = invert_3d_rotational_dofs(axis_0, axis_1, axis_2, q_p, q_c, w_err)
|
|
586
|
+
joint_q[q_start + 0] = qs[0]
|
|
587
|
+
joint_q[q_start + 1] = qs[1]
|
|
588
|
+
joint_q[q_start + 2] = qs[2]
|
|
589
|
+
joint_qd[qd_start + 0] = qds[0]
|
|
590
|
+
joint_qd[qd_start + 1] = qds[1]
|
|
591
|
+
joint_qd[qd_start + 2] = qds[2]
|
|
402
592
|
|
|
403
593
|
return
|
|
404
594
|
|
|
405
595
|
if type == wp.sim.JOINT_UNIVERSAL:
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
axis_0 = wp.vec3(1.0, 0.0, 0.0)
|
|
414
|
-
q_0 = wp.quat_from_axis_angle(axis_0, angles[0])
|
|
415
|
-
|
|
416
|
-
axis_1 = wp.quat_rotate(q_0, wp.vec3(0.0, 1.0, 0.0))
|
|
417
|
-
q_1 = wp.quat_from_axis_angle(axis_1, angles[1])
|
|
418
|
-
|
|
419
|
-
q_w = q_p * q_off
|
|
420
|
-
|
|
421
|
-
joint_q[q_start + 0] = angles[0]
|
|
422
|
-
joint_q[q_start + 1] = angles[1]
|
|
423
|
-
|
|
424
|
-
joint_qd[qd_start + 0] = wp.dot(wp.quat_rotate(q_w, axis_0), w_err)
|
|
425
|
-
joint_qd[qd_start + 1] = wp.dot(wp.quat_rotate(q_w, axis_1), w_err)
|
|
596
|
+
axis_0 = joint_axis[axis_start + 0]
|
|
597
|
+
axis_1 = joint_axis[axis_start + 1]
|
|
598
|
+
qs2, qds2 = invert_2d_rotational_dofs(axis_0, axis_1, q_p, q_c, w_err)
|
|
599
|
+
joint_q[q_start + 0] = qs2[0]
|
|
600
|
+
joint_q[q_start + 1] = qs2[1]
|
|
601
|
+
joint_qd[qd_start + 0] = qds2[0]
|
|
602
|
+
joint_qd[qd_start + 1] = qds2[1]
|
|
426
603
|
|
|
427
604
|
return
|
|
428
605
|
|
|
429
606
|
if type == wp.sim.JOINT_D6:
|
|
607
|
+
x_err_c = wp.quat_rotate_inv(q_p, x_err)
|
|
608
|
+
v_err_c = wp.quat_rotate_inv(q_p, v_err)
|
|
430
609
|
if lin_axis_count > 0:
|
|
431
|
-
axis =
|
|
432
|
-
joint_q[q_start + 0] = wp.dot(
|
|
433
|
-
joint_qd[qd_start + 0] = wp.dot(
|
|
610
|
+
axis = joint_axis[axis_start + 0]
|
|
611
|
+
joint_q[q_start + 0] = wp.dot(x_err_c, axis)
|
|
612
|
+
joint_qd[qd_start + 0] = wp.dot(v_err_c, axis)
|
|
434
613
|
|
|
435
614
|
if lin_axis_count > 1:
|
|
436
|
-
axis =
|
|
437
|
-
joint_q[q_start + 1] = wp.dot(
|
|
438
|
-
joint_qd[qd_start + 1] = wp.dot(
|
|
615
|
+
axis = joint_axis[axis_start + 1]
|
|
616
|
+
joint_q[q_start + 1] = wp.dot(x_err_c, axis)
|
|
617
|
+
joint_qd[qd_start + 1] = wp.dot(v_err_c, axis)
|
|
439
618
|
|
|
440
619
|
if lin_axis_count > 2:
|
|
441
|
-
axis =
|
|
442
|
-
joint_q[q_start + 2] = wp.dot(
|
|
443
|
-
joint_qd[qd_start + 2] = wp.dot(
|
|
444
|
-
|
|
445
|
-
q_pc = wp.quat_inverse(q_p) * q_c
|
|
446
|
-
if ang_axis_count > 0:
|
|
447
|
-
axis = wp.transform_vector(X_wp, joint_axis[axis_start + lin_axis_count + 0])
|
|
448
|
-
joint_q[q_start + lin_axis_count + 0] = quat_twist_angle(axis, q_pc)
|
|
449
|
-
joint_qd[qd_start + lin_axis_count + 0] = wp.dot(w_err, axis)
|
|
620
|
+
axis = joint_axis[axis_start + 2]
|
|
621
|
+
joint_q[q_start + 2] = wp.dot(x_err_c, axis)
|
|
622
|
+
joint_qd[qd_start + 2] = wp.dot(v_err_c, axis)
|
|
450
623
|
|
|
451
|
-
if ang_axis_count
|
|
452
|
-
axis =
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
624
|
+
if ang_axis_count == 1:
|
|
625
|
+
axis = joint_axis[axis_start]
|
|
626
|
+
q_pc = wp.quat_inverse(q_p) * q_c
|
|
627
|
+
q, qd = reconstruct_angular_q_qd(q_pc, w_err, X_wpj, joint_axis[axis_start + lin_axis_count])
|
|
628
|
+
joint_q[q_start + lin_axis_count] = q
|
|
629
|
+
joint_qd[qd_start + lin_axis_count] = qd
|
|
630
|
+
|
|
631
|
+
if ang_axis_count == 2:
|
|
632
|
+
axis_0 = joint_axis[axis_start + lin_axis_count + 0]
|
|
633
|
+
axis_1 = joint_axis[axis_start + lin_axis_count + 1]
|
|
634
|
+
qs2, qds2 = invert_2d_rotational_dofs(axis_0, axis_1, q_p, q_c, w_err)
|
|
635
|
+
joint_q[q_start + lin_axis_count + 0] = qs2[0]
|
|
636
|
+
joint_q[q_start + lin_axis_count + 1] = qs2[1]
|
|
637
|
+
joint_qd[qd_start + lin_axis_count + 0] = qds2[0]
|
|
638
|
+
joint_qd[qd_start + lin_axis_count + 1] = qds2[1]
|
|
639
|
+
|
|
640
|
+
if ang_axis_count == 3:
|
|
641
|
+
axis_0 = joint_axis[axis_start + lin_axis_count + 0]
|
|
642
|
+
axis_1 = joint_axis[axis_start + lin_axis_count + 1]
|
|
643
|
+
axis_2 = joint_axis[axis_start + lin_axis_count + 2]
|
|
644
|
+
qs3, qds3 = invert_3d_rotational_dofs(axis_0, axis_1, axis_2, q_p, q_c, w_err)
|
|
645
|
+
joint_q[q_start + lin_axis_count + 0] = qs3[0]
|
|
646
|
+
joint_q[q_start + lin_axis_count + 1] = qs3[1]
|
|
647
|
+
joint_q[q_start + lin_axis_count + 2] = qs3[2]
|
|
648
|
+
joint_qd[qd_start + lin_axis_count + 0] = qds3[0]
|
|
649
|
+
joint_qd[qd_start + lin_axis_count + 1] = qds3[1]
|
|
650
|
+
joint_qd[qd_start + lin_axis_count + 2] = qds3[2]
|
|
460
651
|
|
|
461
652
|
return
|
|
462
653
|
|
|
463
654
|
|
|
464
655
|
# given maximal coordinate model computes ik (closest point projection)
|
|
465
656
|
def eval_ik(model, state, joint_q, joint_qd):
|
|
657
|
+
"""
|
|
658
|
+
Evaluates the model's inverse kinematics given the state's body information (:attr:`State.body_q` and :attr:`State.body_qd`) and updates the generalized joint coordinates `joint_q` and `joint_qd`.
|
|
659
|
+
|
|
660
|
+
Args:
|
|
661
|
+
model (Model): The model to evaluate.
|
|
662
|
+
state (State): The state with the body's maximal coordinates (positions :attr:`State.body_q` and velocities :attr:`State.body_qd`) to use.
|
|
663
|
+
joint_q (array): Generalized joint position coordinates, shape [joint_coord_count], float
|
|
664
|
+
joint_qd (array): Generalized joint velocity coordinates, shape [joint_dof_count], float
|
|
665
|
+
"""
|
|
466
666
|
wp.launch(
|
|
467
667
|
kernel=eval_articulation_ik,
|
|
468
668
|
dim=model.joint_count,
|