jaxsim 0.4.2.dev19__tar.gz → 0.4.2.dev28__tar.gz
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.
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/PKG-INFO +1 -1
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/_version.py +2 -2
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/api/contact.py +166 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/api/model.py +35 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim.egg-info/PKG-INFO +1 -1
- jaxsim-0.4.2.dev28/tests/test_api_contact.py +147 -0
- jaxsim-0.4.2.dev19/tests/test_api_contact.py +0 -58
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/.devcontainer/Dockerfile +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/.devcontainer/devcontainer.json +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/.gitattributes +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/.github/CODEOWNERS +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/.github/workflows/ci_cd.yml +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/.github/workflows/read_the_docs.yml +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/.gitignore +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/.pre-commit-config.yaml +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/.readthedocs.yaml +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/CONTRIBUTING.md +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/LICENSE +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/README.md +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/docs/Makefile +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/docs/conf.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/docs/examples.rst +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/docs/guide/install.rst +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/docs/index.rst +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/docs/make.bat +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/docs/modules/api.rst +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/docs/modules/integrators.rst +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/docs/modules/math.rst +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/docs/modules/mujoco.rst +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/docs/modules/parsers.rst +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/docs/modules/rbda.rst +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/docs/modules/typing.rst +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/docs/modules/utils.rst +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/environment.yml +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/examples/.gitattributes +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/examples/.gitignore +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/examples/PD_controller.ipynb +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/examples/Parallel_computing.ipynb +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/examples/README.md +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/examples/assets/cartpole.urdf +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/pixi.lock +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/pyproject.toml +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/setup.cfg +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/setup.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/__init__.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/api/__init__.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/api/com.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/api/common.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/api/data.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/api/frame.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/api/joint.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/api/kin_dyn_parameters.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/api/link.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/api/ode.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/api/ode_data.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/api/references.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/exceptions.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/integrators/__init__.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/integrators/common.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/integrators/fixed_step.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/integrators/variable_step.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/logging.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/math/__init__.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/math/adjoint.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/math/cross.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/math/inertia.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/math/joint_model.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/math/quaternion.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/math/rotation.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/math/skew.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/math/transform.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/mujoco/__init__.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/mujoco/__main__.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/mujoco/loaders.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/mujoco/model.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/mujoco/visualizer.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/parsers/__init__.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/parsers/descriptions/__init__.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/parsers/descriptions/collision.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/parsers/descriptions/joint.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/parsers/descriptions/link.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/parsers/descriptions/model.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/parsers/kinematic_graph.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/parsers/rod/__init__.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/parsers/rod/parser.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/parsers/rod/utils.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/rbda/__init__.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/rbda/aba.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/rbda/collidable_points.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/rbda/contacts/__init__.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/rbda/contacts/common.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/rbda/contacts/soft.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/rbda/crba.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/rbda/forward_kinematics.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/rbda/jacobian.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/rbda/rnea.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/rbda/utils.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/terrain/__init__.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/terrain/terrain.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/typing.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/utils/__init__.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/utils/jaxsim_dataclass.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/utils/tracing.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim/utils/wrappers.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim.egg-info/SOURCES.txt +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim.egg-info/dependency_links.txt +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim.egg-info/requires.txt +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/src/jaxsim.egg-info/top_level.txt +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/tests/__init__.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/tests/conftest.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/tests/test_api_com.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/tests/test_api_data.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/tests/test_api_frame.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/tests/test_api_joint.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/tests/test_api_link.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/tests/test_api_model.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/tests/test_automatic_differentiation.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/tests/test_contact.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/tests/test_exceptions.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/tests/test_pytree.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/tests/test_simulations.py +0 -0
- {jaxsim-0.4.2.dev19 → jaxsim-0.4.2.dev28}/tests/utils_idyntree.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: jaxsim
|
3
|
-
Version: 0.4.2.
|
3
|
+
Version: 0.4.2.dev28
|
4
4
|
Summary: A differentiable physics engine and multibody dynamics library for control and robot learning.
|
5
5
|
Author-email: Diego Ferigo <dgferigo@gmail.com>
|
6
6
|
Maintainer-email: Diego Ferigo <dgferigo@gmail.com>, Filippo Luca Ferretti <filippo.ferretti@iit.it>
|
@@ -12,5 +12,5 @@ __version__: str
|
|
12
12
|
__version_tuple__: VERSION_TUPLE
|
13
13
|
version_tuple: VERSION_TUPLE
|
14
14
|
|
15
|
-
__version__ = version = '0.4.2.
|
16
|
-
__version_tuple__ = version_tuple = (0, 4, 2, '
|
15
|
+
__version__ = version = '0.4.2.dev28'
|
16
|
+
__version_tuple__ = version_tuple = (0, 4, 2, 'dev28')
|
@@ -8,6 +8,7 @@ import jax.numpy as jnp
|
|
8
8
|
import jaxsim.api as js
|
9
9
|
import jaxsim.terrain
|
10
10
|
import jaxsim.typing as jtp
|
11
|
+
from jaxsim.math import Adjoint, Cross, Transform
|
11
12
|
from jaxsim.rbda.contacts.soft import SoftContactsParams
|
12
13
|
|
13
14
|
from .common import VelRepr
|
@@ -411,3 +412,168 @@ def jacobian(
|
|
411
412
|
raise ValueError(output_vel_repr)
|
412
413
|
|
413
414
|
return O_J_WC
|
415
|
+
|
416
|
+
|
417
|
+
@functools.partial(jax.jit, static_argnames=["output_vel_repr"])
|
418
|
+
def jacobian_derivative(
|
419
|
+
model: js.model.JaxSimModel,
|
420
|
+
data: js.data.JaxSimModelData,
|
421
|
+
*,
|
422
|
+
output_vel_repr: VelRepr | None = None,
|
423
|
+
) -> jtp.Matrix:
|
424
|
+
r"""
|
425
|
+
Compute the derivative of the free-floating jacobian of the contact points.
|
426
|
+
|
427
|
+
Args:
|
428
|
+
model: The model to consider.
|
429
|
+
data: The data of the considered model.
|
430
|
+
output_vel_repr:
|
431
|
+
The output velocity representation of the free-floating jacobian derivative.
|
432
|
+
|
433
|
+
Returns:
|
434
|
+
The derivative of the :math:`6 \times (6+n)` free-floating jacobian of the contact points.
|
435
|
+
|
436
|
+
Note:
|
437
|
+
The input representation of the free-floating jacobian derivative is the active
|
438
|
+
velocity representation.
|
439
|
+
"""
|
440
|
+
|
441
|
+
output_vel_repr = (
|
442
|
+
output_vel_repr if output_vel_repr is not None else data.velocity_representation
|
443
|
+
)
|
444
|
+
|
445
|
+
# Get the index of the parent link and the position of the collidable point.
|
446
|
+
parent_link_idxs = jnp.array(model.kin_dyn_parameters.contact_parameters.body)
|
447
|
+
L_p_Ci = jnp.array(model.kin_dyn_parameters.contact_parameters.point)
|
448
|
+
contact_idxs = jnp.arange(L_p_Ci.shape[0])
|
449
|
+
|
450
|
+
# Get the transforms of all the parent links.
|
451
|
+
W_H_Li = js.model.forward_kinematics(model=model, data=data)
|
452
|
+
|
453
|
+
# =====================================================
|
454
|
+
# Compute quantities to adjust the input representation
|
455
|
+
# =====================================================
|
456
|
+
|
457
|
+
def compute_T(model: js.model.JaxSimModel, X: jtp.Matrix) -> jtp.Matrix:
|
458
|
+
In = jnp.eye(model.dofs())
|
459
|
+
T = jax.scipy.linalg.block_diag(X, In)
|
460
|
+
return T
|
461
|
+
|
462
|
+
def compute_Ṫ(model: js.model.JaxSimModel, Ẋ: jtp.Matrix) -> jtp.Matrix:
|
463
|
+
On = jnp.zeros(shape=(model.dofs(), model.dofs()))
|
464
|
+
Ṫ = jax.scipy.linalg.block_diag(Ẋ, On)
|
465
|
+
return Ṫ
|
466
|
+
|
467
|
+
# Compute the operator to change the representation of ν, and its
|
468
|
+
# time derivative.
|
469
|
+
match data.velocity_representation:
|
470
|
+
case VelRepr.Inertial:
|
471
|
+
W_H_W = jnp.eye(4)
|
472
|
+
W_X_W = Adjoint.from_transform(transform=W_H_W)
|
473
|
+
W_Ẋ_W = jnp.zeros((6, 6))
|
474
|
+
|
475
|
+
T = compute_T(model=model, X=W_X_W)
|
476
|
+
Ṫ = compute_Ṫ(model=model, Ẋ=W_Ẋ_W)
|
477
|
+
|
478
|
+
case VelRepr.Body:
|
479
|
+
W_H_B = data.base_transform()
|
480
|
+
W_X_B = Adjoint.from_transform(transform=W_H_B)
|
481
|
+
B_v_WB = data.base_velocity()
|
482
|
+
B_vx_WB = Cross.vx(B_v_WB)
|
483
|
+
W_Ẋ_B = W_X_B @ B_vx_WB
|
484
|
+
|
485
|
+
T = compute_T(model=model, X=W_X_B)
|
486
|
+
Ṫ = compute_Ṫ(model=model, Ẋ=W_Ẋ_B)
|
487
|
+
|
488
|
+
case VelRepr.Mixed:
|
489
|
+
W_H_B = data.base_transform()
|
490
|
+
W_H_BW = W_H_B.at[0:3, 0:3].set(jnp.eye(3))
|
491
|
+
W_X_BW = Adjoint.from_transform(transform=W_H_BW)
|
492
|
+
BW_v_WB = data.base_velocity()
|
493
|
+
BW_v_W_BW = BW_v_WB.at[3:6].set(jnp.zeros(3))
|
494
|
+
BW_vx_W_BW = Cross.vx(BW_v_W_BW)
|
495
|
+
W_Ẋ_BW = W_X_BW @ BW_vx_W_BW
|
496
|
+
|
497
|
+
T = compute_T(model=model, X=W_X_BW)
|
498
|
+
Ṫ = compute_Ṫ(model=model, Ẋ=W_Ẋ_BW)
|
499
|
+
|
500
|
+
case _:
|
501
|
+
raise ValueError(data.velocity_representation)
|
502
|
+
|
503
|
+
# =====================================================
|
504
|
+
# Compute quantities to adjust the output representation
|
505
|
+
# =====================================================
|
506
|
+
|
507
|
+
with data.switch_velocity_representation(VelRepr.Inertial):
|
508
|
+
# Compute the Jacobian of the parent link in inertial representation.
|
509
|
+
W_J_WL_W = js.model.generalized_free_floating_jacobian(
|
510
|
+
model=model,
|
511
|
+
data=data,
|
512
|
+
output_vel_repr=VelRepr.Inertial,
|
513
|
+
)
|
514
|
+
# Compute the Jacobian derivative of the parent link in inertial representation.
|
515
|
+
W_J̇_WL_W = js.model.generalized_free_floating_jacobian_derivative(
|
516
|
+
model=model,
|
517
|
+
data=data,
|
518
|
+
output_vel_repr=VelRepr.Inertial,
|
519
|
+
)
|
520
|
+
|
521
|
+
# Get the Jacobian of the collidable points in the mixed representation.
|
522
|
+
with data.switch_velocity_representation(VelRepr.Mixed):
|
523
|
+
CW_J_WC_BW = jacobian(
|
524
|
+
model=model,
|
525
|
+
data=data,
|
526
|
+
output_vel_repr=VelRepr.Mixed,
|
527
|
+
)
|
528
|
+
|
529
|
+
def compute_O_J̇_WC_I(
|
530
|
+
L_p_C: jtp.Vector,
|
531
|
+
contact_idx: jtp.Int,
|
532
|
+
CW_J_WC_BW: jtp.Matrix,
|
533
|
+
W_H_L: jtp.Matrix,
|
534
|
+
) -> jtp.Matrix:
|
535
|
+
|
536
|
+
parent_link_idx = parent_link_idxs[contact_idx]
|
537
|
+
|
538
|
+
match output_vel_repr:
|
539
|
+
case VelRepr.Inertial:
|
540
|
+
O_X_W = W_X_W = Adjoint.from_transform(transform=jnp.eye(4))
|
541
|
+
O_Ẋ_W = W_Ẋ_W = jnp.zeros((6, 6))
|
542
|
+
|
543
|
+
case VelRepr.Body:
|
544
|
+
L_H_C = Transform.from_rotation_and_translation(translation=L_p_C)
|
545
|
+
W_H_C = W_H_L[parent_link_idx] @ L_H_C
|
546
|
+
O_X_W = C_X_W = Adjoint.from_transform(transform=W_H_C, inverse=True)
|
547
|
+
with data.switch_velocity_representation(VelRepr.Inertial):
|
548
|
+
W_nu = data.generalized_velocity()
|
549
|
+
W_v_WC = W_J_WL_W[parent_link_idx] @ W_nu
|
550
|
+
W_vx_WC = Cross.vx(W_v_WC)
|
551
|
+
O_Ẋ_W = C_Ẋ_W = -C_X_W @ W_vx_WC
|
552
|
+
|
553
|
+
case VelRepr.Mixed:
|
554
|
+
L_H_C = Transform.from_rotation_and_translation(translation=L_p_C)
|
555
|
+
W_H_C = W_H_L[parent_link_idx] @ L_H_C
|
556
|
+
W_H_CW = W_H_C.at[0:3, 0:3].set(jnp.eye(3))
|
557
|
+
CW_H_W = Transform.inverse(W_H_CW)
|
558
|
+
O_X_W = CW_X_W = Adjoint.from_transform(transform=CW_H_W)
|
559
|
+
with data.switch_velocity_representation(VelRepr.Mixed):
|
560
|
+
CW_v_WC = CW_J_WC_BW @ data.generalized_velocity()
|
561
|
+
W_v_W_CW = jnp.zeros(6).at[0:3].set(CW_v_WC[0:3])
|
562
|
+
W_vx_W_CW = Cross.vx(W_v_W_CW)
|
563
|
+
O_Ẋ_W = CW_Ẋ_W = -CW_X_W @ W_vx_W_CW
|
564
|
+
|
565
|
+
case _:
|
566
|
+
raise ValueError(output_vel_repr)
|
567
|
+
|
568
|
+
O_J̇_WC_I = jnp.zeros(shape=(6, 6 + model.dofs()))
|
569
|
+
O_J̇_WC_I += O_Ẋ_W @ W_J_WL_W[parent_link_idx] @ T
|
570
|
+
O_J̇_WC_I += O_X_W @ W_J̇_WL_W[parent_link_idx] @ T
|
571
|
+
O_J̇_WC_I += O_X_W @ W_J_WL_W[parent_link_idx] @ Ṫ
|
572
|
+
|
573
|
+
return O_J̇_WC_I
|
574
|
+
|
575
|
+
O_J̇_WC = jax.vmap(compute_O_J̇_WC_I, in_axes=(0, 0, 0, None))(
|
576
|
+
L_p_Ci, contact_idxs, CW_J_WC_BW, W_H_Li
|
577
|
+
)
|
578
|
+
|
579
|
+
return O_J̇_WC
|
@@ -576,6 +576,41 @@ def generalized_free_floating_jacobian(
|
|
576
576
|
return O_J_WL_I
|
577
577
|
|
578
578
|
|
579
|
+
@functools.partial(jax.jit, static_argnames=["output_vel_repr"])
|
580
|
+
def generalized_free_floating_jacobian_derivative(
|
581
|
+
model: JaxSimModel,
|
582
|
+
data: js.data.JaxSimModelData,
|
583
|
+
*,
|
584
|
+
output_vel_repr: VelRepr | None = None,
|
585
|
+
) -> jtp.Matrix:
|
586
|
+
"""
|
587
|
+
Compute the free-floating jacobian derivatives of all links.
|
588
|
+
|
589
|
+
Args:
|
590
|
+
model: The model to consider.
|
591
|
+
data: The data of the considered model.
|
592
|
+
output_vel_repr:
|
593
|
+
The output velocity representation of the free-floating jacobian derivatives.
|
594
|
+
|
595
|
+
Returns:
|
596
|
+
The `(nL, 6, 6+dofs)` array containing the stacked free-floating
|
597
|
+
jacobian derivatives of the links. The first axis is the link index.
|
598
|
+
"""
|
599
|
+
|
600
|
+
output_vel_repr = (
|
601
|
+
output_vel_repr if output_vel_repr is not None else data.velocity_representation
|
602
|
+
)
|
603
|
+
|
604
|
+
O_J̇_WL_I = jax.vmap(
|
605
|
+
lambda model, data, link_idxs, output_vel_repr: js.link.jacobian_derivative(
|
606
|
+
model, data, link_index=link_idxs, output_vel_repr=output_vel_repr
|
607
|
+
),
|
608
|
+
in_axes=(None, None, 0, None),
|
609
|
+
)(model, data, jnp.arange(model.number_of_links()), output_vel_repr)
|
610
|
+
|
611
|
+
return O_J̇_WL_I
|
612
|
+
|
613
|
+
|
579
614
|
@functools.partial(jax.jit, static_argnames=["prefer_aba"])
|
580
615
|
def forward_dynamics(
|
581
616
|
model: JaxSimModel,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: jaxsim
|
3
|
-
Version: 0.4.2.
|
3
|
+
Version: 0.4.2.dev28
|
4
4
|
Summary: A differentiable physics engine and multibody dynamics library for control and robot learning.
|
5
5
|
Author-email: Diego Ferigo <dgferigo@gmail.com>
|
6
6
|
Maintainer-email: Diego Ferigo <dgferigo@gmail.com>, Filippo Luca Ferretti <filippo.ferretti@iit.it>
|
@@ -0,0 +1,147 @@
|
|
1
|
+
import jax
|
2
|
+
import jax.numpy as jnp
|
3
|
+
import pytest
|
4
|
+
import rod
|
5
|
+
|
6
|
+
import jaxsim.api as js
|
7
|
+
from jaxsim import VelRepr
|
8
|
+
|
9
|
+
|
10
|
+
def test_contact_kinematics(
|
11
|
+
jaxsim_models_types: js.model.JaxSimModel,
|
12
|
+
velocity_representation: VelRepr,
|
13
|
+
prng_key: jax.Array,
|
14
|
+
):
|
15
|
+
|
16
|
+
model = jaxsim_models_types
|
17
|
+
|
18
|
+
_, subkey = jax.random.split(prng_key, num=2)
|
19
|
+
data = js.data.random_model_data(
|
20
|
+
model=model,
|
21
|
+
key=subkey,
|
22
|
+
velocity_representation=velocity_representation,
|
23
|
+
)
|
24
|
+
|
25
|
+
# =====
|
26
|
+
# Tests
|
27
|
+
# =====
|
28
|
+
|
29
|
+
# Compute the pose of the implicit contact frame associated to the collidable points
|
30
|
+
# and the transforms of all links.
|
31
|
+
W_H_C = js.contact.transforms(model=model, data=data)
|
32
|
+
W_H_L = js.model.forward_kinematics(model=model, data=data)
|
33
|
+
|
34
|
+
# Check that the orientation of the implicit contact frame matches with the
|
35
|
+
# orientation of the link to which the contact point is attached.
|
36
|
+
for contact_idx, index_of_parent_link in enumerate(
|
37
|
+
model.kin_dyn_parameters.contact_parameters.body
|
38
|
+
):
|
39
|
+
assert W_H_C[contact_idx, 0:3, 0:3] == pytest.approx(
|
40
|
+
W_H_L[index_of_parent_link][0:3, 0:3]
|
41
|
+
)
|
42
|
+
|
43
|
+
# Check that the origin of the implicit contact frame is located over the
|
44
|
+
# collidable point.
|
45
|
+
W_p_C = js.contact.collidable_point_positions(model=model, data=data)
|
46
|
+
assert W_p_C == pytest.approx(W_H_C[:, 0:3, 3])
|
47
|
+
|
48
|
+
# Compute the velocity of the collidable point.
|
49
|
+
# This quantity always matches with the linear component of the mixed 6D velocity
|
50
|
+
# of the implicit frame associated to the collidable point.
|
51
|
+
W_ṗ_C = js.contact.collidable_point_velocities(model=model, data=data)
|
52
|
+
|
53
|
+
# Compute the velocity of the collidable point using the contact Jacobian.
|
54
|
+
ν = data.generalized_velocity()
|
55
|
+
CW_J_WC = js.contact.jacobian(model=model, data=data, output_vel_repr=VelRepr.Mixed)
|
56
|
+
CW_vl_WC = jnp.einsum("c6g,g->c6", CW_J_WC, ν)[:, 0:3]
|
57
|
+
|
58
|
+
# Compare the two velocities.
|
59
|
+
assert W_ṗ_C == pytest.approx(CW_vl_WC)
|
60
|
+
|
61
|
+
|
62
|
+
def test_contact_jacobian_derivative(
|
63
|
+
jaxsim_models_floating_base: js.model.JaxSimModel,
|
64
|
+
velocity_representation: VelRepr,
|
65
|
+
prng_key: jax.Array,
|
66
|
+
):
|
67
|
+
|
68
|
+
model = jaxsim_models_floating_base
|
69
|
+
|
70
|
+
_, subkey = jax.random.split(prng_key, num=2)
|
71
|
+
data = js.data.random_model_data(
|
72
|
+
model=model,
|
73
|
+
key=subkey,
|
74
|
+
velocity_representation=velocity_representation,
|
75
|
+
)
|
76
|
+
|
77
|
+
# =====
|
78
|
+
# Tests
|
79
|
+
# =====
|
80
|
+
|
81
|
+
# Extract the parent link names and the poses of the contact points.
|
82
|
+
parent_link_names = js.link.idxs_to_names(
|
83
|
+
model=model, link_indices=model.kin_dyn_parameters.contact_parameters.body
|
84
|
+
)
|
85
|
+
W_p_Ci = model.kin_dyn_parameters.contact_parameters.point
|
86
|
+
|
87
|
+
# Load the model in ROD.
|
88
|
+
rod_model = rod.Sdf.load(sdf=model.built_from, is_urdf=True).model
|
89
|
+
|
90
|
+
# Add dummy frames on the contact points.
|
91
|
+
for idx, (link_name, W_p_C) in enumerate(
|
92
|
+
zip(parent_link_names, W_p_Ci, strict=True)
|
93
|
+
):
|
94
|
+
rod_model.add_frame(
|
95
|
+
frame=rod.Frame(
|
96
|
+
name=f"contact_point_{idx}",
|
97
|
+
attached_to=link_name,
|
98
|
+
pose=rod.Pose(
|
99
|
+
relative_to=link_name, pose=jnp.zeros(shape=(6,)).at[0:3].set(W_p_C)
|
100
|
+
),
|
101
|
+
),
|
102
|
+
)
|
103
|
+
|
104
|
+
# Rebuild the JaxSim model.
|
105
|
+
model_with_frames = js.model.JaxSimModel.build_from_model_description(
|
106
|
+
model_description=rod_model
|
107
|
+
)
|
108
|
+
model_with_frames = js.model.reduce(
|
109
|
+
model=model_with_frames, considered_joints=model.joint_names()
|
110
|
+
)
|
111
|
+
|
112
|
+
# Rebuild the JaxSim data.
|
113
|
+
data_with_frames = js.data.JaxSimModelData.build(
|
114
|
+
model=model_with_frames,
|
115
|
+
base_position=data.base_position(),
|
116
|
+
base_quaternion=data.base_orientation(dcm=False),
|
117
|
+
joint_positions=data.joint_positions(),
|
118
|
+
base_linear_velocity=data.base_velocity()[0:3],
|
119
|
+
base_angular_velocity=data.base_velocity()[3:6],
|
120
|
+
joint_velocities=data.joint_velocities(),
|
121
|
+
velocity_representation=velocity_representation,
|
122
|
+
)
|
123
|
+
|
124
|
+
# Extract the indexes of the frames attached to the contact points.
|
125
|
+
frame_idxs = js.frame.names_to_idxs(
|
126
|
+
model=model_with_frames,
|
127
|
+
frame_names=(
|
128
|
+
f"contact_point_{idx}" for idx in list(range(len(parent_link_names)))
|
129
|
+
),
|
130
|
+
)
|
131
|
+
|
132
|
+
# Check that the number of frames is correct.
|
133
|
+
assert len(frame_idxs) == len(parent_link_names)
|
134
|
+
|
135
|
+
# Compute the contact Jacobian derivative.
|
136
|
+
J̇_WC = js.contact.jacobian_derivative(
|
137
|
+
model=model_with_frames, data=data_with_frames
|
138
|
+
)
|
139
|
+
|
140
|
+
# Compute the contact Jacobian derivative using frames.
|
141
|
+
J̇_WF = jax.vmap(
|
142
|
+
js.frame.jacobian_derivative,
|
143
|
+
in_axes=(None, None),
|
144
|
+
)(model_with_frames, data, frame_index=frame_idxs)
|
145
|
+
|
146
|
+
# Compare the two Jacobians.
|
147
|
+
assert J̇_WC == pytest.approx(J̇_WF)
|
@@ -1,58 +0,0 @@
|
|
1
|
-
import jax
|
2
|
-
import jax.numpy as jnp
|
3
|
-
import pytest
|
4
|
-
|
5
|
-
import jaxsim.api as js
|
6
|
-
from jaxsim import VelRepr
|
7
|
-
|
8
|
-
|
9
|
-
def test_contact_kinematics(
|
10
|
-
jaxsim_models_types: js.model.JaxSimModel,
|
11
|
-
velocity_representation: VelRepr,
|
12
|
-
prng_key: jax.Array,
|
13
|
-
):
|
14
|
-
|
15
|
-
model = jaxsim_models_types
|
16
|
-
|
17
|
-
_, subkey = jax.random.split(prng_key, num=2)
|
18
|
-
data = js.data.random_model_data(
|
19
|
-
model=model,
|
20
|
-
key=subkey,
|
21
|
-
velocity_representation=velocity_representation,
|
22
|
-
)
|
23
|
-
|
24
|
-
# =====
|
25
|
-
# Tests
|
26
|
-
# =====
|
27
|
-
|
28
|
-
# Compute the pose of the implicit contact frame associated to the collidable points
|
29
|
-
# and the transforms of all links.
|
30
|
-
W_H_C = js.contact.transforms(model=model, data=data)
|
31
|
-
W_H_L = js.model.forward_kinematics(model=model, data=data)
|
32
|
-
|
33
|
-
# Check that the orientation of the implicit contact frame matches with the
|
34
|
-
# orientation of the link to which the contact point is attached.
|
35
|
-
for contact_idx, index_of_parent_link in enumerate(
|
36
|
-
model.kin_dyn_parameters.contact_parameters.body
|
37
|
-
):
|
38
|
-
assert W_H_C[contact_idx, 0:3, 0:3] == pytest.approx(
|
39
|
-
W_H_L[index_of_parent_link][0:3, 0:3]
|
40
|
-
)
|
41
|
-
|
42
|
-
# Check that the origin of the implicit contact frame is located over the
|
43
|
-
# collidable point.
|
44
|
-
W_p_C = js.contact.collidable_point_positions(model=model, data=data)
|
45
|
-
assert W_p_C == pytest.approx(W_H_C[:, 0:3, 3])
|
46
|
-
|
47
|
-
# Compute the velocity of the collidable point.
|
48
|
-
# This quantity always matches with the linear component of the mixed 6D velocity
|
49
|
-
# of the implicit frame associated to the collidable point.
|
50
|
-
W_ṗ_C = js.contact.collidable_point_velocities(model=model, data=data)
|
51
|
-
|
52
|
-
# Compute the velocity of the collidable point using the contact Jacobian.
|
53
|
-
ν = data.generalized_velocity()
|
54
|
-
CW_J_WC = js.contact.jacobian(model=model, data=data, output_vel_repr=VelRepr.Mixed)
|
55
|
-
CW_vl_WC = jnp.einsum("c6g,g->c6", CW_J_WC, ν)[:, 0:3]
|
56
|
-
|
57
|
-
# Compare the two velocities.
|
58
|
-
assert W_ṗ_C == pytest.approx(CW_vl_WC)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|