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.
Files changed (118) hide show
  1. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/PKG-INFO +1 -1
  2. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/_version.py +2 -2
  3. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/model.py +121 -2
  4. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim.egg-info/PKG-INFO +1 -1
  5. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/test_api_link.py +64 -1
  6. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/test_api_model.py +90 -0
  7. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/test_simulations.py +1 -1
  8. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/.devcontainer/Dockerfile +0 -0
  9. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/.devcontainer/devcontainer.json +0 -0
  10. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/.gitattributes +0 -0
  11. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/.github/CODEOWNERS +0 -0
  12. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/.github/workflows/ci_cd.yml +0 -0
  13. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/.github/workflows/read_the_docs.yml +0 -0
  14. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/.github/workflows/style.yml +0 -0
  15. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/.gitignore +0 -0
  16. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/.pre-commit-config.yaml +0 -0
  17. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/.readthedocs.yaml +0 -0
  18. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/CONTRIBUTING.md +0 -0
  19. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/LICENSE +0 -0
  20. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/README.md +0 -0
  21. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/Makefile +0 -0
  22. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/conf.py +0 -0
  23. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/guide/install.rst +0 -0
  24. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/index.rst +0 -0
  25. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/make.bat +0 -0
  26. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/modules/api.rst +0 -0
  27. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/modules/index.rst +0 -0
  28. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/modules/integrators.rst +0 -0
  29. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/modules/math.rst +0 -0
  30. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/modules/mujoco.rst +0 -0
  31. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/modules/parsers.rst +0 -0
  32. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/modules/rbda.rst +0 -0
  33. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/modules/typing.rst +0 -0
  34. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/docs/modules/utils.rst +0 -0
  35. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/environment.yml +0 -0
  36. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/examples/.gitattributes +0 -0
  37. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/examples/.gitignore +0 -0
  38. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/examples/PD_controller.ipynb +0 -0
  39. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/examples/Parallel_computing.ipynb +0 -0
  40. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/examples/README.md +0 -0
  41. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/examples/assets/cartpole.urdf +0 -0
  42. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/pixi.lock +0 -0
  43. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/pyproject.toml +0 -0
  44. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/setup.cfg +0 -0
  45. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/setup.py +0 -0
  46. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/__init__.py +0 -0
  47. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/__init__.py +0 -0
  48. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/com.py +0 -0
  49. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/common.py +0 -0
  50. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/contact.py +0 -0
  51. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/data.py +0 -0
  52. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/frame.py +0 -0
  53. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/joint.py +0 -0
  54. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/kin_dyn_parameters.py +0 -0
  55. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/link.py +0 -0
  56. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/ode.py +0 -0
  57. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/ode_data.py +0 -0
  58. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/api/references.py +0 -0
  59. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/integrators/__init__.py +0 -0
  60. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/integrators/common.py +0 -0
  61. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/integrators/fixed_step.py +0 -0
  62. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/integrators/variable_step.py +0 -0
  63. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/logging.py +0 -0
  64. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/math/__init__.py +0 -0
  65. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/math/adjoint.py +0 -0
  66. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/math/cross.py +0 -0
  67. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/math/inertia.py +0 -0
  68. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/math/joint_model.py +0 -0
  69. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/math/quaternion.py +0 -0
  70. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/math/rotation.py +0 -0
  71. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/math/skew.py +0 -0
  72. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/math/transform.py +0 -0
  73. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/mujoco/__init__.py +0 -0
  74. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/mujoco/__main__.py +0 -0
  75. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/mujoco/loaders.py +0 -0
  76. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/mujoco/model.py +0 -0
  77. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/mujoco/visualizer.py +0 -0
  78. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/parsers/__init__.py +0 -0
  79. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/parsers/descriptions/__init__.py +0 -0
  80. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/parsers/descriptions/collision.py +0 -0
  81. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/parsers/descriptions/joint.py +0 -0
  82. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/parsers/descriptions/link.py +0 -0
  83. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/parsers/descriptions/model.py +0 -0
  84. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/parsers/kinematic_graph.py +0 -0
  85. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/parsers/rod/__init__.py +0 -0
  86. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/parsers/rod/parser.py +0 -0
  87. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/parsers/rod/utils.py +0 -0
  88. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/rbda/__init__.py +0 -0
  89. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/rbda/aba.py +0 -0
  90. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/rbda/collidable_points.py +0 -0
  91. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/rbda/crba.py +0 -0
  92. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/rbda/forward_kinematics.py +0 -0
  93. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/rbda/jacobian.py +0 -0
  94. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/rbda/rnea.py +0 -0
  95. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/rbda/soft_contacts.py +0 -0
  96. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/rbda/utils.py +0 -0
  97. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/terrain/__init__.py +0 -0
  98. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/terrain/terrain.py +0 -0
  99. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/typing.py +0 -0
  100. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/utils/__init__.py +0 -0
  101. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/utils/jaxsim_dataclass.py +0 -0
  102. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/utils/tracing.py +0 -0
  103. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim/utils/wrappers.py +0 -0
  104. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim.egg-info/SOURCES.txt +0 -0
  105. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim.egg-info/dependency_links.txt +0 -0
  106. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim.egg-info/not-zip-safe +0 -0
  107. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim.egg-info/requires.txt +0 -0
  108. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/src/jaxsim.egg-info/top_level.txt +0 -0
  109. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/__init__.py +0 -0
  110. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/conftest.py +0 -0
  111. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/test_api_com.py +0 -0
  112. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/test_api_data.py +0 -0
  113. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/test_api_frame.py +0 -0
  114. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/test_api_joint.py +0 -0
  115. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/test_automatic_differentiation.py +0 -0
  116. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/test_contact.py +0 -0
  117. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/test_pytree.py +0 -0
  118. {jaxsim-0.2.1.dev121 → jaxsim-0.2.1.dev128}/tests/utils_idyntree.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jaxsim
3
- Version: 0.2.1.dev121
3
+ Version: 0.2.1.dev128
4
4
  Home-page: https://github.com/ami-iit/jaxsim
5
5
  Author: Diego Ferigo
6
6
  Author-email: diego.ferigo@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.2.1.dev121'
16
- __version_tuple__ = version_tuple = (0, 2, 1, 'dev121')
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jaxsim
3
- Version: 0.2.1.dev121
3
+ Version: 0.2.1.dev128
4
4
  Home-page: https://github.com/ami-iit/jaxsim
5
5
  Author: Diego Ferigo
6
6
  Author-email: diego.ferigo@iit.it
@@ -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(O_a_bias_WL)
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,
@@ -169,5 +169,5 @@ def test_box_with_zero_gravity(
169
169
  assert data.base_position() == pytest.approx(
170
170
  data0.base_position()
171
171
  + 0.5 * L_f[:, :3].squeeze() / js.model.total_mass(model=model) * tf**2,
172
- rel=1e-4,
172
+ abs=1e-3,
173
173
  )
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes