jaxsim 0.2.1.dev123__tar.gz → 0.2.1.dev155__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.dev123 → jaxsim-0.2.1.dev155}/.github/workflows/ci_cd.yml +2 -3
  2. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/.gitignore +5 -0
  3. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/PKG-INFO +5 -5
  4. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/README.md +4 -4
  5. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155/examples}/.gitattributes +0 -1
  6. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/__init__.py +39 -7
  7. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/_version.py +2 -2
  8. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/api/contact.py +4 -4
  9. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/api/kin_dyn_parameters.py +4 -1
  10. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/api/link.py +2 -2
  11. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/api/model.py +137 -25
  12. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/api/ode.py +15 -2
  13. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/math/joint_model.py +2 -2
  14. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/mujoco/loaders.py +4 -5
  15. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/mujoco/model.py +1 -1
  16. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/mujoco/visualizer.py +1 -1
  17. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/parsers/descriptions/collision.py +58 -23
  18. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/parsers/descriptions/joint.py +39 -17
  19. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/parsers/descriptions/link.py +9 -6
  20. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/parsers/descriptions/model.py +31 -11
  21. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/parsers/kinematic_graph.py +36 -11
  22. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/parsers/rod/parser.py +1 -1
  23. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/parsers/rod/utils.py +5 -7
  24. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/rbda/crba.py +2 -2
  25. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/rbda/forward_kinematics.py +1 -1
  26. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/typing.py +4 -1
  27. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim.egg-info/PKG-INFO +5 -5
  28. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/tests/test_api_com.py +1 -5
  29. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/tests/test_api_model.py +168 -10
  30. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/tests/test_automatic_differentiation.py +3 -3
  31. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/tests/test_simulations.py +2 -2
  32. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/tests/utils_idyntree.py +1 -1
  33. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/.devcontainer/Dockerfile +0 -0
  34. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/.devcontainer/devcontainer.json +0 -0
  35. {jaxsim-0.2.1.dev123/examples → jaxsim-0.2.1.dev155}/.gitattributes +0 -0
  36. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/.github/CODEOWNERS +0 -0
  37. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/.github/workflows/read_the_docs.yml +0 -0
  38. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/.github/workflows/style.yml +0 -0
  39. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/.pre-commit-config.yaml +0 -0
  40. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/.readthedocs.yaml +0 -0
  41. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/CONTRIBUTING.md +0 -0
  42. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/LICENSE +0 -0
  43. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/docs/Makefile +0 -0
  44. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/docs/conf.py +0 -0
  45. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/docs/guide/install.rst +0 -0
  46. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/docs/index.rst +0 -0
  47. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/docs/make.bat +0 -0
  48. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/docs/modules/api.rst +0 -0
  49. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/docs/modules/index.rst +0 -0
  50. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/docs/modules/integrators.rst +0 -0
  51. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/docs/modules/math.rst +0 -0
  52. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/docs/modules/mujoco.rst +0 -0
  53. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/docs/modules/parsers.rst +0 -0
  54. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/docs/modules/rbda.rst +0 -0
  55. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/docs/modules/typing.rst +0 -0
  56. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/docs/modules/utils.rst +0 -0
  57. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/environment.yml +0 -0
  58. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/examples/.gitignore +0 -0
  59. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/examples/PD_controller.ipynb +0 -0
  60. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/examples/Parallel_computing.ipynb +0 -0
  61. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/examples/README.md +0 -0
  62. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/examples/assets/cartpole.urdf +0 -0
  63. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/pixi.lock +0 -0
  64. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/pyproject.toml +0 -0
  65. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/setup.cfg +0 -0
  66. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/setup.py +0 -0
  67. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/api/__init__.py +0 -0
  68. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/api/com.py +0 -0
  69. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/api/common.py +0 -0
  70. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/api/data.py +0 -0
  71. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/api/frame.py +0 -0
  72. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/api/joint.py +0 -0
  73. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/api/ode_data.py +0 -0
  74. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/api/references.py +0 -0
  75. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/integrators/__init__.py +0 -0
  76. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/integrators/common.py +0 -0
  77. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/integrators/fixed_step.py +0 -0
  78. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/integrators/variable_step.py +0 -0
  79. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/logging.py +0 -0
  80. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/math/__init__.py +0 -0
  81. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/math/adjoint.py +0 -0
  82. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/math/cross.py +0 -0
  83. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/math/inertia.py +0 -0
  84. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/math/quaternion.py +0 -0
  85. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/math/rotation.py +0 -0
  86. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/math/skew.py +0 -0
  87. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/math/transform.py +0 -0
  88. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/mujoco/__init__.py +0 -0
  89. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/mujoco/__main__.py +0 -0
  90. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/parsers/__init__.py +0 -0
  91. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/parsers/descriptions/__init__.py +0 -0
  92. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/parsers/rod/__init__.py +0 -0
  93. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/rbda/__init__.py +0 -0
  94. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/rbda/aba.py +0 -0
  95. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/rbda/collidable_points.py +0 -0
  96. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/rbda/jacobian.py +0 -0
  97. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/rbda/rnea.py +0 -0
  98. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/rbda/soft_contacts.py +0 -0
  99. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/rbda/utils.py +0 -0
  100. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/terrain/__init__.py +0 -0
  101. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/terrain/terrain.py +0 -0
  102. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/utils/__init__.py +0 -0
  103. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/utils/jaxsim_dataclass.py +0 -0
  104. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/utils/tracing.py +0 -0
  105. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim/utils/wrappers.py +0 -0
  106. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim.egg-info/SOURCES.txt +0 -0
  107. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim.egg-info/dependency_links.txt +0 -0
  108. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim.egg-info/not-zip-safe +0 -0
  109. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim.egg-info/requires.txt +0 -0
  110. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/src/jaxsim.egg-info/top_level.txt +0 -0
  111. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/tests/__init__.py +0 -0
  112. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/tests/conftest.py +0 -0
  113. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/tests/test_api_data.py +0 -0
  114. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/tests/test_api_frame.py +0 -0
  115. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/tests/test_api_joint.py +0 -0
  116. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/tests/test_api_link.py +0 -0
  117. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/tests/test_contact.py +0 -0
  118. {jaxsim-0.2.1.dev123 → jaxsim-0.2.1.dev155}/tests/test_pytree.py +0 -0
