@@ -462,7 +462,7 @@ def aba(
462
462
base_transform : npt .ArrayLike ,
463
463
joint_positions : npt .ArrayLike ,
464
464
joint_velocities : npt .ArrayLike ,
465
- joint_torques : npt .ArrayLike ,
465
+ tau : npt .ArrayLike ,
466
466
g : npt .ArrayLike ,
467
467
) -> npt .ArrayLike :
468
468
"""Implementation of Articulated Body Algorithm
@@ -483,24 +483,27 @@ def aba(
483
483
c = self .math .factory .zeros (self .model .N , 6 , 1 )
484
484
pA = self .math .factory .zeros (self .model .N , 6 , 1 )
485
485
IA = self .math .factory .zeros (self .model .N , 6 , 6 )
486
- U = self .math .factory .zeros (self .model .N , 6 , 6 )
487
- D = self .math .factory .zeros (self .model .N , 6 , 6 )
488
- u = self .math .factory .zeros (self .model .N , 6 , 1 )
486
+ U = self .math .factory .zeros (self .model .N , 6 , 1 )
487
+ D = self .math .factory .zeros (self .model .N , 1 , 1 )
488
+ u = self .math .factory .zeros (self .model .N , 1 , 1 )
489
489
a = self .math .factory .zeros (self .model .N , 6 , 1 )
490
- f = self .math .factory .zeros (self .model .N , 6 , 1 )
490
+ sdd = self .math .factory .zeros (self .model .N , 1 , 1 )
491
+ B_X_W = self .math .adjoint_mixed_inverse (base_transform )
491
492
492
493
# Pass 1
493
494
for i , node in enumerate (self .model .tree ):
494
495
link_i , joint_i , link_pi = node .get_elements ()
495
496
496
497
if link_i .name == self .root_link :
497
498
continue
499
+ q = joint_positions [joint_i .idx ] if joint_i .idx is not None else 0.0
500
+ q_dot = joint_velocities [joint_i .idx ] if joint_i .idx is not None else 0.0
498
501
499
502
pi = self .model .tree .get_idx_from_name (link_pi .name )
500
503
501
504
# Parent-child transform
502
- i_X_pi [i ] = joint_i .spatial_transform (joint_positions [ i ] )
503
- v_J = joint_i .motion_subspace () * joint_velocities [ i ]
505
+ i_X_pi [i ] = joint_i .spatial_transform (q )
506
+ v_J = joint_i .motion_subspace () * q_dot
504
507
505
508
v [i ] = i_X_pi [i ] @ v [pi ] + v_J
506
509
c [i ] = i_X_pi [i ] @ c [pi ] + self .math .spatial_skew (v [i ]) @ v_J
@@ -519,26 +522,47 @@ def aba(
519
522
continue
520
523
521
524
pi = self .model .tree .get_idx_from_name (link_pi .name )
525
+ tau_i = tau [joint_i .idx ] if joint_i .idx is not None else 0.0
522
526
523
- U [i ] = IA [i ] @ node . joint .motion_subspace ()
524
- D [i ] = node . joint .motion_subspace ().T @ U [i ]
525
- u [i ] = tau [ i ] - node . joint .motion_subspace ().T @ pA [i ]
527
+ U [i ] = IA [i ] @ joint_i .motion_subspace ()
528
+ D [i ] = joint_i .motion_subspace ().T @ U [i ]
529
+ u [i ] = self . math . vertcat ( tau_i ) - joint_i .motion_subspace ().T @ pA [i ]
526
530
527
531
Ia = IA [i ] - U [i ] / D [i ] @ U [i ].T
528
532
pa = pA [i ] + Ia @ c [i ] + U [i ] * u [i ] / D [i ]
529
533
534
+ a [0 ] = B_X_W @ g if self .model .floating_base else self .math .solve (- IA [0 ], pA [0 ])
535
+
530
536
# Pass 3
531
537
for i , node in enumerate (self .model .tree ):
532
538
link_i , joint_i , link_pi = node .get_elements ()
533
539
534
540
if link_i .name == self .root_link :
535
- IA [pi ] += i_X_pi [i ].T @ Ia @ i_X_pi [i ]
536
- pA [pi ] += i_X_pi [i ].T @ pa
541
+ continue
537
542
538
543
pi = self .model .tree .get_idx_from_name (link_pi .name )
539
544
540
- sdd = (u [i ] - U [i ].T @ a [i ]) / D [i ]
545
+ sdd [i - 1 ] = (u [i ] - U [i ].T @ a [i ]) / D [i ]
546
+
547
+ a [i ] += i_X_pi [i ].T @ a [pi ] + joint_i .motion_subspace () * sdd [i - 1 ] + c [i ]
548
+
549
+ # Filter sdd to remove NaNs generate with lumped joints
550
+ s_ddot = self .math .vertcat (
551
+ * [sdd [i ] for i in range (self .model .N ) if sdd [i ] == sdd [i ]]
552
+ )
541
553
542
- a [i ] = i_X_pi [i ].T @ a [pi ] + node .joint .motion_subspace () * sdd + c [i ]
554
+ if (
555
+ self .frame_velocity_representation
556
+ == Representations .BODY_FIXED_REPRESENTATION
557
+ ):
558
+ return a [0 ], s_ddot
543
559
544
- return a , sdd
560
+ elif self .frame_velocity_representation == Representations .MIXED_REPRESENTATION :
561
+ return (
562
+ self .math .vertcat (
563
+ self .math .solve (B_X_W , a [0 ]) + g
564
+ if self .model .floating_base
565
+ else self .math .zeros (6 , 1 ),
566
+ ),
567
+ s_ddot ,
568
+ )
0 commit comments