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.
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/PKG-INFO +1 -1
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/_version.py +2 -2
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/frame.py +156 -1
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/model.py +2 -2
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim.egg-info/PKG-INFO +1 -1
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_api_frame.py +125 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/.devcontainer/Dockerfile +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/.devcontainer/devcontainer.json +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/.gitattributes +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/.github/CODEOWNERS +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/.github/workflows/ci_cd.yml +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/.github/workflows/read_the_docs.yml +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/.gitignore +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/.pre-commit-config.yaml +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/.readthedocs.yaml +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/CONTRIBUTING.md +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/LICENSE +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/README.md +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/Makefile +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/conf.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/examples.rst +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/guide/install.rst +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/index.rst +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/make.bat +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/modules/api.rst +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/modules/integrators.rst +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/modules/math.rst +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/modules/mujoco.rst +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/modules/parsers.rst +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/modules/rbda.rst +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/modules/typing.rst +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/docs/modules/utils.rst +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/environment.yml +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/examples/.gitattributes +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/examples/.gitignore +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/examples/PD_controller.ipynb +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/examples/Parallel_computing.ipynb +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/examples/README.md +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/examples/assets/cartpole.urdf +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/pixi.lock +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/pyproject.toml +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/setup.cfg +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/setup.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/__init__.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/__init__.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/com.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/common.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/contact.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/data.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/joint.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/kin_dyn_parameters.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/link.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/ode.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/ode_data.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/api/references.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/exceptions.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/integrators/__init__.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/integrators/common.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/integrators/fixed_step.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/integrators/variable_step.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/logging.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/math/__init__.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/math/adjoint.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/math/cross.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/math/inertia.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/math/joint_model.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/math/quaternion.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/math/rotation.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/math/skew.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/math/transform.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/mujoco/__init__.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/mujoco/__main__.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/mujoco/loaders.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/mujoco/model.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/mujoco/visualizer.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/parsers/__init__.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/parsers/descriptions/__init__.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/parsers/descriptions/collision.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/parsers/descriptions/joint.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/parsers/descriptions/link.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/parsers/descriptions/model.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/parsers/kinematic_graph.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/parsers/rod/__init__.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/parsers/rod/parser.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/parsers/rod/utils.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/__init__.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/aba.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/collidable_points.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/contacts/__init__.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/contacts/common.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/contacts/soft.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/crba.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/forward_kinematics.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/jacobian.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/rnea.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/rbda/utils.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/terrain/__init__.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/terrain/terrain.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/typing.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/utils/__init__.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/utils/jaxsim_dataclass.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/utils/tracing.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim/utils/wrappers.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim.egg-info/SOURCES.txt +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim.egg-info/dependency_links.txt +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim.egg-info/requires.txt +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/src/jaxsim.egg-info/top_level.txt +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/__init__.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/conftest.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_api_com.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_api_contact.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_api_data.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_api_joint.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_api_link.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_api_model.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_automatic_differentiation.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_contact.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_exceptions.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_pytree.py +0 -0
- {jaxsim-0.4.1.dev26 → jaxsim-0.4.2.dev12}/tests/test_simulations.py +0 -0
- {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.
|
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.
|
16
|
-
__version_tuple__ = version_tuple = (0, 4,
|
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
|
304
|
+
Return the names of the frames in the model.
|
305
305
|
|
306
306
|
Returns:
|
307
|
-
The names of the
|
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.
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|