@@ -118,8 +118,7 @@ jobs:
118
118
  - *src
119
119
  - *tests
120
120
 
121
- # https://gazebosim.org/docs/harmonic/install_ubuntu
122
- - name: Install Gazebo Sim
121
+ - name: Install 'gz sdf' system command
123
122
  if: |
124
123
  contains(matrix.os, 'ubuntu') &&
125
124
  (github.event_name != 'pull_request' ||
@@ -130,7 +129,7 @@ jobs:
130
129
  sudo wget https://packages.osrfoundation.org/gazebo.gpg -O /usr/share/keyrings/pkgs-osrf-archive-keyring.gpg
131
130
  echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/pkgs-osrf-archive-keyring.gpg] http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null
132
131
  sudo apt-get update
133
- sudo apt-get install gz-harmonic
132
+ sudo apt-get install --no-install-recommends libsdformat13 gz-tools2
134
133
 
135
134
  - name: Run the Python tests
136
135
  if: |
@@ -140,5 +140,10 @@ src/jaxsim/_version.py
140
140
 
141
141
  # ruff
142
142
  .ruff_cache/
143
+
143
144
  # pixi environments
144
145
  .pixi
146
+
147
+ # data
148
+ .mp4
149
+ .png
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jaxsim
3
- Version: 0.2.1.dev123
3
+ Version: 0.2.1.dev155
4
4
  Home-page: https://github.com/ami-iit/jaxsim
5
5
  Author: Diego Ferigo
6
6
  Author-email: diego.ferigo@iit.it
@@ -68,7 +68,7 @@ Requires-Dist: mujoco>=3.0.0; extra == "all"
68
68
 
69
69
  JaxSim is a **differentiable physics engine** and **multibody dynamics library** designed for applications in control and robot learning, implemented with JAX.
70
70
 
71
- Its design facilitates research and accelerates prototyping in the intersection of robotics and artificial intelligence.
71
+ Its design facilitates research and accelerates prototyping in the intersection of robotics and artificial intelligence.
72
72
 
73
73
  ## Features
74
74
 
@@ -91,7 +91,7 @@ Its design facilitates research and accelerates prototyping in the intersection
91
91
 
92
92
  ### JaxSim as a multibody dynamics library
93
93
 
94
- - Provides rigid body dynamics algorithms (RBDAs) like RNEA, ABA, CRBA, and Jacobians.
94
+ - Provides rigid body dynamics algorithms (RBDAs) like RNEA, ABA, CRBA, and Jacobians.
95
95
  - Provides all the quantities included in the Euler-Poincarè formulation of the equations of motion.
96
96
  - Supports body-fixed, inertial-fixed, and mixed [velocity representations][notation].
97
97
  - Exposes all the necessary quantities to develop controllers in centroidal coordinates.
@@ -198,10 +198,10 @@ The main differences between MJX/Brax and JaxSim are as follows:
198
198
 
199
199
  - JaxSim supports out-of-the-box all SDF models with [Pose Frame Semantics][PFS].
200
200
  - JaxSim only supports collisions between points rigidly attached to bodies and a compliant ground surface.
201
- Our contact model requires careful tuning of its spring-damper parameters, but being an instantaneous
201
+ Our contact model requires careful tuning of its spring-damper parameters, but being an instantaneous
202
202
  function of the state $(\mathbf{q}, \boldsymbol{\nu})$, it doesn't require running any optimization algorithm
203
203
  when stepping the simulation forward.
204
- - JaxSim mitigates the stiffness of the contact-aware system dynamics by providing variable-step integrators.
204
+ - JaxSim mitigates the stiffness of the contact-aware system dynamics by providing variable-step integrators.
205
205
 
206
206
  [brax]: https://github.com/google/brax
207
207
  [mjx]: https://mujoco.readthedocs.io/en/3.0.0/mjx.html
@@ -2,7 +2,7 @@
2
2
 
3
3
  JaxSim is a **differentiable physics engine** and **multibody dynamics library** designed for applications in control and robot learning, implemented with JAX.
4
4
 
5
- Its design facilitates research and accelerates prototyping in the intersection of robotics and artificial intelligence.
5
+ Its design facilitates research and accelerates prototyping in the intersection of robotics and artificial intelligence.
6
6
 
7
7
  ## Features
8
8
 
@@ -25,7 +25,7 @@ Its design facilitates research and accelerates prototyping in the intersection
25
25
 
26
26
  ### JaxSim as a multibody dynamics library
27
27
 
28
- - Provides rigid body dynamics algorithms (RBDAs) like RNEA, ABA, CRBA, and Jacobians.
28
+ - Provides rigid body dynamics algorithms (RBDAs) like RNEA, ABA, CRBA, and Jacobians.
29
29
  - Provides all the quantities included in the Euler-Poincarè formulation of the equations of motion.
30
30
  - Supports body-fixed, inertial-fixed, and mixed [velocity representations][notation].
31
31
  - Exposes all the necessary quantities to develop controllers in centroidal coordinates.
@@ -132,10 +132,10 @@ The main differences between MJX/Brax and JaxSim are as follows:
132
132
 
133
133
  - JaxSim supports out-of-the-box all SDF models with [Pose Frame Semantics][PFS].
134
134
  - JaxSim only supports collisions between points rigidly attached to bodies and a compliant ground surface.
135
- Our contact model requires careful tuning of its spring-damper parameters, but being an instantaneous
135
+ Our contact model requires careful tuning of its spring-damper parameters, but being an instantaneous
136
136
  function of the state $(\mathbf{q}, \boldsymbol{\nu})$, it doesn't require running any optimization algorithm
137
137
  when stepping the simulation forward.
138
- - JaxSim mitigates the stiffness of the contact-aware system dynamics by providing variable-step integrators.
138
+ - JaxSim mitigates the stiffness of the contact-aware system dynamics by providing variable-step integrators.
139
139
 
140
140
  [brax]: https://github.com/google/brax
141
141
  [mjx]: https://mujoco.readthedocs.io/en/3.0.0/mjx.html
@@ -1,3 +1,2 @@
1
1
  # GitHub syntax highlighting
2
2
  pixi.lock linguist-language=YAML
3
-
@@ -8,8 +8,9 @@ def _jnp_options() -> None:
8
8
 
9
9
  import jax
10
10
 
11
- # Enable by default
12
- if not ("JAX_ENABLE_X64" in os.environ and os.environ["JAX_ENABLE_X64"] == "0"):
11
+ # Enable by default 64bit precision in JAX.
12
+ if os.environ.get("JAX_ENABLE_X64", "1") != "0":
13
+
13
14
  logging.info("Enabling JAX to use 64bit precision")
14
15
  jax.config.update("jax_enable_x64", True)
15
16
 
@@ -27,6 +28,7 @@ def _np_options() -> None:
27
28
 
28
29
 
29
30
  def _is_editable() -> bool:
31
+
30
32
  import importlib.util
31
33
  import pathlib
32
34
  import site
@@ -45,11 +47,40 @@ def _is_editable() -> bool:
45
47
  return jaxsim_package_dir not in site.getsitepackages()
46
48
 
47
49
 
