jaxsim 0.4.3.dev100__tar.gz → 0.4.3.dev115__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 (125) hide show
  1. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/PKG-INFO +2 -2
  2. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/environment.yml +1 -1
  3. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/examples/PD_controller.ipynb +1 -1
  4. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/pyproject.toml +1 -1
  5. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/_version.py +2 -2
  6. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/api/contact.py +3 -1
  7. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/api/model.py +3 -3
  8. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/mujoco/loaders.py +1 -1
  9. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/parsers/rod/parser.py +30 -22
  10. jaxsim-0.4.3.dev115/src/jaxsim/rbda/contacts/__init__.py +8 -0
  11. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/rbda/contacts/common.py +15 -8
  12. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/rbda/contacts/relaxed_rigid.py +22 -12
  13. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/rbda/contacts/rigid.py +28 -16
  14. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/rbda/contacts/soft.py +205 -180
  15. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim.egg-info/PKG-INFO +2 -2
  16. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim.egg-info/requires.txt +1 -1
  17. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/tests/conftest.py +0 -15
  18. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/tests/test_api_contact.py +1 -1
  19. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/tests/test_pytree.py +2 -4
  20. jaxsim-0.4.3.dev100/tests/__init__.py +0 -0
  21. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/.devcontainer/Dockerfile +0 -0
  22. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/.devcontainer/devcontainer.json +0 -0
  23. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/.gitattributes +0 -0
  24. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/.github/CODEOWNERS +0 -0
  25. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/.github/workflows/ci_cd.yml +0 -0
  26. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/.github/workflows/read_the_docs.yml +0 -0
  27. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/.github/workflows/update_pixi_lockfile.yml +0 -0
  28. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/.gitignore +0 -0
  29. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/.pre-commit-config.yaml +0 -0
  30. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/.readthedocs.yaml +0 -0
  31. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/CONTRIBUTING.md +0 -0
  32. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/LICENSE +0 -0
  33. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/README.md +0 -0
  34. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/docs/Makefile +0 -0
  35. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/docs/conf.py +0 -0
  36. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/docs/examples.rst +0 -0
  37. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/docs/guide/install.rst +0 -0
  38. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/docs/index.rst +0 -0
  39. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/docs/make.bat +0 -0
  40. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/docs/modules/api.rst +0 -0
  41. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/docs/modules/integrators.rst +0 -0
  42. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/docs/modules/math.rst +0 -0
  43. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/docs/modules/mujoco.rst +0 -0
  44. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/docs/modules/parsers.rst +0 -0
  45. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/docs/modules/rbda.rst +0 -0
  46. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/docs/modules/typing.rst +0 -0
  47. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/docs/modules/utils.rst +0 -0
  48. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/examples/.gitattributes +0 -0
  49. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/examples/.gitignore +0 -0
  50. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/examples/Parallel_computing.ipynb +0 -0
  51. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/examples/README.md +0 -0
  52. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/examples/assets/cartpole.urdf +0 -0
  53. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/pixi.lock +0 -0
  54. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/setup.cfg +0 -0
  55. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/setup.py +0 -0
  56. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/__init__.py +0 -0
  57. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/api/__init__.py +0 -0
  58. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/api/com.py +0 -0
  59. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/api/common.py +0 -0
  60. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/api/data.py +0 -0
  61. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/api/frame.py +0 -0
  62. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/api/joint.py +0 -0
  63. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/api/kin_dyn_parameters.py +0 -0
  64. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/api/link.py +0 -0
  65. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/api/ode.py +0 -0
  66. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/api/ode_data.py +0 -0
  67. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/api/references.py +0 -0
  68. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/exceptions.py +0 -0
  69. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/integrators/__init__.py +0 -0
  70. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/integrators/common.py +0 -0
  71. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/integrators/fixed_step.py +0 -0
  72. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/integrators/variable_step.py +0 -0
  73. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/logging.py +0 -0
  74. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/math/__init__.py +0 -0
  75. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/math/adjoint.py +0 -0
  76. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/math/cross.py +0 -0
  77. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/math/inertia.py +0 -0
  78. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/math/joint_model.py +0 -0
  79. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/math/quaternion.py +0 -0
  80. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/math/rotation.py +0 -0
  81. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/math/skew.py +0 -0
  82. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/math/transform.py +0 -0
  83. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/mujoco/__init__.py +0 -0
  84. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/mujoco/__main__.py +0 -0
  85. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/mujoco/model.py +0 -0
  86. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/mujoco/visualizer.py +0 -0
  87. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/parsers/__init__.py +0 -0
  88. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/parsers/descriptions/__init__.py +0 -0
  89. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/parsers/descriptions/collision.py +0 -0
  90. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/parsers/descriptions/joint.py +0 -0
  91. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/parsers/descriptions/link.py +0 -0
  92. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/parsers/descriptions/model.py +0 -0
  93. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/parsers/kinematic_graph.py +0 -0
  94. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/parsers/rod/__init__.py +0 -0
  95. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/parsers/rod/utils.py +0 -0
  96. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/rbda/__init__.py +0 -0
  97. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/rbda/aba.py +0 -0
  98. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/rbda/collidable_points.py +0 -0
  99. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/rbda/crba.py +0 -0
  100. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/rbda/forward_kinematics.py +0 -0
  101. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/rbda/jacobian.py +0 -0
  102. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/rbda/rnea.py +0 -0
  103. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/rbda/utils.py +0 -0
  104. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/terrain/__init__.py +0 -0
  105. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/terrain/terrain.py +0 -0
  106. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/typing.py +0 -0
  107. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/utils/__init__.py +0 -0
  108. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/utils/jaxsim_dataclass.py +0 -0
  109. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/utils/tracing.py +0 -0
  110. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim/utils/wrappers.py +0 -0
  111. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim.egg-info/SOURCES.txt +0 -0
  112. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim.egg-info/dependency_links.txt +0 -0
  113. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/src/jaxsim.egg-info/top_level.txt +0 -0
  114. {jaxsim-0.4.3.dev100/src/jaxsim/rbda/contacts → jaxsim-0.4.3.dev115/tests}/__init__.py +0 -0
  115. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/tests/test_api_com.py +0 -0
  116. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/tests/test_api_data.py +0 -0
  117. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/tests/test_api_frame.py +0 -0
  118. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/tests/test_api_joint.py +0 -0
  119. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/tests/test_api_link.py +0 -0
  120. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/tests/test_api_model.py +0 -0
  121. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/tests/test_automatic_differentiation.py +0 -0
  122. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/tests/test_contact.py +0 -0
  123. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/tests/test_exceptions.py +0 -0
  124. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/tests/test_simulations.py +0 -0
  125. {jaxsim-0.4.3.dev100 → jaxsim-0.4.3.dev115}/tests/utils_idyntree.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jaxsim
3
- Version: 0.4.3.dev100
3
+ Version: 0.4.3.dev115
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>
@@ -67,7 +67,7 @@ Requires-Dist: jaxlie>=1.3.0
67
67
  Requires-Dist: jax_dataclasses>=1.4.0
68
68
  Requires-Dist: pptree
69
69
  Requires-Dist: qpax
70
- Requires-Dist: rod>=0.3.0
70
+ Requires-Dist: rod>=0.3.3
71
71
  Requires-Dist: typing_extensions; python_version < "3.12"
72
72
  Provides-Extra: style
73
73
  Requires-Dist: black[jupyter]~=24.0; extra == "style"
@@ -14,7 +14,7 @@ dependencies:
14
14
  - jax-dataclasses >= 1.4.0
15
15
  - pptree
16
16
  - qpax
17
- - rod >= 0.3.0
17
+ - rod >= 0.3.3
18
18
  - typing_extensions # python<3.12
19
19
  # ====================================
20
20
  # Optional dependencies from setup.cfg
@@ -100,7 +100,7 @@
100
100
  "num_steps = int(integration_time / dt)\n",
101
101
  "\n",
102
102
  "model = js.model.JaxSimModel.build_from_model_description(\n",
103
- " model_description=model_urdf_string, is_urdf=True\n",
103
+ " model_description=model_urdf_string\n",
104
104
  ")\n",
105
105
  "data = js.data.JaxSimModelData.build(model=model)\n",
106
106
  "integrator = integrators.fixed_step.RungeKutta4SO3.build(\n",
@@ -51,7 +51,7 @@ dependencies = [
51
51
  "jax_dataclasses >= 1.4.0",
52
52
  "pptree",
53
53
  "qpax",
54
- "rod >= 0.3.0",
54
+ "rod >= 0.3.3",
55
55
  "typing_extensions ; python_version < '3.12'",
56
56
  ]
