jaxsim 0.4.3.dev305__tar.gz → 0.4.3.dev327__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 (129) hide show
  1. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/.github/workflows/ci_cd.yml +3 -2
  2. jaxsim-0.4.3.dev305/.github/workflows/update_pixi_lockfile.yml → jaxsim-0.4.3.dev327/.github/workflows/pixi.yml +14 -5
  3. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/PKG-INFO +2 -1
  4. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/pyproject.toml +60 -22
  5. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/_version.py +2 -2
  6. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/api/contact.py +65 -28
  7. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/api/kin_dyn_parameters.py +3 -0
  8. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/api/model.py +11 -3
  9. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/rbda/collidable_points.py +18 -5
  10. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/rbda/contacts/common.py +11 -9
  11. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/rbda/contacts/relaxed_rigid.py +14 -5
  12. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/rbda/contacts/rigid.py +9 -6
  13. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/rbda/contacts/soft.py +17 -4
  14. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim.egg-info/PKG-INFO +2 -1
  15. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim.egg-info/SOURCES.txt +1 -1
  16. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/tests/test_api_contact.py +30 -10
  17. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/tests/test_simulations.py +30 -0
  18. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/.devcontainer/Dockerfile +0 -0
  19. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/.devcontainer/devcontainer.json +0 -0
  20. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/.gitattributes +0 -0
  21. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/.github/CODEOWNERS +0 -0
  22. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/.github/dependabot.yml +0 -0
  23. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/.github/workflows/read_the_docs.yml +0 -0
  24. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/.gitignore +0 -0
  25. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/.pre-commit-config.yaml +0 -0
  26. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/.readthedocs.yaml +0 -0
  27. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/CONTRIBUTING.md +0 -0
  28. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/LICENSE +0 -0
  29. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/README.md +0 -0
  30. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/docs/Makefile +0 -0
  31. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/docs/conf.py +0 -0
  32. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/docs/examples.rst +0 -0
  33. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/docs/guide/install.rst +0 -0
  34. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/docs/index.rst +0 -0
  35. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/docs/make.bat +0 -0
  36. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/docs/modules/api.rst +0 -0
  37. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/docs/modules/integrators.rst +0 -0
  38. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/docs/modules/math.rst +0 -0
  39. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/docs/modules/mujoco.rst +0 -0
  40. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/docs/modules/parsers.rst +0 -0
  41. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/docs/modules/rbda.rst +0 -0
  42. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/docs/modules/typing.rst +0 -0
  43. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/docs/modules/utils.rst +0 -0
  44. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/environment.yml +0 -0
  45. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/examples/.gitattributes +0 -0
  46. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/examples/.gitignore +0 -0
  47. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/examples/README.md +0 -0
  48. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/examples/assets/build_cartpole_urdf.py +0 -0
  49. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/examples/assets/cartpole.urdf +0 -0
  50. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/examples/jaxsim_as_multibody_dynamics_library.ipynb +0 -0
  51. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/examples/jaxsim_as_physics_engine.ipynb +0 -0
  52. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/examples/jaxsim_for_robot_controllers.ipynb +0 -0
  53. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/pixi.lock +0 -0
  54. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/setup.cfg +0 -0
  55. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/setup.py +0 -0
  56. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/__init__.py +0 -0
  57. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/api/__init__.py +0 -0
  58. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/api/com.py +0 -0
  59. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/api/common.py +0 -0
  60. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/api/data.py +0 -0
  61. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/api/frame.py +0 -0
  62. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/api/joint.py +0 -0
  63. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/api/link.py +0 -0
  64. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/api/ode.py +0 -0
  65. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/api/ode_data.py +0 -0
  66. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/api/references.py +0 -0
  67. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/exceptions.py +0 -0
  68. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/integrators/__init__.py +0 -0
  69. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/integrators/common.py +0 -0
  70. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/integrators/fixed_step.py +0 -0
  71. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/integrators/variable_step.py +0 -0
  72. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/logging.py +0 -0
  73. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/math/__init__.py +0 -0
  74. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/math/adjoint.py +0 -0
  75. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/math/cross.py +0 -0
  76. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/math/inertia.py +0 -0
  77. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/math/joint_model.py +0 -0
  78. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/math/quaternion.py +0 -0
  79. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/math/rotation.py +0 -0
  80. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/math/skew.py +0 -0
  81. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/math/transform.py +0 -0
  82. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/mujoco/__init__.py +0 -0
  83. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/mujoco/__main__.py +0 -0
  84. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/mujoco/loaders.py +0 -0
  85. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/mujoco/model.py +0 -0
  86. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/mujoco/utils.py +0 -0
  87. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/mujoco/visualizer.py +0 -0
  88. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/parsers/__init__.py +0 -0
  89. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/parsers/descriptions/__init__.py +0 -0
  90. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/parsers/descriptions/collision.py +0 -0
  91. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/parsers/descriptions/joint.py +0 -0
  92. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/parsers/descriptions/link.py +0 -0
  93. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/parsers/descriptions/model.py +0 -0
  94. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/parsers/kinematic_graph.py +0 -0
  95. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/parsers/rod/__init__.py +0 -0
  96. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/parsers/rod/parser.py +0 -0
  97. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/parsers/rod/utils.py +0 -0
  98. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/rbda/__init__.py +0 -0
  99. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/rbda/aba.py +0 -0
  100. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/rbda/contacts/__init__.py +0 -0
  101. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/rbda/contacts/visco_elastic.py +0 -0
  102. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/rbda/crba.py +0 -0
  103. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/rbda/forward_kinematics.py +0 -0
  104. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/rbda/jacobian.py +0 -0
  105. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/rbda/rnea.py +0 -0
  106. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/rbda/utils.py +0 -0
  107. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/terrain/__init__.py +0 -0
  108. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/terrain/terrain.py +0 -0
  109. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/typing.py +0 -0
  110. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/utils/__init__.py +0 -0
  111. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/utils/jaxsim_dataclass.py +0 -0
  112. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/utils/tracing.py +0 -0
  113. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim/utils/wrappers.py +0 -0
  114. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim.egg-info/dependency_links.txt +0 -0
  115. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim.egg-info/requires.txt +0 -0
  116. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/src/jaxsim.egg-info/top_level.txt +0 -0
  117. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/tests/__init__.py +0 -0
  118. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/tests/conftest.py +0 -0
  119. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/tests/test_api_com.py +0 -0
  120. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/tests/test_api_data.py +0 -0
  121. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/tests/test_api_frame.py +0 -0
  122. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/tests/test_api_joint.py +0 -0
  123. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/tests/test_api_link.py +0 -0
  124. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/tests/test_api_model.py +0 -0
  125. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/tests/test_automatic_differentiation.py +0 -0
  126. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/tests/test_contact.py +0 -0
  127. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/tests/test_exceptions.py +0 -0
  128. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/tests/test_pytree.py +0 -0
  129. {jaxsim-0.4.3.dev305 → jaxsim-0.4.3.dev327}/tests/utils_idyntree.py +0 -0
