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 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.1.dev24'
16
- __version_tuple__ = version_tuple = (0, 4, 1, 'dev24')
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.from_quaternion_xyzw(
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(B_X_L @ L_v_WL - B_v_WB)
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(B_X_LW @ LW_v_B_LW)
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