48
- # Initialize the logging verbosity
49
- if _is_editable():
50
- logging.configure(level=logging.LoggingLevel.DEBUG)
51
- else:
52
- logging.configure(level=logging.LoggingLevel.WARNING)
50
+ def _get_default_logging_level(env_var: str) -> logging.LoggingLevel:
51
+ """
52
+ Get the default logging level.
53
+
54
+ Args:
55
+ env_var: The environment variable to check.
56
+
57
+ Returns:
58
+ The logging level to set.
59
+ """
60
+
61
+ import os
62
+
63
+ # Define the default logging level depending on the installation mode.
64
+ default_logging_level = (
65
+ logging.LoggingLevel.DEBUG
66
+ if _is_editable() # noqa: F821
67
+ else logging.LoggingLevel.WARNING
68
+ )
69
+
70
+ # Allow to override the default logging level with an environment variable.
71
+ try:
72
+ return logging.LoggingLevel[
73
+ os.environ.get(env_var, default_logging_level.name).upper()
74
+ ]
75
+
76
+ except KeyError as exc:
77
+ msg = f"Invalid logging level defined in {env_var}='{os.environ[env_var]}'"
78
+ raise RuntimeError(msg) from exc
79
+
80
+
81
+ # Configure the logger with the default logging level.
82
+ logging.configure(level=_get_default_logging_level(env_var="JAXSIM_LOGGING_LEVEL"))
83
+
53
84
 
54
85
  # Configure JAX
55
86
  _jnp_options()
@@ -59,6 +90,7 @@ _np_options()
59
90
 
60
91
  del _jnp_options
61
92
  del _np_options
93
+ del _get_default_logging_level
62
94
  del _is_editable
63
95
 
64
96
  from . import terrain # isort:skip
@@ -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.dev123'
16
- __version_tuple__ = version_tuple = (0, 2, 1, 'dev123')
15
+ __version__ = version = '0.2.1.dev155'
16
+ __version_tuple__ = version_tuple = (0, 2, 1, 'dev155')
@@ -365,20 +365,20 @@ def jacobian(
365
365
 
366
366
  W_H_C = transforms(model=model, data=data)
367
367
 
368
- def jacobian(W_H_C: jtp.Matrix, W_J_WC: jtp.Matrix) -> jtp.Matrix:
368
+ def body_jacobian(W_H_C: jtp.Matrix, W_J_WC: jtp.Matrix) -> jtp.Matrix:
369
369
  C_X_W = jaxsim.math.Adjoint.from_transform(
370
370
  transform=W_H_C, inverse=True
371
371
  )
372
372
  C_J_WC = C_X_W @ W_J_WC
373
373
  return C_J_WC
374
374
 
375
- O_J_WC = jax.vmap(jacobian)(W_H_C, W_J_WC)
375
+ O_J_WC = jax.vmap(body_jacobian)(W_H_C, W_J_WC)
376
376
 
377
377
  case VelRepr.Mixed:
378
378
 
379
379
  W_H_C = transforms(model=model, data=data)
380
380
 
381
- def jacobian(W_H_C: jtp.Matrix, W_J_WC: jtp.Matrix) -> jtp.Matrix:
381
+ def mixed_jacobian(W_H_C: jtp.Matrix, W_J_WC: jtp.Matrix) -> jtp.Matrix:
382
382
 
383
383
  W_H_CW = W_H_C.at[0:3, 0:3].set(jnp.eye(3))
384
384
 
@@ -389,7 +389,7 @@ def jacobian(
389
389
  CW_J_WC = CW_X_W @ W_J_WC
390
390
  return CW_J_WC
391
391
 
392
- O_J_WC = jax.vmap(jacobian)(W_H_C, W_J_WC)
392
+ O_J_WC = jax.vmap(mixed_jacobian)(W_H_C, W_J_WC)
393
393
 
394
394
  case _:
395
395
  raise ValueError(output_vel_repr)
@@ -6,6 +6,7 @@ import jax.lax
6
6
  import jax.numpy as jnp
7
7
  import jax_dataclasses
8
8
  import jaxlie
9
+ import numpy as np
9
10
  from jax_dataclasses import Static
10
11
 
11
12
  import jaxsim.typing as jtp
@@ -220,7 +221,9 @@ class KynDynParameters(JaxsimDataclass):
220
221
  (
221
222
  hash(self.number_of_links()),
222
223
  hash(self.number_of_joints()),
223
- hash(tuple(jnp.atleast_1d(self.parent_array).flatten().tolist())),
224
+ hash(tuple(np.atleast_1d(self.parent_array).flatten().tolist())),
225
+ hash(self._parent_array),
226
+ hash(self._support_body_array_bool),
224
227
  )
225
228
  )
226
229
 
@@ -241,8 +241,8 @@ def jacobian(
241
241
  )
242
242
 
243
243
  # Compute the actual doubly-left free-floating jacobian of the link.
244
- κ = model.kin_dyn_parameters.support_body_array_bool[link_index]
245
- B_J_WL_B = jnp.hstack([jnp.ones(5), κ]) * B_J_full_WX_B
244
+ κb = model.kin_dyn_parameters.support_body_array_bool[link_index]
245
+ B_J_WL_B = jnp.hstack([jnp.ones(5), κb]) * B_J_full_WX_B
246
246
 
247
247
  # Adjust the input representation such that `J_WL_I @ I_ν`.
248
248
  match data.velocity_representation:
@@ -16,7 +16,8 @@ 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.utils import HashlessObject, JaxsimDataclass, Mutability
19
+ from jaxsim.math import Cross
20
+ from jaxsim.utils import JaxsimDataclass, Mutability
20
21
 
21
22
  from .common import VelRepr
22
23
 
@@ -32,6 +33,7 @@ class JaxSimModel(JaxsimDataclass):
32
33
  terrain: Static[jaxsim.terrain.Terrain] = dataclasses.field(
33
34
  default=jaxsim.terrain.FlatTerrain(), repr=False, compare=False, hash=False
34
35
  )
36
+
35
37
  kin_dyn_parameters: js.kin_dyn_parameters.KynDynParameters | None = (
36
38
  dataclasses.field(default=None, repr=False, compare=False, hash=False)
37
39
  )
@@ -40,13 +42,9 @@ class JaxSimModel(JaxsimDataclass):
40
42
  default=None, repr=False, compare=False, hash=False
41
43
  )
