jaxsim 0.4.1.dev26__tar.gz → 0.4.2.dev12__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 (121) hide show
  1. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/PKG-INFO +1 -1
  2. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/_version.py +2 -2
  3. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/frame.py +156 -1
  4. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/model.py +2 -2
  5. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim.egg-info/PKG-INFO +1 -1
  6. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_api_frame.py +125 -0
  7. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/.devcontainer/Dockerfile +0 -0
  8. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/.devcontainer/devcontainer.json +0 -0
  9. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/.gitattributes +0 -0
  10. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/.github/CODEOWNERS +0 -0
  11. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/.github/workflows/ci_cd.yml +0 -0
  12. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/.github/workflows/read_the_docs.yml +0 -0
  13. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/.gitignore +0 -0
  14. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/.pre-commit-config.yaml +0 -0
  15. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/.readthedocs.yaml +0 -0
  16. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/CONTRIBUTING.md +0 -0
  17. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/LICENSE +0 -0
  18. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/README.md +0 -0
  19. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/Makefile +0 -0
  20. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/conf.py +0 -0
  21. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/examples.rst +0 -0
  22. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/guide/install.rst +0 -0
  23. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/index.rst +0 -0
  24. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/make.bat +0 -0
  25. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/modules/api.rst +0 -0
  26. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/modules/integrators.rst +0 -0
  27. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/modules/math.rst +0 -0
  28. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/modules/mujoco.rst +0 -0
  29. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/modules/parsers.rst +0 -0
  30. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/modules/rbda.rst +0 -0
  31. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/modules/typing.rst +0 -0
  32. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/modules/utils.rst +0 -0
  33. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/environment.yml +0 -0
  34. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/examples/.gitattributes +0 -0
  35. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/examples/.gitignore +0 -0
  36. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/examples/PD_controller.ipynb +0 -0
  37. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/examples/Parallel_computing.ipynb +0 -0
  38. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/examples/README.md +0 -0
  39. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/examples/assets/cartpole.urdf +0 -0
  40. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/pixi.lock +0 -0
  41. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/pyproject.toml +0 -0
  42. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/setup.cfg +0 -0
  43. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/setup.py +0 -0
  44. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/__init__.py +0 -0
  45. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/__init__.py +0 -0
  46. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/com.py +0 -0
  47. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/common.py +0 -0
  48. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/contact.py +0 -0
  49. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/data.py +0 -0
  50. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/joint.py +0 -0
  51. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/kin_dyn_parameters.py +0 -0
  52. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/link.py +0 -0
  53. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/ode.py +0 -0
  54. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/ode_data.py +0 -0
  55. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/references.py +0 -0
  56. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/exceptions.py +0 -0
  57. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/integrators/__init__.py +0 -0
  58. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/integrators/common.py +0 -0
  59. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/integrators/fixed_step.py +0 -0
  60. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/integrators/variable_step.py +0 -0
  61. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/logging.py +0 -0
  62. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/math/__init__.py +0 -0
  63. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/math/adjoint.py +0 -0
  64. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/math/cross.py +0 -0
  65. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/math/inertia.py +0 -0
  66. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/math/joint_model.py +0 -0
  67. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/math/quaternion.py +0 -0
  68. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/math/rotation.py +0 -0
  69. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/math/skew.py +0 -0
  70. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/math/transform.py +0 -0
  71. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/mujoco/__init__.py +0 -0
  72. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/mujoco/__main__.py +0 -0
  73. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/mujoco/loaders.py +0 -0
  74. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/mujoco/model.py +0 -0
  75. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/mujoco/visualizer.py +0 -0
  76. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/parsers/__init__.py +0 -0
  77. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/parsers/descriptions/__init__.py +0 -0
  78. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/parsers/descriptions/collision.py +0 -0
  79. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/parsers/descriptions/joint.py +0 -0
  80. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/parsers/descriptions/link.py +0 -0
  81. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/parsers/descriptions/model.py +0 -0
  82. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/parsers/kinematic_graph.py +0 -0
  83. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/parsers/rod/__init__.py +0 -0
  84. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/parsers/rod/parser.py +0 -0
  85. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/parsers/rod/utils.py +0 -0
  86. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/__init__.py +0 -0
  87. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/aba.py +0 -0
  88. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/collidable_points.py +0 -0
  89. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/contacts/__init__.py +0 -0
  90. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/contacts/common.py +0 -0
  91. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/contacts/soft.py +0 -0
  92. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/crba.py +0 -0
  93. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/forward_kinematics.py +0 -0
  94. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/jacobian.py +0 -0
  95. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/rnea.py +0 -0
  96. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/utils.py +0 -0
  97. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/terrain/__init__.py +0 -0
  98. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/terrain/terrain.py +0 -0
  99. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/typing.py +0 -0
  100. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/utils/__init__.py +0 -0
  101. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/utils/jaxsim_dataclass.py +0 -0
  102. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/utils/tracing.py +0 -0
  103. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/utils/wrappers.py +0 -0
  104. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim.egg-info/SOURCES.txt +0 -0
  105. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim.egg-info/dependency_links.txt +0 -0
  106. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim.egg-info/requires.txt +0 -0
  107. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim.egg-info/top_level.txt +0 -0
  108. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/__init__.py +0 -0
  109. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/conftest.py +0 -0
  110. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_api_com.py +0 -0
  111. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_api_contact.py +0 -0
  112. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_api_data.py +0 -0
  113. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_api_joint.py +0 -0
  114. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_api_link.py +0 -0
  115. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_api_model.py +0 -0
  116. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_automatic_differentiation.py +0 -0
  117. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_contact.py +0 -0
  118. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_exceptions.py +0 -0
  119. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_pytree.py +0 -0
  120. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_simulations.py +0 -0
  121. {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/utils_idyntree.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jaxsim
3
- Version: 0.4.1.dev26
3
+ Version: 0.4.2.dev12
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>
@@ -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.1.dev26'
16
- __version_tuple__ = version_tuple = (0, 4, 1, 'dev26')
15
+ __version__ = version = '0.4.2.dev12'
16
+ __version_tuple__ = version_tuple = (0, 4, 2, 'dev12')
@@ -7,7 +7,7 @@ import jax.numpy as jnp
7
7
  import jaxsim.api as js
8
8
  import jaxsim.typing as jtp
9
9
  from jaxsim import exceptions
10
- from jaxsim.math import Adjoint, Transform
10
+ from jaxsim.math import Adjoint, Cross, Transform
11
11
 
12
12
  from .common import VelRepr
13
13
 
@@ -257,3 +257,158 @@ def jacobian(
257
257
  raise ValueError(output_vel_repr)
258
258
 
259
259
  return O_J_WL_I
260
+
261
+
262
+ @functools.partial(jax.jit, static_argnames=["output_vel_repr"])
263
+ def jacobian_derivative(
264
+ model: js.model.JaxSimModel,
265
+ data: js.data.JaxSimModelData,
266
+ *,
267
+ frame_index: jtp.IntLike,
268
+ output_vel_repr: VelRepr | None = None,
269
+ ) -> jtp.Matrix:
270
+ r"""
271
+ Compute the derivative of the free-floating jacobian of the frame.
272
+
273
+ Args:
274
+ model: The model to consider.
275
+ data: The data of the considered model.
276
+ frame_index: The index of the frame.
277
+ output_vel_repr:
278
+ The output velocity representation of the free-floating jacobian derivative.
279
+
280
+ Returns:
281
+ The derivative of the :math:`6 \times (6+n)` free-floating jacobian of the frame.
282
+
283
+ Note:
284
+ The input representation of the free-floating jacobian derivative is the active
285
+ velocity representation.
286
+ """
287
+
288
+ n_l = model.number_of_links()
289
+ n_f = len(model.frame_names())
290
+
291
+ exceptions.raise_value_error_if(
292
+ condition=jnp.array([frame_index < n_l, frame_index >= n_l + n_f]).any(),
293
+ msg="Invalid frame index '{idx}'",
294
+ idx=frame_index,
295
+ )
296
+
297
+ output_vel_repr = (
298
+ output_vel_repr if output_vel_repr is not None else data.velocity_representation
299
+ )
300
+
301
+ # Get the index of the parent link.
302
+ L = idx_of_parent_link(model=model, frame_index=frame_index)
303
+
304
+ with data.switch_velocity_representation(VelRepr.Inertial):
305
+ # Compute the Jacobian of the parent link in inertial representation.
306
+ W_J_WL_W = js.link.jacobian(
307
+ model=model,
308
+ data=data,
309
+ link_index=L,
310
+ output_vel_repr=VelRepr.Inertial,
311
+ )
312
+
313
+ # Compute the Jacobian derivative of the parent link in inertial representation.
314
+ W_J̇_WL_W = js.link.jacobian_derivative(
315
+ model=model,
316
+ data=data,
317
+ link_index=L,
318
+ output_vel_repr=VelRepr.Inertial,
319
+ )
320
+
321
+ # =====================================================
322
+ # Compute quantities to adjust the input representation
323
+ # =====================================================
324
+
325
+ def compute_T(model: js.model.JaxSimModel, X: jtp.Matrix) -> jtp.Matrix:
326
+ In = jnp.eye(model.dofs())
327
+ T = jax.scipy.linalg.block_diag(X, In)
328
+ return T
329
+
330
+ def compute_Ṫ(model: js.model.JaxSimModel, Ẋ: jtp.Matrix) -> jtp.Matrix:
331
+ On = jnp.zeros(shape=(model.dofs(), model.dofs()))
332
+ Ṫ = jax.scipy.linalg.block_diag(Ẋ, On)
333
+ return Ṫ
334
+
335
+ # Compute the operator to change the representation of ν, and its
336
+ # time derivative.
337
+ match data.velocity_representation:
338
+ case VelRepr.Inertial:
339
+ W_H_W = jnp.eye(4)
340
+ W_X_W = Adjoint.from_transform(transform=W_H_W)
341
+ W_Ẋ_W = jnp.zeros((6, 6))
342
+
343
+ T = compute_T(model=model, X=W_X_W)
344
+ Ṫ = compute_Ṫ(model=model, Ẋ=W_Ẋ_W)
345
+
346
+ case VelRepr.Body:
347
+ W_H_B = data.base_transform()
348
+ W_X_B = Adjoint.from_transform(transform=W_H_B)
349
+ B_v_WB = data.base_velocity()
350
+ B_vx_WB = Cross.vx(B_v_WB)
351
+ W_Ẋ_B = W_X_B @ B_vx_WB
352
+
353
+ T = compute_T(model=model, X=W_X_B)
354
+ Ṫ = compute_Ṫ(model=model, Ẋ=W_Ẋ_B)
355
+
356
+ case VelRepr.Mixed:
357
+ W_H_B = data.base_transform()
358
+ W_H_BW = W_H_B.at[0:3, 0:3].set(jnp.eye(3))
359
+ W_X_BW = Adjoint.from_transform(transform=W_H_BW)
360
+ BW_v_WB = data.base_velocity()
361
+ BW_v_W_BW = BW_v_WB.at[3:6].set(jnp.zeros(3))
362
+ BW_vx_W_BW = Cross.vx(BW_v_W_BW)
363
+ W_Ẋ_BW = W_X_BW @ BW_vx_W_BW
364
+
365
+ T = compute_T(model=model, X=W_X_BW)
366
+ Ṫ = compute_Ṫ(model=model, Ẋ=W_Ẋ_BW)
367
+
368
+ case _:
369
+ raise ValueError(data.velocity_representation)
370
+
371
+ # =====================================================
372
+ # Compute quantities to adjust the output representation
373
+ # =====================================================
374
+
375
+ match output_vel_repr:
376
+ case VelRepr.Inertial:
377
+ O_X_W = W_X_W = Adjoint.from_transform(transform=jnp.eye(4))
378
+ O_Ẋ_W = W_Ẋ_W = jnp.zeros((6, 6))
379
+
380
+ case VelRepr.Body:
381
+ W_H_F = transform(model=model, data=data, frame_index=frame_index)
382
+ O_X_W = F_X_W = Adjoint.from_transform(transform=W_H_F, inverse=True)
383
+ with data.switch_velocity_representation(VelRepr.Inertial):
384
+ W_nu = data.generalized_velocity()
385
+ W_v_WF = W_J_WL_W @ W_nu
386
+ W_vx_WF = Cross.vx(W_v_WF)
387
+ O_Ẋ_W = F_Ẋ_W = -F_X_W @ W_vx_WF
388
+
389
+ case VelRepr.Mixed:
390
+ W_H_F = transform(model=model, data=data, frame_index=frame_index)
391
+ W_H_FW = W_H_F.at[0:3, 0:3].set(jnp.eye(3))
392
+ FW_H_W = Transform.inverse(W_H_FW)
393
+ O_X_W = FW_X_W = Adjoint.from_transform(transform=FW_H_W)
394
+ with data.switch_velocity_representation(VelRepr.Mixed):
395
+ FW_J_WF_FW = jacobian(
396
+ model=model,
397
+ data=data,
398
+ frame_index=frame_index,
399
+ output_vel_repr=VelRepr.Mixed,
400
+ )
401
+ FW_v_WF = FW_J_WF_FW @ data.generalized_velocity()
402
+ W_v_W_FW = jnp.zeros(6).at[0:3].set(FW_v_WF[0:3])
403
+ W_vx_W_FW = Cross.vx(W_v_W_FW)
404
+ O_Ẋ_W = FW_Ẋ_W = -FW_X_W @ W_vx_W_FW
405
+
406
+ case _:
407
+ raise ValueError(output_vel_repr)
408
+
409
+ O_J̇_WF_I = jnp.zeros(shape=(6, 6 + model.dofs()))
410
+ O_J̇_WF_I += O_Ẋ_W @ W_J_WL_W @ T
411
+ O_J̇_WF_I += O_X_W @ W_J̇_WL_W @ T
412
+ O_J̇_WF_I += O_X_W @ W_J_WL_W @ Ṫ
413
+
414
+ return O_J̇_WF_I
@@ -301,10 +301,10 @@ class JaxSimModel(JaxsimDataclass):
301
301
 
302
302
  def frame_names(self) -> tuple[str, ...]:
303
303
  """
304
- Return the names of the links in the model.
304
+ Return the names of the frames in the model.
305
305
 
306
306
  Returns:
307
- The names of the links in the model.
307
+ The names of the frames in the model.
308
308
  """
309
309
 
310
310
  return self.kin_dyn_parameters.frame_parameters.name
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jaxsim
3
- Version: 0.4.1.dev26
3
+ Version: 0.4.2.dev12
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>
@@ -5,6 +5,7 @@ import pytest
5
5
 
6
6
  import jaxsim.api as js
7
7
  from jaxsim import VelRepr
8
+ from jaxsim.math.quaternion import Quaternion
8
9
 
9
10
  from . import utils_idyntree
10
11
 
@@ -168,3 +169,127 @@ def test_frame_jacobians(
168
169
  J_WL_js = js.frame.jacobian(model=model, data=data, frame_index=frame_index)
169
170
  J_WL_idt = kin_dyn.jacobian_frame(frame_name=frame_name)
170
171
  assert J_WL_js == pytest.approx(J_WL_idt, abs=1e-9)
172
+
173
+
174
+ def test_frame_jacobian_derivative(
175
+ jaxsim_models_types: js.model.JaxSimModel,
176
+ velocity_representation: VelRepr,
177
+ prng_key: jax.Array,
178
+ ):
179
+ model = jaxsim_models_types
180
+
181
+ _, subkey = jax.random.split(prng_key, num=2)
182
+ data = js.data.random_model_data(
183
+ model=model, key=subkey, velocity_representation=velocity_representation
184
+ )
185
+
186
+ kin_dyn = utils_idyntree.build_kindyncomputations_from_jaxsim_model(
187
+ model=model, data=data
188
+ )
189
+
190
+ # Get all names of frames in the iDynTree model.
191
+ frame_names = [
192
+ frame.name
193
+ for frame in model.description.frames
194
+ if frame.name in kin_dyn.frame_names()
195
+ ]
196
+
197
+ # Skip some entry of models with many frames.
198
+ frame_names = [
199
+ name
200
+ for name in frame_names
201
+ if "skin" not in name or "laser" not in name or "depth" not in name
202
+ ]
203
+
204
+ frame_idxs = js.frame.names_to_idxs(model=model, frame_names=tuple(frame_names))
205
+
206
+ # ===============
207
+ # Test against AD
208
+ # ===============
209
+
210
+ # Get the generalized velocity.
211
+ I_ν = data.generalized_velocity()
212
+
213
+ # Compute J̇.
214
+ O_J̇_WF_I = jax.vmap(
215
+ lambda frame_index: js.frame.jacobian_derivative(
216
+ model=model, data=data, frame_index=frame_index
217
+ )
218
+ )(frame_idxs)
219
+
220
+ assert O_J̇_WF_I.shape == (len(frame_names), 6, 6 + model.dofs())
221
+
222
+ # Compute the plain Jacobian.
223
+ # This function will be used to compute the Jacobian derivative with AD.
224
+ def J(q, frame_idxs) -> jax.Array:
225
+ data_ad = js.data.JaxSimModelData.zero(
226
+ model=model, velocity_representation=data.velocity_representation
227
+ )
228
+
229
+ data_ad = data_ad.reset_base_position(base_position=q[:3])
230
+ data_ad = data_ad.reset_base_quaternion(base_quaternion=q[3:7])
231
+ data_ad = data_ad.reset_joint_positions(positions=q[7:])
232
+
233
+ O_J_ad_WF_I = jax.vmap(
234
+ lambda model, data, frame_index: js.frame.jacobian(
235
+ model=model, data=data, frame_index=frame_index
236
+ ),
237
+ in_axes=(None, None, 0),
238
+ )(model, data_ad, frame_idxs)
239
+
240
+ return O_J_ad_WF_I
241
+
242
+ def compute_q(data: js.data.JaxSimModelData) -> jax.Array:
243
+ q = jnp.hstack(
244
+ [
245
+ data.base_position(),
246
+ data.base_orientation(),
247
+ data.joint_positions(),
248
+ ]
249
+ )
250
+
251
+ return q
252
+
253
+ def compute_q̇(data: js.data.JaxSimModelData) -> jax.Array:
254
+ with data.switch_velocity_representation(VelRepr.Body):
255
+ B_ω_WB = data.base_velocity()[3:6]
256
+
257
+ with data.switch_velocity_representation(VelRepr.Mixed):
258
+ W_ṗ_B = data.base_velocity()[0:3]
259
+
260
+ W_Q̇_B = Quaternion.derivative(
261
+ quaternion=data.base_orientation(),
262
+ omega=B_ω_WB,
263
+ omega_in_body_fixed=True,
264
+ K=0.0,
265
+ ).squeeze()
266
+
267
+ q̇ = jnp.hstack([W_ṗ_B, W_Q̇_B, data.joint_velocities()])
268
+
269
+ return q̇
270
+
271
+ # Compute q and q̇.
272
+ q = compute_q(data)
273
+ q̇ = compute_q̇(data)
274
+
275
+ # Compute dJ/dt with AD.
276
+ dJ_dq = jax.jacfwd(J, argnums=0)(q, frame_idxs)
277
+ O_J̇_ad_WF_I = jnp.einsum("ijkq,q->ijk", dJ_dq, q̇)
278
+
279
+ assert O_J̇_WF_I == pytest.approx(expected=O_J̇_ad_WF_I)
280
+
281
+ # =====================
282
+ # Test against iDynTree
283
+ # =====================
284
+
285
+ # Compute the product J̇ν.
286
+ O_a_bias_WF = jax.vmap(
287
+ lambda O_J̇_WF_I, I_ν: O_J̇_WF_I @ I_ν,
288
+ in_axes=(0, None),
289
+ )(O_J̇_WF_I, I_ν)
290
+
291
+ # Compare the two computations.
292
+ for index, name in enumerate(frame_names):
293
+ J̇ν_idt = kin_dyn.frame_bias_acc(frame_name=name)
294
+ J̇ν_js = O_a_bias_WF[index]
295
+ assert J̇ν_js == pytest.approx(J̇ν_idt, abs=1e-9)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes