@@ -480,78 +480,98 @@ def aba(
480
480
base_acceleration (T): The base acceleration in mixed representation
481
481
joint_accelerations (T): The joints acceleration
482
482
"""
483
- i_X_pi = self .math .factory .zeros (self .model .N , 6 , 6 )
484
- v = self .math .factory .zeros (self .model .N , 6 , 1 )
485
- c = self .math .factory .zeros (self .model .N , 6 , 1 )
486
- pA = self .math .factory .zeros (self .model .N , 6 , 1 )
487
- IA = self .math .factory .zeros (self .model .N , 6 , 6 )
488
- U = self .math .factory .zeros (self .model .N , 6 , 1 )
489
- D = self .math .factory .zeros (self .model .N , 1 , 1 )
490
- u = self .math .factory .zeros (self .model .N , 1 , 1 )
491
- a = self .math .factory .zeros (self .model .N , 6 , 1 )
492
- sdd = self .math .factory .zeros (self .model .N , 1 , 1 )
493
- B_X_W = self .math .adjoint_mixed_inverse (base_transform )
483
+ model = self .model .reduce (self .model .actuated_joints )
494
484
495
- # Pass 1
496
- for i , node in enumerate (self .model .tree ):
497
- link_i , joint_i , link_pi = node .get_elements ()
485
+ joints = list (
486
+ filter (
487
+ lambda joint : joint .name in self .model .actuated_joints ,
488
+ self .model .joints .values (),
489
+ )
490
+ )
498
491
499
- if link_i .name == self .root_link :
500
- continue
501
- q = joint_positions [joint_i .idx ] if joint_i .idx is not None else 0.0
502
- q_dot = joint_velocities [joint_i .idx ] if joint_i .idx is not None else 0.0
492
+ joints .sort (key = lambda joint : joint .idx )
493
+
494
+ NB = model .N
495
+
496
+ i_X_pi = self .math .factory .zeros (NB , 6 , 6 )
497
+ v = self .math .factory .zeros (NB , 6 , 1 )
498
+ c = self .math .factory .zeros (NB , 6 , 1 )
499
+ pA = self .math .factory .zeros (NB , 6 , 1 )
500
+ IA = self .math .factory .zeros (NB , 6 , 6 )
501
+ U = self .math .factory .zeros (NB , 6 , 1 )
502
+ D = self .math .factory .zeros (NB , 1 , 1 )
503
+ u = self .math .factory .zeros (NB , 1 , 1 )
504
+
505
+ a = self .math .factory .zeros (NB , 6 , 1 )
506
+ sdd = self .math .factory .zeros (NB , 1 , 1 )
507
+ B_X_W = self .math .adjoint_mixed (base_transform )
508
+
509
+ if self .model .floating_base :
510
+ IA [0 ] = self .model .tree .get_node_from_name (
511
+ self .root_link
512
+ ).link .spatial_inertia ()
513
+ v [0 ] = B_X_W @ base_velocity
514
+ pA [0 ] = (
515
+ self .math .spatial_skew_star (v [0 ]) @ IA [0 ] @ v [0 ]
516
+ ) # - self.math.adjoint_inverse(B_X_W).T @ f_ext[0]
517
+ tree_transform = self .model .tree
503
518
504
- pi = self .model .tree .get_idx_from_name (link_pi .name )
519
+ # Pass 1
520
+ for i , joint in enumerate (joints [1 :], start = 1 ):
521
+ q = joint_positions [i ]
522
+ q_dot = joint_velocities [i ]
523
+
524
+ pi = model .tree .get_idx_from_name (joint .parent )
505
525
506
526
# Parent-child transform
507
- i_X_pi [i ] = joint_i .spatial_transform (q )
508
- v_J = joint_i .motion_subspace () * q_dot
527
+ i_X_pi [i ] = joint .spatial_transform (q )
528
+ v_J = joint .motion_subspace () * q_dot
509
529
510
530
v [i ] = i_X_pi [i ] @ v [pi ] + v_J
511
531
c [i ] = i_X_pi [i ] @ c [pi ] + self .math .spatial_skew (v [i ]) @ v_J
512
532
513
- IA [i ] = link_i .spatial_inertia ()
533
+ IA [i ] = model . tree . get_node_from_name ( joint . parent ). link .spatial_inertia ()
514
534
515
535
pA [i ] = IA [i ] @ c [i ] + self .math .spatial_skew_star (v [i ]) @ IA [i ] @ v [i ]
516
536
517
537
# Pass 2
518
- for i , node in reversed (list (enumerate (self .model .tree ))):
519
- link_i , joint_i , link_pi = node .get_elements ()
520
-
521
- if link_i .name == self .root_link :
522
- IA [pi ] += i_X_pi [i ].T @ Ia @ i_X_pi [i ]
523
- pA [pi ] += i_X_pi [i ].T @ pa
524
- continue
525
-
526
- pi = self .model .tree .get_idx_from_name (link_pi .name )
527
- tau_i = tau [joint_i .idx ] if joint_i .idx is not None else 0.0
538
+ for i , joint in reversed (
539
+ list (
540
+ enumerate (
541
+ joints [1 :],
542
+ start = 1 ,
543
+ )
544
+ )
545
+ ):
546
+ pi = self .model .tree .get_idx_from_name (joint .parent )
528
547
529
- U [i ] = IA [i ] @ joint_i .motion_subspace ()
530
- D [i ] = joint_i .motion_subspace ().T @ U [i ]
531
- u [i ] = self .math .vertcat (tau_i ) - joint_i .motion_subspace ().T @ pA [i ]
548
+ U [i ] = IA [i ] @ joint .motion_subspace ()
549
+ D [i ] = joint .motion_subspace ().T @ U [i ]
550
+ u [i ] = self .math .vertcat (tau [ joint . idx ] ) - joint .motion_subspace ().T @ pA [i ]
532
551
533
552
Ia = IA [i ] - U [i ] / D [i ] @ U [i ].T
534
553
pa = pA [i ] + Ia @ c [i ] + U [i ] * u [i ] / D [i ]
535
554
555
+ if joint .parent != self .root_link or not self .model .floating_base :
556
+ IA [pi ] += i_X_pi [i ].T @ Ia @ i_X_pi [i ]
557
+ pA [pi ] += i_X_pi [i ].T @ pa
558
+ continue
559
+
536
560
a [0 ] = B_X_W @ g if self .model .floating_base else self .math .solve (- IA [0 ], pA [0 ])
537
561
538
562
# Pass 3
539
- for i , node in enumerate (self .model .tree ):
540
- link_i , joint_i , link_pi = node .get_elements ()
541
-
542
- if link_i .name == self .root_link :
563
+ for i , joint in enumerate (joints [1 :], start = 1 ):
564
+ if joint .parent == self .root_link :
543
565
continue
544
566
545
- pi = self .model .tree .get_idx_from_name (link_pi . name )
567
+ pi = self .model .tree .get_idx_from_name (joint . parent )
546
568
547
569
sdd [i - 1 ] = (u [i ] - U [i ].T @ a [i ]) / D [i ]
548
570
549
- a [i ] += i_X_pi [i ].T @ a [pi ] + joint_i .motion_subspace () * sdd [i - 1 ] + c [i ]
571
+ a [i ] += i_X_pi [i ].T @ a [pi ] + joint .motion_subspace () * sdd [i - 1 ] + c [i ]
550
572
551
- # Filter sdd to remove NaNs generate with lumped joints
552
- s_ddot = self .math .vertcat (
553
- * [sdd [i ] for i in range (self .model .N ) if sdd [i ] == sdd [i ]]
554
- )
573
+ # Squeeze sdd
574
+ s_ddot = self .math .vertcat (* [sdd [i ] for i in range (sdd .shape [0 ])])
555
575
556
576
if (
557
577
self .frame_velocity_representation
0 commit comments