@@ -8,8 +8,7 @@ on:
8
8
  types:
9
9
  - published
10
10
  schedule:
11
- # * is a special character in YAML so you have to quote this string
12
- # Execute a "nightly" build at 2 AM UTC
11
+ # Execute a nightly build at 2am UTC.
13
12
  - cron: '0 2 * * *'
14
13
 
15
14
 
@@ -138,6 +137,8 @@ jobs:
138
137
  steps.changes.outputs.all == 'true')
139
138
  run: pytest
140
139
  env:
140
+ # https://github.com/pytest-dev/pytest/issues/7443#issuecomment-656642591
141
+ PY_COLORS: "1"
141
142
  JAX_PLATFORM_NAME: cpu
142
143
 
143
144
  publish:
@@ -1,4 +1,4 @@
1
- name: Update pixi lockfile
1
+ name: Pixi
2
2
 
3
3
  permissions:
4
4
  contents: write
@@ -7,12 +7,16 @@ permissions:
7
7
  on:
8
8
  workflow_dispatch:
9
9
  schedule:
10
- - cron: 0 5 1 * *
10
+ # Execute at 5am UTC on the first day of the month.
11
+ - cron: '0 5 1 * *'
11
12
 
12
13
  jobs:
14
+
13
15
  pixi-update:
14
- runs-on: ubuntu-22.04
16
+ runs-on: ubuntu-24.04
17
+
15
18
  steps:
19
+
16
20
  - uses: actions/checkout@v4
17
21
  with:
18
22
  lfs: true
@@ -30,9 +34,14 @@ jobs:
30
34
  set -o pipefail
31
35
  pixi update --json | pixi exec pixi-diff-to-markdown --explicit-column > diff.md
32
36
 
37
+ - name: Test project against updated pixi
38
+ run: pixi run --environment tasks-cpu tests
39
+ env:
40
+ PY_COLORS: "1"
41
+ JAX_PLATFORM_NAME: cpu
42
+
33
43
  - name: Commit and push changes
34
- run: |
35
- echo "BRANCH_NAME=update-pixi-$(date +'%Y%m%d%H%M%S')" >> $GITHUB_ENV
44
+ run: echo "BRANCH_NAME=update-pixi-$(date +'%Y%m%d%H%M%S')" >> $GITHUB_ENV
36
45
 
37
46
  - name: Create pull request
