jaxsim 0.4.1.dev24__py3-none-any.whl → 0.4.2__py3-none-any.whl
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/_version.py +2 -2
- jaxsim/api/com.py +12 -12
- jaxsim/api/contact.py +168 -0
- jaxsim/api/data.py +2 -11
- jaxsim/api/frame.py +156 -1
- jaxsim/api/link.py +10 -7
- jaxsim/api/model.py +68 -24
- jaxsim/api/references.py +107 -1
- jaxsim/integrators/common.py +4 -2
- jaxsim/math/adjoint.py +3 -4
- jaxsim/math/joint_model.py +2 -2
- jaxsim/math/quaternion.py +2 -4
- jaxsim/math/transform.py +1 -3
- jaxsim/mujoco/loaders.py +12 -2
- jaxsim/mujoco/model.py +5 -5
- jaxsim/rbda/aba.py +2 -2
- jaxsim/rbda/collidable_points.py +2 -2
- jaxsim/rbda/contacts/soft.py +1 -1
- jaxsim/rbda/crba.py +24 -12
- jaxsim/rbda/forward_kinematics.py +10 -6
- jaxsim/rbda/jacobian.py +24 -12
- jaxsim/rbda/rnea.py +2 -2
- jaxsim/terrain/terrain.py +1 -1
- {jaxsim-0.4.1.dev24.dist-info → jaxsim-0.4.2.dist-info}/METADATA +31 -19
- {jaxsim-0.4.1.dev24.dist-info → jaxsim-0.4.2.dist-info}/RECORD +28 -28
- {jaxsim-0.4.1.dev24.dist-info → jaxsim-0.4.2.dist-info}/WHEEL +1 -1
- {jaxsim-0.4.1.dev24.dist-info → jaxsim-0.4.2.dist-info}/LICENSE +0 -0
- {jaxsim-0.4.1.dev24.dist-info → jaxsim-0.4.2.dist-info}/top_level.txt +0 -0
jaxsim/_version.py
CHANGED
@@ -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'
|
16
|
+
__version_tuple__ = version_tuple = (0, 4, 2)
|
jaxsim/api/com.py
CHANGED
@@ -137,9 +137,9 @@ def centroidal_momentum_jacobian(
|
|
137
137
|
|
138
138
|
match data.velocity_representation:
|
139
139
|
case VelRepr.Inertial | VelRepr.Mixed:
|
140
|
-
W_H_G = W_H_GW = jnp.eye(4).at[0:3, 3].set(W_p_CoM)
|
140
|
+
W_H_G = W_H_GW = jnp.eye(4).at[0:3, 3].set(W_p_CoM) # noqa: F841
|
141
141
|
case VelRepr.Body:
|
142
|
-
W_H_G = W_H_GB = W_H_B.at[0:3, 3].set(W_p_CoM)
|
142
|
+
W_H_G = W_H_GB = W_H_B.at[0:3, 3].set(W_p_CoM) # noqa: F841
|
143
143
|
case _:
|
144
144
|
raise ValueError(data.velocity_representation)
|
145
145
|
|
@@ -172,9 +172,9 @@ def locked_centroidal_spatial_inertia(
|
|
172
172
|
|
173
173
|
match data.velocity_representation:
|
174
174
|
case VelRepr.Inertial | VelRepr.Mixed:
|
175
|
-
W_H_G = W_H_GW = jnp.eye(4).at[0:3, 3].set(W_p_CoM)
|
175
|
+
W_H_G = W_H_GW = jnp.eye(4).at[0:3, 3].set(W_p_CoM) # noqa: F841
|
176
176
|
case VelRepr.Body:
|
177
|
-
W_H_G = W_H_GB = W_H_B.at[0:3, 3].set(W_p_CoM)
|
177
|
+
W_H_G = W_H_GB = W_H_B.at[0:3, 3].set(W_p_CoM) # noqa: F841
|
178
178
|
case _:
|
179
179
|
raise ValueError(data.velocity_representation)
|
180
180
|
|
@@ -290,14 +290,14 @@ def bias_acceleration(
|
|
290
290
|
|
291
291
|
case VelRepr.Inertial:
|
292
292
|
|
293
|
-
C_v̇_WL = W_v̇_bias_WL = v̇_bias_WL
|
294
|
-
C_v_WC = W_v_WW = jnp.zeros(6)
|
293
|
+
C_v̇_WL = W_v̇_bias_WL = v̇_bias_WL # noqa: F841
|
294
|
+
C_v_WC = W_v_WW = jnp.zeros(6) # noqa: F841
|
295
295
|
|
296
|
-
L_H_C = L_H_W = jax.vmap(
|
296
|
+
L_H_C = L_H_W = jax.vmap( # noqa: F841
|
297
297
|
lambda W_H_L: jaxsim.math.Transform.inverse(W_H_L)
|
298
298
|
)(W_H_L)
|
299
299
|
|
300
|
-
L_v_LC = L_v_LW = jax.vmap(
|
300
|
+
L_v_LC = L_v_LW = jax.vmap( # noqa: F841
|
301
301
|
lambda i: -js.link.velocity(
|
302
302
|
model=model, data=data, link_index=i, output_vel_repr=VelRepr.Body
|
303
303
|
)
|
@@ -314,9 +314,9 @@ def bias_acceleration(
|
|
314
314
|
|
315
315
|
case VelRepr.Mixed:
|
316
316
|
|
317
|
-
C_v̇_WL = LW_v̇_bias_WL = v̇_bias_WL
|
317
|
+
C_v̇_WL = LW_v̇_bias_WL = v̇_bias_WL # noqa: F841
|
318
318
|
|
319
|
-
C_v_WC = LW_v_W_LW = jax.vmap(
|
319
|
+
C_v_WC = LW_v_W_LW = jax.vmap( # noqa: F841
|
320
320
|
lambda i: js.link.velocity(
|
321
321
|
model=model, data=data, link_index=i, output_vel_repr=VelRepr.Mixed
|
322
322
|
)
|
@@ -324,13 +324,13 @@ def bias_acceleration(
|
|
324
324
|
.set(jnp.zeros(3))
|
325
325
|
)(jnp.arange(model.number_of_links()))
|
326
326
|
|
327
|
-
L_H_C = L_H_LW = jax.vmap(
|
327
|
+
L_H_C = L_H_LW = jax.vmap( # noqa: F841
|
328
328
|
lambda W_H_L: jaxsim.math.Transform.inverse(
|
329
329
|
W_H_L.at[0:3, 3].set(jnp.zeros(3))
|
330
330
|
)
|
331
331
|
)(W_H_L)
|
332
332
|
|
333
|
-
L_v_LC = L_v_L_LW = jax.vmap(
|
333
|
+
L_v_LC = L_v_L_LW = jax.vmap( # noqa: F841
|
334
334
|
lambda i: -js.link.velocity(
|
335
335
|
model=model, data=data, link_index=i, output_vel_repr=VelRepr.Body
|
336
336
|
)
|
jaxsim/api/contact.py
CHANGED
@@ -8,6 +8,7 @@ import jax.numpy as jnp
|
|
8
8
|
import jaxsim.api as js
|
9
9
|
import jaxsim.terrain
|
10
10
|
import jaxsim.typing as jtp
|
11
|
+
from jaxsim.math import Adjoint, Cross, Transform
|
11
12
|
from jaxsim.rbda.contacts.soft import SoftContactsParams
|
12
13
|
|
13
14
|
from .common import VelRepr
|
@@ -411,3 +412,170 @@ def jacobian(
|
|
411
412
|
raise ValueError(output_vel_repr)
|
412
413
|
|
413
414
|
return O_J_WC
|
415
|
+
|
416
|
+
|
417
|
+
@functools.partial(jax.jit, static_argnames=["output_vel_repr"])
|
418
|
+
def jacobian_derivative(
|
419
|
+
model: js.model.JaxSimModel,
|
420
|
+
data: js.data.JaxSimModelData,
|
421
|
+
*,
|
422
|
+
output_vel_repr: VelRepr | None = None,
|
423
|
+
) -> jtp.Matrix:
|
424
|
+
r"""
|
425
|
+
Compute the derivative of the free-floating jacobian of the contact points.
|
426
|
+
|
427
|
+
Args:
|
428
|
+
model: The model to consider.
|
429
|
+
data: The data of the considered model.
|
430
|
+
output_vel_repr:
|
431
|
+
The output velocity representation of the free-floating jacobian derivative.
|
432
|
+
|
433
|
+
Returns:
|
434
|
+
The derivative of the :math:`6 \times (6+n)` free-floating jacobian of the contact points.
|
435
|
+
|
436
|
+
Note:
|
437
|
+
The input representation of the free-floating jacobian derivative is the active
|
438
|
+
velocity representation.
|
439
|
+
"""
|
440
|
+
|
441
|
+
output_vel_repr = (
|
442
|
+
output_vel_repr if output_vel_repr is not None else data.velocity_representation
|
443
|
+
)
|
444
|
+
|
445
|
+
# Get the index of the parent link and the position of the collidable point.
|
446
|
+
parent_link_idxs = jnp.array(model.kin_dyn_parameters.contact_parameters.body)
|
447
|
+
L_p_Ci = jnp.array(model.kin_dyn_parameters.contact_parameters.point)
|
448
|
+
contact_idxs = jnp.arange(L_p_Ci.shape[0])
|
449
|
+
|
450
|
+
# Get the transforms of all the parent links.
|
451
|
+
W_H_Li = js.model.forward_kinematics(model=model, data=data)
|
452
|
+
|
453
|
+
# =====================================================
|
454
|
+
# Compute quantities to adjust the input representation
|
455
|
+
# =====================================================
|
456
|
+
|
457
|
+
def compute_T(model: js.model.JaxSimModel, X: jtp.Matrix) -> jtp.Matrix:
|
458
|
+
In = jnp.eye(model.dofs())
|
459
|
+
T = jax.scipy.linalg.block_diag(X, In)
|
460
|
+
return T
|
461
|
+
|
462
|
+
def compute_Ṫ(model: js.model.JaxSimModel, Ẋ: jtp.Matrix) -> jtp.Matrix:
|
463
|
+
On = jnp.zeros(shape=(model.dofs(), model.dofs()))
|
464
|
+
Ṫ = jax.scipy.linalg.block_diag(Ẋ, On)
|
465
|
+
return Ṫ
|
466
|
+
|
467
|
+
# Compute the operator to change the representation of ν, and its
|
468
|
+
# time derivative.
|
469
|
+
match data.velocity_representation:
|
470
|
+
case VelRepr.Inertial:
|
471
|
+
W_H_W = jnp.eye(4)
|
472
|
+
W_X_W = Adjoint.from_transform(transform=W_H_W)
|
473
|
+
W_Ẋ_W = jnp.zeros((6, 6))
|
474
|
+
|
475
|
+
T = compute_T(model=model, X=W_X_W)
|
476
|
+
Ṫ = compute_Ṫ(model=model, Ẋ=W_Ẋ_W)
|
477
|
+
|
478
|
+
case VelRepr.Body:
|
479
|
+
W_H_B = data.base_transform()
|
480
|
+
W_X_B = Adjoint.from_transform(transform=W_H_B)
|
481
|
+
B_v_WB = data.base_velocity()
|
482
|
+
B_vx_WB = Cross.vx(B_v_WB)
|
483
|
+
W_Ẋ_B = W_X_B @ B_vx_WB
|
484
|
+
|
485
|
+
T = compute_T(model=model, X=W_X_B)
|
486
|
+
Ṫ = compute_Ṫ(model=model, Ẋ=W_Ẋ_B)
|
487
|
+
|
488
|
+
case VelRepr.Mixed:
|
489
|
+
W_H_B = data.base_transform()
|
490
|
+
W_H_BW = W_H_B.at[0:3, 0:3].set(jnp.eye(3))
|
491
|
+
W_X_BW = Adjoint.from_transform(transform=W_H_BW)
|
492
|
+
BW_v_WB = data.base_velocity()
|
493
|
+
BW_v_W_BW = BW_v_WB.at[3:6].set(jnp.zeros(3))
|
494
|
+
BW_vx_W_BW = Cross.vx(BW_v_W_BW)
|
495
|
+
W_Ẋ_BW = W_X_BW @ BW_vx_W_BW
|
496
|
+
|
497
|
+
T = compute_T(model=model, X=W_X_BW)
|
498
|
+
Ṫ = compute_Ṫ(model=model, Ẋ=W_Ẋ_BW)
|
499
|
+
|
500
|
+
case _:
|
501
|
+
raise ValueError(data.velocity_representation)
|
502
|
+
|
503
|
+
# =====================================================
|
504
|
+
# Compute quantities to adjust the output representation
|
505
|
+
# =====================================================
|
506
|
+
|
507
|
+
with data.switch_velocity_representation(VelRepr.Inertial):
|
508
|
+
# Compute the Jacobian of the parent link in inertial representation.
|
509
|
+
W_J_WL_W = js.model.generalized_free_floating_jacobian(
|
510
|
+
model=model,
|
511
|
+
data=data,
|
512
|
+
output_vel_repr=VelRepr.Inertial,
|
513
|
+
)
|
514
|
+
# Compute the Jacobian derivative of the parent link in inertial representation.
|
515
|
+
W_J̇_WL_W = js.model.generalized_free_floating_jacobian_derivative(
|
516
|
+
model=model,
|
517
|
+
data=data,
|
518
|
+
output_vel_repr=VelRepr.Inertial,
|
519
|
+
)
|
520
|
+
|
521
|
+
# Get the Jacobian of the collidable points in the mixed representation.
|
522
|
+
with data.switch_velocity_representation(VelRepr.Mixed):
|
523
|
+
CW_J_WC_BW = jacobian(
|
524
|
+
model=model,
|
525
|
+
data=data,
|
526
|
+
output_vel_repr=VelRepr.Mixed,
|
527
|
+
)
|
528
|
+
|
529
|
+
def compute_O_J̇_WC_I(
|
530
|
+
L_p_C: jtp.Vector,
|
531
|
+
contact_idx: jtp.Int,
|
532
|
+
CW_J_WC_BW: jtp.Matrix,
|
533
|
+
W_H_L: jtp.Matrix,
|
534
|
+
) -> jtp.Matrix:
|
535
|
+
|
536
|
+
parent_link_idx = parent_link_idxs[contact_idx]
|
537
|
+
|
538
|
+
match output_vel_repr:
|
539
|
+
case VelRepr.Inertial:
|
540
|
+
O_X_W = W_X_W = Adjoint.from_transform( # noqa: F841
|
541
|
+
transform=jnp.eye(4)
|
542
|
+
)
|
543
|
+
O_Ẋ_W = W_Ẋ_W = jnp.zeros((6, 6)) # noqa: F841
|
544
|
+
|
545
|
+
case VelRepr.Body:
|
546
|
+
L_H_C = Transform.from_rotation_and_translation(translation=L_p_C)
|
547
|
+
W_H_C = W_H_L[parent_link_idx] @ L_H_C
|
548
|
+
O_X_W = C_X_W = Adjoint.from_transform(transform=W_H_C, inverse=True)
|
549
|
+
with data.switch_velocity_representation(VelRepr.Inertial):
|
550
|
+
W_nu = data.generalized_velocity()
|
551
|
+
W_v_WC = W_J_WL_W[parent_link_idx] @ W_nu
|
552
|
+
W_vx_WC = Cross.vx(W_v_WC)
|
553
|
+
O_Ẋ_W = C_Ẋ_W = -C_X_W @ W_vx_WC # noqa: F841
|
554
|
+
|
555
|
+
case VelRepr.Mixed:
|
556
|
+
L_H_C = Transform.from_rotation_and_translation(translation=L_p_C)
|
557
|
+
W_H_C = W_H_L[parent_link_idx] @ L_H_C
|
558
|
+
W_H_CW = W_H_C.at[0:3, 0:3].set(jnp.eye(3))
|
559
|
+
CW_H_W = Transform.inverse(W_H_CW)
|
560
|
+
O_X_W = CW_X_W = Adjoint.from_transform(transform=CW_H_W)
|
561
|
+
with data.switch_velocity_representation(VelRepr.Mixed):
|
562
|
+
CW_v_WC = CW_J_WC_BW @ data.generalized_velocity()
|
563
|
+
W_v_W_CW = jnp.zeros(6).at[0:3].set(CW_v_WC[0:3])
|
564
|
+
W_vx_W_CW = Cross.vx(W_v_W_CW)
|
565
|
+
O_Ẋ_W = CW_Ẋ_W = -CW_X_W @ W_vx_W_CW # noqa: F841
|
566
|
+
|
567
|
+
case _:
|
568
|
+
raise ValueError(output_vel_repr)
|
569
|
+
|
570
|
+
O_J̇_WC_I = jnp.zeros(shape=(6, 6 + model.dofs()))
|
571
|
+
O_J̇_WC_I += O_Ẋ_W @ W_J_WL_W[parent_link_idx] @ T
|
572
|
+
O_J̇_WC_I += O_X_W @ W_J̇_WL_W[parent_link_idx] @ T
|
573
|
+
O_J̇_WC_I += O_X_W @ W_J_WL_W[parent_link_idx] @ Ṫ
|
574
|
+
|
575
|
+
return O_J̇_WC_I
|
576
|
+
|
577
|
+
O_J̇_WC = jax.vmap(compute_O_J̇_WC_I, in_axes=(0, 0, 0, None))(
|
578
|
+
L_p_Ci, contact_idxs, CW_J_WC_BW, W_H_Li
|
579
|
+
)
|
580
|
+
|
581
|
+
return O_J̇_WC
|
jaxsim/api/data.py
CHANGED
@@ -12,7 +12,6 @@ import jaxlie
|
|
12
12
|
import jaxsim.api as js
|
13
13
|
import jaxsim.rbda
|
14
14
|
import jaxsim.typing as jtp
|
15
|
-
from jaxsim.math import Quaternion
|
16
15
|
from jaxsim.rbda.contacts.soft import SoftContacts
|
17
16
|
from jaxsim.utils import Mutability
|
18
17
|
from jaxsim.utils.tracing import not_tracing
|
@@ -191,9 +190,7 @@ class JaxSimModelData(common.ModelDataWithVelocityRepresentation):
|
|
191
190
|
|
192
191
|
W_H_B = jaxlie.SE3.from_rotation_and_translation(
|
193
192
|
translation=base_position,
|
194
|
-
rotation=jaxlie.SO3
|
195
|
-
base_quaternion[jnp.array([1, 2, 3, 0])]
|
196
|
-
),
|
193
|
+
rotation=jaxlie.SO3(wxyz=base_quaternion),
|
197
194
|
).as_matrix()
|
198
195
|
|
199
196
|
v_WB = JaxSimModelData.other_representation_to_inertial(
|
@@ -380,13 +377,7 @@ class JaxSimModelData(common.ModelDataWithVelocityRepresentation):
|
|
380
377
|
on_false=W_Q_B / jnp.linalg.norm(W_Q_B),
|
381
378
|
)
|
382
379
|
|
383
|
-
return (
|
384
|
-
W_Q_B
|
385
|
-
if not dcm
|
386
|
-
else jaxlie.SO3.from_quaternion_xyzw(
|
387
|
-
Quaternion.to_xyzw(wxyz=W_Q_B)
|
388
|
-
).as_matrix()
|
389
|
-
).astype(float)
|
380
|
+
return (W_Q_B if not dcm else jaxlie.SO3(wxyz=W_Q_B).as_matrix()).astype(float)
|
390
381
|
|
391
382
|
@jax.jit
|
392
383
|
def base_transform(self) -> jtp.Matrix:
|
jaxsim/api/frame.py
CHANGED
@@ -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 # noqa: F841
|
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 # noqa: F841
|
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
|
jaxsim/api/link.py
CHANGED
@@ -288,7 +288,7 @@ def jacobian(
|
|
288
288
|
case VelRepr.Inertial:
|
289
289
|
W_H_B = data.base_transform()
|
290
290
|
B_X_W = Adjoint.from_transform(transform=W_H_B, inverse=True)
|
291
|
-
B_J_WL_I = B_J_WL_W = B_J_WL_B @ jax.scipy.linalg.block_diag(
|
291
|
+
B_J_WL_I = B_J_WL_W = B_J_WL_B @ jax.scipy.linalg.block_diag( # noqa: F841
|
292
292
|
B_X_W, jnp.eye(model.dofs())
|
293
293
|
)
|
294
294
|
|
@@ -299,7 +299,7 @@ def jacobian(
|
|
299
299
|
W_R_B = data.base_orientation(dcm=True)
|
300
300
|
BW_H_B = jnp.eye(4).at[0:3, 0:3].set(W_R_B)
|
301
301
|
B_X_BW = Adjoint.from_transform(transform=BW_H_B, inverse=True)
|
302
|
-
B_J_WL_I = B_J_WL_BW = B_J_WL_B @ jax.scipy.linalg.block_diag(
|
302
|
+
B_J_WL_I = B_J_WL_BW = B_J_WL_B @ jax.scipy.linalg.block_diag( # noqa: F841
|
303
303
|
B_X_BW, jnp.eye(model.dofs())
|
304
304
|
)
|
305
305
|
|
@@ -313,7 +313,7 @@ def jacobian(
|
|
313
313
|
case VelRepr.Inertial:
|
314
314
|
W_H_B = data.base_transform()
|
315
315
|
W_X_B = Adjoint.from_transform(transform=W_H_B)
|
316
|
-
O_J_WL_I = W_J_WL_I = W_X_B @ B_J_WL_I
|
316
|
+
O_J_WL_I = W_J_WL_I = W_X_B @ B_J_WL_I # noqa: F841
|
317
317
|
|
318
318
|
case VelRepr.Body:
|
319
319
|
L_X_B = Adjoint.from_transform(transform=B_H_L, inverse=True)
|
@@ -505,7 +505,7 @@ def jacobian_derivative(
|
|
505
505
|
with data.switch_velocity_representation(VelRepr.Body):
|
506
506
|
B_v_WB = data.base_velocity()
|
507
507
|
|
508
|
-
O_Ẋ_B = W_Ẋ_B = W_X_B @ jaxsim.math.Cross.vx(B_v_WB)
|
508
|
+
O_Ẋ_B = W_Ẋ_B = W_X_B @ jaxsim.math.Cross.vx(B_v_WB) # noqa: F841
|
509
509
|
|
510
510
|
case VelRepr.Body:
|
511
511
|
|
@@ -519,7 +519,9 @@ def jacobian_derivative(
|
|
519
519
|
B_v_WB = data.base_velocity()
|
520
520
|
L_v_WL = js.link.velocity(model=model, data=data, link_index=link_index)
|
521
521
|
|
522
|
-
O_Ẋ_B = L_Ẋ_B = -L_X_B @ jaxsim.math.Cross.vx(
|
522
|
+
O_Ẋ_B = L_Ẋ_B = -L_X_B @ jaxsim.math.Cross.vx( # noqa: F841
|
523
|
+
B_X_L @ L_v_WL - B_v_WB
|
524
|
+
)
|
523
525
|
|
524
526
|
case VelRepr.Mixed:
|
525
527
|
|
@@ -544,8 +546,9 @@ def jacobian_derivative(
|
|
544
546
|
LW_v_LW_L = LW_v_WL - LW_v_W_LW
|
545
547
|
LW_v_B_LW = LW_v_WL - LW_X_B @ B_v_WB - LW_v_LW_L
|
546
548
|
|
547
|
-
O_Ẋ_B = LW_Ẋ_B = -LW_X_B @ jaxsim.math.Cross.vx(
|
548
|
-
|
549
|
+
O_Ẋ_B = LW_Ẋ_B = -LW_X_B @ jaxsim.math.Cross.vx( # noqa: F841
|
550
|
+
B_X_LW @ LW_v_B_LW
|
551
|
+
)
|
549
552
|
case _:
|
550
553
|
raise ValueError(output_vel_repr)
|
551
554
|
|