57
57
 
@@ -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.3.dev100'
16
- __version_tuple__ = version_tuple = (0, 4, 3, 'dev100')
15
+ __version__ = version = '0.4.3.dev115'
16
+ __version_tuple__ = version_tuple = (0, 4, 3, 'dev115')
@@ -186,7 +186,9 @@ def collidable_point_dynamics(
186
186
  # Note that the material deformation rate is always returned in the mixed frame
187
187
  # C[W] = (W_p_C, [W]). This is convenient for integration purpose.
188
188
  W_f_Ci, (CW_ṁ,) = jax.vmap(soft_contacts.compute_contact_forces)(
189
- W_p_Ci, W_ṗ_Ci, data.state.contact.tangential_deformation
189
+ position=W_p_Ci,
190
+ velocity=W_ṗ_Ci,
191
+ tangential_deformation=data.state.contact.tangential_deformation,
190
192
  )
191
193
  aux_data = dict(m_dot=CW_ṁ)
192
194
 
@@ -106,8 +106,8 @@ class JaxSimModel(JaxsimDataclass):
106
106
  terrain:
107
107
  The optional terrain to consider.
108
108
  is_urdf:
109
- Whether the model description is a URDF or an SDF. This is
110
- automatically inferred if the model description is a path to a file.
109
+ The optional flag to force the model description to be parsed as a
110
+ URDF or a SDF. This is otherwise automatically inferred.
111
111
  considered_joints:
112
112
  The list of joints to consider. If None, all joints are considered.
113
113
 
@@ -120,7 +120,7 @@ class JaxSimModel(JaxsimDataclass):
120
120
  # Parse the input resource (either a path to file or a string with the URDF/SDF)
121
121
  # and build the -intermediate- model description.
122
122
  intermediate_description = jaxsim.parsers.rod.build_model_description(
123
- model_description=model_description, is_urdf=is_urdf
123
+ model_description=model_description
124
124
  )
125
125
 
126
126
  # Lump links together if not all joints are considered.
@@ -25,7 +25,7 @@ def load_rod_model(
25
25
 
26
26
  Args:
27
27
  model_description: The URDF/SDF file or ROD model to load.
28
- is_urdf: Whether the model description is a URDF file.
28
+ is_urdf: Whether to force parsing the model description as a URDF file.
29
29
  model_name: The name of the model to load from the resource.
30
30
 
31
31
  Returns:
@@ -33,7 +33,7 @@ class SDFData(NamedTuple):
33
33
 
34
34
 
35
35
  def extract_model_data(
36
- model_description: pathlib.Path | str | rod.Model,
36
+ model_description: pathlib.Path | str | rod.Model | rod.Sdf,
37
37
  model_name: str | None = None,
38
38
  is_urdf: bool | None = None,
39
39
  ) -> SDFData:
@@ -41,30 +41,37 @@ def extract_model_data(
41
41
  Extract data from an SDF/URDF resource useful to build a JaxSim model.
42
42
 
43
43
  Args:
44
- model_description: A path to an SDF/URDF file, a string containing its content,
45
- or a pre-parsed/pre-built rod model.
44
+ model_description:
45
+ A path to an SDF/URDF file, a string containing its content, or
46
+ a pre-parsed/pre-built rod model.
46
47
  model_name: The name of the model to extract from the SDF resource.
47
- is_urdf: Whether the SDF resource is a URDF file. Needed only if model_description
48
- is a URDF string.
48
+ is_urdf:
49
+ Whether to force parsing the resource as a URDF file. Automatically
50
+ detected if not provided.
49
51
 
50
52
  Returns:
51
53
  The extracted model data.
52
54
  """
53
55
 
54
- if isinstance(model_description, rod.Model):
55
- sdf_model = model_description
56
- else:
57
- # Parse the SDF resource.
58
- sdf_element = rod.Sdf.load(sdf=model_description, is_urdf=is_urdf)
59
-
60
- if len(sdf_element.models()) == 0:
61
- raise RuntimeError("Failed to find any model in SDF resource")
62
-
63
- # Assume the SDF resource has only one model, or the desired model name is given.
64
- sdf_models = {m.name: m for m in sdf_element.models()}
65
- sdf_model = (
66
- sdf_element.models()[0] if len(sdf_models) == 1 else sdf_models[model_name]
67
- )
56
+ match model_description:
57
+ case rod.Model():
58
+ sdf_model = model_description
59
+ case rod.Sdf() | str() | pathlib.Path():
60
+ sdf_element = (
61
+ model_description
62
+ if isinstance(model_description, rod.Sdf)
63
+ else rod.Sdf.load(sdf=model_description, is_urdf=is_urdf)
64
+ )
65
+ if not sdf_element.models():
66
+ raise RuntimeError("Failed to find any model in SDF resource")
67
+
68
+ # Assume the SDF resource has only one model, or the desired model name is given.
69
+ sdf_models = {m.name: m for m in sdf_element.models()}
70
+ sdf_model = (
71
+ sdf_element.models()[0]
72
+ if len(sdf_models) == 1
73
+ else sdf_models[model_name]
74
+ )
68
75
 
69
76
  # Log model name.
70
77
  logging.debug(msg=f"Found model '{sdf_model.name}' in SDF resource")
@@ -344,7 +351,7 @@ def extract_model_data(
344
351
 
345
352
  def build_model_description(
346
353
  model_description: pathlib.Path | str | rod.Model,
347
- is_urdf: bool | None = False,
354
+ is_urdf: bool | None = None,
348
355
  ) -> descriptions.ModelDescription:
349
356
  """
350
357
  Builds a model description from an SDF/URDF resource.
@@ -352,8 +359,9 @@ def build_model_description(
352
359
  Args:
353
360
  model_description: A path to an SDF/URDF file, a string containing its content,
354
361
  or a pre-parsed/pre-built rod model.
355
- is_urdf: Whether the SDF resource is a URDF file. Needed only if model_description
356
- is a URDF string.
362
+ is_urdf: Whether the force parsing the resource as a URDF file. Automatically
363
+ detected if not provided.
364
+
357
365
  Returns:
358
366
  The parsed model description.
359
367
  """
@@ -0,0 +1,8 @@
1
+ from .common import ContactModel, ContactsParams, ContactsState
2
+ from .relaxed_rigid import (
3
+ RelaxedRigidContacts,
4
+ RelaxedRigidContactsParams,
5
+ RelaxedRigidContactsState,
6
+ )
7
+ from .rigid import RigidContacts, RigidContactsParams, RigidContactsState
8
+ from .soft import SoftContacts, SoftContactsParams, SoftContactsState
@@ -7,15 +7,20 @@ import jaxsim.terrain
7
7
  import jaxsim.typing as jtp
8
8
  from jaxsim.utils import JaxsimDataclass
9
9
 
10
+ try:
11
+ from typing import Self
12
+ except ImportError:
13
+ from typing_extensions import Self
10
14
 
11
- class ContactsState(abc.ABC):
15
+
16
+ class ContactsState(JaxsimDataclass):
12
17
  """
13
18
  Abstract class storing the state of the contacts model.
14
19
  """
15
20
 
16
21
  @classmethod
17
22
  @abc.abstractmethod
18
- def build(cls, **kwargs) -> ContactsState:
23
+ def build(cls: type[Self], **kwargs) -> Self:
19
24
  """
20
25
  Build the contact state object.
21
26
 
@@ -26,7 +31,7 @@ class ContactsState(abc.ABC):
26
31
 
27
32
  @classmethod
28
33
  @abc.abstractmethod
29
- def zero(cls, **kwargs) -> ContactsState:
34
+ def zero(cls: type[Self], **kwargs) -> Self:
30
35
  """
31
36
  Build a zero contact state.
32
37
 
@@ -36,7 +41,7 @@ class ContactsState(abc.ABC):
36
41
  pass
37
42
 
38
43
  @abc.abstractmethod
39
- def valid(self, **kwargs) -> bool:
44
+ def valid(self, **kwargs) -> jtp.BoolLike:
40
45
  """
41
46
  Check if the contacts state is valid.
42
47
  """
@@ -50,18 +55,20 @@ class ContactsParams(JaxsimDataclass):
50
55
 
51
56
  @classmethod
52
57
  @abc.abstractmethod
53
- def build(cls) -> ContactsParams:
58
+ def build(cls: type[Self], **kwargs) -> Self:
54
59
  """
55
60
  Create a `ContactsParams` instance with specified parameters.
61
+
56
62
  Returns:
57
63
  The `ContactsParams` instance.
58
64
  """
59
65
  pass
60
66
 
61
67
  @abc.abstractmethod
62
- def valid(self, *args, **kwargs) -> bool:
68
+ def valid(self, **kwargs) -> jtp.BoolLike:
63
69
  """
64
70
  Check if the parameters are valid.
71
+
65
72
  Returns:
66
73
  True if the parameters are valid, False otherwise.
67
74
  """
@@ -83,8 +90,8 @@ class ContactModel(JaxsimDataclass):
83
90
  @abc.abstractmethod
84
91
  def compute_contact_forces(
85
92
  self,
86
- position: jtp.Vector,
87
- velocity: jtp.Vector,
93
+ position: jtp.VectorLike,
94
+ velocity: jtp.VectorLike,
88
95
  **kwargs,
89
96
  ) -> tuple[jtp.Vector, tuple[Any, ...]]:
90
97
  """
@@ -16,6 +16,11 @@ from jaxsim.terrain.terrain import FlatTerrain, Terrain
16
16
 
17
17
  from .common import ContactModel, ContactsParams, ContactsState
18
18
 
19
+ try:
20
+ from typing import Self
21
+ except ImportError:
22
+ from typing_extensions import Self
23
+
19
24
 
20
25
  @jax_dataclasses.pytree_dataclass
21
26
  class RelaxedRigidContactsParams(ContactsParams):
@@ -106,7 +111,8 @@ class RelaxedRigidContactsParams(ContactsParams):
106
111
 
107
112
  @classmethod
108
113
  def build(
109
- cls,
114
+ cls: type[Self],
115
+ *,
110
116
  time_constant: jtp.FloatLike | None = None,
111
117
  damping_coefficient: jtp.FloatLike | None = None,
112
118
  d_min: jtp.FloatLike | None = None,
@@ -119,7 +125,7 @@ class RelaxedRigidContactsParams(ContactsParams):
119
125
  mu: jtp.FloatLike | None = None,
120
126
  max_iterations: jtp.IntLike | None = None,
121
127
  tolerance: jtp.FloatLike | None = None,
122
- ) -> RelaxedRigidContactsParams:
128
+ ) -> Self:
123
129
  """Create a `RelaxedRigidContactsParams` instance"""
124
130
 
125
131
  return cls(
@@ -132,7 +138,8 @@ class RelaxedRigidContactsParams(ContactsParams):
132
138
  }
133
139
  )
134
140
 
135
- def valid(self) -> bool:
141
+ def valid(self) -> jtp.BoolLike:
142
+
136
143
  return bool(
137
144
  jnp.all(self.time_constant >= 0.0)
138
145
  and jnp.all(self.damping_coefficient > 0.0)
@@ -155,18 +162,19 @@ class RelaxedRigidContactsState(ContactsState):
155
162
  def __eq__(self, other: RelaxedRigidContactsState) -> bool:
156
163
  return hash(self) == hash(other)
157
164
 
158
- @staticmethod
159
- def build() -> RelaxedRigidContactsState:
165
+ @classmethod
166
+ def build(cls: type[Self]) -> Self:
160
167
  """Create a `RelaxedRigidContactsState` instance"""
161
168
 
162
- return RelaxedRigidContactsState()
169
+ return cls()
163
170
 
164
- @staticmethod
165
- def zero(model: js.model.JaxSimModel) -> RelaxedRigidContactsState:
171
+ @classmethod
172
+ def zero(cls: type[Self]) -> Self:
166
173
  """Build a zero `RelaxedRigidContactsState` instance from a `JaxSimModel`."""
167
- return RelaxedRigidContactsState.build()
168
174
 
169
- def valid(self, model: js.model.JaxSimModel) -> bool:
175
+ return cls.build()
176
+
177
+ def valid(self, *, model: js.model.JaxSimModel) -> jtp.BoolLike:
170
178
  return True
171
179
 
172
180
 
@@ -182,10 +190,12 @@ class RelaxedRigidContacts(ContactModel):
182
190
  default_factory=FlatTerrain
183
191
  )
184
192
 
193
+ @jax.jit
185
194
  def compute_contact_forces(
186
195
  self,
187
- position: jtp.Vector,
188
- velocity: jtp.Vector,
196
+ position: jtp.VectorLike,
197
+ velocity: jtp.VectorLike,
198
+ *,
189
199
  model: js.model.JaxSimModel,
190
200
  data: js.data.JaxSimModelData,
191
201
  link_forces: jtp.MatrixLike | None = None,
@@ -14,6 +14,11 @@ from jaxsim.terrain import FlatTerrain, Terrain
14
14
 
15
15
  from .common import ContactModel, ContactsParams, ContactsState
16
16
 
17
+ try:
18
+ from typing import Self
19
+ except ImportError:
20
+ from typing_extensions import Self
21
+
17
22
 
18
23
  @jax_dataclasses.pytree_dataclass
19
24
  class RigidContactsParams(ContactsParams):
@@ -50,19 +55,22 @@ class RigidContactsParams(ContactsParams):
50
55
 
51
56
  @classmethod
52
57
  def build(
53
- cls,
58
+ cls: type[Self],
59
+ *,
54
60
  mu: jtp.FloatLike | None = None,
55
61
  K: jtp.FloatLike | None = None,
56
62
  D: jtp.FloatLike | None = None,
57
- ) -> RigidContactsParams:
63
+ ) -> Self:
58
64
  """Create a `RigidContactParams` instance"""
59
- return RigidContactsParams(
65
+
66
+ return cls(
60
67
  mu=mu or cls.__dataclass_fields__["mu"].default,
61
68
  K=K or cls.__dataclass_fields__["K"].default,
62
69
  D=D or cls.__dataclass_fields__["D"].default,
63
70
  )
64
71
 
65
- def valid(self) -> bool:
72
+ def valid(self) -> jtp.BoolLike:
73
+
66
74
  return bool(
67
75
  jnp.all(self.mu >= 0.0)
68
76
  and jnp.all(self.K >= 0.0)
@@ -77,18 +85,19 @@ class RigidContactsState(ContactsState):
77
85
  def __eq__(self, other: RigidContactsState) -> bool:
78
86
  return hash(self) == hash(other)
79
87
 
80
- @staticmethod
81
- def build(**kwargs) -> RigidContactsState:
88
+ @classmethod
89
+ def build(cls: type[Self]) -> Self:
82
90
  """Create a `RigidContactsState` instance"""
83
91
 
84
- return RigidContactsState()
92
+ return cls()
85
93
 
86
- @staticmethod
87
- def zero(**kwargs) -> RigidContactsState:
94
+ @classmethod
95
+ def zero(cls: type[Self]) -> Self:
88
96
  """Build a zero `RigidContactsState` instance from a `JaxSimModel`."""
89
- return RigidContactsState.build()
90
97
 
91
- def valid(self, **kwargs) -> bool:
98
+ return cls.build()
99
+
100
+ def valid(self) -> jtp.BoolLike:
92
101
  return True
93
102
 
94
103
 
@@ -117,7 +126,8 @@ class RigidContacts(ContactModel):
117
126
  terrain_height: The height of the terrain at the collidable point position.
118
127
 
119
128
  Returns:
120
- A tuple containing the activation state of the collidable points and the contact penetration depth h.
129
+ A tuple containing the activation state of the collidable points
130
+ and the contact penetration depth h.
121
131
  """
122
132
 
123
133
  # TODO: reduce code duplication with js.contact.in_contact
@@ -154,8 +164,8 @@ class RigidContacts(ContactModel):
154
164
 
155
165
  Args:
156
166
  inactive_collidable_points: The activation state of the collidable points.
157
- M: The mass matrix of the system.
158
- J_WC: The Jacobian matrix of the collidable points.
167
+ M: The mass matrix of the system (in mixed representation).
168
+ J_WC: The Jacobian matrix of the collidable points (in mixed representation).
159
169
  data: The `JaxSimModelData` instance.
160
170
  """
161
171
 
@@ -206,10 +216,12 @@ class RigidContacts(ContactModel):
206
216
 
207
217
  return BW_ν_post_impact
208
218
 
219
+ @jax.jit
209
220
  def compute_contact_forces(
210
221
  self,
211
- position: jtp.Vector,
212
- velocity: jtp.Vector,
222
+ position: jtp.VectorLike,
223
+ velocity: jtp.VectorLike,
224
+ *,
213
225
  model: js.model.JaxSimModel,
214
226
  data: js.data.JaxSimModelData,
215
227
  link_forces: jtp.MatrixLike | None = None,