38
47
  uses: peter-evans/create-pull-request@v7
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jaxsim
3
- Version: 0.4.3.dev305
3
+ Version: 0.4.3.dev327
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>, Filippo Luca Ferretti <filippoluca.ferretti@outlook.com>
6
6
  Maintainer-email: Filippo Luca Ferretti <filippo.ferretti@iit.it>, Alessandro Croci <alessandro.croci@iit.it>
@@ -51,6 +51,7 @@ Classifier: Programming Language :: Python :: 3 :: Only
51
51
  Classifier: Programming Language :: Python :: 3.10
52
52
  Classifier: Programming Language :: Python :: 3.11
53
53
  Classifier: Programming Language :: Python :: 3.12
54
+ Classifier: Programming Language :: Python :: 3.13
54
55
  Classifier: Programming Language :: Python :: Implementation :: CPython
55
56
  Classifier: Topic :: Games/Entertainment :: Simulation
56
57
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
@@ -37,6 +37,7 @@ classifiers = [
37
37
  "Programming Language :: Python :: 3.10",
38
38
  "Programming Language :: Python :: 3.11",
39
39
  "Programming Language :: Python :: 3.12",
40
+ "Programming Language :: Python :: 3.13",
40
41
  "Programming Language :: Python :: Implementation :: CPython",
41
42
  "Topic :: Games/Entertainment :: Simulation",
42
43
  "Topic :: Scientific/Engineering :: Artificial Intelligence",
@@ -132,8 +133,10 @@ testpaths = [
132
133
  [tool.ruff]
133
134
  exclude = [
134
135
  ".git",
136
+ ".pixi",
135
137
  ".pytest_cache",
136
138
  ".ruff_cache",
139
+ ".idea",
137
140
  ".vscode",
138
141
  ".devcontainer",
139
142
  "__pycache__",
@@ -179,52 +182,87 @@ ignore = [
179
182
  channels = ["conda-forge"]
180
183
  platforms = ["linux-64", "osx-arm64", "osx-64"]
181
184
 
185
+ [tool.pixi.environments]
186
+ # We resolve only two groups: cpu and gpu.
187
+ # Then, multiple environments can be created from these groups.
188
+ default = { solve-group = "cpugroup" }
189
+ gpu = { features = ["gpu"], solve-group = "gpugroup" }
190
+ tasks-cpu = { features = ["test", "examples"], solve-group = "cpugroup" }
191
+ tasks-gpu = { features = ["test", "examples", "gpu"], solve-group = "gpugroup" }
192
+
193
+ # ---------------
194
+ # feature.default
195
+ # ---------------
196
+
197
+ # Dependencies from conda-forge.
182
198
  [tool.pixi.dependencies]
199
+ #
200
+ # Matching `project.dependencies`.
201
+ #
183
202
  coloredlogs = "*"
184
203
  jax = "*"
185
- jax-dataclasses = "*"
186
- jaxopt = "*"
187
204
  jaxlib = "*"
188
205
  jaxlie = "*"
189
- lxml = "*"
190
- mediapy = "*"
191
- mujoco = "*"
192
- notebook = "*"
206
+ jax-dataclasses = "*"
193
207
  pptree = "*"
208
+ optax = "*"
194
209
  qpax = "*"
195
210
  rod = "*"
196
- sdformat14 = "*"
197
211
  typing_extensions = "*"
212
+ #
213
+ # Optional dependencies.
214
+ #
215
+ lxml = "*"
216
+ mediapy = "*"
217
+ mujoco = "*"
218
+ scipy = "*"
219
+ #
220
+ # Additional dependencies.
221
+ #
222
+ pip = "*"
223
+
224
+ # Dependendencies from PyPI.
225
+ [tool.pixi.pypi-dependencies]
226
+ jaxsim = { path = "./", editable = true }
227
+
228
+ # ------------
229
+ # feature.test
230
+ # ------------
198
231
 
199
232
  [tool.pixi.feature.test.tasks]
200
- examples = { cmd = "jupyter notebook ./examples" }
201
233
  pipcheck = "pip check"
202
- test = { cmd = "pytest", depends_on = ["pipcheck"] }
234
+ tests = { cmd = "pytest", depends_on = ["pipcheck"] }
203
235
 
204
236
  [tool.pixi.feature.test.dependencies]
205
237
  black = "24.*"
206
238
  idyntree = "*"
207
239
  isort = "*"
208
- pip = "*"
209
240
  pre-commit = "*"
210
241
  pytest = "*"
211
242
  pytest-icdiff = "*"
212
243
  robot_descriptions = "*"
213
244
 
245
+ # ----------------
246
+ # feature.examples
247
+ # ----------------
248
+
249
+ [tool.pixi.feature.examples.tasks]
250
+ examples = { cmd = "jupyter notebook ./examples" }
251
+
252
+ [tool.pixi.feature.examples.dependencies]
253
+ notebook = "*"
254
+ robot_descriptions = "*"
255
+
256
+ # -----------
257
+ # feature.gpu
258
+ # -----------
259
+
214
260
  [tool.pixi.feature.gpu]
215
261
  platforms = ["linux-64"]
216
- system-requirements = { cuda = "12.1" }
262
+ system-requirements = { cuda = "12" }
217
263
 
218
264
  [tool.pixi.feature.gpu.dependencies]
219
- cuda-cupti = "*"
220
265
  cuda-version = "12.*"
221
- jaxlib = {version = "*", build = "*cuda*"}
222
-
223
- [tool.pixi.pypi-dependencies]
224
- jaxsim = { path = "./", editable = true }
225
-
226
- [tool.pixi.environments]
227
- default = { solve-group = "cpugroup" }
228
- gpu = { features = ["gpu"], solve-group = "gpugroup" }
229
- test-cpu = { features = ["test"], solve-group = "cpugroup" }
230
- test-gpu = { features = ["test", "gpu"], solve-group = "gpugroup" }
266
+ # Pinning a specific version awaiting the following to get addressed:
267
+ # https://github.com/conda-forge/jaxlib-feedstock/issues/285
268
+ jaxlib = { version = "<0.4.31", build = "*cuda*" }
@@ -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.dev305'
16
- __version_tuple__ = version_tuple = (0, 4, 3, 'dev305')
15
+ __version__ = version = '0.4.3.dev327'
16
+ __version_tuple__ = version_tuple = (0, 4, 3, 'dev327')
@@ -138,7 +138,7 @@ def collidable_point_dynamics(
138
138
  **kwargs,
139
139
  ) -> tuple[jtp.Matrix, dict[str, jtp.PyTree]]:
140
140
  r"""
141
- Compute the 6D force applied to each collidable point.
141
+ Compute the 6D force applied to each enabled collidable point.
142
142
 
143
143
  Args:
144
144
  model: The model to consider.
@@ -151,7 +151,7 @@ def collidable_point_dynamics(
151
151
  kwargs: Additional keyword arguments to pass to the active contact model.
152
152
 
153
153
  Returns:
154
- The 6D force applied to each collidable point and additional data based
154
+ The 6D force applied to each eneabled collidable point and additional data based
155
155
  on the contact model configured:
156
156
  - Soft: the material deformation rate.
157
157
  - Rigid: no additional data.
@@ -199,15 +199,19 @@ def collidable_point_dynamics(
199
199
  )
200
200
 
201
201
  # Compute the transforms of the implicit frames `C[L] = (W_p_C, [L])`
202
- # associated to each collidable point.
202
+ # associated to the enabled collidable point.
203
203
  # In inertial-fixed representation, the computation of these transforms
204
204
  # is not necessary and the conversion below becomes a no-op.
205
+
206
+ # Get the indices of the enabled collidable points.
207
+ indices_of_enabled_collidable_points = (
208
+ model.kin_dyn_parameters.contact_parameters.indices_of_enabled_collidable_points
209
+ )
210
+
205
211
  W_H_C = (
206
212
  js.contact.transforms(model=model, data=data)
207
213
  if data.velocity_representation is not VelRepr.Inertial
208
- else jnp.zeros(
209
- shape=(len(model.kin_dyn_parameters.contact_parameters.body), 4, 4)
210
- )
214
+ else jnp.zeros(shape=(len(indices_of_enabled_collidable_points), 4, 4))
211
215
  )
212
216
 
213
217
  # Convert the 6D forces to the active representation.
@@ -246,6 +250,15 @@ def in_contact(
246
250
  if link_names is not None and set(link_names).difference(model.link_names()):
247
251
  raise ValueError("One or more link names are not part of the model")
248
252
 
253
+ # Get the indices of the enabled collidable points.
254
+ indices_of_enabled_collidable_points = (
255
+ model.kin_dyn_parameters.contact_parameters.indices_of_enabled_collidable_points
256
+ )
257
+
258
+ parent_link_idx_of_enabled_collidable_points = jnp.array(
259
+ model.kin_dyn_parameters.contact_parameters.body, dtype=int
260
+ )[indices_of_enabled_collidable_points]
261
+
249
262
  W_p_Ci = collidable_point_positions(model=model, data=data)
250
263
 
251
264
  terrain_height = jax.vmap(lambda x, y: model.terrain.height(x=x, y=y))(
@@ -262,7 +275,7 @@ def in_contact(
262
275
 
263
276
  links_in_contact = jax.vmap(
264
277
  lambda link_index: jnp.where(
265
- jnp.array(model.kin_dyn_parameters.contact_parameters.body) == link_index,
278
+ parent_link_idx_of_enabled_collidable_points == link_index,
266
279
  below_terrain,
267
280
  jnp.zeros_like(below_terrain, dtype=bool),
268
281
  ).any()
@@ -426,14 +439,14 @@ def estimate_good_contact_parameters(
426
439
  @jax.jit
427
440
  def transforms(model: js.model.JaxSimModel, data: js.data.JaxSimModelData) -> jtp.Array:
428
441
  r"""
429
- Return the pose of the collidable points.
442
+ Return the pose of the enabled collidable points.
430
443
 
431
444
  Args:
432
445
  model: The model to consider.
433
446
  data: The data of the considered model.
434
447
 
435
448
  Returns:
436
- The stacked SE(3) matrices of all collidable points.
449
+ The stacked SE(3) matrices of all enabled collidable points.
437
450
 
438
451
  Note:
439
452
  Each collidable point is implicitly associated with a frame
@@ -442,16 +455,27 @@ def transforms(model: js.model.JaxSimModel, data: js.data.JaxSimModelData) -> jt
442
455
  rigidly attached to.
443
456
  """
444
457
 
458
+ # Get the indices of the enabled collidable points.
459
+ indices_of_enabled_collidable_points = (
460
+ model.kin_dyn_parameters.contact_parameters.indices_of_enabled_collidable_points
461
+ )
462
+
463
+ parent_link_idx_of_enabled_collidable_points = jnp.array(
464
+ model.kin_dyn_parameters.contact_parameters.body, dtype=int
465
+ )[indices_of_enabled_collidable_points]
466
+
445
467
  # Get the transforms of the parent link of all collidable points.
446
468
  W_H_L = js.model.forward_kinematics(model=model, data=data)[
447
- jnp.array(model.kin_dyn_parameters.contact_parameters.body, dtype=int)
469
+ parent_link_idx_of_enabled_collidable_points
470
+ ]
471
+
472
+ L_p_Ci = model.kin_dyn_parameters.contact_parameters.point[
473
+ indices_of_enabled_collidable_points
448
474
  ]
449
475
 
450
476
  # Build the link-to-point transform from the displacement between the link frame L
451
477
  # and the implicit contact frame C.
452
- L_H_C = jax.vmap(lambda L_p_C: jnp.eye(4).at[0:3, 3].set(L_p_C))(
453
- model.kin_dyn_parameters.contact_parameters.point
454
- )
478
+ L_H_C = jax.vmap(lambda L_p_C: jnp.eye(4).at[0:3, 3].set(L_p_C))(L_p_Ci)
455
479
 
456
480
  # Compose the work-to-link and link-to-point transforms.
457
481
  return jax.vmap(lambda W_H_Li, L_H_Ci: W_H_Li @ L_H_Ci)(W_H_L, L_H_C)
@@ -465,7 +489,7 @@ def jacobian(
465
489
  output_vel_repr: VelRepr | None = None,
466
490
  ) -> jtp.Array:
467
491
  r"""
468
- Return the free-floating Jacobian of the collidable points.
492
+ Return the free-floating Jacobian of the enabled collidable points.
469
493
 
470
494
  Args:
471
495
  model: The model to consider.
@@ -475,7 +499,7 @@ def jacobian(
475
499
 
476
500
  Returns:
477
501
  The stacked :math:`6 \times (6+n)` free-floating jacobians of the frames associated to the
478
- collidable points.
502
+ enabled collidable points.
479
503
 
480
504
  Note:
481
505
  Each collidable point is implicitly associated with a frame
@@ -488,6 +512,15 @@ def jacobian(
488
512
  output_vel_repr if output_vel_repr is not None else data.velocity_representation
489
513
  )
490
514
 
515
+ # Get the indices of the enabled collidable points.
516
+ indices_of_enabled_collidable_points = (
517
+ model.kin_dyn_parameters.contact_parameters.indices_of_enabled_collidable_points
518
+ )
519
+
520
+ parent_link_idx_of_enabled_collidable_points = jnp.array(
521
+ model.kin_dyn_parameters.contact_parameters.body, dtype=int
522
+ )[indices_of_enabled_collidable_points]
523
+
491
524
  # Compute the Jacobians of all links.
492
525
  W_J_WL = js.model.generalized_free_floating_jacobian(
493
526
  model=model, data=data, output_vel_repr=VelRepr.Inertial
@@ -496,9 +529,7 @@ def jacobian(
496
529
  # Compute the contact Jacobian.
497
530
  # In inertial-fixed output representation, the Jacobian of the parent link is also
498
531
  # the Jacobian of the frame C implicitly associated with the collidable point.
499
- W_J_WC = W_J_WL[
500
- jnp.array(model.kin_dyn_parameters.contact_parameters.body, dtype=int)
501
- ]
532
+ W_J_WC = W_J_WL[parent_link_idx_of_enabled_collidable_points]
502
533
 
503
534
  # Adjust the output representation.
504
535
  match output_vel_repr:
@@ -550,7 +581,7 @@ def jacobian_derivative(
550
581
  output_vel_repr: VelRepr | None = None,
551
582
  ) -> jtp.Matrix:
552
583
  r"""
553
- Compute the derivative of the free-floating jacobian of the contact points.
584
+ Compute the derivative of the free-floating jacobian of the enabled collidable points.
554
585
 
555
586
  Args:
556
587
  model: The model to consider.
@@ -559,7 +590,7 @@ def jacobian_derivative(
559
590
  The output velocity representation of the free-floating jacobian derivative.
560
591
 
561
592
  Returns:
562
- The derivative of the :math:`6 \times (6+n)` free-floating jacobian of the contact points.
593
+ The derivative of the :math:`6 \times (6+n)` free-floating jacobian of the enabled collidable points.
563
594
 
564
595
  Note:
565
596
  The input representation of the free-floating jacobian derivative is the active
@@ -570,10 +601,18 @@ def jacobian_derivative(
570
601
  output_vel_repr if output_vel_repr is not None else data.velocity_representation
571
602
  )
572
603
 
604
+ indices_of_enabled_collidable_points = (
605
+ model.kin_dyn_parameters.contact_parameters.indices_of_enabled_collidable_points
606
+ )
607
+
573
608
  # Get the index of the parent link and the position of the collidable point.
574
- parent_link_idxs = jnp.array(model.kin_dyn_parameters.contact_parameters.body)
575
- L_p_Ci = jnp.array(model.kin_dyn_parameters.contact_parameters.point)
576
- contact_idxs = jnp.arange(L_p_Ci.shape[0])
609
+ parent_link_idx_of_enabled_collidable_points = jnp.array(
610
+ model.kin_dyn_parameters.contact_parameters.body, dtype=int
611
+ )[indices_of_enabled_collidable_points]
612
+
613
+ L_p_Ci = model.kin_dyn_parameters.contact_parameters.point[
614
+ indices_of_enabled_collidable_points
615
+ ]
577
616
 
578
617
  # Get the transforms of all the parent links.
579
618
  W_H_Li = js.model.forward_kinematics(model=model, data=data)
@@ -646,7 +685,7 @@ def jacobian_derivative(
646
685
  output_vel_repr=VelRepr.Inertial,
647
686
  )
648
687
 
649
- # Get the Jacobian of the collidable points in the mixed representation.
688
+ # Get the Jacobian of the enabled collidable points in the mixed representation.
650
689
  with data.switch_velocity_representation(VelRepr.Mixed):
651
690
  CW_J_WC_BW = jacobian(
652
691
  model=model,
@@ -656,13 +695,11 @@ def jacobian_derivative(
656
695
 
657
696
  def compute_O_J̇_WC_I(
658
697
  L_p_C: jtp.Vector,
659
- contact_idx: jtp.Int,
698
+ parent_link_idx: jtp.Int,
660
699
  CW_J_WC_BW: jtp.Matrix,
661
700
  W_H_L: jtp.Matrix,
662
701
  ) -> jtp.Matrix:
663
702
 
664
- parent_link_idx = parent_link_idxs[contact_idx]
665
-
666
703
  match output_vel_repr:
667
704
  case VelRepr.Inertial:
668
705
  O_X_W = W_X_W = Adjoint.from_transform( # noqa: F841
@@ -703,7 +740,7 @@ def jacobian_derivative(
703
740
  return O_J̇_WC_I
704
741
 
705
742
  O_J̇_WC = jax.vmap(compute_O_J̇_WC_I, in_axes=(0, 0, 0, None))(
706
- L_p_Ci, contact_idxs, CW_J_WC_BW, W_H_Li
743
+ L_p_Ci, parent_link_idx_of_enabled_collidable_points, CW_J_WC_BW, W_H_Li
707
744
  )
708
745
 
709
746
  return O_J̇_WC
@@ -743,6 +743,9 @@ class ContactParameters(JaxsimDataclass):
743
743
  point:
744
744
  The translations between the link frame and the collidable point, expressed
745
745
  in the coordinates of the parent link frame.
746
+ enabled:
747
+ A tuple of booleans representing, for each collidable point, whether it is
748
+ enabled or not in contact models.
746
749
 
747
750
  Note:
748
751
  Contrarily to LinkParameters and JointParameters, this class is not meant
@@ -2287,7 +2287,14 @@ def step(
2287
2287
  msg="Baumgarte stabilization is not supported with ForwardEuler integrators",
2288
2288
  )
2289
2289
 
2290
- W_p_C = js.contact.collidable_point_positions(model, data_tf)
2290
+ # Extract the indices corresponding to the enabled collidable points.
2291
+ indices_of_enabled_collidable_points = (
2292
+ model.kin_dyn_parameters.contact_parameters.indices_of_enabled_collidable_points
2293
+ )
2294
+
2295
+ W_p_C = js.contact.collidable_point_positions(model, data_tf)[
2296
+ indices_of_enabled_collidable_points
2297
+ ]
2291
2298
 
2292
2299
  # Compute the penetration depth of the collidable points.
2293
2300
  δ, *_ = jax.vmap(
@@ -2296,8 +2303,9 @@ def step(
2296
2303
  )(W_p_C, jnp.zeros_like(W_p_C), model.terrain)
2297
2304
 
2298
2305
  with data_tf.switch_velocity_representation(VelRepr.Mixed):
2299
-
2300
- J_WC = js.contact.jacobian(model, data_tf)
2306
+ J_WC = js.contact.jacobian(model, data_tf)[
2307
+ indices_of_enabled_collidable_points
2308
+ ]
2301
2309
  M = js.model.free_floating_mass_matrix(model, data_tf)
2302
2310
 
2303
2311
  # Compute the impact velocity.
@@ -21,7 +21,7 @@ def collidable_points_pos_vel(
21
21
  ) -> tuple[jtp.Matrix, jtp.Matrix]:
22
22
  """
23
23
 
24
- Compute the position and linear velocity of collidable points in the world frame.
24
+ Compute the position and linear velocity of the enabled collidable points in the world frame.
25
25
 
26
26
  Args:
27
27
  model: The model to consider.
@@ -35,10 +35,23 @@ def collidable_points_pos_vel(
35
35
  joint_velocities: The velocities of the joints.
36
36
 
37
37
  Returns:
38
- A tuple containing the position and linear velocity of collidable points.
38
+ A tuple containing the position and linear velocity of the enabled collidable points.
39
39
  """
40
40
 
41
- if len(model.kin_dyn_parameters.contact_parameters.body) == 0:
41
+ # Get the indices of the enabled collidable points.
42
+ indices_of_enabled_collidable_points = (
43
+ model.kin_dyn_parameters.contact_parameters.indices_of_enabled_collidable_points
44
+ )
45
+
46
+ parent_link_idx_of_enabled_collidable_points = jnp.array(
47
+ model.kin_dyn_parameters.contact_parameters.body, dtype=int
48
+ )[indices_of_enabled_collidable_points]
49
+
50
+ L_p_Ci = model.kin_dyn_parameters.contact_parameters.point[
51
+ indices_of_enabled_collidable_points
52
+ ]
53
+
54
+ if len(indices_of_enabled_collidable_points) == 0:
42
55
  return jnp.array(0).astype(float), jnp.empty(0).astype(float)
43
56
 
44
57
  W_p_B, W_Q_B, s, W_v_WB, ṡ, _, _, _, _, _ = utils.process_inputs(
@@ -136,8 +149,8 @@ def collidable_points_pos_vel(
136
149
 
137
150
  # Process all the collidable points in parallel.
138
151
  W_p_Ci, CW_vl_WC = jax.vmap(process_point_kinematics)(
139
- model.kin_dyn_parameters.contact_parameters.point,
140
- jnp.array(model.kin_dyn_parameters.contact_parameters.body),
152
+ L_p_Ci,
153
+ parent_link_idx_of_enabled_collidable_points,
141
154
  )
142
155
 
143
156
  return W_p_Ci, CW_vl_WC
@@ -216,11 +216,21 @@ class ContactModel(JaxsimDataclass):
216
216
  the velocity representation of data.
217
217
  """
218
218
 
219
+ # Get the object storing the contact parameters of the model.
220
+ contact_parameters = model.kin_dyn_parameters.contact_parameters
221
+
222
+ # Extract the indices corresponding to the enabled collidable points.
223
+ indices_of_enabled_collidable_points = (
224
+ contact_parameters.indices_of_enabled_collidable_points
225
+ )
226
+
219
227
  # Convert the contact forces to a JAX array.
220
228
  f_C = jnp.atleast_2d(jnp.array(contact_forces, dtype=float).squeeze())
221
229
 
222
230
  # Get the pose of the enabled collidable points.
223
- W_H_C = js.contact.transforms(model=model, data=data)
231
+ W_H_C = js.contact.transforms(model=model, data=data)[
232
+ indices_of_enabled_collidable_points
233
+ ]
224
234
 
225
235
  # Convert the contact forces to inertial-fixed representation.
226
236
  W_f_C = jax.vmap(
@@ -234,14 +244,6 @@ class ContactModel(JaxsimDataclass):
234
244
  )
235
245
  )(f_C, W_H_C)
236
246
 
237
- # Get the object storing the contact parameters of the model.
238
- contact_parameters = model.kin_dyn_parameters.contact_parameters
239
-
240
- # Extract the indices corresponding to the enabled collidable points.
241
- indices_of_enabled_collidable_points = (
242
- contact_parameters.indices_of_enabled_collidable_points
243
- )
244
-
245
247
  # Construct the vector defining the parent link index of each collidable point.
246
248
  # We use this vector to sum the 6D forces of all collidable points rigidly
247
249
  # attached to the same link.
@@ -357,13 +357,15 @@ class RelaxedRigidContacts(common.ContactModel):
357
357
 
358
358
  Jl_WC = jnp.vstack(
359
359
  jax.vmap(lambda J, height: J * (height < 0))(
360
- js.contact.jacobian(model=model, data=data)[:, :3, :], δ
360
+ js.contact.jacobian(model=model, data=data)[:, :3, :],
361
+ δ,
361
362
  )
362
363
  )
363
364
 
364
365
  J̇_WC = jnp.vstack(
365
366
  jax.vmap(lambda J̇, height: J̇ * (height < 0))(
366
- js.contact.jacobian_derivative(model=model, data=data)[:, :3], δ
367
+ js.contact.jacobian_derivative(model=model, data=data)[:, :3],
368
+ δ,
367
369
  ),
368
370
  )
369
371
 
@@ -530,6 +532,15 @@ class RelaxedRigidContacts(common.ContactModel):
530
532
  )
531
533
  )
532
534
 
535
+ # Get the indices of the enabled collidable points.
536
+ indices_of_enabled_collidable_points = (
537
+ model.kin_dyn_parameters.contact_parameters.indices_of_enabled_collidable_points
538
+ )
539
+
540
+ parent_link_idx_of_enabled_collidable_points = jnp.array(
541
+ model.kin_dyn_parameters.contact_parameters.body, dtype=int
542
+ )[indices_of_enabled_collidable_points]
543
+
533
544
  # Compute the 6D inertia matrices of all links.
534
545
  M_L = js.model.link_spatial_inertia_matrices(model=model)
535
546
 
@@ -595,9 +606,7 @@ class RelaxedRigidContacts(common.ContactModel):
595
606
  f=jnp.concatenate,
596
607
  tree=(
597
608
  *jax.vmap(compute_row)(
598
- link_idx=jnp.array(
599
- model.kin_dyn_parameters.contact_parameters.body
600
- ),
609
+ link_idx=parent_link_idx_of_enabled_collidable_points,
601
610
  penetration=penetration,
602
611
  velocity=velocity,
603
612
  ),
@@ -285,6 +285,13 @@ class RigidContacts(ContactModel):
285
285
  # Import qpax privately just in this method.
286
286
  import qpax
287
287
 
288
+ # Get the indices of the enabled collidable points.
289
+ indices_of_enabled_collidable_points = (
290
+ model.kin_dyn_parameters.contact_parameters.indices_of_enabled_collidable_points
291
+ )
292
+
293
+ n_collidable_points = len(indices_of_enabled_collidable_points)
294
+
288
295
  link_forces = jnp.atleast_2d(
289
296
  jnp.array(link_forces, dtype=float).squeeze()
290
297
  if link_forces is not None
@@ -299,7 +306,6 @@ class RigidContacts(ContactModel):
299
306
 
300
307
  # Compute kin-dyn quantities used in the contact model.
301
308
  with data.switch_velocity_representation(VelRepr.Mixed):
302
-
303
309
  BW_ν = data.generalized_velocity()
304
310
 
305
311
  M = js.model.free_floating_mass_matrix(model=model, data=data)
@@ -310,14 +316,11 @@ class RigidContacts(ContactModel):
310
316
  W_H_C = js.contact.transforms(model=model, data=data)
311
317
 
312
318
  # Compute the position and linear velocities (mixed representation) of
313
- # all collidable points belonging to the robot.
319
+ # all enabled collidable points belonging to the robot.
314
320
  position, velocity = js.contact.collidable_point_kinematics(
315
321
  model=model, data=data
316
322
  )
317
323
 
318
- # Get the number of collidable points.
319
- n_collidable_points = len(model.kin_dyn_parameters.contact_parameters.body)
320
-
321
324
  # Compute the penetration depth and velocity of the collidable points.
322
325
  # Note that this function considers the penetration in the normal direction.
323
326
  δ, δ_dot, n̂ = jax.vmap(common.compute_penetration_data, in_axes=(0, 0, None))(
@@ -460,7 +463,7 @@ class RigidContacts(ContactModel):
460
463
  return G
461
464
 
462
465
  @staticmethod
463
- def _compute_ineq_bounds(n_collidable_points: jtp.FloatLike) -> jtp.Vector:
466
+ def _compute_ineq_bounds(n_collidable_points: int) -> jtp.Vector:
464
467
 
465
468
  n_constraints = 6 * n_collidable_points
466
469
  return jnp.zeros(shape=(n_constraints,))