jaxsim 0.2.1.dev121__tar.gz → 0.2.1.dev128__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.2.1.dev121 → jaxsim-0.2.1.dev128}/PKG-INFO +1 -1
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/_version.py +2 -2
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/model.py +121 -2
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim.egg-info/PKG-INFO +1 -1
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/test_api_link.py +64 -1
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/test_api_model.py +90 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/test_simulations.py +1 -1
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/.devcontainer/Dockerfile +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/.devcontainer/devcontainer.json +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/.gitattributes +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/.github/CODEOWNERS +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/.github/workflows/ci_cd.yml +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/.github/workflows/read_the_docs.yml +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/.github/workflows/style.yml +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/.gitignore +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/.pre-commit-config.yaml +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/.readthedocs.yaml +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/CONTRIBUTING.md +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/LICENSE +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/README.md +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/Makefile +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/conf.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/guide/install.rst +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/index.rst +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/make.bat +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/modules/api.rst +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/modules/index.rst +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/modules/integrators.rst +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/modules/math.rst +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/modules/mujoco.rst +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/modules/parsers.rst +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/modules/rbda.rst +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/modules/typing.rst +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/modules/utils.rst +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/environment.yml +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/examples/.gitattributes +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/examples/.gitignore +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/examples/PD_controller.ipynb +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/examples/Parallel_computing.ipynb +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/examples/README.md +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/examples/assets/cartpole.urdf +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/pixi.lock +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/pyproject.toml +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/setup.cfg +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/setup.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/__init__.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/__init__.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/com.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/common.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/contact.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/data.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/frame.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/joint.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/kin_dyn_parameters.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/link.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/ode.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/ode_data.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/references.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/integrators/__init__.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/integrators/common.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/integrators/fixed_step.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/integrators/variable_step.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/logging.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/math/__init__.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/math/adjoint.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/math/cross.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/math/inertia.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/math/joint_model.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/math/quaternion.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/math/rotation.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/math/skew.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/math/transform.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/mujoco/__init__.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/mujoco/__main__.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/mujoco/loaders.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/mujoco/model.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/mujoco/visualizer.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/parsers/__init__.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/parsers/descriptions/__init__.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/parsers/descriptions/collision.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/parsers/descriptions/joint.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/parsers/descriptions/link.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/parsers/descriptions/model.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/parsers/kinematic_graph.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/parsers/rod/__init__.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/parsers/rod/parser.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/parsers/rod/utils.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/rbda/__init__.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/rbda/aba.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/rbda/collidable_points.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/rbda/crba.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/rbda/forward_kinematics.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/rbda/jacobian.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/rbda/rnea.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/rbda/soft_contacts.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/rbda/utils.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/terrain/__init__.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/terrain/terrain.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/typing.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/utils/__init__.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/utils/jaxsim_dataclass.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/utils/tracing.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/utils/wrappers.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim.egg-info/SOURCES.txt +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim.egg-info/dependency_links.txt +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim.egg-info/not-zip-safe +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim.egg-info/requires.txt +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim.egg-info/top_level.txt +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/__init__.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/conftest.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/test_api_com.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/test_api_data.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/test_api_frame.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/test_api_joint.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/test_automatic_differentiation.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/test_contact.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/test_pytree.py +0 -0
- {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/utils_idyntree.py +0 -0
@@ -12,5 +12,5 @@ __version__: str
|
|
12
12
|
__version_tuple__: VERSION_TUPLE
|
13
13
|
version_tuple: VERSION_TUPLE
|
14
14
|
|
15
|
-
__version__ = version = '0.2.1.
|
16
|
-
__version_tuple__ = version_tuple = (0, 2, 1, '
|
15
|
+
__version__ = version = '0.2.1.dev128'
|
16
|
+
__version_tuple__ = version_tuple = (0, 2, 1, 'dev128')
|
@@ -16,6 +16,7 @@ from jax_dataclasses import Static
|
|
16
16
|
import jaxsim.api as js
|
17
17
|
import jaxsim.parsers.descriptions
|
18
18
|
import jaxsim.typing as jtp
|
19
|
+
from jaxsim.math import Cross
|
19
20
|
from jaxsim.utils import HashlessObject, JaxsimDataclass, Mutability
|
20
21
|
|
21
22
|
from .common import VelRepr
|
@@ -871,6 +872,126 @@ def free_floating_mass_matrix(
|
|
871
872
|
raise ValueError(data.velocity_representation)
|
872
873
|
|
873
874
|
|
875
|
+
@jax.jit
|
876
|
+
def free_floating_coriolis_matrix(
|
877
|
+
model: JaxSimModel, data: js.data.JaxSimModelData
|
878
|
+
) -> jtp.Matrix:
|
879
|
+
"""
|
880
|
+
Compute the free-floating Coriolis matrix of the model.
|
881
|
+
|
882
|
+
Args:
|
883
|
+
model: The model to consider.
|
884
|
+
data: The data of the considered model.
|
885
|
+
|
886
|
+
Returns:
|
887
|
+
The free-floating Coriolis matrix of the model.
|
888
|
+
|
889
|
+
Note:
|
890
|
+
This function, contrarily to other quantities of the equations of motion,
|
891
|
+
does not exploit any iterative algorithm. Therefore, the computation of
|
892
|
+
the Coriolis matrix may be much slower than other quantities.
|
893
|
+
"""
|
894
|
+
|
895
|
+
# We perform all the calculation in body-fixed.
|
896
|
+
# The Coriolis matrix computed in this representation is converted later
|
897
|
+
# to the active representation stored in data.
|
898
|
+
with data.switch_velocity_representation(VelRepr.Body):
|
899
|
+
|
900
|
+
B_ν = data.generalized_velocity()
|
901
|
+
|
902
|
+
# Doubly-left free-floating Jacobian.
|
903
|
+
L_J_WL_B = generalized_free_floating_jacobian(model=model, data=data)
|
904
|
+
|
905
|
+
# Doubly-left free-floating Jacobian derivative.
|
906
|
+
L_J̇_WL_B = jax.vmap(
|
907
|
+
lambda link_index: js.link.jacobian_derivative(
|
908
|
+
model=model, data=data, link_index=link_index
|
909
|
+
)
|
910
|
+
)(js.link.names_to_idxs(model=model, link_names=model.link_names()))
|
911
|
+
|
912
|
+
L_M_L = link_spatial_inertia_matrices(model=model)
|
913
|
+
|
914
|
+
# Body-fixed link velocities.
|
915
|
+
# Note: we could have called link.velocity() instead of computing it ourselves,
|
916
|
+
# but since we need the link Jacobians later, we can save a double calculation.
|
917
|
+
L_v_WL = jax.vmap(lambda J: J @ B_ν)(L_J_WL_B)
|
918
|
+
|
919
|
+
# Compute the contribution of each link to the Coriolis matrix.
|
920
|
+
def compute_link_contribution(M, v, J, J̇) -> jtp.Array:
|
921
|
+
|
922
|
+
return J.T @ ((Cross.vx_star(v) @ M + M @ Cross.vx(v)) @ J + M @ J̇)
|
923
|
+
|
924
|
+
C_B_links = jax.vmap(compute_link_contribution)(
|
925
|
+
L_M_L,
|
926
|
+
L_v_WL,
|
927
|
+
L_J_WL_B,
|
928
|
+
L_J̇_WL_B,
|
929
|
+
)
|
930
|
+
|
931
|
+
# We need to adjust the Coriolis matrix for fixed-base models.
|
932
|
+
# In this case, the base link does not contribute to the matrix, and we need to zero
|
933
|
+
# the off-diagonal terms mapping joint quantities onto the base configuration.
|
934
|
+
if model.floating_base():
|
935
|
+
C_B = C_B_links.sum(axis=0)
|
936
|
+
else:
|
937
|
+
C_B = C_B_links[1:].sum(axis=0)
|
938
|
+
C_B = C_B.at[0:6, 6:].set(0.0)
|
939
|
+
C_B = C_B.at[6:, 0:6].set(0.0)
|
940
|
+
|
941
|
+
# Adjust the representation of the Coriolis matrix.
|
942
|
+
# Refer to https://github.com/traversaro/traversaro-phd-thesis, Section 3.6.
|
943
|
+
match data.velocity_representation:
|
944
|
+
|
945
|
+
case VelRepr.Body:
|
946
|
+
return C_B
|
947
|
+
|
948
|
+
case VelRepr.Inertial:
|
949
|
+
|
950
|
+
n = model.dofs()
|
951
|
+
W_H_B = data.base_transform()
|
952
|
+
B_X_W = jaxsim.math.Adjoint.from_transform(W_H_B, inverse=True)
|
953
|
+
B_T_W = jax.scipy.linalg.block_diag(B_X_W, jnp.eye(n))
|
954
|
+
|
955
|
+
with data.switch_velocity_representation(VelRepr.Inertial):
|
956
|
+
W_v_WB = data.base_velocity()
|
957
|
+
B_Ẋ_W = -B_X_W @ jaxsim.math.Cross.vx(W_v_WB)
|
958
|
+
|
959
|
+
B_Ṫ_W = jax.scipy.linalg.block_diag(B_Ẋ_W, jnp.zeros(shape=(n, n)))
|
960
|
+
|
961
|
+
with data.switch_velocity_representation(VelRepr.Body):
|
962
|
+
M = free_floating_mass_matrix(model=model, data=data)
|
963
|
+
|
964
|
+
C = B_T_W.T @ (M @ B_Ṫ_W + C_B @ B_T_W)
|
965
|
+
|
966
|
+
return C
|
967
|
+
|
968
|
+
case VelRepr.Mixed:
|
969
|
+
|
970
|
+
n = model.dofs()
|
971
|
+
BW_H_B = data.base_transform().at[0:3, 3].set(jnp.zeros(3))
|
972
|
+
B_X_BW = jaxsim.math.Adjoint.from_transform(transform=BW_H_B, inverse=True)
|
973
|
+
B_T_BW = jax.scipy.linalg.block_diag(B_X_BW, jnp.eye(n))
|
974
|
+
|
975
|
+
with data.switch_velocity_representation(VelRepr.Mixed):
|
976
|
+
BW_v_WB = data.base_velocity()
|
977
|
+
BW_v_W_BW = BW_v_WB.at[3:6].set(jnp.zeros(3))
|
978
|
+
|
979
|
+
BW_v_BW_B = BW_v_WB - BW_v_W_BW
|
980
|
+
B_Ẋ_BW = -B_X_BW @ jaxsim.math.Cross.vx(BW_v_BW_B)
|
981
|
+
|
982
|
+
B_Ṫ_BW = jax.scipy.linalg.block_diag(B_Ẋ_BW, jnp.zeros(shape=(n, n)))
|
983
|
+
|
984
|
+
with data.switch_velocity_representation(VelRepr.Body):
|
985
|
+
M = free_floating_mass_matrix(model=model, data=data)
|
986
|
+
|
987
|
+
C = B_T_BW.T @ (M @ B_Ṫ_BW + C_B @ B_T_BW)
|
988
|
+
|
989
|
+
return C
|
990
|
+
|
991
|
+
case _:
|
992
|
+
raise ValueError(data.velocity_representation)
|
993
|
+
|
994
|
+
|
874
995
|
@jax.jit
|
875
996
|
def inverse_dynamics(
|
876
997
|
model: JaxSimModel,
|
@@ -931,8 +1052,6 @@ def inverse_dynamics(
|
|
931
1052
|
expressed in a generic frame C to the inertial-fixed representation W_v̇_WB.
|
932
1053
|
"""
|
933
1054
|
|
934
|
-
from jaxsim.math import Cross
|
935
|
-
|
936
1055
|
W_X_C = jaxlie.SE3.from_matrix(W_H_C).adjoint()
|
937
1056
|
C_X_W = jaxlie.SE3.from_matrix(W_H_C).inverse().adjoint()
|
938
1057
|
C_v_WC = C_X_W @ W_v_WC
|
@@ -3,6 +3,7 @@ import jax.numpy as jnp
|
|
3
3
|
import pytest
|
4
4
|
|
5
5
|
import jaxsim.api as js
|
6
|
+
import jaxsim.math
|
6
7
|
from jaxsim import VelRepr
|
7
8
|
|
8
9
|
from . import utils_idyntree
|
@@ -250,4 +251,66 @@ def test_link_jacobian_derivative(
|
|
250
251
|
)(js.link.names_to_idxs(model=model, link_names=model.link_names()))
|
251
252
|
|
252
253
|
# Compare the two computations.
|
253
|
-
assert jnp.einsum("l6g,g->l6", O_J̇_WL_I, I_ν) == pytest.approx(
|
254
|
+
assert jnp.einsum("l6g,g->l6", O_J̇_WL_I, I_ν) == pytest.approx(
|
255
|
+
O_a_bias_WL, abs=1e-9
|
256
|
+
)
|
257
|
+
|
258
|
+
# Compute the plain Jacobian.
|
259
|
+
# This function will be used to compute the Jacobian derivative with AD.
|
260
|
+
# Given q, computing J̇ by AD-ing this function should work out-of-the-box with
|
261
|
+
# all velocity representations, that are handled internally when computing J.
|
262
|
+
def J(q) -> jax.Array:
|
263
|
+
|
264
|
+
data_ad = js.data.JaxSimModelData.zero(
|
265
|
+
model=model, velocity_representation=data.velocity_representation
|
266
|
+
)
|
267
|
+
|
268
|
+
data_ad = data_ad.reset_base_position(base_position=q[:3])
|
269
|
+
data_ad = data_ad.reset_base_quaternion(base_quaternion=q[3:7])
|
270
|
+
data_ad = data_ad.reset_joint_positions(positions=q[7:])
|
271
|
+
|
272
|
+
O_J_WL_I = js.model.generalized_free_floating_jacobian(
|
273
|
+
model=model, data=data_ad
|
274
|
+
)
|
275
|
+
|
276
|
+
return O_J_WL_I
|
277
|
+
|
278
|
+
def compute_q(data: js.data.JaxSimModelData) -> jax.Array:
|
279
|
+
|
280
|
+
q = jnp.hstack(
|
281
|
+
[data.base_position(), data.base_orientation(), data.joint_positions()]
|
282
|
+
)
|
283
|
+
|
284
|
+
return q
|
285
|
+
|
286
|
+
def compute_q̇(data: js.data.JaxSimModelData) -> jax.Array:
|
287
|
+
|
288
|
+
with data.switch_velocity_representation(VelRepr.Body):
|
289
|
+
B_ω_WB = data.base_velocity()[3:6]
|
290
|
+
|
291
|
+
with data.switch_velocity_representation(VelRepr.Mixed):
|
292
|
+
W_ṗ_B = data.base_velocity()[0:3]
|
293
|
+
|
294
|
+
W_Q̇_B = jaxsim.math.Quaternion.derivative(
|
295
|
+
quaternion=data.base_orientation(),
|
296
|
+
omega=B_ω_WB,
|
297
|
+
omega_in_body_fixed=True,
|
298
|
+
K=0.0,
|
299
|
+
).squeeze()
|
300
|
+
|
301
|
+
q̇ = jnp.hstack([W_ṗ_B, W_Q̇_B, data.joint_velocities()])
|
302
|
+
|
303
|
+
return q̇
|
304
|
+
|
305
|
+
# Compute q and q̇.
|
306
|
+
q = compute_q(data)
|
307
|
+
q̇ = compute_q̇(data)
|
308
|
+
|
309
|
+
# Compute dJ/dt with AD.
|
310
|
+
dJ_dq = jax.jacfwd(J, argnums=0)(q)
|
311
|
+
O_J̇_ad_WL_I = jnp.einsum("ijkq,q->ijk", dJ_dq, q̇)
|
312
|
+
|
313
|
+
assert O_J̇_ad_WL_I == pytest.approx(O_J̇_WL_I)
|
314
|
+
assert jnp.einsum("l6g,g->l6", O_J̇_ad_WL_I, I_ν) == pytest.approx(
|
315
|
+
jnp.einsum("l6g,g->l6", O_J̇_WL_I, I_ν)
|
316
|
+
)
|
@@ -7,6 +7,7 @@ import pytest
|
|
7
7
|
import rod
|
8
8
|
|
9
9
|
import jaxsim.api as js
|
10
|
+
import jaxsim.math
|
10
11
|
from jaxsim import VelRepr
|
11
12
|
|
12
13
|
from . import utils_idyntree
|
@@ -319,6 +320,95 @@ def test_model_jacobian(
|
|
319
320
|
assert pytest.approx(JTf_inertial) == JTf_other, vel_repr.name
|
320
321
|
|
321
322
|
|
323
|
+
def test_coriolis_matrix(
|
324
|
+
jaxsim_models_types: js.model.JaxSimModel,
|
325
|
+
velocity_representation: VelRepr,
|
326
|
+
prng_key: jax.Array,
|
327
|
+
):
|
328
|
+
|
329
|
+
model = jaxsim_models_types
|
330
|
+
|
331
|
+
_, subkey = jax.random.split(prng_key, num=2)
|
332
|
+
data = js.data.random_model_data(
|
333
|
+
model=model, key=subkey, velocity_representation=velocity_representation
|
334
|
+
)
|
335
|
+
|
336
|
+
# =====
|
337
|
+
# Tests
|
338
|
+
# =====
|
339
|
+
|
340
|
+
I_ν = data.generalized_velocity()
|
341
|
+
C = js.model.free_floating_coriolis_matrix(model=model, data=data)
|
342
|
+
|
343
|
+
h = js.model.free_floating_bias_forces(model=model, data=data)
|
344
|
+
g = js.model.free_floating_gravity_forces(model=model, data=data)
|
345
|
+
Cν = h - g
|
346
|
+
|
347
|
+
assert C @ I_ν == pytest.approx(Cν)
|
348
|
+
|
349
|
+
# Compute the free-floating mass matrix.
|
350
|
+
# This function will be used to compute the Ṁ with AD.
|
351
|
+
# Given q, computing Ṁ by AD-ing this function should work out-of-the-box with
|
352
|
+
# all velocity representations, that are handled internally when computing M.
|
353
|
+
def M(q) -> jax.Array:
|
354
|
+
|
355
|
+
data_ad = js.data.JaxSimModelData.zero(
|
356
|
+
model=model, velocity_representation=data.velocity_representation
|
357
|
+
)
|
358
|
+
|
359
|
+
data_ad = data_ad.reset_base_position(base_position=q[:3])
|
360
|
+
data_ad = data_ad.reset_base_quaternion(base_quaternion=q[3:7])
|
361
|
+
data_ad = data_ad.reset_joint_positions(positions=q[7:])
|
362
|
+
|
363
|
+
M = js.model.free_floating_mass_matrix(model=model, data=data_ad)
|
364
|
+
|
365
|
+
return M
|
366
|
+
|
367
|
+
def compute_q(data: js.data.JaxSimModelData) -> jax.Array:
|
368
|
+
|
369
|
+
q = jnp.hstack(
|
370
|
+
[data.base_position(), data.base_orientation(), data.joint_positions()]
|
371
|
+
)
|
372
|
+
|
373
|
+
return q
|
374
|
+
|
375
|
+
def compute_q̇(data: js.data.JaxSimModelData) -> jax.Array:
|
376
|
+
|
377
|
+
with data.switch_velocity_representation(VelRepr.Body):
|
378
|
+
B_ω_WB = data.base_velocity()[3:6]
|
379
|
+
|
380
|
+
with data.switch_velocity_representation(VelRepr.Mixed):
|
381
|
+
W_ṗ_B = data.base_velocity()[0:3]
|
382
|
+
|
383
|
+
W_Q̇_B = jaxsim.math.Quaternion.derivative(
|
384
|
+
quaternion=data.base_orientation(),
|
385
|
+
omega=B_ω_WB,
|
386
|
+
omega_in_body_fixed=True,
|
387
|
+
K=0.0,
|
388
|
+
).squeeze()
|
389
|
+
|
390
|
+
q̇ = jnp.hstack([W_ṗ_B, W_Q̇_B, data.joint_velocities()])
|
391
|
+
|
392
|
+
return q̇
|
393
|
+
|
394
|
+
# Compute q and q̇.
|
395
|
+
q = compute_q(data)
|
396
|
+
q̇ = compute_q̇(data)
|
397
|
+
|
398
|
+
# Compute Ṁ with AD.
|
399
|
+
dM_dq = jax.jacfwd(M, argnums=0)(q)
|
400
|
+
Ṁ = jnp.einsum("ijq,q->ij", dM_dq, q̇)
|
401
|
+
|
402
|
+
# We need to zero the blocks projecting joint variables to the base configuration
|
403
|
+
# for fixed-base models.
|
404
|
+
if not model.floating_base():
|
405
|
+
Ṁ = Ṁ.at[0:6, 6:].set(0)
|
406
|
+
Ṁ = Ṁ.at[6:, 0:6].set(0)
|
407
|
+
|
408
|
+
# Ensure that (Ṁ - 2C) is skew symmetric.
|
409
|
+
assert Ṁ - C - C.T == pytest.approx(0)
|
410
|
+
|
411
|
+
|
322
412
|
def test_model_fd_id_consistency(
|
323
413
|
jaxsim_models_types: js.model.JaxSimModel,
|
324
414
|
velocity_representation: VelRepr,
|
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
|