42
44
 
43
- _description: Static[
44
- HashlessObject[jaxsim.parsers.descriptions.ModelDescription | None]
45
- ] = dataclasses.field(default=None, repr=False, compare=False, hash=False)
46
-
47
- @property
48
- def description(self) -> jaxsim.parsers.descriptions.ModelDescription:
49
- return self._description.get()
45
+ description: Static[jaxsim.parsers.descriptions.ModelDescription | None] = (
46
+ dataclasses.field(default=None, repr=False, compare=False, hash=False)
47
+ )
50
48
 
51
49
  def __eq__(self, other: JaxSimModel) -> bool:
52
50
 
@@ -60,6 +58,7 @@ class JaxSimModel(JaxsimDataclass):
60
58
  return hash(
61
59
  (
62
60
  hash(self.model_name),
61
+ hash(self.description),
63
62
  hash(self.kin_dyn_parameters),
64
63
  )
65
64
  )
@@ -156,7 +155,7 @@ class JaxSimModel(JaxsimDataclass):
156
155
  # Build the model
157
156
  model = JaxSimModel(
158
157
  model_name=model_name,
159
- _description=HashlessObject(obj=model_description),
158
+ description=model_description,
160
159
  kin_dyn_parameters=js.kin_dyn_parameters.KynDynParameters.build(
161
160
  model_description=model_description
162
161
  ),
@@ -301,7 +300,7 @@ def reduce(
301
300
  locked_joint_positions:
302
301
  A dictionary containing the positions of the joints to be considered
303
302
  in the reduction process. The removed joints in the reduced model
304
- will have their position locked to their value in this dictionary.
303
+ will have their position locked to their value of this dictionary.
305
304
  If a joint is not part of the dictionary, its position is set to zero.
306
305
  """
307
306
 
@@ -314,10 +313,9 @@ def reduce(
314
313
  new_joints = set(model.joint_names()) - set(locked_joint_positions)
315
314
  raise ValueError(f"Passed joints not existing in the model: {new_joints}")
316
315
 
317
- # Copy the model description with a deep copy of the joints.
318
- intermediate_description = dataclasses.replace(
319
- model.description, joints=copy.deepcopy(model.description.joints)
320
- )
316
+ # Operate on a deep copy of the model description in order to prevent problems
317
+ # when mutable attributes are updated.
318
+ intermediate_description = copy.deepcopy(model.description)
321
319
 
322
320
  # Update the initial position of the joints.
323
321
  # This is necessary to compute the correct pose of the link pairs connected
@@ -685,8 +683,6 @@ def forward_dynamics_aba(
685
683
  another representation C_v̇_WB expressed in a generic frame C.
686
684
  """
687
685
 
688
- from jaxsim.math import Cross
689
-
690
686
  # In Mixed representation, we need to include a cross product in ℝ⁶.
691
687
  # In Inertial and Body representations, the cross product is always zero.
692
688
  C_X_W = jaxlie.SE3.from_matrix(W_H_C).inverse().adjoint()
@@ -871,6 +867,126 @@ def free_floating_mass_matrix(
871
867
  raise ValueError(data.velocity_representation)
872
868
 
873
869
 
870
+ @jax.jit
871
+ def free_floating_coriolis_matrix(
872
+ model: JaxSimModel, data: js.data.JaxSimModelData
873
+ ) -> jtp.Matrix:
874
+ """
875
+ Compute the free-floating Coriolis matrix of the model.
876
+
877
+ Args:
878
+ model: The model to consider.
879
+ data: The data of the considered model.
880
+
881
+ Returns:
882
+ The free-floating Coriolis matrix of the model.
883
+
884
+ Note:
885
+ This function, contrarily to other quantities of the equations of motion,
886
+ does not exploit any iterative algorithm. Therefore, the computation of
887
+ the Coriolis matrix may be much slower than other quantities.
888
+ """
889
+
890
+ # We perform all the calculation in body-fixed.
891
+ # The Coriolis matrix computed in this representation is converted later
892
+ # to the active representation stored in data.
893
+ with data.switch_velocity_representation(VelRepr.Body):
894
+
895
+ B_ν = data.generalized_velocity()
896
+
897
+ # Doubly-left free-floating Jacobian.
898
+ L_J_WL_B = generalized_free_floating_jacobian(model=model, data=data)
899
+
900
+ # Doubly-left free-floating Jacobian derivative.
901
+ L_J̇_WL_B = jax.vmap(
902
+ lambda link_index: js.link.jacobian_derivative(
903
+ model=model, data=data, link_index=link_index
904
+ )
905
+ )(js.link.names_to_idxs(model=model, link_names=model.link_names()))
906
+
907
+ L_M_L = link_spatial_inertia_matrices(model=model)
908
+
909
+ # Body-fixed link velocities.
910
+ # Note: we could have called link.velocity() instead of computing it ourselves,
911
+ # but since we need the link Jacobians later, we can save a double calculation.
912
+ L_v_WL = jax.vmap(lambda J: J @ B_ν)(L_J_WL_B)
913
+
914
+ # Compute the contribution of each link to the Coriolis matrix.
915
+ def compute_link_contribution(M, v, J, J̇) -> jtp.Array:
916
+
917
+ return J.T @ ((Cross.vx_star(v) @ M + M @ Cross.vx(v)) @ J + M @ J̇)
918
+
919
+ C_B_links = jax.vmap(compute_link_contribution)(
920
+ L_M_L,
921
+ L_v_WL,
922
+ L_J_WL_B,
923
+ L_J̇_WL_B,
924
+ )
925
+
926
+ # We need to adjust the Coriolis matrix for fixed-base models.
927
+ # In this case, the base link does not contribute to the matrix, and we need to zero
928
+ # the off-diagonal terms mapping joint quantities onto the base configuration.
929
+ if model.floating_base():
930
+ C_B = C_B_links.sum(axis=0)
931
+ else:
932
+ C_B = C_B_links[1:].sum(axis=0)
933
+ C_B = C_B.at[0:6, 6:].set(0.0)
934
+ C_B = C_B.at[6:, 0:6].set(0.0)
935
+
936
+ # Adjust the representation of the Coriolis matrix.
937
+ # Refer to https://github.com/traversaro/traversaro-phd-thesis, Section 3.6.
938
+ match data.velocity_representation:
939
+
940
+ case VelRepr.Body:
941
+ return C_B
942
+
943
+ case VelRepr.Inertial:
944
+
945
+ n = model.dofs()
946
+ W_H_B = data.base_transform()
947
+ B_X_W = jaxsim.math.Adjoint.from_transform(W_H_B, inverse=True)
948
+ B_T_W = jax.scipy.linalg.block_diag(B_X_W, jnp.eye(n))
949
+
950
+ with data.switch_velocity_representation(VelRepr.Inertial):
951
+ W_v_WB = data.base_velocity()
952
+ B_Ẋ_W = -B_X_W @ jaxsim.math.Cross.vx(W_v_WB)
953
+
954
+ B_Ṫ_W = jax.scipy.linalg.block_diag(B_Ẋ_W, jnp.zeros(shape=(n, n)))
955
+
956
+ with data.switch_velocity_representation(VelRepr.Body):
957
+ M = free_floating_mass_matrix(model=model, data=data)
958
+
959
+ C = B_T_W.T @ (M @ B_Ṫ_W + C_B @ B_T_W)
960
+
961
+ return C
962
+
963
+ case VelRepr.Mixed:
964
+
965
+ n = model.dofs()
966
+ BW_H_B = data.base_transform().at[0:3, 3].set(jnp.zeros(3))
967
+ B_X_BW = jaxsim.math.Adjoint.from_transform(transform=BW_H_B, inverse=True)
968
+ B_T_BW = jax.scipy.linalg.block_diag(B_X_BW, jnp.eye(n))
969
+
970
+ with data.switch_velocity_representation(VelRepr.Mixed):
971
+ BW_v_WB = data.base_velocity()
972
+ BW_v_W_BW = BW_v_WB.at[3:6].set(jnp.zeros(3))
973
+
974
+ BW_v_BW_B = BW_v_WB - BW_v_W_BW
975
+ B_Ẋ_BW = -B_X_BW @ jaxsim.math.Cross.vx(BW_v_BW_B)
976
+
977
+ B_Ṫ_BW = jax.scipy.linalg.block_diag(B_Ẋ_BW, jnp.zeros(shape=(n, n)))
978
+
979
+ with data.switch_velocity_representation(VelRepr.Body):
980
+ M = free_floating_mass_matrix(model=model, data=data)
981
+
982
+ C = B_T_BW.T @ (M @ B_Ṫ_BW + C_B @ B_T_BW)
983
+
984
+ return C
985
+
986
+ case _:
987
+ raise ValueError(data.velocity_representation)
988
+
989
+
874
990
  @jax.jit
875
991
  def inverse_dynamics(
876
992
  model: JaxSimModel,
@@ -931,8 +1047,6 @@ def inverse_dynamics(
931
1047
  expressed in a generic frame C to the inertial-fixed representation W_v̇_WB.
932
1048
  """
933
1049
 
934
- from jaxsim.math import Cross
935
-
936
1050
  W_X_C = jaxlie.SE3.from_matrix(W_H_C).adjoint()
937
1051
  C_X_W = jaxlie.SE3.from_matrix(W_H_C).inverse().adjoint()
938
1052
  C_v_WC = C_X_W @ W_v_WC
@@ -1364,12 +1478,7 @@ def link_bias_accelerations(
1364
1478
  # ================================================
1365
1479
 
1366
1480
  # Compute the base transform.
1367
- W_H_B = jaxlie.SE3.from_rotation_and_translation(
1368
- rotation=jaxlie.SO3.from_quaternion_xyzw(
1369
- xyzw=jaxsim.math.Quaternion.to_xyzw(wxyz=data.base_orientation())
1370
- ),
1371
- translation=data.base_position(),
1372
- ).as_matrix()
1481
+ W_H_B = data.base_transform()
1373
1482
 
1374
1483
  def other_representation_to_inertial(
1375
1484
  C_v̇_WB: jtp.Vector, C_v_WB: jtp.Vector, W_H_C: jtp.Matrix, W_v_WC: jtp.Vector
@@ -1410,9 +1519,12 @@ def link_bias_accelerations(
1410
1519
  W_H_C = W_H_BW
1411
1520
  with data.switch_velocity_representation(VelRepr.Mixed):
1412
1521
  W_ṗ_B = data.base_velocity()[0:3]
1413
- W_v_WC = W_v_W_BW = jnp.zeros(6).at[0:3].set(W_ṗ_B)
1522
+ BW_v_W_BW = jnp.zeros(6).at[0:3].set(W_ṗ_B)
1523
+ W_X_BW = jaxsim.math.Adjoint.from_transform(transform=W_H_BW)
1524
+ W_v_WC = W_v_W_BW = W_X_BW @ BW_v_W_BW
1414
1525
  with data.switch_velocity_representation(VelRepr.Mixed):
1415
1526
  C_v_WB = BW_v_WB = data.base_velocity()
1527
+
1416
1528
  case _:
1417
1529
  raise ValueError(data.velocity_representation)
1418
1530
 
@@ -223,7 +223,9 @@ def system_velocity_dynamics(
223
223
 
224
224
  @jax.jit
225
225
  def system_position_dynamics(
226
- model: js.model.JaxSimModel, data: js.data.JaxSimModelData
226
+ model: js.model.JaxSimModel,
227
+ data: js.data.JaxSimModelData,
228
+ baumgarte_quaternion_regularization: jtp.FloatLike = 1.0,
227
229
  ) -> tuple[jtp.Vector, jtp.Vector, jtp.Vector]:
228
230
  """
229
231
  Compute the dynamics of the system position.
@@ -231,6 +233,8 @@ def system_position_dynamics(
231
233
  Args:
232
234
  model: The model to consider.
233
235
  data: The data of the considered model.
236
+ baumgarte_quaternion_regularization:
237
+ The Baumgarte regularization coefficient for adjusting the quaternion norm.
234
238
 
235
239
  Returns:
236
240
  A tuple containing the derivative of the base position, the derivative of the
@@ -250,6 +254,7 @@ def system_position_dynamics(
250
254
  quaternion=W_Q_B,
251
255
  omega=W_ω_WB,
252
256
  omega_in_body_fixed=False,
257
+ K=baumgarte_quaternion_regularization,
253
258
  ).squeeze()
254
259
 
255
260
  return W_ṗ_B, W_Q̇_B, ṡ
@@ -262,6 +267,7 @@ def system_dynamics(
262
267
  *,
263
268
  joint_forces: jtp.Vector | None = None,
264
269
  link_forces: jtp.Vector | None = None,
270
+ baumgarte_quaternion_regularization: jtp.FloatLike = 1.0,
265
271
  ) -> tuple[ODEState, dict[str, Any]]:
266
272
  """
267
273
  Compute the dynamics of the system.
@@ -271,6 +277,9 @@ def system_dynamics(
271
277
  data: The data of the considered model.
272
278
  joint_forces: The joint forces to apply.
273
279
  link_forces: The 6D forces to apply to the links.
280
+ baumgarte_quaternion_regularization:
281
+ The Baumgarte regularization coefficient used to adjust the norm of the
282
+ quaternion (only used in integrators not operating on the SO(3) manifold).
274
283
 
275
284
  Returns:
276
285
  A tuple with an `ODEState` object storing in each of its attributes the
@@ -287,7 +296,11 @@ def system_dynamics(
287
296
  )
288
297
 
289
298
  # Extract the velocities.
290
- W_ṗ_B, W_Q̇_B, ṡ = system_position_dynamics(model=model, data=data)
299
+ W_ṗ_B, W_Q̇_B, ṡ = system_position_dynamics(
300
+ model=model,
301
+ data=data,
302
+ baumgarte_quaternion_regularization=baumgarte_quaternion_regularization,
303
+ )
291
304
 
292
305
  # Create an ODEState object populated with the derivative of each leaf.
293
306
  # Our integrators, operating on generic pytrees, will be able to handle it
@@ -34,8 +34,8 @@ class JointModel:
34
34
  already in a vectorized form. In other words, it cannot be created using vmap.
35
35
  """
36
36
 
37
- λ_H_pre: jax.Array
38
- suc_H_i: jax.Array
37
+ λ_H_pre: jtp.Array
38
+ suc_H_i: jtp.Array
39
39
 
40
40
  joint_dofs: Static[tuple[int, ...]]
41
41
  joint_names: Static[tuple[str, ...]]
@@ -188,10 +188,9 @@ class RodModelToMjcf:
188
188
  )
189
189
 
190
190
  # If considered joints are passed, make sure that they are all part of the model.
191
- if considered_joints - set([j.name for j in rod_model.joints()]):
192
- extra_joints = set(considered_joints) - set(
193
- [j.name for j in rod_model.joints()]
194
- )
191
+ if considered_joints - {j.name for j in rod_model.joints()}:
192
+ extra_joints = set(considered_joints) - {j.name for j in rod_model.joints()}
193
+
195
194
  msg = f"Couldn't find the following joints in the model: '{extra_joints}'"
196
195
  raise ValueError(msg)
197
196
 
@@ -352,7 +351,7 @@ class RodModelToMjcf:
352
351
  # Set alpha=0 to the color of all collision elements
353
352
  for geometry_element in mujoco_element.findall(".//geom[@rgba]"):
354
353
  if geometry_element.attrib.get("name") in collision_names:
355
- r, g, b, a = geometry_element.attrib["rgba"].split(" ")
354
+ r, g, b, _ = geometry_element.attrib["rgba"].split(" ")
356
355
  geometry_element.set("rgba", f"{r} {g} {b} 0")
357
356
 
358
357
  # -----------------------
@@ -73,7 +73,7 @@ class MujocoModelHelper:
73
73
  new_hfield = generate_hfield(heightmap, (nrow, ncol))
74
74
  model.hfield_data = new_hfield
75
75
 
76
- return MujocoModelHelper(model=model, data=mj.MjData(model))
76
+ return MujocoModelHelper(model=model, data=data)
77
77
 
78
78
  def time(self) -> float:
79
79
  """Return the simulation time."""
@@ -173,4 +173,4 @@ class MujocoVisualizer:
173
173
  try:
174
174
  yield handle
175
175
  finally:
176
- handle.close() if close_on_exit else None
176
+ _ = handle.close() if close_on_exit else None