Skip to content

Commit 241750f

Browse files
committed
Use reduce model in ABA
1 parent 8568e17 commit 241750f

File tree

1 file changed

+65
-45
lines changed

1 file changed

+65
-45
lines changed

src/adam/core/rbd_algorithms.py

+65-45
Original file line numberDiff line numberDiff line change
@@ -480,78 +480,98 @@ def aba(
480480
base_acceleration (T): The base acceleration in mixed representation
481481
joint_accelerations (T): The joints acceleration
482482
"""
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)
494484

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+
)
498491

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
503518

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)
505525

506526
# 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
509529

510530
v[i] = i_X_pi[i] @ v[pi] + v_J
511531
c[i] = i_X_pi[i] @ c[pi] + self.math.spatial_skew(v[i]) @ v_J
512532

513-
IA[i] = link_i.spatial_inertia()
533+
IA[i] = model.tree.get_node_from_name(joint.parent).link.spatial_inertia()
514534

515535
pA[i] = IA[i] @ c[i] + self.math.spatial_skew_star(v[i]) @ IA[i] @ v[i]
516536

517537
# 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)
528547

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]
532551

533552
Ia = IA[i] - U[i] / D[i] @ U[i].T
534553
pa = pA[i] + Ia @ c[i] + U[i] * u[i] / D[i]
535554

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+
536560
a[0] = B_X_W @ g if self.model.floating_base else self.math.solve(-IA[0], pA[0])
537561

538562
# 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:
543565
continue
544566

545-
pi = self.model.tree.get_idx_from_name(link_pi.name)
567+
pi = self.model.tree.get_idx_from_name(joint.parent)
546568

547569
sdd[i - 1] = (u[i] - U[i].T @ a[i]) / D[i]
548570

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]
550572

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])])
555575

556576
if (
557577
self.frame_velocity_representation

0 commit comments

Comments
 (0)