in differentiable_robot_model/robot_model.py [0:0]
def iterative_newton_euler(self, base_acc: SpatialMotionVec) -> None:
r"""
Args:
base_acc: spatial acceleration of base (for fixed manipulators this is zero)
"""
body = self._bodies[0]
body.acc = base_acc
# forward pass to propagate accelerations from root to end-effector link
for i in range(1, len(self._bodies)):
body = self._bodies[i]
parent_name = self._urdf_model.get_name_of_parent_body(body.name)
parent_body = self._bodies[self._name_to_idx_map[parent_name]]
# get the inverse of the current joint pose
inv_pose = body.joint_pose.inverse()
# transform spatial acceleration of parent body into this body's frame
acc_parent_body = parent_body.acc.transform(inv_pose)
# body velocity cross joint vel
tmp = body.vel.cross_motion_vec(body.joint_vel)
body.acc = acc_parent_body.add_motion_vec(body.joint_acc).add_motion_vec(
tmp
)
# reset all forces for backward pass
for i in range(0, len(self._bodies)):
self._bodies[i].force = SpatialForceVec(device=self._device)
# backward pass to propagate forces up (from endeffector to root body)
for i in range(len(self._bodies) - 1, 0, -1):
body = self._bodies[i]
joint_pose = body.joint_pose
# body force on joint
icxacc = body.inertia.multiply_motion_vec(body.acc)
icxvel = body.inertia.multiply_motion_vec(body.vel)
tmp_force = body.vel.cross_force_vec(icxvel)
body.force = body.force.add_force_vec(icxacc).add_force_vec(tmp_force)
# pose x body_force => propagate to parent
if i > 0:
parent_name = self._urdf_model.get_name_of_parent_body(body.name)
parent_body = self._bodies[self._name_to_idx_map[parent_name]]
backprop_force = body.force.transform(joint_pose)
parent_body.force = parent_body.force.add_force_vec(backprop_force)
return